2016-05-06 21:33:21 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2016 Intel Corporation
|
|
|
|
*
|
2017-01-19 09:01:01 +08:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
2016-05-06 21:33:21 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <adc.h>
|
|
|
|
#include <device.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <sensor.h>
|
|
|
|
#include <zephyr.h>
|
|
|
|
|
|
|
|
#define SYS_LOG_DOMAIN "GROVE_LIGHT_SENSOR"
|
2016-10-08 05:38:37 +08:00
|
|
|
#define SYS_LOG_LEVEL CONFIG_SYS_LOG_GROVE_LEVEL
|
2016-12-18 01:56:56 +08:00
|
|
|
#include <logging/sys_log.h>
|
2016-05-06 21:33:21 +08:00
|
|
|
|
|
|
|
struct gls_data {
|
|
|
|
struct device *adc;
|
|
|
|
struct adc_seq_entry sample;
|
|
|
|
struct adc_seq_table adc_table;
|
2017-04-21 23:03:20 +08:00
|
|
|
u8_t adc_buffer[4];
|
2016-05-06 21:33:21 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static int gls_sample_fetch(struct device *dev, enum sensor_channel chan)
|
|
|
|
{
|
|
|
|
struct gls_data *drv_data = dev->driver_data;
|
|
|
|
|
|
|
|
return adc_read(drv_data->adc, &drv_data->adc_table);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int gls_channel_get(struct device *dev,
|
|
|
|
enum sensor_channel chan,
|
|
|
|
struct sensor_value *val)
|
|
|
|
{
|
|
|
|
struct gls_data *drv_data = dev->driver_data;
|
2017-04-21 23:03:20 +08:00
|
|
|
u16_t analog_val;
|
2016-12-09 18:57:20 +08:00
|
|
|
double ldr_val, dval;
|
2016-05-06 21:33:21 +08:00
|
|
|
|
|
|
|
/* rescale sample from 12bit (Zephyr) to 10bit (Grove) */
|
2017-04-21 23:03:20 +08:00
|
|
|
analog_val = ((u16_t)drv_data->adc_buffer[1] << 8) |
|
2016-05-06 21:33:21 +08:00
|
|
|
drv_data->adc_buffer[0];
|
|
|
|
analog_val = analog_val >> 2;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The formula for converting the analog value to lux is taken from
|
|
|
|
* the UPM project:
|
|
|
|
* https://github.com/intel-iot-devkit/upm/blob/master/src/grove/grove.cxx#L161
|
|
|
|
*/
|
|
|
|
ldr_val = (1023.0 - analog_val) * 10.0 / analog_val;
|
2016-12-09 18:57:20 +08:00
|
|
|
dval = 10000.0 / pow(ldr_val * 15.0, 4.0/3.0);
|
|
|
|
|
2017-04-21 23:03:20 +08:00
|
|
|
val->val1 = (s32_t)dval;
|
|
|
|
val->val2 = ((s32_t)(dval * 1000000)) % 1000000;
|
2016-05-06 21:33:21 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-10-24 15:24:22 +08:00
|
|
|
static const struct sensor_driver_api gls_api = {
|
2016-05-06 21:33:21 +08:00
|
|
|
.sample_fetch = &gls_sample_fetch,
|
|
|
|
.channel_get = &gls_channel_get,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int gls_init(struct device *dev)
|
|
|
|
{
|
|
|
|
struct gls_data *drv_data = dev->driver_data;
|
|
|
|
|
|
|
|
drv_data->adc =
|
|
|
|
device_get_binding(CONFIG_GROVE_LIGHT_SENSOR_ADC_DEV_NAME);
|
|
|
|
if (drv_data->adc == NULL) {
|
|
|
|
SYS_LOG_ERR("Failed to get ADC device.");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
drv_data->sample.sampling_delay = 12;
|
|
|
|
drv_data->sample.channel_id = CONFIG_GROVE_LIGHT_SENSOR_ADC_CHANNEL;
|
|
|
|
drv_data->sample.buffer = drv_data->adc_buffer;
|
|
|
|
drv_data->sample.buffer_length = 4;
|
|
|
|
|
|
|
|
drv_data->adc_table.entries = &drv_data->sample;
|
|
|
|
drv_data->adc_table.num_entries = 1;
|
|
|
|
|
|
|
|
adc_enable(drv_data->adc);
|
|
|
|
|
|
|
|
dev->driver_api = &gls_api;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-10-26 12:52:55 +08:00
|
|
|
static struct gls_data gls_data;
|
2016-05-06 21:33:21 +08:00
|
|
|
|
|
|
|
DEVICE_INIT(gls_dev, CONFIG_GROVE_LIGHT_SENSOR_NAME, &gls_init, &gls_data,
|
2016-11-09 03:06:55 +08:00
|
|
|
NULL, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY);
|