1. 设备驱动加载及系统配置
关于sensor的开发环境、MPP的工作原理、ISP简介等可参考shugenyin的博客——海思Hi3518EV200。
cd ko ./load3516a -a -sensor sc3035 -osmem 64
在load脚本中添加sensor的相关配置,这里使用smartsens的SC3035-M的360万像素CMOS sensor。
insert_sns() { case $SNS_TYPE in sc3035) himm 0x200f0050 0x2; # i2c0_scl himm 0x200f0054 0x2; # i2c0_sda himm 0x2003002c 0xB0007 # sensolsr unreset, clk 27MHz, VI 250MHz ;; *) echo "xxxx Invalid sensor type $SNS_TYPE xxxx" report_error ;; esac }
2. sensor的库文件生成(.so)
sensor的库文件需要在Linux服务器中的SDK包中编译得到,将生成的.so文件放到SDK包中的stream软件包中的Hi3516A_Stream_xxx/libs目录下。
sc3035_sensor_ctl.c实现sensor的初始化。
void sensor_init() { sensor_i2c_init(); sensor_init_3M_1536p_4lan(); } void sensor_init_3M_1536p_4lan() { sensor_write_register(0x0100,0x00); sensor_write_register(0x4500,0x31);// rnc sel sensor_write_register(0x3416,0x11); sensor_write_register(0x4501,0xa4);// bit ctrl sensor_write_register(0x3e03,0x03);// aec sensor_write_register(0x3e08,0x00); sensor_write_register(0x3e09,0x10); sensor_write_register(0x3e01,0x30); sensor_write_register(0x322e,0x00); sensor_write_register(0x322f,0xaf); sensor_write_register(0x3306,0x56); sensor_write_register(0x3307,0x17); sensor_write_register(0x330b,0x54); sensor_write_register(0x3303,0x20); sensor_write_register(0x3309,0x20); sensor_write_register(0x3308,0x08); sensor_write_register(0x331e,0x16); sensor_write_register(0x331f,0x16); sensor_write_register(0x3320,0x18); sensor_write_register(0x3321,0x18); sensor_write_register(0x3322,0x18); sensor_write_register(0x3323,0x18); sensor_write_register(0x330c,0x0b); sensor_write_register(0x330f,0x07); sensor_write_register(0x3310,0x42); sensor_write_register(0x3324,0x07); sensor_write_register(0x3325,0x07); sensor_write_register(0x335b,0xca); sensor_write_register(0x335e,0x07); sensor_write_register(0x335f,0x10); sensor_write_register(0x3334,0x00); sensor_write_register(0x3F01,0x04); sensor_write_register(0x3F04,0x01); sensor_write_register(0x3F05,0x30); sensor_write_register(0x3626,0x01); sensor_write_register(0x3635,0x60); sensor_write_register(0x3631,0x84); sensor_write_register(0x3636,0x88); sensor_write_register(0x3633,0x3f); sensor_write_register(0x3639,0x80); sensor_write_register(0x3622,0x12); sensor_write_register(0x3627,0x02); sensor_write_register(0x3038,0xa4); sensor_write_register(0x3621,0x18); sensor_write_register(0x363a,0x1c); sensor_write_register(0x3637,0xbe); sensor_write_register(0x3638,0x85); sensor_write_register(0x363c,0x48);// ramp cur sensor_write_register(0x5780,0xff);// dpc sensor_write_register(0x5781,0x04); sensor_write_register(0x5785,0x10); sensor_write_register(0x301e,0xe0);// [4] 0:close tempsens sensor_write_register(0x3662,0x82); sensor_write_register(0x3d0d,0x00);// close random code sensor_write_register(0x3039,0x20); sensor_write_register(0x303a,0x38);//74.25M pclk sensor_write_register(0x303b,0x00); sensor_write_register(0x3306,0x56); sensor_write_register(0x330b,0xc0); sensor_write_register(0x3038,0xf8);//pump clk div sensor_write_register(0x320c,0x04); //hts=2500 sensor_write_register(0x320d,0xe2); sensor_write_register(0x320e,0x06); //vts=1584 sensor_write_register(0x320f,0x30); sensor_write_register(0x3202,0x00);// ystart=48 sensor_write_register(0x3203,0x00); sensor_write_register(0x3206,0x06);// yend=1545 1545 rows selected sensor_write_register(0x3207,0x08); sensor_write_register(0x3200,0x00);// xstart= 136 sensor_write_register(0x3201,0x88); sensor_write_register(0x3204,0x09);// xend = 2447 2312 cols selected sensor_write_register(0x3205,0x8f); sensor_write_register(0x3211,0x04); // xstart sensor_write_register(0x3213,0x04); // ystart sensor_write_register(0x3208,0x09); //2304x1536 sensor_write_register(0x3209,0x00); sensor_write_register(0x320a,0x06); sensor_write_register(0x320b,0x00); sensor_write_register(0x3312,0x06);// sa1 timing sensor_write_register(0x3340,0x04); sensor_write_register(0x3341,0xd2); sensor_write_register(0x3342,0x01); sensor_write_register(0x3343,0xb0); sensor_write_register(0x335d,0x2a);// cmp timing sensor_write_register(0x3348,0x04); sensor_write_register(0x3349,0xd2); sensor_write_register(0x334a,0x01); sensor_write_register(0x334b,0xb0); sensor_write_register(0x3368,0x03);// auto precharge sensor_write_register(0x3369,0x30); sensor_write_register(0x336a,0x06); sensor_write_register(0x336b,0x30); sensor_write_register(0x3367,0x05); sensor_write_register(0x330e,0x17); sensor_write_register(0x3d08,0x00);// pclk inv sensor_write_register(0x303f,0x82); sensor_write_register(0x3c03,0x10);//fifo sram read position sensor_write_register(0x3c00,0x45);// Dig SRAM reset sensor_write_register(0x3630,0x83);//0xb9 sensor_write_register(0x3635,0x60);//0x66 sensor_write_register(0x3620,0x62);//0x82 sensor_write_register(0x3c00,0x00);//[2]: 0 mipi->fifo sensor_write_register(0x303f,0x02);//[7]: 0 sel pll_pclk sensor_write_register(0x3031,0x0a);//[3:0] 10bit sensor_write_register(0x3018,0x73);//[7:5] sel lane=reg+1 sensor_write_register(0x3030,0x14); sensor_write_register(0x3039,0x21); sensor_write_register(0x303a,0x0F); sensor_write_register(0x303b,0x06); sensor_write_register(0x303c,0x38); sensor_write_register(0x3650,0x46); sensor_write_register(0x0100,0x01); printf("SC3035 sensor 3M-1536p 30fps init success!\n"); }
sc3035_cmos.c主要实现ISP需要的回调函数,传递参数,包括ISP、AE、AWB等。
//ISP function HI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) { memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); pstSensorExpFunc->pfn_cmos_sensor_init = sensor_init; pstSensorExpFunc->pfn_cmos_sensor_exit = sensor_exit; pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; pstSensorExpFunc->pfn_cmos_set_p_w_picpath_mode = cmos_set_p_w_picpath_mode; pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_isp_black_level; pstSensorExpFunc->pfn_cmos_set_pixel_detect = cmos_set_pixel_detect; pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; return 0; } //AE function HI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) { memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; pstExpFuncs->pfn_cmos_slow_framerate_set= cmos_slow_framerate_set; pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; return 0; } //AWB function HI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) { memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; return 0; }
3. 修改stream软件包的.ini文件
sc3035_3m_4lan.ini文件在Hi3516A_Stream_xxx/configs目录下,改文件主要指定.so文件的位置、输入视频的接口(LVDS/MIPI/DVP)、视频格式(分辨率、同步方式、目标帧率等)等系统配置。
[sensor] Sensor_type =sc3035 ;sensor name Mode =0 ;WDR_MODE_NONE = 0 ;WDR_MODE_BUILT_IN = 1 ;WDR_MODE_2To1_LINE = 2 ;WDR_MODE_2To1_FRAME = 3 ;WDR_MODE_2To1_FRAME_FULL_RATE =4 ...etc DllFile =libs/libsns_sc3035_4lan.so ;sensor lib path [mode] input_mode =0 ;INPUT_MODE_MIPI = 0 ;INPUT_MODE_SUBLVDS = 1 ;INPUT_MODE_LVDS = 2 ...etc dev_attr = 0 ;mipi_dev_attr_t = 0 ;lvds_dev_attr_t = 1 ;NULL =2 [mipi] ;----------only for mipi_dev--------- data_type = 1 ;raw data type: 8/10/12/14 bit ;RAW_DATA_8BIT = 0 ;RAW_DATA_10BIT = 1 ;RAW_DATA_12BIT = 2 ;RAW_DATA_14BIT = 3 lane_id = 0| 1 | 2 | 3 |-1|-1|-1|-1| ;lane_id: -1 - disable [isp_p_w_picpath] Isp_x =0 Isp_y =0 Isp_W =2304 Isp_H =1536 Isp_FrameRate=30 Isp_Bayer =3 ;BAYER_RGGB=0, BAYER_GRBG=1, BAYER_GBRG=2, BAYER_BGGR=3
4. 运行stream软件
运行stream软件包中的HiIspTool.sh脚本,通过以太网卡与上位机的PQTools建立通信。
cd Hi3516A_Stream_V1.0.5.0 ./HiIspTools.sh -a -p sc3035_3m_4lan.ini
ittb_control进程是基于TCP的服务端,负责控制信号的传输。
ittb_stream进程也是基于TCP的服务端,负责播放H.265或YUV视频流。
5. 运行PQ Tools
双击PQ Tools图片,弹出如下对话框,设置IP地址。
在下拉菜单中选择TTP_Stream.exe选项
6. 最终结果
上位机显示视频结果,图像分辨率为2304*1536,帧率为30。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。