From 2295ecdbd949224cfcc034f3e018c27e02c26950 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sun, 17 Jan 2016 23:04:34 +0100 Subject: [PATCH] Renamed adc-sensors/adc-wrapper to adc-zoul/adc-sensors, to have a better wording reflecting the intented use --- examples/zolertia/zoul/Makefile | 4 +- .../zolertia/zoul/test-grove-light-sensor.c | 8 +- .../zoul/test-grove-loudness-sensor.c | 8 +- examples/zolertia/zoul/test-rotation-sensor.c | 8 +- examples/zolertia/zoul/zoul-demo.c | 10 +- platform/zoul/Makefile.zoul | 2 +- platform/zoul/dev/adc-sensors.c | 243 ++++++++++-------- platform/zoul/dev/adc-sensors.h | 110 ++------ platform/zoul/dev/adc-wrapper.c | 215 ---------------- platform/zoul/dev/adc-wrapper.h | 85 ------ platform/zoul/dev/adc-zoul.c | 187 ++++++++++++++ platform/zoul/dev/adc-zoul.h | 148 +++++++++++ 12 files changed, 514 insertions(+), 514 deletions(-) delete mode 100644 platform/zoul/dev/adc-wrapper.c delete mode 100644 platform/zoul/dev/adc-wrapper.h create mode 100644 platform/zoul/dev/adc-zoul.c create mode 100644 platform/zoul/dev/adc-zoul.h diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index 8c1422549..7ead94a69 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -1,9 +1,11 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" + CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-pwm test-power-mgmt CONTIKI_PROJECT += test-bmp085 test-motion test-rotation-sensor CONTIKI_PROJECT += test-grove-light-sensor test-grove-loudness-sensor + CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmp085.c motion-sensor.c -CONTIKI_TARGET_SOURCEFILES += adc-wrapper.c +CONTIKI_TARGET_SOURCEFILES += adc-sensors.c all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/test-grove-light-sensor.c b/examples/zolertia/zoul/test-grove-light-sensor.c index c81f7b931..b4104f2b8 100644 --- a/examples/zolertia/zoul/test-grove-light-sensor.c +++ b/examples/zolertia/zoul/test-grove-light-sensor.c @@ -38,7 +38,7 @@ * @{ * * \file - * Grove's LDR sensor example using the ADC wrapper + * Grove's LDR sensor example using the ADC sensors wrapper * * \author * Antonio Lignan @@ -47,7 +47,7 @@ #include #include "contiki.h" #include "dev/leds.h" -#include "dev/adc-wrapper.h" +#include "dev/adc-sensors.h" /*---------------------------------------------------------------------------*/ #define ADC_PIN 5 #define SENSOR_READ_INTERVAL (CLOCK_SECOND / 4) @@ -64,7 +64,7 @@ PROCESS_THREAD(remote_grove_light_process, ev, data) uint16_t ldr; /* Use pin number not mask, for example if using the PA5 pin then use 5 */ - adc_wrapper.configure(ANALOG_GROVE_LIGHT, 5); + adc_sensors.configure(ANALOG_GROVE_LIGHT, 5); /* And periodically poll the sensor */ @@ -72,7 +72,7 @@ PROCESS_THREAD(remote_grove_light_process, ev, data) etimer_set(&et, SENSOR_READ_INTERVAL); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - ldr = adc_wrapper.value(ANALOG_GROVE_LIGHT); + ldr = adc_sensors.value(ANALOG_GROVE_LIGHT); if(ldr != ADC_WRAPPER_ERROR) { printf("LDR (resistor) = %u\n", ldr); diff --git a/examples/zolertia/zoul/test-grove-loudness-sensor.c b/examples/zolertia/zoul/test-grove-loudness-sensor.c index 85907e3e3..b5042f814 100644 --- a/examples/zolertia/zoul/test-grove-loudness-sensor.c +++ b/examples/zolertia/zoul/test-grove-loudness-sensor.c @@ -38,7 +38,7 @@ * @{ * * \file - * Grove's loudness sensor example using the ADC wrapper + * Grove's loudness sensor example using the ADC sensors wrapper * * \author * Antonio Lignan @@ -47,7 +47,7 @@ #include #include "contiki.h" #include "dev/leds.h" -#include "dev/adc-wrapper.h" +#include "dev/adc-sensors.h" /*---------------------------------------------------------------------------*/ #define ADC_PIN 5 #define SENSOR_READ_INTERVAL (CLOCK_SECOND / 8) @@ -64,7 +64,7 @@ PROCESS_THREAD(remote_grove_loudness_process, ev, data) uint16_t loudness; /* Use pin number not mask, for example if using the PA5 pin then use 5 */ - adc_wrapper.configure(ANALOG_GROVE_LOUDNESS, ADC_PIN); + adc_sensors.configure(ANALOG_GROVE_LOUDNESS, ADC_PIN); /* And periodically poll the sensor */ @@ -72,7 +72,7 @@ PROCESS_THREAD(remote_grove_loudness_process, ev, data) etimer_set(&et, SENSOR_READ_INTERVAL); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - loudness = adc_wrapper.value(ANALOG_GROVE_LOUDNESS); + loudness = adc_sensors.value(ANALOG_GROVE_LOUDNESS); if(loudness != ADC_WRAPPER_ERROR) { printf("%u\n", loudness); diff --git a/examples/zolertia/zoul/test-rotation-sensor.c b/examples/zolertia/zoul/test-rotation-sensor.c index 220d86fca..76fb029ec 100644 --- a/examples/zolertia/zoul/test-rotation-sensor.c +++ b/examples/zolertia/zoul/test-rotation-sensor.c @@ -38,7 +38,7 @@ * @{ * * \file - * Phidget analog rotation sensor example using the ADC wrapper + * Phidget analog rotation sensor example using the ADC sensor wrapper * * \author * Antonio Lignan @@ -47,7 +47,7 @@ #include #include "contiki.h" #include "dev/leds.h" -#include "dev/adc-wrapper.h" +#include "dev/adc-sensors.h" /*---------------------------------------------------------------------------*/ #define ADC_PIN 5 #define SENSOR_READ_INTERVAL (CLOCK_SECOND / 4) @@ -64,7 +64,7 @@ PROCESS_THREAD(remote_rotation_process, ev, data) uint16_t rotation; /* Use pin number not mask, for example if using the PA5 pin then use 5 */ - adc_wrapper.configure(ANALOG_PHIDGET_ROTATION_1109, 5); + adc_sensors.configure(ANALOG_PHIDGET_ROTATION_1109, 5); /* And periodically poll the sensor */ @@ -72,7 +72,7 @@ PROCESS_THREAD(remote_rotation_process, ev, data) etimer_set(&et, SENSOR_READ_INTERVAL); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - rotation = adc_wrapper.value(ANALOG_PHIDGET_ROTATION_1109); + rotation = adc_sensors.value(ANALOG_PHIDGET_ROTATION_1109); if(rotation != ADC_WRAPPER_ERROR) { printf("Rotation = %u\n", rotation); diff --git a/examples/zolertia/zoul/zoul-demo.c b/examples/zolertia/zoul/zoul-demo.c index 25e49235f..127c18d50 100644 --- a/examples/zolertia/zoul/zoul-demo.c +++ b/examples/zolertia/zoul/zoul-demo.c @@ -69,7 +69,7 @@ #include "dev/leds.h" #include "dev/uart.h" #include "dev/button-sensor.h" -#include "dev/adc-sensors.h" +#include "dev/adc-zoul.h" #include "dev/zoul-sensors.h" #include "dev/watchdog.h" #include "dev/serial-line.h" @@ -132,7 +132,7 @@ PROCESS_THREAD(zoul_demo_process, ev, data) BUTTON_PRESS_EVENT_INTERVAL); /* Configure the ADC ports */ - adc_sensors.configure(SENSORS_HW_INIT, ZOUL_SENSORS_ADC_ALL); + adc_zoul.configure(SENSORS_HW_INIT, ZOUL_SENSORS_ADC_ALL); printf("Zoul test application\n"); @@ -155,15 +155,16 @@ PROCESS_THREAD(zoul_demo_process, ev, data) cc2538_temp_sensor.value(CC2538_SENSORS_VALUE_TYPE_CONVERTED)); printf("ADC1 = %d raw\n", - adc_sensors.value(ZOUL_SENSORS_ADC1)); + adc_zoul.value(ZOUL_SENSORS_ADC1)); printf("ADC3 = %d raw\n", - adc_sensors.value(ZOUL_SENSORS_ADC3)); + adc_zoul.value(ZOUL_SENSORS_ADC3)); etimer_set(&et, LOOP_INTERVAL); rtimer_set(&rt, RTIMER_NOW() + LEDS_OFF_HYSTERISIS, 1, rt_callback, NULL); counter++; + } else if(ev == sensors_event) { if(data == &button_sensor) { if(button_sensor.value(BUTTON_SENSOR_VALUE_TYPE_LEVEL) == @@ -175,6 +176,7 @@ PROCESS_THREAD(zoul_demo_process, ev, data) printf("...and released!\n"); } } + } else if(ev == serial_line_event_message) { leds_toggle(LEDS_SERIAL_IN); } else if(ev == button_press_duration_exceeded) { diff --git a/platform/zoul/Makefile.zoul b/platform/zoul/Makefile.zoul index 027c1a79b..49e6ed13b 100644 --- a/platform/zoul/Makefile.zoul +++ b/platform/zoul/Makefile.zoul @@ -27,7 +27,7 @@ PLATFORM_ROOT_DIR = $(CONTIKI)/platform/$(TARGET) ### Include CONTIKI_TARGET_SOURCEFILES += contiki-main.c CONTIKI_TARGET_SOURCEFILES += leds.c leds-arch.c cc1200-zoul-arch.c -CONTIKI_TARGET_SOURCEFILES += adc-sensors.c button-sensor.c zoul-sensors.c +CONTIKI_TARGET_SOURCEFILES += adc-zoul.c button-sensor.c zoul-sensors.c CONTIKI_TARGET_SOURCEFILES += $(BOARD_SOURCEFILES) CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) diff --git a/platform/zoul/dev/adc-sensors.c b/platform/zoul/dev/adc-sensors.c index da1ca844d..b69dfc8cf 100644 --- a/platform/zoul/dev/adc-sensors.c +++ b/platform/zoul/dev/adc-sensors.c @@ -1,6 +1,5 @@ /* - * Copyright (c) 2015, Zolertia - http://www.zolertia.com - * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * Copyright (c) 2016, Zolertia - http://www.zolertia.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,7 +34,7 @@ * @{ * * \file - * Generic driver for the Zoul ADC sensors + * Generic driver for the Zoul ADC wrapper for analogue sensors */ /*---------------------------------------------------------------------------*/ #include "contiki.h" @@ -44,7 +43,9 @@ #include "dev/gpio.h" #include "dev/adc.h" #include "adc-sensors.h" +#include "adc-zoul.h" #include "zoul-sensors.h" + #include #include /*---------------------------------------------------------------------------*/ @@ -55,133 +56,153 @@ #define PRINTF(...) #endif /*---------------------------------------------------------------------------*/ -static uint8_t decimation_rate; -static uint8_t enabled_channels; +typedef struct { + int type; + uint8_t pin_mask; + uint8_t vdd3; +} adc_info_t; + +typedef struct { + uint8_t sensors_num; + uint8_t sensors_ports; + adc_info_t sensor[ADC_SENSORS_MAX]; +} adc_wrapper_t; + +static adc_wrapper_t sensors; /*---------------------------------------------------------------------------*/ -static int -set_decimation_rate(uint8_t rate) +static uint16_t +convert_to_value(uint8_t index) { - switch(rate) { - case SOC_ADC_ADCCON_DIV_64: - case SOC_ADC_ADCCON_DIV_128: - case SOC_ADC_ADCCON_DIV_256: - case SOC_ADC_ADCCON_DIV_512: - decimation_rate = rate; - break; - default: - return ZOUL_SENSORS_ERROR; + uint32_t value; + value = adc_zoul.value(sensors.sensor[index].pin_mask); + + if(value == ZOUL_SENSORS_ERROR) { + PRINTF("ADC sensors: failed retrieving data\n"); + return ADC_WRAPPER_ERROR; } - return decimation_rate; -} -/*---------------------------------------------------------------------------*/ -static int -get_channel_pin(int type) -{ - if((ZOUL_SENSORS_ADC1) && (type == ZOUL_SENSORS_ADC1)) { - return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC1_PIN; - } - if((ZOUL_SENSORS_ADC2) && (type == ZOUL_SENSORS_ADC2)) { - return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC2_PIN; - } - if((ZOUL_SENSORS_ADC3) && (type == ZOUL_SENSORS_ADC3)) { - return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC3_PIN; - } - if((ZOUL_SENSORS_ADC4) && (type == ZOUL_SENSORS_ADC4)) { - return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC4_PIN; - } - if((ZOUL_SENSORS_ADC5) && (type == ZOUL_SENSORS_ADC5)) { - return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC5_PIN; - } - return ZOUL_SENSORS_ERROR; -} -/*---------------------------------------------------------------------------*/ -static int -value(int type) -{ - int channel; - int16_t res; + /* Default voltage divisor relation is 5/3 aprox, change at adc_wrapper.h, + * calculations below assume a decimation rate of 512 (12 bits ENOB) and + * AVVD5 voltage reference of 3.3V + */ - if(!(type & enabled_channels)) { - PRINTF("ADC: channel not enabled\n"); - return ZOUL_SENSORS_ERROR; + if(!sensors.sensor[index].vdd3) { + value *= ADC_WRAPPER_EXTERNAL_VREF; + value /= ADC_WRAPPER_EXTERNAL_VREF_CROSSVAL; } - channel = get_channel_pin(type); + switch(sensors.sensor[index].type) { + case ANALOG_GROVE_LIGHT: + /* Light dependant resistor (LDR) resistance value*/ + value = (10230 - (value * 10)) / value; + /* TODO: With the resistance we could calculate the lux as 63*R^(-0.7) */ + return (uint16_t)value; - if(channel == ZOUL_SENSORS_ERROR) { - PRINTF("ADC: pin not active\n"); - return ZOUL_SENSORS_ERROR; - } + case ANALOG_GROVE_LOUDNESS: + /* Based on the LM2904 amplifier (blue version with potentiometer) */ + return (uint16_t)value; - res = adc_get(channel, ADC_SENSORS_REFERENCE, decimation_rate); - - /* Only allow negative values if using differential input */ - if((ADC_SENSORS_REFERENCE != SOC_ADC_ADCCON_REF_EXT_DIFF) && (res < 0)) { - res = 0; - } - - return res; -} -/*---------------------------------------------------------------------------*/ -static int -configure(int type, int value) -{ - switch(type) { - case SENSORS_HW_INIT: - - /* This should filter out disabled sensors as its value should be zero */ - if((value < ZOUL_SENSORS_ADC_MIN) || (value > ZOUL_SENSORS_ADC_ALL)) { - PRINTF("ADC: invalid adc pin mask (0x%02X)\n", value); - return ZOUL_SENSORS_ERROR; - } - - if((value != ZOUL_SENSORS_ADC1) && (value != ZOUL_SENSORS_ADC2) && - (value != ZOUL_SENSORS_ADC3) && (value != ZOUL_SENSORS_ADC4) && - (value != ZOUL_SENSORS_ADC5)) { - PRINTF("ADC: invalid adc pin mask\n"); - return ZOUL_SENSORS_ERROR; - } - - GPIO_SOFTWARE_CONTROL(GPIO_A_BASE, value); - GPIO_SET_INPUT(GPIO_A_BASE, value); - - if(value & ZOUL_SENSORS_ADC1) { - ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC1_PIN, IOC_OVERRIDE_ANA); - } - if(value & ZOUL_SENSORS_ADC2) { - ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC2_PIN, IOC_OVERRIDE_ANA); - } - if(value & ZOUL_SENSORS_ADC3) { - ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC3_PIN, IOC_OVERRIDE_ANA); - } - if(value & ZOUL_SENSORS_ADC4) { - ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC4_PIN, IOC_OVERRIDE_ANA); - } - if(value & ZOUL_SENSORS_ADC5) { - ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC5_PIN, IOC_OVERRIDE_ANA); - } - adc_init(); - set_decimation_rate(SOC_ADC_ADCCON_DIV_512); - enabled_channels = value; - break; - - case ZOUL_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE: - return set_decimation_rate((uint8_t)value); + case ANALOG_PHIDGET_ROTATION_1109: + /* Linear sensor with 0-300º, 300/33000 = 0.00909 */ + value *= 909; + value /= 100000; + return (uint16_t)value; default: - return ZOUL_SENSORS_ERROR; + return ADC_WRAPPER_ERROR; + } + + return ADC_WRAPPER_ERROR; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +is_sensor_in_list(int type) +{ + uint8_t i; + + for(i = 0; i <= sensors.sensors_num; i++) { + if(sensors.sensor[i].type == type) { + return i + 1; + } } return 0; } /*---------------------------------------------------------------------------*/ static int -status(int type) +value(int type) { - return 1; + uint8_t index; + uint16_t sensor_value; + + index = is_sensor_in_list(type); + + if(!index) { + PRINTF("ADC sensors: sensor not registered\n"); + return ADC_WRAPPER_SUCCESS; + } + + /* Restore index value after the check */ + index -= 1; + sensor_value = convert_to_value(index); + + return sensor_value; } /*---------------------------------------------------------------------------*/ -SENSORS_SENSOR(adc_sensors, ADC_SENSORS, value, configure, status); +static int +configure(int type, int value) +{ + uint8_t pin_mask = GPIO_PIN_MASK(value); + + if((type != ANALOG_GROVE_LIGHT) && (type != ANALOG_PHIDGET_ROTATION_1109) && + (type != ANALOG_GROVE_LOUDNESS)) { + PRINTF("ADC sensors: sensor not supported, check adc_wrapper.h header\n"); + return ADC_WRAPPER_ERROR; + } + + if(sensors.sensors_num >= ADC_SENSORS_MAX) { + PRINTF("ADC sensors: all adc channels available have been assigned\n"); + return ADC_WRAPPER_ERROR; + } + + if((value < 0x01) || (value > 0x07) || (value == BUTTON_USER_PIN)) { + PRINTF("ADC sensors: invalid pin value, (PA0-PA1, PA3) are reserved\n"); + return ADC_WRAPPER_ERROR; + } + + if(sensors.sensors_ports & pin_mask) { + PRINTF("ADC sensors: a sensor has been already assigned to this pin\n"); + return ADC_WRAPPER_ERROR; + } + + switch(type) { + /* V+3.3 sensors */ + case ANALOG_GROVE_LIGHT: + case ANALOG_GROVE_LOUDNESS: + case ANALOG_PHIDGET_ROTATION_1109: + if(adc_zoul.configure(SENSORS_HW_INIT, pin_mask) == ZOUL_SENSORS_ERROR) { + return ADC_WRAPPER_ERROR; + } + sensors.sensor[sensors.sensors_num].type = type; + sensors.sensor[sensors.sensors_num].pin_mask = pin_mask; + sensors.sensor[sensors.sensors_num].vdd3 = 1; + break; + + default: + return ADC_WRAPPER_ERROR; + } + + PRINTF("ADC sensors: type %u mask 0x%02X vdd3 %u\n", + sensors.sensor[sensors.sensors_num].type, + sensors.sensor[sensors.sensors_num].pin_mask, + sensors.sensor[sensors.sensors_num].vdd3); + + sensors.sensors_num++; + sensors.sensors_ports |= pin_mask; + + return ADC_WRAPPER_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(adc_sensors, ADC_SENSORS, value, configure, NULL); /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/platform/zoul/dev/adc-sensors.h b/platform/zoul/dev/adc-sensors.h index 1a10c8d39..8d29a9134 100644 --- a/platform/zoul/dev/adc-sensors.h +++ b/platform/zoul/dev/adc-sensors.h @@ -34,39 +34,26 @@ * \addtogroup zoul-sensors * @{ * - * \defgroup zoul-adc-sensors Zoul Generic ADC sensor + * \defgroup zoul-adc-sensors Zoul adc wrapper to use analogue sensors * - * Driver for the Zoul ADC sensors + * The ADC wrapper implement analogue sensors on top of the ADC interface, + * obscuring the ADC configuration and required calculations to obtain actual + * sensor values. The driver allows to reuse the adc-wrapper implementation and + * add sensors easily, without duplicating code, providing also a simplified + * interface and exposing the available ADC assigned channels by a given + * platform. * - * This driver supports analogue sensors connected to ADC1, ADC2 and AND3 inputs - * This is controlled by the type argument of the value() function. Possible - * choices are: - * - ZOUL_SENSORS_ADC1 - * - ZOUL_SENSORS_ADC2 - * - ZOUL_SENSORS_ADC3 + * To use a given sensor simply use: adc_sensors.configure(SENSOR_NAME, pin_no), + * where pin_no is a given pin in the PA port, check out the board.h for more + * information on available pins. To read a value just use + * adc_sensors.value(SENSOR_NAME), the expected result would be the sensor value + * already converted to the sensor variable type, check the adc-wrapper file + * for more information. * - * To initialize the ADC sensors use the configure() function, using as first - * argument SENSORS_HW_INIT, and choose which ADC channels to enable passing as - * second argument any single or combined (sum) values as below: - * - ZOUL_SENSORS_ADC1 - * - ZOUL_SENSORS_ADC2 - * - ZOUL_SENSORS_ADC3 - * - ZOUL_SENSORS_ADC_ALL (all channels above) - * - * Using an invalid combination will return ZOUL_SENSORS_ERROR. - * - * The decimation rate can be set by passing - * ZOUL_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE as the type argument to the - * configure() function and then specifying the rate through the value - * argument. Valid values are: - * - SOC_ADC_ADCCON_DIV_64 (64 bit rate) - * - SOC_ADC_ADCCON_DIV_128 (128 bit rate) - * - SOC_ADC_ADCCON_DIV_256 (256 bit rate) - * - SOC_ADC_ADCCON_DIV_512 (512 bit rate) * @{ * * \file - * Header file for the Zoul Generic Driver for ADC sensors + * Header file for the Zoul ADC sensors API */ /*---------------------------------------------------------------------------*/ #ifndef ADC_SENSORS_H_ @@ -74,66 +61,19 @@ /*---------------------------------------------------------------------------*/ #include "lib/sensors.h" #include "dev/soc-adc.h" +#include "dev/adc-zoul.h" /*---------------------------------------------------------------------------*/ -/** - * \name Generic ADC sensors - * @{ - */ -#define ADC_SENSORS "ADC sensors" -#define ADC_SENSORS_PORT_BASE GPIO_PORT_TO_BASE(ADC_SENSORS_PORT) - -#ifdef ADC_SENSORS_CONF_REFERENCE -#define ADC_SENSORS_REFERENCE ADC_SENSORS_CONF_REFERENCE -#else -#define ADC_SENSORS_REFERENCE SOC_ADC_ADCCON_REF_AVDD5 -#endif - -/* - * PA0-PA3 are hardcoded to UART0 and the user button for most Zolertia - * platforms, the following assumes PA0-1 shall not be used as ADC input, else - * re-write the below definitions - */ -#define ZOUL_SENSORS_ADC_MIN 2 /**< PA1 pin mask */ - -/* ADC phidget-like connector ADC1 */ -#if ADC_SENSORS_ADC1_PIN >= ZOUL_SENSORS_ADC_MIN -#define ZOUL_SENSORS_ADC1 GPIO_PIN_MASK(ADC_SENSORS_ADC1_PIN) -#else -#define ZOUL_SENSORS_ADC1 0 -#endif -/* ADC phidget-like connector ADC2 */ -#if ADC_SENSORS_ADC2_PIN >= ZOUL_SENSORS_ADC_MIN -#define ZOUL_SENSORS_ADC2 GPIO_PIN_MASK(ADC_SENSORS_ADC2_PIN) -#else -#define ZOUL_SENSORS_ADC2 0 -#endif -/* ADC phidget-like connector ADC3 */ -#if ADC_SENSORS_ADC3_PIN >= ZOUL_SENSORS_ADC_MIN -#define ZOUL_SENSORS_ADC3 GPIO_PIN_MASK(ADC_SENSORS_ADC3_PIN) -#else -#define ZOUL_SENSORS_ADC3 0 -#endif -/* ADC phidget-like connector ADC4 */ -#if ADC_SENSORS_ADC4_PIN >= ZOUL_SENSORS_ADC_MIN -#define ZOUL_SENSORS_ADC4 GPIO_PIN_MASK(ADC_SENSORS_ADC4_PIN) -#else -#define ZOUL_SENSORS_ADC4 0 -#endif -/* ADC phidget-like connector ADC5 */ -#if ADC_SENSORS_ADC5_PIN >= ZOUL_SENSORS_ADC_MIN -#define ZOUL_SENSORS_ADC5 GPIO_PIN_MASK(ADC_SENSORS_ADC5_PIN) -#else -#define ZOUL_SENSORS_ADC5 0 -#endif -/* - * This is safe as the disabled sensors should have a zero value thus not - * affecting the mask operations - */ -#define ZOUL_SENSORS_ADC_ALL (ZOUL_SENSORS_ADC1 + ZOUL_SENSORS_ADC2 + \ - ZOUL_SENSORS_ADC3 + ZOUL_SENSORS_ADC4 + \ - ZOUL_SENSORS_ADC5) -/** @} */ +#define ADC_WRAPPER_SUCCESS 0x00 +#define ADC_WRAPPER_ERROR (-1) +#define ADC_WRAPPER_EXTERNAL_VREF 5000 +#define ADC_WRAPPER_EXTERNAL_VREF_CROSSVAL 3300 /*---------------------------------------------------------------------------*/ +#define ANALOG_GROVE_LIGHT 0x01 +#define ANALOG_PHIDGET_ROTATION_1109 0x02 +#define ANALOG_GROVE_LOUDNESS 0x03 +/* -------------------------------------------------------------------------- */ +#define ADC_SENSORS "ADC sensors API" +/* -------------------------------------------------------------------------- */ extern const struct sensors_sensor adc_sensors; /*---------------------------------------------------------------------------*/ #endif /* ADC_SENSORS_H_ */ diff --git a/platform/zoul/dev/adc-wrapper.c b/platform/zoul/dev/adc-wrapper.c deleted file mode 100644 index 02cb5f77c..000000000 --- a/platform/zoul/dev/adc-wrapper.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2016, Zolertia - http://www.zolertia.com - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/*---------------------------------------------------------------------------*/ -/** - * \addtogroup zoul-adc-wrapper - * @{ - * - * \file - * Generic driver for the Zoul ADC wrapper for analogue sensors - */ -/*---------------------------------------------------------------------------*/ -#include "contiki.h" -#include "sys/clock.h" -#include "dev/ioc.h" -#include "dev/gpio.h" -#include "dev/adc.h" -#include "adc-sensors.h" -#include "adc-wrapper.h" -#include "zoul-sensors.h" - -#include -#include -/*---------------------------------------------------------------------------*/ -#define DEBUG 1 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif -/*---------------------------------------------------------------------------*/ -typedef struct { - int type; - uint8_t pin_mask; - uint8_t vdd3; -} adc_info_t; - -typedef struct { - uint8_t sensors_num; - uint8_t sensors_ports; - adc_info_t sensor[ADC_SENSORS_MAX]; -} adc_wrapper_t; - -static adc_wrapper_t sensors; -/*---------------------------------------------------------------------------*/ -static uint16_t -convert_to_value(uint8_t index) -{ - uint32_t value; - value = adc_sensors.value(sensors.sensor[index].pin_mask); - - if(value == ZOUL_SENSORS_ERROR) { - PRINTF("ADC wrapper: failed retrieving data\n"); - return ADC_WRAPPER_ERROR; - } - - /* Default voltage divisor relation is 5/3 aprox, change at adc_wrapper.h, - * calculations below assume a decimation rate of 512 (12 bits ENOB) and - * AVVD5 voltage reference of 3.3V - */ - - if(!sensors.sensor[index].vdd3) { - value *= ADC_WRAPPER_EXTERNAL_VREF; - value /= ADC_WRAPPER_EXTERNAL_VREF_CROSSVAL; - } - - switch(sensors.sensor[index].type) { - case ANALOG_GROVE_LIGHT: - /* Light dependant resistor (LDR) resistance value*/ - value = (10230 - (value * 10)) / value; - /* TODO: With the resistance we could calculate the lux as 63*R^(-0.7) */ - return (uint16_t)value; - - case ANALOG_GROVE_LOUDNESS: - /* Based on the LM2904 amplifier (blue version with potentiometer) */ - return (uint16_t)value; - - case ANALOG_PHIDGET_ROTATION_1109: - /* Linear sensor with 0-300º, 300/33000 = 0.00909 */ - value *= 909; - value /= 100000; - return (uint16_t)value; - - default: - return ADC_WRAPPER_ERROR; - } - - return ADC_WRAPPER_ERROR; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -is_sensor_in_list(int type) -{ - uint8_t i; - - for(i = 0; i <= sensors.sensors_num; i++) { - if(sensors.sensor[i].type == type) { - return i + 1; - } - } - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -value(int type) -{ - uint8_t index; - uint16_t sensor_value; - - index = is_sensor_in_list(type); - - if(!index) { - PRINTF("ADC wrapper: sensor not registered\n"); - return ADC_WRAPPER_SUCCESS; - } - - /* Restore index value after the check */ - index -= 1; - sensor_value = convert_to_value(index); - - return sensor_value; -} -/*---------------------------------------------------------------------------*/ -static int -configure(int type, int value) -{ - uint8_t pin_mask = GPIO_PIN_MASK(value); - - if((type != ANALOG_GROVE_LIGHT) && (type != ANALOG_PHIDGET_ROTATION_1109) && - (type != ANALOG_GROVE_LOUDNESS)) { - PRINTF("ADC wrapper: sensor not supported, check adc_wrapper.h header\n"); - return ADC_WRAPPER_ERROR; - } - - if(sensors.sensors_num >= ADC_SENSORS_MAX) { - PRINTF("ADC wrapper: all adc channels available have been assigned\n"); - return ADC_WRAPPER_ERROR; - } - - if((value < 0x01) || (value > 0x07) || (value == BUTTON_USER_PIN)) { - PRINTF("ADC wrapper: invalid pin value, (PA0-PA1, PA3) are reserved\n"); - return ADC_WRAPPER_ERROR; - } - - if(sensors.sensors_ports & pin_mask) { - PRINTF("ADC wrapper: a sensor has been already assigned to this pin\n"); - return ADC_WRAPPER_ERROR; - } - - switch(type) { - /* V+3.3 sensors */ - case ANALOG_GROVE_LIGHT: - case ANALOG_GROVE_LOUDNESS: - case ANALOG_PHIDGET_ROTATION_1109: - if(adc_sensors.configure(SENSORS_HW_INIT, pin_mask) == - ZOUL_SENSORS_ERROR) { - return ADC_WRAPPER_ERROR; - } - sensors.sensor[sensors.sensors_num].type = type; - sensors.sensor[sensors.sensors_num].pin_mask = pin_mask; - sensors.sensor[sensors.sensors_num].vdd3 = 1; - break; - - default: - return ADC_WRAPPER_ERROR; - } - - PRINTF("ADC wrapper: type %u mask 0x%02X vdd3 %u\n", - sensors.sensor[sensors.sensors_num].type, - sensors.sensor[sensors.sensors_num].pin_mask, - sensors.sensor[sensors.sensors_num].vdd3); - - sensors.sensors_num++; - sensors.sensors_ports |= pin_mask; - - return ADC_WRAPPER_SUCCESS; -} -/*---------------------------------------------------------------------------*/ -static int -status(int type) -{ - return 1; -} -/*---------------------------------------------------------------------------*/ -SENSORS_SENSOR(adc_wrapper, ADC_WRAPPER, value, configure, status); -/*---------------------------------------------------------------------------*/ -/** @} */ - diff --git a/platform/zoul/dev/adc-wrapper.h b/platform/zoul/dev/adc-wrapper.h deleted file mode 100644 index 5a9e63b19..000000000 --- a/platform/zoul/dev/adc-wrapper.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2015, Zolertia - http://www.zolertia.com - * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/*---------------------------------------------------------------------------*/ -/** - * \addtogroup zoul-sensors - * @{ - * - * \defgroup zoul-adc-wrapper Zoul adc wrapper to use analogue sensors - * - * The ADC wrapper allows to use analogue sensors on top of the ADC interface, - * obscuring the ADC configuration and required calculations to obtain actual - * sensor values. The driver allows to reuse the adc-wrapper implementation and - * add sensors easily, without duplicating code, providing also a simplified - * interface and exposing the available ADC assigned channels by a given - * platform. - * - * To use a given sensor simply use: adc_wrapper.configure(SENSOR_NAME, pin_no), - * where pin_no is a given pin in the PA port, check out the board.h for more - * information on available pins. To read a value just use - * adc_wrapper.value(SENSOR_NAME), the expected result would be the sensor value - * already converted to the sensor variable type, check the adc-wrapper file - * for more information. - * - * @{ - * - * \file - * Header file for the Zoul ADC wrapper - */ -/*---------------------------------------------------------------------------*/ -#ifndef ADC_WRAPPER_H_ -#define ADC_WRAPPER_H_ -/*---------------------------------------------------------------------------*/ -#include "lib/sensors.h" -#include "dev/soc-adc.h" -#include "dev/adc-sensors.h" -/*---------------------------------------------------------------------------*/ -#define ADC_WRAPPER_SUCCESS 0x00 -#define ADC_WRAPPER_ERROR (-1) -#define ADC_WRAPPER_EXTERNAL_VREF 5000 -#define ADC_WRAPPER_EXTERNAL_VREF_CROSSVAL 3300 -/*---------------------------------------------------------------------------*/ -#define ANALOG_GROVE_LIGHT 0x01 -#define ANALOG_PHIDGET_ROTATION_1109 0x02 -#define ANALOG_GROVE_LOUDNESS 0x03 -/* -------------------------------------------------------------------------- */ -#define ADC_WRAPPER "ADC wrapper API" -/* -------------------------------------------------------------------------- */ -extern const struct sensors_sensor adc_wrapper; -/*---------------------------------------------------------------------------*/ -#endif /* ADC_WRAPPER_H_ */ -/*---------------------------------------------------------------------------*/ -/** - * @} - * @} - */ - diff --git a/platform/zoul/dev/adc-zoul.c b/platform/zoul/dev/adc-zoul.c new file mode 100644 index 000000000..4e309dcf4 --- /dev/null +++ b/platform/zoul/dev/adc-zoul.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-adc-interface + * @{ + * + * \file + * Generic driver for the Zoul ADC interface + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/clock.h" +#include "dev/ioc.h" +#include "dev/gpio.h" +#include "dev/adc.h" +#include "adc-zoul.h" +#include "zoul-sensors.h" +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t decimation_rate; +static uint8_t enabled_channels; +/*---------------------------------------------------------------------------*/ +static int +set_decimation_rate(uint8_t rate) +{ + switch(rate) { + case SOC_ADC_ADCCON_DIV_64: + case SOC_ADC_ADCCON_DIV_128: + case SOC_ADC_ADCCON_DIV_256: + case SOC_ADC_ADCCON_DIV_512: + decimation_rate = rate; + break; + default: + return ZOUL_SENSORS_ERROR; + } + + return decimation_rate; +} +/*---------------------------------------------------------------------------*/ +static int +get_channel_pin(int type) +{ + if((ZOUL_SENSORS_ADC1) && (type == ZOUL_SENSORS_ADC1)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC1_PIN; + } + if((ZOUL_SENSORS_ADC2) && (type == ZOUL_SENSORS_ADC2)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC2_PIN; + } + if((ZOUL_SENSORS_ADC3) && (type == ZOUL_SENSORS_ADC3)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC3_PIN; + } + if((ZOUL_SENSORS_ADC4) && (type == ZOUL_SENSORS_ADC4)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC4_PIN; + } + if((ZOUL_SENSORS_ADC5) && (type == ZOUL_SENSORS_ADC5)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC5_PIN; + } + return ZOUL_SENSORS_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + int channel; + int16_t res; + + if(!(type & enabled_channels)) { + PRINTF("ADC: channel not enabled\n"); + return ZOUL_SENSORS_ERROR; + } + + channel = get_channel_pin(type); + + if(channel == ZOUL_SENSORS_ERROR) { + PRINTF("ADC: pin not active\n"); + return ZOUL_SENSORS_ERROR; + } + + res = adc_get(channel, ADC_SENSORS_REFERENCE, decimation_rate); + + /* Only allow negative values if using differential input */ + if((ADC_SENSORS_REFERENCE != SOC_ADC_ADCCON_REF_EXT_DIFF) && (res < 0)) { + res = 0; + } + + return res; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + + /* This should filter out disabled sensors as its value should be zero */ + if((value < ZOUL_SENSORS_ADC_MIN) || (value > ZOUL_SENSORS_ADC_ALL)) { + PRINTF("ADC: invalid adc pin mask (0x%02X)\n", value); + return ZOUL_SENSORS_ERROR; + } + + if((value != ZOUL_SENSORS_ADC1) && (value != ZOUL_SENSORS_ADC2) && + (value != ZOUL_SENSORS_ADC3) && (value != ZOUL_SENSORS_ADC4) && + (value != ZOUL_SENSORS_ADC5)) { + PRINTF("ADC: invalid adc pin mask\n"); + return ZOUL_SENSORS_ERROR; + } + + GPIO_SOFTWARE_CONTROL(GPIO_A_BASE, value); + GPIO_SET_INPUT(GPIO_A_BASE, value); + + if(value & ZOUL_SENSORS_ADC1) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC1_PIN, IOC_OVERRIDE_ANA); + } + if(value & ZOUL_SENSORS_ADC2) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC2_PIN, IOC_OVERRIDE_ANA); + } + if(value & ZOUL_SENSORS_ADC3) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC3_PIN, IOC_OVERRIDE_ANA); + } + if(value & ZOUL_SENSORS_ADC4) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC4_PIN, IOC_OVERRIDE_ANA); + } + if(value & ZOUL_SENSORS_ADC5) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC5_PIN, IOC_OVERRIDE_ANA); + } + adc_init(); + set_decimation_rate(SOC_ADC_ADCCON_DIV_512); + enabled_channels = value; + break; + + case ZOUL_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE: + return set_decimation_rate((uint8_t)value); + + default: + return ZOUL_SENSORS_ERROR; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(adc_zoul, ADC_ZOUL, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ + diff --git a/platform/zoul/dev/adc-zoul.h b/platform/zoul/dev/adc-zoul.h new file mode 100644 index 000000000..d47da43c7 --- /dev/null +++ b/platform/zoul/dev/adc-zoul.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-adc-interface Zoul Generic ADC interface + * + * Driver for the Zoul ADC interface + * + * This driver supports analogue sensors connected to ADC1, ADC2 and AND3 inputs + * This is controlled by the type argument of the value() function. Possible + * choices are: + * + * - ZOUL_SENSORS_ADC1 + * - ZOUL_SENSORS_ADC2 + * - ZOUL_SENSORS_ADC3 + * - ZOUL_SENSORS_ADC4 + * - ZOUL_SENSORS_ADC5 + * + * To initialize the ADC sensors use the configure() function, using as first + * argument SENSORS_HW_INIT, and choose which ADC channels to enable passing as + * second argument any single or combined (sum) values as below: + * + * - Either use multiple values (i.e ZOUL_SENSORS_ADC1 + ZOUL_SENSORS_ADC2) + * - ZOUL_SENSORS_ADC_ALL (all channels above) + * + * Using an invalid combination will return ZOUL_SENSORS_ERROR. + * + * The decimation rate can be set by passing + * ZOUL_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE as the type argument to the + * configure() function and then specifying the rate through the value + * argument. Valid values are: + * + * - SOC_ADC_ADCCON_DIV_64 (64 bit rate) + * - SOC_ADC_ADCCON_DIV_128 (128 bit rate) + * - SOC_ADC_ADCCON_DIV_256 (256 bit rate) + * - SOC_ADC_ADCCON_DIV_512 (512 bit rate) + * @{ + * + * \file + * Header file for the Zoul ADC interface + */ +/*---------------------------------------------------------------------------*/ +#ifndef ADC_ZOUL_H_ +#define ADC_ZOUL_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "dev/soc-adc.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Generic ADC sensors + * @{ + */ +#define ADC_ZOUL "ADC sensor interface" +#define ADC_SENSORS_PORT_BASE GPIO_PORT_TO_BASE(ADC_SENSORS_PORT) + +#ifdef ADC_SENSORS_CONF_REFERENCE +#define ADC_SENSORS_REFERENCE ADC_SENSORS_CONF_REFERENCE +#else +#define ADC_SENSORS_REFERENCE SOC_ADC_ADCCON_REF_AVDD5 +#endif + +/* + * PA0-PA3 are hardcoded to UART0 and the user button for most Zolertia + * platforms, the following assumes PA0-1 shall not be used as ADC input, else + * re-write the below definitions + */ +#define ZOUL_SENSORS_ADC_MIN 2 /**< PA1 pin mask */ + +/* ADC phidget-like connector ADC1 */ +#if ADC_SENSORS_ADC1_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC1 GPIO_PIN_MASK(ADC_SENSORS_ADC1_PIN) +#else +#define ZOUL_SENSORS_ADC1 0 +#endif +/* ADC phidget-like connector ADC2 */ +#if ADC_SENSORS_ADC2_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC2 GPIO_PIN_MASK(ADC_SENSORS_ADC2_PIN) +#else +#define ZOUL_SENSORS_ADC2 0 +#endif +/* ADC phidget-like connector ADC3 */ +#if ADC_SENSORS_ADC3_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC3 GPIO_PIN_MASK(ADC_SENSORS_ADC3_PIN) +#else +#define ZOUL_SENSORS_ADC3 0 +#endif +/* ADC phidget-like connector ADC4 */ +#if ADC_SENSORS_ADC4_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC4 GPIO_PIN_MASK(ADC_SENSORS_ADC4_PIN) +#else +#define ZOUL_SENSORS_ADC4 0 +#endif +/* ADC phidget-like connector ADC5 */ +#if ADC_SENSORS_ADC5_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC5 GPIO_PIN_MASK(ADC_SENSORS_ADC5_PIN) +#else +#define ZOUL_SENSORS_ADC5 0 +#endif +/* + * This is safe as the disabled sensors should have a zero value thus not + * affecting the mask operations + */ +#define ZOUL_SENSORS_ADC_ALL (ZOUL_SENSORS_ADC1 + ZOUL_SENSORS_ADC2 + \ + ZOUL_SENSORS_ADC3 + ZOUL_SENSORS_ADC4 + \ + ZOUL_SENSORS_ADC5) +/** @} */ +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor adc_zoul; +/*---------------------------------------------------------------------------*/ +#endif /* ADC_ZOUL_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ +