【zephyr】 设备驱动和设备模型_apds9660 接近(Proximity)传感器(二)

目录

1.apds9960_driver_api接口函数实现说明

1.1sample_fetch

1.2  channel_get

2. apds9960 传感器初始化动作

1. proxy接近传感器 

 2.2 环境光ALS 初始化


1.apds9960_driver_api接口函数实现说明

1.1sample_fetch

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;
}

 

1.2  channel_get

  1. 光感数据
  2. 红,绿,蓝 数据
  3. 接近传感器数值 
//根据传感器通道类型,回传感器数据 

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;
}

2. apds9960 传感器初始化动作

1. proxy接近传感器 

  • 设置接近门限值 APDS9960_POFFSET_UR_REG
  • 设置远离门限值  APDS9960_POFFSET_DL_REG
  • 设置脉冲个数:APDS9960_PPULSE_REG
  • 设置驱动电流:APDS9960_CONTROL_REG
  • 设置增益:APDS9960_CONTROL_REG
  • APDS9960_PILT_REG
  • APDS9960_PIHT_REG
  • 打开接近传感器 功能:APDS9960_ENABLE_REG
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;
}

 2.2 环境光ALS 初始化

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;
}

 

你可能感兴趣的:(zephyr,IOT)