sensors: grove_light: convert to devicetree bindings
Replace Kconfig configuration data with devicetree bindings using (ADC) io channels. Rework the sample to document expectations about the relationship between the reference voltage and the divider input voltage, and update the sensor configuration to support Nordic SAADC. Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
parent
bc60245787
commit
a8d15c1279
|
@ -10,28 +10,6 @@ config GROVE_LIGHT_SENSOR
|
|||
Setting this value will enable driver support for the Grove Light
|
||||
Sensor.
|
||||
|
||||
if GROVE_LIGHT_SENSOR
|
||||
config GROVE_LIGHT_SENSOR_NAME
|
||||
string "Driver name"
|
||||
default "GROVE_LIGHT_SENSOR"
|
||||
help
|
||||
Specify the device name with which the sensor is identified.
|
||||
|
||||
config GROVE_LIGHT_SENSOR_ADC_DEV_NAME
|
||||
string "ADC where Grove Light Sensor is connected"
|
||||
default "ADC_0"
|
||||
help
|
||||
Specify the device name of the ADC to which the Grove Light Sensor
|
||||
is connected.
|
||||
|
||||
config GROVE_LIGHT_SENSOR_ADC_CHANNEL
|
||||
int "ADC channel used by Grove Light Sensor"
|
||||
default 10
|
||||
help
|
||||
Specify the channel of the ADC to which the Grove Light Sensor is
|
||||
connected.
|
||||
endif
|
||||
|
||||
config GROVE_TEMPERATURE_SENSOR
|
||||
bool "Enable the Seeed Grove Temperature Sensor"
|
||||
depends on ADC && !MINIMAL_LIBC
|
||||
|
|
|
@ -13,10 +13,27 @@
|
|||
|
||||
LOG_MODULE_REGISTER(grove_light, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
/* The effect of gain and reference voltage must cancel. */
|
||||
#ifdef CONFIG_ADC_NRFX_SAADC
|
||||
#define GROVE_GAIN ADC_GAIN_1_4
|
||||
#define GROVE_REF ADC_REF_VDD_1_4
|
||||
#define GROVE_RESOLUTION 12
|
||||
#else
|
||||
#define GROVE_GAIN ADC_GAIN_1
|
||||
#define GROVE_REF ADC_REF_VDD_1
|
||||
#define GROVE_RESOLUTION 12
|
||||
#endif
|
||||
|
||||
|
||||
struct gls_data {
|
||||
struct device *adc;
|
||||
struct adc_channel_cfg ch10_cfg;
|
||||
u8_t adc_buffer[4];
|
||||
struct adc_channel_cfg ch_cfg;
|
||||
u16_t raw;
|
||||
};
|
||||
|
||||
struct gls_config {
|
||||
const char *adc_label;
|
||||
u8_t adc_channel;
|
||||
};
|
||||
|
||||
static struct adc_sequence_options options = {
|
||||
|
@ -28,8 +45,6 @@ static struct adc_sequence adc_table = {
|
|||
.options = &options,
|
||||
};
|
||||
|
||||
#define ADC_RESOLUTION 12
|
||||
|
||||
static int gls_sample_fetch(struct device *dev, enum sensor_channel chan)
|
||||
{
|
||||
struct gls_data *drv_data = dev->driver_data;
|
||||
|
@ -42,20 +57,15 @@ static int gls_channel_get(struct device *dev,
|
|||
struct sensor_value *val)
|
||||
{
|
||||
struct gls_data *drv_data = dev->driver_data;
|
||||
u16_t analog_val;
|
||||
u16_t analog_val = drv_data->raw;
|
||||
double ldr_val, dval;
|
||||
|
||||
/* rescale sample from 12bit (Zephyr) to 10bit (Grove) */
|
||||
analog_val = ((u16_t)drv_data->adc_buffer[1] << 8) |
|
||||
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;
|
||||
ldr_val = (BIT(GROVE_RESOLUTION) - 1.0 - analog_val) * 10.0 / analog_val;
|
||||
dval = 10000.0 / pow(ldr_val * 15.0, 4.0/3.0);
|
||||
|
||||
val->val1 = (s32_t)dval;
|
||||
|
@ -72,32 +82,41 @@ static const struct sensor_driver_api gls_api = {
|
|||
static int gls_init(struct device *dev)
|
||||
{
|
||||
struct gls_data *drv_data = dev->driver_data;
|
||||
const struct gls_config *cfg = dev->config->config_info;
|
||||
|
||||
drv_data->adc = device_get_binding(cfg->adc_label);
|
||||
|
||||
drv_data->adc =
|
||||
device_get_binding(CONFIG_GROVE_LIGHT_SENSOR_ADC_DEV_NAME);
|
||||
if (drv_data->adc == NULL) {
|
||||
LOG_ERR("Failed to get ADC device.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*Change following parameters according to board if necessary*/
|
||||
drv_data->ch10_cfg.channel_id = CONFIG_GROVE_LIGHT_SENSOR_ADC_CHANNEL;
|
||||
drv_data->ch10_cfg.differential = false;
|
||||
drv_data->ch10_cfg.gain = ADC_GAIN_1,
|
||||
drv_data->ch10_cfg.reference = ADC_REF_INTERNAL;
|
||||
drv_data->ch10_cfg.acquisition_time = ADC_ACQ_TIME_DEFAULT;
|
||||
adc_table.buffer = drv_data->adc_buffer;
|
||||
adc_table.channels = BIT(CONFIG_GROVE_LIGHT_SENSOR_ADC_CHANNEL);
|
||||
adc_table.resolution = ADC_RESOLUTION;
|
||||
adc_table.buffer_size = 4;
|
||||
drv_data->ch_cfg = (struct adc_channel_cfg){
|
||||
.gain = GROVE_GAIN,
|
||||
.reference = GROVE_REF,
|
||||
.acquisition_time = ADC_ACQ_TIME_DEFAULT,
|
||||
.channel_id = cfg->adc_channel,
|
||||
#ifdef CONFIG_ADC_NRFX_SAADC
|
||||
.input_positive = SAADC_CH_PSELP_PSELP_AnalogInput0 + cfg->adc_channel,
|
||||
#endif
|
||||
};
|
||||
adc_table.buffer = &drv_data->raw;
|
||||
adc_table.buffer_size = sizeof(drv_data->raw);
|
||||
adc_table.resolution = GROVE_RESOLUTION;
|
||||
adc_table.channels = BIT(cfg->adc_channel);
|
||||
|
||||
adc_channel_setup(drv_data->adc, &drv_data->ch10_cfg);
|
||||
adc_channel_setup(drv_data->adc, &drv_data->ch_cfg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct gls_data gls_data;
|
||||
static const struct gls_config gls_cfg = {
|
||||
.adc_label = DT_INST_0_GROVE_LIGHT_IO_CHANNELS_CONTROLLER,
|
||||
.adc_channel = DT_INST_0_GROVE_LIGHT_IO_CHANNELS_INPUT,
|
||||
};
|
||||
|
||||
DEVICE_AND_API_INIT(gls_dev, CONFIG_GROVE_LIGHT_SENSOR_NAME, &gls_init,
|
||||
&gls_data, NULL, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY,
|
||||
DEVICE_AND_API_INIT(gls_dev, DT_INST_0_GROVE_LIGHT_LABEL, &gls_init,
|
||||
&gls_data, &gls_cfg, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY,
|
||||
&gls_api);
|
||||
|
|
15
dts/bindings/sensor/grove,light.yaml
Normal file
15
dts/bindings/sensor/grove,light.yaml
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Copyright (c) 2019 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: Grove Photo-Resistor Light Sensor
|
||||
|
||||
compatible: "grove,light"
|
||||
|
||||
include: base.yaml
|
||||
|
||||
properties:
|
||||
io-channels:
|
||||
type: phandle-array
|
||||
required: true
|
||||
description: |
|
||||
IO channel associated with the resistor voltage divider.
|
13
samples/sensor/grove_light/boards/nrf52_pca10040.overlay
Normal file
13
samples/sensor/grove_light/boards/nrf52_pca10040.overlay
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/ {
|
||||
ntc {
|
||||
label = "GLS";
|
||||
compatible = "grove,light";
|
||||
io-channels = <&arduino_adc 0>;
|
||||
};
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
CONFIG_ADC=y
|
||||
CONFIG_GROVE_LIGHT_SENSOR=y
|
||||
CONFIG_SENSOR=y
|
||||
CONFIG_GROVE_LIGHT_SENSOR=y
|
||||
CONFIG_NEWLIB_LIBC=y
|
||||
CONFIG_STDOUT_CONSOLE=y
|
||||
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
|
||||
|
|
|
@ -3,5 +3,6 @@ sample:
|
|||
tests:
|
||||
sample.sensor.grove_light:
|
||||
tags: drivers sensor grove light
|
||||
platform_whitelist: nrf52_pca10040
|
||||
harness: grove
|
||||
depends_on: adc
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include <zephyr.h>
|
||||
#include <init.h>
|
||||
#include <sys/printk.h>
|
||||
#include <stdio.h>
|
||||
#include <drivers/sensor.h>
|
||||
|
||||
|
@ -14,10 +13,10 @@
|
|||
|
||||
void main(void)
|
||||
{
|
||||
struct device *dev = device_get_binding(CONFIG_GROVE_LIGHT_SENSOR_NAME);
|
||||
struct device *dev = device_get_binding(DT_INST_0_GROVE_LIGHT_LABEL);
|
||||
|
||||
if (dev == NULL) {
|
||||
printk("device not found. aborting test.\n");
|
||||
printf("device not found. aborting test.\n");
|
||||
return;
|
||||
}
|
||||
while (1) {
|
||||
|
@ -26,17 +25,14 @@ void main(void)
|
|||
|
||||
read = sensor_sample_fetch(dev);
|
||||
if (read) {
|
||||
printk("sample fetch error %d\n", read);
|
||||
printf("sample fetch error %d\n", read);
|
||||
continue;
|
||||
}
|
||||
|
||||
sensor_channel_get(dev, SENSOR_CHAN_LIGHT, &lux);
|
||||
|
||||
#ifdef CONFIG_NEWLIB_LIBC_FLOAT_PRINTF
|
||||
printk("lux: %d\n", sensor_value_to_double(&lux));
|
||||
#else
|
||||
printk("lux: %d\n", lux.val1);
|
||||
#endif
|
||||
printf("lux: %f\n", sensor_value_to_double(&lux));
|
||||
|
||||
k_sleep(SLEEP_TIME);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -402,6 +402,12 @@
|
|||
#define DT_INST_0_INVENSENSE_MPU6050_INT_GPIOS_PIN 0
|
||||
#endif
|
||||
|
||||
#ifndef DT_INST_0_GROVE_LIGHT_LABEL
|
||||
#define DT_INST_0_GROVE_LIGHT_LABEL ""
|
||||
#define DT_INST_0_GROVE_LIGHT_IO_CHANNELS_CONTROLLER ""
|
||||
#define DT_INST_0_GROVE_LIGHT_IO_CHANNELS_INPUT 0
|
||||
#endif
|
||||
|
||||
#ifndef DT_INST_0_GROVE_TEMPERATURE_LABEL
|
||||
#define DT_INST_0_GROVE_TEMPERATURE_LABEL ""
|
||||
#define DT_INST_0_GROVE_TEMPERATURE_IO_CHANNELS_CONTROLLER ""
|
||||
|
|
Loading…
Reference in a new issue