花了4天的时间在展讯7731平台上来调试SILICON SI1132这颗环境光和紫外线传感器。厂家提供的资料有限,没有Linux版本的驱动,虽然有基于mcu的demo版本参考代码,但是这些代码是支持SILICON公司si114x、si115x及si1132全系列产品的,功能包括距离、环境(可见)光、红外线、紫外线(UV)传感器,要厘清代码里的各个寄存器作用及函数功能实现,需要仔细阅读芯片datasheet。而且,没有linux版本驱动,就更没有HAL层代码了。这就意味着,哥不仅要自己写linux版本的驱动,还要自己写硬件抽象层HAL代码。
反复仔细阅读了si1132 datasheet,总结了以下一些要点:
1. Si1132的slave address为0x60(high 7 bit);寄存器0为芯片ID寄存器,值为0x32。在driver初始化时,我们可以通过读取该寄存器来判断I2C通讯是否成功,SI1132电路是否工作正常。
2. Si1132支持环境(可见)光、红外线、紫外线(UV)三种光线类型的测量;
3. Si1132支持自动转换和强迫转换两种工作模式,通过配置ALS_FORCE命令进入强制转换模式;通过配置ALS_AUTO命令进入自动转换模式;当使用强制转换模式时,系统功耗最低.
4. 在对si1132的寄存器进行操作前,我们必须要先往HW_KEY @ 0x07寄存器写入0x17这个值;
5. MEAS_RATE0及MEAS_RATE1这两个寄存器用于存储自动转换模式的时间参数,其组成16 bit的数据乘以31.25 us,即为si1132自动转换的时间间隔。当使用强制转换工作模式时,这两个寄存器要配置为0。
6. 通过配置INT_CFG @ 0x03及IRQ_ENABLE @ 0x04寄存器,当光线强度检测完成之后,si1132的int gpio将会产生中断。
7. COMMAND @ 0x18为si1132的命令寄存器,这个寄存器比较特殊,用于进行一些专用命令、特殊参数的设置。
(1) 可以往该寄存器直接写命令参数,分别:
0x01:si1132 reset 复位
0x06: si1132工作于强制转换模式
0x0e: si1132工作于自动转换模式
(2) 可以设置芯片关键的工作参数,需要通过与PARAM_SET(0xa0)或上低5 bit的指令地址作为真正的地址,且需要我们先往PARAM_WR@ 0x17这个地址写入参数配置。
使能uv、环境可见光感、红外线转换,就是通过这个命令来配置。
8. 使用UV紫外线转换功能,还必须先往UCOEF [0:3]这四个寄存器分别依次写入0x7B,0x6B, 0x01, and 0x00这几个值。
9. 检测(转换)完成后,环境光的数据存储于ALS_VIS_DATA寄存器;红外光的数据存储于ALS_IR_DATA寄存器,紫外线UV数据存储于UX_DATA寄存器。
10. Si1132内设其他寄存器支持数据辅助校准功能,以便数据检测更为准确可靠,这个没有细看。
了解完si1132 datasheet的寄存器描述及功能实现说明之后,编写linux驱动程序及HAL层控制代码,使用poll定时上报数据的方式,顺利实现si1132的光感和紫外线检测功能,使用sensorlist apk可以顺利检查到光感和紫外线数据。
附:比较关键的系统参数设置函数
static int SI1132_param_op(struct si1132_data *data, u8 op, u8 param, u8 value)
{
struct i2c_client *client = data->client;
int ret;
mutex_lock(&data->data_lock);
if (op != SI1132_CMD_PARAM_QUERY) {
ret = i2c_smbus_write_byte_data(client,
SI1132_REG_PARAM_WR, value);
if (ret < 0)
goto error;
}
ret = i2c_smbus_write_byte_data(client, SI1132_REG_COMMAND,
op | (param & 0x1F));
if (ret < 0)
goto error;
ret = i2c_smbus_read_byte_data(client, SI1132_REG_PARAM_RD);
if (ret < 0)
return ret;
mutex_unlock(&data->data_lock);
return ret & 0xff;
error:
mutex_unlock(&data->data_lock);
return ret;
}