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>
diff --git a/drivers/sensor/grove/Kconfig b/drivers/sensor/grove/Kconfig
index c55a81d..032c3dd 100644
--- a/drivers/sensor/grove/Kconfig
+++ b/drivers/sensor/grove/Kconfig
@@ -10,28 +10,6 @@
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
diff --git a/drivers/sensor/grove/light_sensor.c b/drivers/sensor/grove/light_sensor.c
index abb91a5..a72a0f4 100644
--- a/drivers/sensor/grove/light_sensor.c
+++ b/drivers/sensor/grove/light_sensor.c
@@ -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 @@
.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 @@
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 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(CONFIG_GROVE_LIGHT_SENSOR_ADC_DEV_NAME);
+ drv_data->adc = device_get_binding(cfg->adc_label);
+
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);
diff --git a/dts/bindings/sensor/grove,light.yaml b/dts/bindings/sensor/grove,light.yaml
new file mode 100644
index 0000000..f33fc22
--- /dev/null
+++ b/dts/bindings/sensor/grove,light.yaml
@@ -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.
diff --git a/samples/sensor/grove_light/boards/nrf52_pca10040.overlay b/samples/sensor/grove_light/boards/nrf52_pca10040.overlay
new file mode 100644
index 0000000..509355d
--- /dev/null
+++ b/samples/sensor/grove_light/boards/nrf52_pca10040.overlay
@@ -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>;
+ };
+};
diff --git a/samples/sensor/grove_light/prj.conf b/samples/sensor/grove_light/prj.conf
index 2bff964..ee0a4b6 100644
--- a/samples/sensor/grove_light/prj.conf
+++ b/samples/sensor/grove_light/prj.conf
@@ -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
diff --git a/samples/sensor/grove_light/sample.yaml b/samples/sensor/grove_light/sample.yaml
index 38c2c8f..7576190 100644
--- a/samples/sensor/grove_light/sample.yaml
+++ b/samples/sensor/grove_light/sample.yaml
@@ -3,5 +3,6 @@
tests:
sample.sensor.grove_light:
tags: drivers sensor grove light
+ platform_whitelist: nrf52_pca10040
harness: grove
depends_on: adc
diff --git a/samples/sensor/grove_light/src/main.c b/samples/sensor/grove_light/src/main.c
index 94ca31e..c33d73f 100644
--- a/samples/sensor/grove_light/src/main.c
+++ b/samples/sensor/grove_light/src/main.c
@@ -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 @@
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);
}
}
diff --git a/tests/drivers/build_all/dts_fixup.h b/tests/drivers/build_all/dts_fixup.h
index d2c5419..3cbeada 100644
--- a/tests/drivers/build_all/dts_fixup.h
+++ b/tests/drivers/build_all/dts_fixup.h
@@ -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 ""