海思Hi3516A(3)图像sensor驱动开发

简介:

1. 设备驱动加载及系统配置

关于sensor的开发环境、MPP的工作原理、ISP简介等可参考shugenyin的博客——海思Hi3518EV200。

1
2
cd  ko
. /load3516a  -a -sensor sc3035 -osmem 64

在load脚本中添加sensor的相关配置,这里使用smartsens的SC3035-M的360万像素CMOS sensor。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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目录下。

wKiom1fqDVnwo6s8AADLefhHtRE231.jpg

sc3035_sensor_ctl.c实现sensor的初始化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//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_image_mode = cmos_set_image_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)、视频格式(分辨率、同步方式、目标帧率等)等系统配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[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_image]
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建立通信。

1
2
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地址。

wKioL1fqEO-TKNnHAABUKKjyqaw591.jpg

在下拉菜单中选择TTP_Stream.exe选项

wKioL1fqERCjQM7uAAHVzmAgmqI307.jpg


6. 最终结果

上位机显示视频结果,图像分辨率为2304*1536,帧率为30。

wKiom1fqEYXRtkK1AAGJPV5TMI0216.jpg


本文转自 shugenyin 51CTO博客,原文链接:http://blog.51cto.com/shugenyin/1856959

相关文章
|
传感器 存储 定位技术
一起玩转树莓派(18)——MPU6050陀螺仪加速度传感器模块应用
现在智能手机的功能已经非常强大,除了基础的通信功能外,测位测速,空间角度等数据的测量也非常方便,这在线路导航,地图,体感游戏等应用中十分重要。不知你是否想过,智能设备是如何获取到其所在的空间状态与加速度等数据的呢?MPU6050就是提供这类数据测量的一种传感器模块。
1896 0
|
6月前
|
传感器 Linux
Linux驱动基础(SR501人体感应模块)
Linux驱动基础(SR501人体感应模块)
57 0
|
10月前
|
物联网 芯片
国产MCU-CW32F030开发学习-OLED模块
国产MCU-CW32F030开发学习-OLED模块
65 0
国产MCU-CW32F030开发学习-OLED模块
|
11月前
|
传感器 开发框架 API
【HaaS Python 硬件积木】 BMP280气压传感器
【HaaS Python 硬件积木】 BMP280气压传感器
201 0
|
传感器 API
HarmonyOS系统中内核实现三轴加速度检测方法
大家好,今天主要和大家聊一聊,如何使用鸿蒙系统读取三轴加速度的方法。
121 0
HarmonyOS系统中内核实现三轴加速度检测方法
|
存储 算法 API
HarmonyOS系统中内核实现ADC采样的方法
大家好,今天主要和大家聊一聊,如何使用鸿蒙系统实现ADC采样。
153 0
HarmonyOS系统中内核实现ADC采样的方法
|
编解码 人工智能 物联网
透过ALSA这层迷雾剖析AliOS Things音频框架设计
ALSA是Advanced Linux Sound Architecture的缩写,即高级Linux音频架构,在Linux上提供了对音频和MIDI(较少使用)的支持。在Linux 2.6的内核版本后,AlSA目前已经成为了linux的主流音频体系结构。
透过ALSA这层迷雾剖析AliOS Things音频框架设计
|
人工智能 机器人 云计算
Xilinx Zynq-7015 SoC工业级核心板 SOM-XQ7Z15 Cortex-A9 + Artix-7
SOM-XQ7Z15是广州星嵌电子科技有限公司新推出的一款基于Xilinx Zynq-7000系列XC7Z015高性能低功耗处理器设计的异构多核工业级核心板,处理器集成PS端单/双核ARM Cortex-A9 + PL端Artix-7架构28nm可编程逻辑资源、最大频率766MHz,支持6.25G的高速SerDes,可支持PCIe、SATA、SFP等。
Xilinx Zynq-7015 SoC工业级核心板 SOM-XQ7Z15 Cortex-A9 + Artix-7
|
数据采集 传感器 监控
SOM-XQ6657Z45工业级核心板DSP+ARM+FPGA C6657 ZYNQ7035/45
一款基于TI KeyStone 架构C6000 系列TMS320C6657 双核C66x定点/浮点DSP以及Xilinx Zynq-7000 系列XC7Z035/045 SoC 处理器设计的工业级核心板。
SOM-XQ6657Z45工业级核心板DSP+ARM+FPGA C6657 ZYNQ7035/45