平台信息:
内核:linux3.0.68
系统:android/android6.0
平台:RK3288
作者:庄泽彬(欢迎转载,请注明作者)
邮箱:2760715357@qq.com
说明:通过I2C总线获取摄像头的ID号。
一、查看规格书,确定摄像头存放ID号的寄存器地址.
二、应用层通过I2C总线的编程模型获取摄像头的Sensor ID.详细的代码如下:
camera.cpp
1 #include <sys/types.h> 2 #include <sys/stat.h> 3 #include <fcntl.h> 4 #include <stdlib.h> 5 #include <stdio.h> 6 #include <fcntl.h> /* Definition of AT_* constants */ 7 #include <unistd.h> 8 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <unistd.h> 13 #include <time.h> 14 #include <fcntl.h> 15 #include <dlfcn.h> 16 #include <sys/ioctl.h> 17 #include <sys/mman.h> 18 #include <sys/stat.h> 19 20 #include <sys/types.h> 21 #include <sys/stat.h> 22 #include <sys/file.h> 23 #include <string.h> 24 #include <pthread.h> 25 //#include <linux/videodev.h> 26 #include <sys/ioctl.h> 27 #include <sys/mman.h> 28 #include <errno.h> 29 #include <fcntl.h> 30 #include <time.h> 31 #include <sys/time.h> 32 #include <signal.h> 33 //#include <linux/ion.h> 34 //#include "ion.h" 35 #include "../../system/core/libion/kernel-headers/linux/rockchip_ion.h" 36 //#include <linux/android_pmem.h> 37 #include <linux/videodev2.h> 38 #include <linux/fb.h> 39 #include <linux/version.h> 40 41 #include "camsys_head.h" 42 43 #define CAMSYS_DEVNAME "/dev/camsys_marvin" 44 45 46 47 static int camsys_fd = -1; 48 49 //hkw add; 50 int extdev_register() 51 { 52 int err = 0; 53 int numLane = 2; 54 camsys_devio_name_t extdev; 55 56 extdev.dev_id = CAMSYS_DEVID_SENSOR_1B; 57 strlcpy((char*)extdev.avdd.name, "NC",sizeof(extdev.avdd.name)); 58 extdev.avdd.min_uv = 0; 59 extdev.avdd.max_uv = 0; 60 strlcpy((char*)extdev.dovdd.name,"NC",sizeof(extdev.dovdd.name)); 61 extdev.dovdd.min_uv = 18000000; 62 extdev.dovdd.max_uv = 18000000; 63 strlcpy((char*)extdev.dvdd.name, "NC",sizeof(extdev.dvdd.name)); 64 strlcpy((char*)extdev.afvdd.name, "NC",sizeof(extdev.afvdd.name)); 65 strlcpy((char*)extdev.pwrdn.name, "RK30_PIN2_PB7",sizeof(extdev.pwrdn.name)); 66 extdev.pwrdn.active = 0x00; 67 strlcpy((char*)extdev.pwren.name, "RK30_PIN0_PC1",sizeof(extdev.pwren.name)); 68 extdev.pwren.active = 0x01; 69 strlcpy((char*)extdev.rst.name,"RK30_PIN2_PB5",sizeof(extdev.rst.name)); 70 extdev.rst.active = 0x0; 71 strlcpy((char*)extdev.afpwrdn.name,"NC",sizeof(extdev.afpwrdn.name)); 72 strlcpy((char*)extdev.afpwr.name,"NC",sizeof(extdev.afpwr.name)); 73 extdev.phy.type = CamSys_Phy_Mipi; 74 //extdev.phy.info.mipi.phy_index = 1; //MIPI_PHY_INDEX; 75 extdev.phy.info.mipi.data_en_bit = 0x01; //? 76 77 /*if (numLane == 1) { 78 extdev.phy.info.mipi.data_en_bit = 0x01; 79 extdev.phy.info.mipi.bit_rate = 656; 80 } else if (numLane == 2) { 81 extdev.phy.info.mipi.data_en_bit = 0x03; 82 extdev.phy.info.mipi.bit_rate = 328; 83 } else if (numLane == 4) { 84 extdev.phy.info.mipi.data_en_bit = 0x0f; 85 extdev.phy.info.mipi.bit_rate = 408; 86 }*/ 87 extdev.clk.in_rate = 24000000; 88 89 printf("----CAMSYS_REGISTER_DEVIO---- "); 90 err = ioctl(camsys_fd, CAMSYS_REGISTER_DEVIO, &extdev); 91 if (err<0) { 92 printf("CAMSYS_REGISTER_DEVIO failed "); 93 } 94 95 return err; 96 } 97 98 //int extdev_init(unsigned int *i2cbase) 99 int extdev_init() 100 { 101 int err,i2cbytes,i; 102 struct rk_sensor_reg *sensor_reg; 103 unsigned char *i2cchar; 104 camsys_sysctrl_t sysctl; 105 camsys_i2c_info_t i2cinfo; 106 int id = 0; 107 108 sysctl.dev_mask = (CAMSYS_DEVID_SENSOR_1B & HAL_DEVID_EXTERNAL); 109 sysctl.ops = CamSys_Avdd; 110 sysctl.on = 1; 111 err = ioctl(camsys_fd, CAMSYS_SYSCTRL, &sysctl); 112 if (err<0) { 113 printf("CamSys_Avdd on failed!"); 114 } 115 116 sysctl.ops = CamSys_Dvdd; 117 sysctl.on = 1; 118 err = ioctl(camsys_fd, CAMSYS_SYSCTRL, &sysctl); 119 if (err<0) { 120 printf("CamSys_Dvdd on failed! "); 121 } 122 123 sysctl.ops = CamSys_Dovdd; 124 sysctl.on = 1; 125 err = ioctl(camsys_fd, CAMSYS_SYSCTRL, &sysctl); 126 if (err<0) { 127 printf("CamSys_Dovdd on failed!"); 128 } 129 usleep(5000); 130 131 sysctl.dev_mask = (CAMSYS_DEVID_SENSOR_1B | CAMSYS_DEVID_MARVIN); 132 sysctl.ops = CamSys_ClkIn; 133 sysctl.on = 1; 134 err = ioctl(camsys_fd, CAMSYS_SYSCTRL, &sysctl); 135 if (err<0) { 136 printf("CamSys_ClkIn on failed "); 137 } 138 139 //1)power en 140 usleep(1000); 141 sysctl.dev_mask = (CAMSYS_DEVID_SENSOR_1B & HAL_DEVID_EXTERNAL); 142 sysctl.ops = CamSys_PwrEn; 143 sysctl.on = 1; 144 err = ioctl(camsys_fd, CAMSYS_SYSCTRL, &sysctl); 145 if (err<0) { 146 printf("CamSys_PwrEn on failed"); 147 } 148 149 //2)reset 150 usleep(1000); 151 sysctl.ops = CamSys_Rst; 152 sysctl.on = 0; 153 err = ioctl(camsys_fd, CAMSYS_SYSCTRL, &sysctl); 154 if (err<0) { 155 printf("CamSys_Rst on failed "); 156 } 157 158 //3)power down control 159 usleep(1000); 160 //sysctl.dev_mask = CAMSYS_DEVID_SENSOR_1B; 161 sysctl.ops = CamSys_PwrDn; 162 sysctl.on = 0; 163 err = ioctl(camsys_fd, CAMSYS_SYSCTRL, &sysctl); 164 if (err<0) { 165 printf("CamSys_PwrDn on failed"); 166 } 167 usleep(2000); 168 169 i2cinfo.bus_num = 3; 170 i2cinfo.slave_addr = 0x6C; //0x6c; //0x20; 171 i2cinfo.reg_addr = 0x0103; 172 i2cinfo.reg_size = 2; 173 i2cinfo.val = 0x01; 174 i2cinfo.val_size = 0x01; 175 i2cinfo.i2cbuf_directly = 0; 176 i2cinfo.speed = 100000; 177 178 err = ioctl(camsys_fd, CAMSYS_I2CWR, &i2cinfo); 179 if(err<0) { 180 printf("softreset::CAMSYS_I2CWR failed "); 181 i2cinfo.slave_addr = 0x20; 182 err = ioctl(camsys_fd, CAMSYS_I2CWR, &i2cinfo); 183 if(err<0){ 184 printf("softreset again::CAMSYS_I2CWR failed "); 185 printf("zhuang:{ ID:0x%x } ",id); 186 goto end; 187 } 188 }/* else { 189 printf("I2c write: 0x%x : 0x%x ",i2cinfo.reg_addr,i2cinfo.val); 190 }*/ 191 192 usleep(5000); 193 194 i2cinfo.reg_addr = 0x300a; 195 i2cinfo.val_size = 0x01; 196 err = ioctl(camsys_fd, CAMSYS_I2CRD, &i2cinfo); 197 if (err<0) { 198 printf("CAMSYS_I2CRD failed "); 199 printf("zhuang:{ ID:0x%x } ",id); 200 goto end; 201 } else { 202 printf("I2c read: 0x%x : 0x%x ",i2cinfo.reg_addr,i2cinfo.val); 203 id = (i2cinfo.val<<8); 204 } 205 206 i2cinfo.reg_addr = 0x300b; 207 err = ioctl(camsys_fd, CAMSYS_I2CRD, &i2cinfo); 208 if (err<0) { 209 printf("CAMSYS_I2CRD failed "); 210 printf("{ ID:0x%x } ",id); 211 goto end; 212 } else { 213 printf("I2c read: 0x%x : 0x%x ",i2cinfo.reg_addr,i2cinfo.val); 214 id |= i2cinfo.val; 215 } 216 217 i2cinfo.reg_addr = 0x3011; 218 err = ioctl(camsys_fd, CAMSYS_I2CRD, &i2cinfo); 219 if (err<0) { 220 printf("CAMSYS_I2CRD failed "); 221 printf("{ ID:0x%x } ",id); 222 goto end; 223 } else { 224 printf("IO Streng I2c read: 0x%x : 0x%x ",i2cinfo.reg_addr,i2cinfo.val); 225 } 226 fprintf(stderr,"zhuang-cam:0x%x ",id); 227 printf(" !!!!!!!!!!Back Camera ID: 0x%x; default:0x008858!!!!!!!!!! ",id); 228 if(id == 0x5648){ 229 printf("{ ID:0x%x } ",id); 230 }else{ 231 printf("{ ID:0x%x } ",id); 232 } 233 /* 234 i2cinfo.reg_addr = 0x300c; 235 err = ioctl(camsys_fd, CAMSYS_I2CRD, &i2cinfo); 236 if (err<0) { 237 printf("CAMSYS_I2CRD failed "); 238 } else { 239 printf("I2c read: 0x%x : 0x%x ",i2cinfo.reg_addr,i2cinfo.val); 240 } 241 242 i2cinfo.reg_addr = 0x302a; 243 err = ioctl(camsys_fd, CAMSYS_I2CRD, &i2cinfo); 244 if (err<0) { 245 printf("CAMSYS_I2CRD failed "); 246 } else { 247 printf("I2c read: 0x%x : 0x%x ",i2cinfo.reg_addr,i2cinfo.val); 248 } 249 */ 250 /* 251 i2cchar = (unsigned char*)i2cbase; 252 sensor_reg = sensor_test; 253 i2cbytes = 0x00; 254 for (i=0; i<sizeof(sensor_test)/sizeof(struct rk_sensor_reg); i++) { 255 *i2cchar++ = (sensor_reg->reg&0xff00)>>8; 256 *i2cchar++ = (sensor_reg->reg&0xff); 257 *i2cchar++ = (sensor_reg->val&0xff); 258 sensor_reg++; 259 i2cbytes += 3; 260 } 261 262 i2cinfo.bus_num = 3; 263 i2cinfo.slave_addr = 0x6c; 264 i2cinfo.i2cbuf_directly = 1; 265 i2cinfo.i2cbuf_bytes = ((3<<16)|i2cbytes); 266 i2cinfo.speed = 100000; 267 err = ioctl(camsys_fd, CAMSYS_I2CWR, &i2cinfo); 268 if (err<0) { 269 printf("CAMSYS_I2CWR buf failed "); 270 } 271 printf("Sensor init! "); 272 */ 273 end: 274 return 0; 275 } 276 277 278 int main(int argc,char **argv) 279 { 280 int ret = -1; 281 camsys_devio_name_t extdev; 282 camsys_i2c_info_t i2cinfo; 283 int id = 0; 284 285 ret = access(CAMSYS_DEVNAME,O_RDWR); 286 if(ret < 0){ 287 printf("access %s failed ",CAMSYS_DEVNAME); 288 return -1; 289 } 290 291 camsys_fd = open(CAMSYS_DEVNAME,O_RDWR); 292 if(camsys_fd < 0){ 293 printf("open %s failed ",CAMSYS_DEVNAME); 294 return -1; 295 } 296 297 extdev_register(); 298 extdev_init(); 299 300 if(camsys_fd > 0) 301 close(camsys_fd); 302 303 304 printf("camera:id = 0x%x ",id); 305 306 307 return 0; 308 }
camera_head.h代码如下:
#ifndef __RKCAMSYS_HEAR_H__ #define __RKCAMSYS_HEAR_H__ #include <linux/ioctl.h> /* * C A M S Y S H E A D F I L E V E R S I O N * *v0.0.1: * 1) test version; *v0.0.2: * 1) modify camsys_irqcnnt_t; *v0.0.3: * 1) add support cif phy for marvin; *v0.0.4: * 1) add clock information in struct camsys_devio_name_s; *v0.0.5: * 1) add pwren control *v0.6.0: * 1) add support mipi phy configuration; * 2) add support io domain and mclk driver strength configuration; *v0.7.0: 1) add flash_trigger_out control *v0.8.0: 1) support isp iommu *v0.9.0: 1) add dev_name in struct camsys_devio_name_s; *v0.a.0: 1) support external flash IC *v0.b.0: 1) add CamSys_SensorBit0_CifBit4 in enum camsys_cifio_e. 2) support sensor powerup sequence configurable. */ #define CAMSYS_HEAD_VERSION KERNEL_VERSION(0,0xb,0) #define CAMSYS_MARVIN_DEVNAME "camsys_marvin" #define CAMSYS_CIF0_DEVNAME "camsys_cif0" #define CAMSYS_CIF1_DEVNAME "camsys_cif1" #define CAMSYS_NAME_LEN 32 #define CAMSYS_DEVID_MARVIN 0x00000001 #define CAMSYS_DEVID_CIF_0 0x00000002 #define CAMSYS_DEVID_CIF_1 0x00000004 #define CAMSYS_DEVID_INTERNAL 0x000000FF #define CAMSYS_DEVID_SENSOR_1A 0x01000000 #define CAMSYS_DEVID_SENSOR_1B 0x02000000 #define CAMSYS_DEVID_SENSOR_2 0x04000000 #define CAMSYS_DEVID_EXTERNAL 0xFF000000 #define CAMSYS_DEVID_EXTERNAL_NUM 8 #define CAMSYS_DEVCFG_FLASHLIGHT 0x00000001 #define CAMSYS_DEVCFG_PREFLASHLIGHT 0x00000002 #define CAMSYS_DEVCFG_SHUTTER 0x00000004 //Sensor power up sequence define //type: bit0-bit4 #define SENSOR_PWRSEQ_BEGIN 0x00 #define SENSOR_PWRSEQ_AVDD 0x01 #define SENSOR_PWRSEQ_DOVDD 0x02 #define SENSOR_PWRSEQ_DVDD 0x03 #define SENSOR_PWRSEQ_CLKIN 0x04 #define SENSOR_PWRSEQ_PWR 0x05 #define SENSOR_PWRSEQ_RST 0x06 #define SENSOR_PWRSEQ_PWRDN 0x07 #define SENSOR_PWRSEQ_END 0x0F #define SENSOR_PWRSEQ_CNT 0x07 #define VCM_PWRSEQ_BEGIN 0x00 #define VCM_PWRSEQ_VDD 0x01 #define VCM_PWRSEQ_PWR 0x02 #define VCM_PWRSEQ_PWRDN 0x03 #define VCM_PWRSEQ_END 0x0F #define VCM_PWRSEQ_CNT 0x03 #define POWERSEQ_SET(type,idx) (type<<(idx*4)) #define POWERSEQ_GET(seq,idx) ((seq>>(idx*4))&0x0f) typedef struct camsys_irqsta_s { unsigned int ris; //Raw interrupt status unsigned int mis; //Masked interrupt status } camsys_irqsta_t; typedef struct camsys_irqcnnt_s { int pid; unsigned int timeout; //us unsigned int mis; unsigned int icr; } camsys_irqcnnt_t; typedef enum camsys_mmap_type_e { //this type can be filled in mmap offset argument CamSys_Mmap_RegisterMem, CamSys_Mmap_I2cMem, CamSys_Mmap_End } camsys_mmap_type_t; typedef struct camsys_querymem_s { camsys_mmap_type_t mem_type; unsigned long mem_offset; unsigned int mem_size; } camsys_querymem_t; typedef struct camsys_i2c_info_s { unsigned char bus_num; unsigned short slave_addr; unsigned int reg_addr; //i2c device register address unsigned int reg_size; //register address size unsigned int val; unsigned int val_size; //register value size unsigned int i2cbuf_directly; unsigned int i2cbuf_bytes; unsigned int speed; //100000 == 100KHz } camsys_i2c_info_t; typedef struct camsys_reginfo_s { unsigned int dev_mask; unsigned int reg_offset; unsigned int val; } camsys_reginfo_t; typedef enum camsys_sysctrl_ops_e { CamSys_Vdd_Start_Tag, CamSys_Avdd, CamSys_Dovdd, CamSys_Dvdd, CamSys_Afvdd, CamSys_Vdd_End_Tag, CamSys_Gpio_Start_Tag, CamSys_PwrDn, CamSys_Rst, CamSys_AfPwr, CamSys_AfPwrDn, CamSys_PwrEn, CamSys_Gpio_End_Tag, CamSys_Clk_Start_Tag, CamSys_ClkIn, CamSys_Clk_End_Tag, CamSys_Phy_Start_Tag, CamSys_Phy, CamSys_Phy_End_Tag, CamSys_Flash_Trigger_Start_Tag, CamSys_Flash_Trigger, CamSys_Flash_Trigger_End_Tag, CamSys_IOMMU } camsys_sysctrl_ops_t; typedef struct camsys_regulator_info_s { unsigned char name[CAMSYS_NAME_LEN]; int min_uv; int max_uv; } camsys_regulator_info_t; typedef struct camsys_gpio_info_s { unsigned char name[CAMSYS_NAME_LEN]; unsigned int active; } camsys_gpio_info_t; typedef struct camsys_iommu_s{ int client_fd; int map_fd; unsigned long linear_addr; unsigned long len; }camsys_iommu_t; typedef struct camsys_sysctrl_s { unsigned int dev_mask; camsys_sysctrl_ops_t ops; unsigned int on; unsigned int rev[20]; } camsys_sysctrl_t; typedef struct camsys_flash_info_s { unsigned char fl_drv_name[CAMSYS_NAME_LEN]; camsys_gpio_info_t fl; //fl_trig camsys_gpio_info_t fl_en; } camsys_flash_info_t; typedef struct camsys_mipiphy_s { unsigned int data_en_bit; // data lane enable bit; unsigned int bit_rate; // Mbps/lane unsigned int phy_index; // phy0,phy1 } camsys_mipiphy_t; typedef enum camsys_fmt_e { CamSys_Fmt_Yuv420_8b = 0x18, CamSys_Fmt_Yuv420_10b = 0x19, CamSys_Fmt_LegacyYuv420_8b = 0x19, CamSys_Fmt_Yuv422_8b = 0x1e, CamSys_Fmt_Yuv422_10b = 0x1f, CamSys_Fmt_Raw_6b = 0x28, CamSys_Fmt_Raw_7b = 0x29, CamSys_Fmt_Raw_8b = 0x2a, CamSys_Fmt_Raw_10b = 0x2b, CamSys_Fmt_Raw_12b = 0x2c, CamSys_Fmt_Raw_14b = 0x2d, } camsys_fmt_t; typedef enum camsys_cifio_e { CamSys_SensorBit0_CifBit0 = 0x00, CamSys_SensorBit0_CifBit2 = 0x01, CamSys_SensorBit0_CifBit4 = 0x02, } camsys_cifio_t; typedef struct camsys_cifphy_s { unsigned int cif_num; camsys_fmt_t fmt; camsys_cifio_t cifio; } camsys_cifphy_t; typedef enum camsys_phy_type_e { CamSys_Phy_Mipi, CamSys_Phy_Cif, CamSys_Phy_end } camsys_phy_type_t; typedef struct camsys_extdev_phy_s { camsys_phy_type_t type; union { camsys_mipiphy_t mipi; camsys_cifphy_t cif; } info; } camsys_extdev_phy_t; typedef struct camsys_extdev_clk_s { unsigned int in_rate; unsigned int driver_strength; //0 - 3 } camsys_extdev_clk_t; typedef struct camsys_devio_name_s { unsigned char dev_name[CAMSYS_NAME_LEN]; unsigned int dev_id; camsys_regulator_info_t avdd; // sensor avdd power regulator name camsys_regulator_info_t dovdd; // sensor dovdd power regulator name camsys_regulator_info_t dvdd; // sensor dvdd power regulator name "NC" describe no regulator camsys_regulator_info_t afvdd; camsys_gpio_info_t pwrdn; // standby gpio name camsys_gpio_info_t rst; // hard reset gpio name camsys_gpio_info_t afpwr; // auto focus vcm driver ic power gpio name camsys_gpio_info_t afpwrdn; // auto focus vcm driver ic standby gpio camsys_gpio_info_t pwren; // power enable gpio name camsys_flash_info_t fl; camsys_extdev_phy_t phy; camsys_extdev_clk_t clk; unsigned int dev_cfg; // function bit mask configuration } camsys_devio_name_t; typedef struct camsys_version_s { unsigned int drv_ver; unsigned int head_ver; } camsys_version_t; /* * I O C T L C O D E S F O R R O C K C H I P S C A M S Y S D E V I C E S * */ #define HAL_DEVID_EXTERNAL CAMSYS_DEVID_EXTERNAL //!< just external devices included #define CAMSYS_IOC_MAGIC 'M' #define CAMSYS_IOC_MAXNR 14 #define CAMSYS_VERCHK _IOR(CAMSYS_IOC_MAGIC, 0, camsys_version_t) #define CAMSYS_I2CRD _IOWR(CAMSYS_IOC_MAGIC, 1, camsys_i2c_info_t) #define CAMSYS_I2CWR _IOW(CAMSYS_IOC_MAGIC, 2, camsys_i2c_info_t) #define CAMSYS_SYSCTRL _IOW(CAMSYS_IOC_MAGIC, 3, camsys_sysctrl_t) #define CAMSYS_REGRD _IOWR(CAMSYS_IOC_MAGIC, 4, camsys_reginfo_t) #define CAMSYS_REGWR _IOW(CAMSYS_IOC_MAGIC, 5, camsys_reginfo_t) #define CAMSYS_REGISTER_DEVIO _IOW(CAMSYS_IOC_MAGIC, 6, camsys_devio_name_t) #define CAMSYS_DEREGISTER_DEVIO _IOW(CAMSYS_IOC_MAGIC, 7, unsigned int) #define CAMSYS_IRQCONNECT _IOW(CAMSYS_IOC_MAGIC, 8, camsys_irqcnnt_t) #define CAMSYS_IRQWAIT _IOR(CAMSYS_IOC_MAGIC, 9, camsys_irqsta_t) #define CAMSYS_IRQDISCONNECT _IOW(CAMSYS_IOC_MAGIC, 10, camsys_irqcnnt_t) #define CAMSYS_QUREYMEM _IOR(CAMSYS_IOC_MAGIC, 11, camsys_querymem_t) #define CAMSYS_QUREYIOMMU _IOW(CAMSYS_IOC_MAGIC, 12, int) #endif
Android.mk如下:
1 LOCAL_PATH := $(call my-dir) 2 3 include $(CLEAR_VARS) 4 5 LOCAL_MODULE_TAGS := optional 6 7 LOCAL_MODULE := camera 8 9 LOCAL_SRC_FILES := camera.cpp 10 11 include $(BUILD_EXECUTABLE)
三、实现结果:已经成果获取对应寄存器的地址的内容