前言
关于sensor的驱动,前面分析的很明白了,这里具体研究最底层的实现
代码
int sensor_write_register(int addr, int data)
{
#ifdef HI_GPIO_I2C
i2c_data.dev_addr = sensor_i2c_addr;
i2c_data.reg_addr = addr;
i2c_data.addr_byte_num = sensor_addr_byte;
i2c_data.data = data;
i2c_data.data_byte_num = sensor_data_byte;
ret = ioctl(g_fd, GPIO_I2C_WRITE, &i2c_data);
if (ret)
{
printf("GPIO-I2C write faild!\n");
return ret;
}
#else
if(flag_init == 0)
{
sensor_i2c_init();
flag_init = 1;
}
int idx = 0;
int ret;
char buf[8];
buf[idx++] = addr & 0xFF;
if (sensor_addr_byte == 2)
{
ret = ioctl(g_fd, I2C_16BIT_REG, 1);
buf[idx++] = addr >> 8;
}
else
{
ret = ioctl(g_fd, I2C_16BIT_REG, 0);
}
if (ret < 0)
{
printf("CMD_SET_REG_WIDTH error!\n");
return -1;
}
buf[idx++] = data;
if (sensor_data_byte == 2)
{
ret = ioctl(g_fd, I2C_16BIT_DATA, 1);
buf[idx++] = data >> 8;
}
else
{
ret = ioctl(g_fd, I2C_16BIT_DATA, 0);
}
if (ret)
{
printf("hi_i2c write faild!\n");
return -1;
}
ret = write(g_fd, buf, idx);
if(ret < 0)
{
printf("I2C_WRITE error!\n");
return -1;
}
#endif
return 0;
}
sensor_i2c_init
就是打开最底层的I2C驱动,这个函数是将寄存器的地址和值交给I2C驱动,由I2C驱动来写进去。
buf[idx++] = addr & 0xFF;
将要读写的内容放到buf中,这里写的是寄存器地址,第一次放在buf[0]
sensor_addr_byte
是sensor的寄存器地址,若为两个字节,就将I2C的寄存器设置为16位
由于上面&了0xFF,那么就已经把高八位去掉了,下面的右移8位,就是取高8位。
这样一套操作下来,就是将低8位放在高位,高8位放在低位
接下来放寄存器地址。还是根据sensor寄存器的地址进行判断,一般arm的寄存器是32位的,但是我们使用的ar0130的寄存器地址是16位的。然后用同样的方法将data放进buf
数据手册
所谓sensor的初始化,就是给sensor中的寄存器写值。这些寄存器都在sensor的数据手册中。
比如这里一开始就进行了两次初始化,但是写的值不一样,这个时候就可以查一下数据手册
sensor初始化一般都是sensor厂家做好的,如果出问题,一般是sensor厂家解决,光看数据手册是不好解决的
不过下面有一个是可以动的
就是翻转功能,水平和垂直方向的反转
装摄像头的时候,有可能是挂在屋顶的,这时候就要反转
不过翻转功能一般会封装成API进行实时调用