目录
1.apds9960_driver_api接口函数实现说明
1.1sample_fetch
1.2 channel_get
2. apds9960 传感器初始化动作
1. proxy接近传感器
2.2 环境光ALS 初始化
static int apds9960_sample_fetch(struct device *dev, enum sensor_channel chan)
{
const struct apds9960_config *config = dev->config->config_info;
struct apds9960_data *data = dev->driver_data;
u8_t status;
if (chan != SENSOR_CHAN_ALL) {
LOG_ERR("Unsupported sensor channel");
return -ENOTSUP;
}
//设置中断回调函数 函数
#ifndef CONFIG_APDS9960_TRIGGER
gpio_pin_enable_callback(data->gpio, config->gpio_pin);
//打开ADPS 接近和光感器 中断 寄存器
if (i2c_reg_update_byte(data->i2c, config->i2c_address,
APDS9960_ENABLE_REG,
APDS9960_ENABLE_PON | APDS9960_ENABLE_AIEN,
APDS9960_ENABLE_PON | APDS9960_ENABLE_AIEN)) {
LOG_ERR("Power on bit not set.");
return -EIO;
}
//信号量等待
k_sem_take(&data->data_sem, K_FOREVER);
#endif
//读取传感器当前 接近还是光感
if (i2c_reg_read_byte(data->i2c, config->i2c_address,
APDS9960_STATUS_REG, &status)) {
return -EIO;
}
//接近传感器 读取
LOG_DBG("status: 0x%x", status);
if (status & APDS9960_STATUS_PINT) {
if (i2c_reg_read_byte(data->i2c, config->i2c_address,
APDS9960_PDATA_REG, &data->pdata)) {
return -EIO;
}
}
//环境光 CRGB 读取
if (status & APDS9960_STATUS_AINT) {
if (i2c_burst_read(data->i2c, config->i2c_address,
APDS9960_CDATAL_REG,
(u8_t *)&data->sample_crgb,
sizeof(data->sample_crgb))) {
return -EIO;
}
}
//重新设置或者关闭功能 接近传感器
#ifndef CONFIG_APDS9960_TRIGGER
if (i2c_reg_update_byte(data->i2c, config->i2c_address,
APDS9960_ENABLE_REG,
APDS9960_ENABLE_PON,
0)) {
return -EIO;
}
#endif
if (i2c_reg_write_byte(data->i2c, config->i2c_address,
APDS9960_AICLEAR_REG, 0)) {
return -EIO;
}
return 0;
}
//根据传感器通道类型,回传感器数据
static int apds9960_channel_get(struct device *dev,
enum sensor_channel chan,
struct sensor_value *val)
{
struct apds9960_data *data = dev->driver_data;
switch (chan) {
case SENSOR_CHAN_LIGHT:
val->val1 = sys_le16_to_cpu(data->sample_crgb[0]);
val->val2 = 0;
break;
case SENSOR_CHAN_RED:
val->val1 = sys_le16_to_cpu(data->sample_crgb[1]);
val->val2 = 0;
break;
case SENSOR_CHAN_GREEN:
val->val1 = sys_le16_to_cpu(data->sample_crgb[2]);
val->val2 = 0;
break;
case SENSOR_CHAN_BLUE:
val->val1 = sys_le16_to_cpu(data->sample_crgb[3]);
val->val2 = 0;
break;
case SENSOR_CHAN_PROX:
val->val1 = data->pdata;
val->val2 = 0;
break;
default:
return -ENOTSUP;
}
return 0;
}
static int apds9960_proxy_setup(struct device *dev, int gain)
{
const struct apds9960_config *config = dev->config->config_info;
struct apds9960_data *data = dev->driver_data;
if (i2c_reg_write_byte(data->i2c, config->i2c_address,
APDS9960_POFFSET_UR_REG,
APDS9960_DEFAULT_POFFSET_UR)) {
LOG_ERR("Default offset UR not set ");
return -EIO;
}
if (i2c_reg_write_byte(data->i2c, config->i2c_address,
APDS9960_POFFSET_DL_REG,
APDS9960_DEFAULT_POFFSET_DL)) {
LOG_ERR("Default offset DL not set ");
return -EIO;
}
if (i2c_reg_write_byte(data->i2c, config->i2c_address,
APDS9960_PPULSE_REG,
APDS9960_DEFAULT_PROX_PPULSE)) {
LOG_ERR("Default pulse count not set ");
return -EIO;
}
if (i2c_reg_update_byte(data->i2c, config->i2c_address,
APDS9960_CONTROL_REG,
APDS9960_CONTROL_LDRIVE,
APDS9960_DEFAULT_LDRIVE)) {
LOG_ERR("LED Drive Strength not set");
return -EIO;
}
if (i2c_reg_update_byte(data->i2c, config->i2c_address,
APDS9960_CONTROL_REG, APDS9960_CONTROL_PGAIN,
(gain & APDS9960_PGAIN_8X))) {
LOG_ERR("Gain is not set");
return -EIO;
}
if (i2c_reg_write_byte(data->i2c, config->i2c_address,
APDS9960_PILT_REG, APDS9960_DEFAULT_PILT)) {
LOG_ERR("Low threshold not set");
return -EIO;
}
if (i2c_reg_write_byte(data->i2c, config->i2c_address,
APDS9960_PIHT_REG, APDS9960_DEFAULT_PIHT)) {
LOG_ERR("High threshold not set");
return -EIO;
}
if (i2c_reg_update_byte(data->i2c, config->i2c_address,
APDS9960_ENABLE_REG, APDS9960_ENABLE_PEN,
APDS9960_ENABLE_PEN)) {
LOG_ERR("Proximity mode is not enabled");
return -EIO;
}
return 0;
}
static int apds9960_ambient_setup(struct device *dev, int gain)
{
const struct apds9960_config *config = dev->config->config_info;
struct apds9960_data *data = dev->driver_data;
u16_t th;
/* ADC value */
if (i2c_reg_write_byte(data->i2c, config->i2c_address,
APDS9960_ATIME_REG, APDS9960_DEFAULT_ATIME)) {
LOG_ERR("Default integration time not set for ADC");
return -EIO;
}
/* ALS Gain */
if (i2c_reg_update_byte(data->i2c, config->i2c_address,
APDS9960_CONTROL_REG,
APDS9960_CONTROL_AGAIN,
(gain & APDS9960_AGAIN_64X))) {
LOG_ERR("Ambient Gain is not set");
return -EIO;
}
th = sys_cpu_to_le16(APDS9960_DEFAULT_AILT);
if (i2c_burst_write(data->i2c, config->i2c_address,
APDS9960_INT_AILTL_REG,
(u8_t *)&th, sizeof(th))) {
LOG_ERR("ALS low threshold not set");
return -EIO;
}
th = sys_cpu_to_le16(APDS9960_DEFAULT_AIHT);
if (i2c_burst_write(data->i2c, config->i2c_address,
APDS9960_INT_AIHTL_REG,
(u8_t *)&th, sizeof(th))) {
LOG_ERR("ALS low threshold not set");
return -EIO;
}
/* Enable ALS */
if (i2c_reg_update_byte(data->i2c, config->i2c_address,
APDS9960_ENABLE_REG, APDS9960_ENABLE_AEN,
APDS9960_ENABLE_AEN)) {
LOG_ERR("ALS is not enabled");
return -EIO;
}
return 0;
}