diff --git a/boards/arduino-atmega-common/Makefile.features b/boards/arduino-atmega-common/Makefile.features index 92b1f77884..7b4cdf7eb9 100644 --- a/boards/arduino-atmega-common/Makefile.features +++ b/boards/arduino-atmega-common/Makefile.features @@ -1,4 +1,5 @@ # Put defined MCU peripherals here (in alphabetical order) +FEATURES_PROVIDED += periph_adc FEATURES_PROVIDED += periph_gpio FEATURES_PROVIDED += periph_i2c FEATURES_PROVIDED += periph_spi diff --git a/boards/arduino-atmega-common/include/arduino_board.h b/boards/arduino-atmega-common/include/arduino_board.h index 3a8d7b958e..de5c4c82df 100644 --- a/boards/arduino-atmega-common/include/arduino_board.h +++ b/boards/arduino-atmega-common/include/arduino_board.h @@ -109,6 +109,30 @@ static const gpio_t arduino_pinmap[] = { #endif }; +/** + * @brief Look-up table for the Arduino's analog pins + */ +static const adc_t arduino_analog_map[] = { + ARDUINO_A0, + ARDUINO_A1, + ARDUINO_A2, + ARDUINO_A3, + ARDUINO_A4, + ARDUINO_A5, + ARDUINO_A6, + ARDUINO_A7, +#ifdef CPU_ATMEGA2560 + ARDUINO_A8, + ARDUINO_A9, + ARDUINO_A10, + ARDUINO_A11, + ARDUINO_A12, + ARDUINO_A13, + ARDUINO_A14, + ARDUINO_A15, +#endif +}; + #ifdef __cplusplus } #endif diff --git a/boards/arduino-atmega-common/include/arduino_pinmap.h b/boards/arduino-atmega-common/include/arduino_pinmap.h index feac1c5bc2..842a2d72bd 100644 --- a/boards/arduino-atmega-common/include/arduino_pinmap.h +++ b/boards/arduino-atmega-common/include/arduino_pinmap.h @@ -25,6 +25,9 @@ #ifndef ARDUINO_PINMAP_H #define ARDUINO_PINMAP_H +#include "periph/gpio.h" +#include "periph/adc.h" + #ifdef __cplusplus extern "C" { #endif @@ -155,9 +158,27 @@ extern "C" { #define ARDUINO_PIN_A14 ARDUINO_PIN_68 #define ARDUINO_PIN_A15 ARDUINO_PIN_69 #endif - /** @ */ +#define ARDUINO_A0 ADC_LINE(0) +#define ARDUINO_A1 ADC_LINE(1) +#define ARDUINO_A2 ADC_LINE(2) +#define ARDUINO_A3 ADC_LINE(3) +#define ARDUINO_A4 ADC_LINE(4) +#define ARDUINO_A5 ADC_LINE(5) +#define ARDUINO_A6 ADC_LINE(6) +#define ARDUINO_A7 ADC_LINE(7) +#ifdef CPU_ATMEGA2560 +#define ARDUINO_A8 ADC_LINE(8) +#define ARDUINO_A9 ADC_LINE(9) +#define ARDUINO_A10 ADC_LINE(10) +#define ARDUINO_A11 ADC_LINE(11) +#define ARDUINO_A12 ADC_LINE(12) +#define ARDUINO_A13 ADC_LINE(13) +#define ARDUINO_A14 ADC_LINE(14) +#define ARDUINO_A15 ADC_LINE(15) +#endif + #ifdef __cplusplus } #endif diff --git a/boards/arduino-atmega-common/include/periph_conf.h b/boards/arduino-atmega-common/include/periph_conf.h index af5e5bdcbe..4a1681fde3 100644 --- a/boards/arduino-atmega-common/include/periph_conf.h +++ b/boards/arduino-atmega-common/include/periph_conf.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen * 2016 Laurent Navet + * 2017 HAW Hamburg, Dimitri Nahm * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -17,6 +18,7 @@ * @author Hinnerk van Bruinehsen * @author Laurent Navet * @author Hauke Petersen + * @author Dimitri Nahm */ #ifndef PERIPH_CONF_H @@ -136,9 +138,29 @@ extern "C" { /** @} */ /** - * @brief I2C configuration + * @name I2C configuration + * @{ */ #define I2C_NUMOF 1 +/** @} */ + +/** + * @name ADC configuration + * + * The number of ADC channels of the atmega328p depends on the package: + * - 6-channel 10-bit ADC in PDIP package + * - 8-channel 10-bit ADC in TQFP and QFN/MLF package + * Arduino UNO / Duemilanove has thereby 6 channels. But only 5 channels can be + * used for ADC, because the pin of ADC5 emulate a software triggered interrupt. + * -> boards -> arduino-atmega-common -> include -> board_common.h + * @{ + */ +#if defined (CPU_ATMEGA328P) || defined (CPU_ATMEGA1281) +#define ADC_NUMOF (8U) +#elif defined (CPU_ATMEGA2560) +#define ADC_NUMOF (16U) +#endif +/** @} */ #ifdef __cplusplus } diff --git a/boards/arduino-due/include/arduino_board.h b/boards/arduino-due/include/arduino_board.h index 2a08f2c4f4..e9a8657351 100644 --- a/boards/arduino-due/include/arduino_board.h +++ b/boards/arduino-due/include/arduino_board.h @@ -115,6 +115,24 @@ static const gpio_t arduino_pinmap[] = { ARDUINO_PIN_78, }; +/** + * @brief Look-up table for the Arduino's analog pins + */ +static const adc_t arduino_analog_map[] = { + ARDUINO_A0, + ARDUINO_A1, + ARDUINO_A2, + ARDUINO_A3, + ARDUINO_A4, + ARDUINO_A5, + ARDUINO_A6, + ARDUINO_A7, + ARDUINO_A8, + ARDUINO_A9, + ARDUINO_A10, + ARDUINO_A11, +}; + #ifdef __cplusplus } #endif diff --git a/boards/arduino-mkr-common/include/arduino_board.h b/boards/arduino-mkr-common/include/arduino_board.h index 9d7325eac8..41c8fc8796 100644 --- a/boards/arduino-mkr-common/include/arduino_board.h +++ b/boards/arduino-mkr-common/include/arduino_board.h @@ -55,6 +55,19 @@ static const gpio_t arduino_pinmap[] = { ARDUINO_PIN_A6, }; +/** + * @brief Look-up table for the Arduino's analog pins + */ +static const adc_t arduino_analog_map[] = { + ARDUINO_A0, + ARDUINO_A1, + ARDUINO_A2, + ARDUINO_A3, + ARDUINO_A4, + ARDUINO_A5, + ARDUINO_A6, +}; + #ifdef __cplusplus } #endif diff --git a/boards/arduino-mkr-common/include/arduino_pinmap.h b/boards/arduino-mkr-common/include/arduino_pinmap.h index 7a869771df..b48a11f886 100644 --- a/boards/arduino-mkr-common/include/arduino_pinmap.h +++ b/boards/arduino-mkr-common/include/arduino_pinmap.h @@ -23,6 +23,7 @@ #define ARDUINO_PINMAP_H #include "periph/gpio.h" +#include "periph/adc.h" #ifdef __cplusplus extern "C" { @@ -58,6 +59,19 @@ extern "C" { #define ARDUINO_PIN_A6 GPIO_PIN(PA, 7) /* AIN7 */ /** @} */ +/** + * @name Mapping of Ardunino analog pins to RIOT ADC lines + * @{ + */ +#define ARDUINO_A0 ADC_LINE(0) +#define ARDUINO_A1 ADC_LINE(1) +#define ARDUINO_A2 ADC_LINE(2) +#define ARDUINO_A3 ADC_LINE(3) +#define ARDUINO_A4 ADC_LINE(4) +#define ARDUINO_A5 ADC_LINE(5) +#define ARDUINO_A6 ADC_LINE(6) +/** @} */ + #ifdef __cplusplus } #endif diff --git a/boards/arduino-zero/include/arduino_board.h b/boards/arduino-zero/include/arduino_board.h index 620a6cebe7..ece5c3b1cf 100644 --- a/boards/arduino-zero/include/arduino_board.h +++ b/boards/arduino-zero/include/arduino_board.h @@ -58,6 +58,18 @@ static const gpio_t arduino_pinmap[] = { ARDUINO_PIN_A5, }; +/** + * @brief Look-up table for the Arduino's analog pins + */ +static const adc_t arduino_analog_map[] = { + ARDUINO_A0, + ARDUINO_A1, + ARDUINO_A2, + ARDUINO_A3, + ARDUINO_A4, + ARDUINO_A5, +}; + #ifdef __cplusplus } #endif diff --git a/boards/arduino-zero/include/arduino_pinmap.h b/boards/arduino-zero/include/arduino_pinmap.h index 77d7310fbb..d8ae6f0c1a 100644 --- a/boards/arduino-zero/include/arduino_pinmap.h +++ b/boards/arduino-zero/include/arduino_pinmap.h @@ -23,6 +23,7 @@ #define ARDUINO_PINMAP_H #include "periph/gpio.h" +#include "periph/adc.h" #ifdef __cplusplus extern "C" { @@ -56,6 +57,18 @@ extern "C" { #define ARDUINO_PIN_A5 GPIO_PIN(PB, 2) /** @ */ +/** + * @name Mapping of Ardunino analog pins to RIOT ADC lines + * @{ + */ +#define ARDUINO_A0 ADC_LINE(0) +#define ARDUINO_A1 ADC_LINE(1) +#define ARDUINO_A2 ADC_LINE(2) +#define ARDUINO_A3 ADC_LINE(3) +#define ARDUINO_A4 ADC_LINE(4) +#define ARDUINO_A5 ADC_LINE(5) +/** @} */ + #ifdef __cplusplus } #endif diff --git a/boards/nucleo-common/include/arduino_board.h b/boards/nucleo-common/include/arduino_board.h index fe2e0232ff..2cdd599e2d 100644 --- a/boards/nucleo-common/include/arduino_board.h +++ b/boards/nucleo-common/include/arduino_board.h @@ -58,6 +58,18 @@ static const gpio_t arduino_pinmap[] = { ARDUINO_PIN_A5, }; +/** + * @brief Look-up table for the Arduino's analog pins + */ +static const adc_t arduino_analog_map[] = { + ARDUINO_A0, + ARDUINO_A1, + ARDUINO_A2, + ARDUINO_A3, + ARDUINO_A4, + ARDUINO_A5, +}; + #ifdef __cplusplus } #endif diff --git a/boards/nucleo-common/include/arduino_pinmap.h b/boards/nucleo-common/include/arduino_pinmap.h index 86752c71c6..75bd8aa18c 100644 --- a/boards/nucleo-common/include/arduino_pinmap.h +++ b/boards/nucleo-common/include/arduino_pinmap.h @@ -23,6 +23,7 @@ #define ARDUINO_PINMAP_H #include "periph/gpio.h" +#include "periph/adc.h" #ifdef __cplusplus extern "C" { @@ -64,6 +65,18 @@ extern "C" { #define ARDUINO_PIN_A5 GPIO_PIN(PORT_C, 0) /** @ */ +/** + * @name Mapping of Ardunino analog pins to RIOT ADC lines + * @{ + */ +#define ARDUINO_A0 ADC_LINE(0) +#define ARDUINO_A1 ADC_LINE(1) +#define ARDUINO_A2 ADC_LINE(2) +#define ARDUINO_A3 ADC_LINE(3) +#define ARDUINO_A4 ADC_LINE(4) +#define ARDUINO_A5 ADC_LINE(5) +/** @} */ + #ifdef __cplusplus } #endif diff --git a/boards/nucleo144-common/include/arduino_board.h b/boards/nucleo144-common/include/arduino_board.h index 7d20e8b573..3dae69fc9d 100644 --- a/boards/nucleo144-common/include/arduino_board.h +++ b/boards/nucleo144-common/include/arduino_board.h @@ -53,6 +53,18 @@ static const gpio_t arduino_pinmap[] = { ARDUINO_PIN_A5, }; +/** + * @brief Look-up table for the Arduino's analog pins + */ +static const adc_t arduino_analog_map[] = { + ARDUINO_A0, + ARDUINO_A1, + ARDUINO_A2, + ARDUINO_A3, + ARDUINO_A4, + ARDUINO_A5, +}; + #ifdef __cplusplus } #endif diff --git a/boards/nucleo144-common/include/arduino_pinmap.h b/boards/nucleo144-common/include/arduino_pinmap.h index 80d4c5a436..aceb56dbb1 100644 --- a/boards/nucleo144-common/include/arduino_pinmap.h +++ b/boards/nucleo144-common/include/arduino_pinmap.h @@ -23,6 +23,7 @@ #define ARDUINO_PINMAP_H #include "periph/gpio.h" +#include "periph/adc.h" #ifdef __cplusplus extern "C" { @@ -74,6 +75,18 @@ extern "C" { #endif /** @ */ +/** + * @name Mapping of Ardunino analog pins to RIOT ADC lines + * @{ + */ +#define ARDUINO_A0 ADC_LINE(0) +#define ARDUINO_A1 ADC_LINE(1) +#define ARDUINO_A2 ADC_LINE(2) +#define ARDUINO_A3 ADC_LINE(3) +#define ARDUINO_A4 ADC_LINE(4) +#define ARDUINO_A5 ADC_LINE(5) +/** @} */ + #ifdef __cplusplus } #endif diff --git a/boards/nucleo32-common/include/arduino_board.h b/boards/nucleo32-common/include/arduino_board.h index 2f2b5e3f3d..3d0f7bac0e 100644 --- a/boards/nucleo32-common/include/arduino_board.h +++ b/boards/nucleo32-common/include/arduino_board.h @@ -58,6 +58,20 @@ static const gpio_t arduino_pinmap[] = { ARDUINO_PIN_A7 }; +/** + * @brief Look-up table for the Arduino's analog pins + */ +static const adc_t arduino_analog_map[] = { + ARDUINO_A0, + ARDUINO_A1, + ARDUINO_A2, + ARDUINO_A3, + ARDUINO_A4, + ARDUINO_A5, + ARDUINO_A6, + ARDUINO_A7, +}; + #ifdef __cplusplus } #endif diff --git a/boards/nucleo32-common/include/arduino_pinmap.h b/boards/nucleo32-common/include/arduino_pinmap.h index 7b7db79fef..fa2ce17278 100644 --- a/boards/nucleo32-common/include/arduino_pinmap.h +++ b/boards/nucleo32-common/include/arduino_pinmap.h @@ -23,7 +23,7 @@ #define ARDUINO_PINMAP_H #include "periph/gpio.h" - +#include "periph/adc.h" #ifdef __cplusplus extern "C" { #endif @@ -63,6 +63,20 @@ extern "C" { #define ARDUINO_PIN_A7 GPIO_PIN(PORT_A, 2) /** @ */ +/** + * @name Mapping of Ardunino analog pins to RIOT ADC lines + * @{ + */ +#define ARDUINO_A0 ADC_LINE(0) +#define ARDUINO_A1 ADC_LINE(1) +#define ARDUINO_A2 ADC_LINE(2) +#define ARDUINO_A3 ADC_LINE(3) +#define ARDUINO_A4 ADC_LINE(4) +#define ARDUINO_A5 ADC_LINE(5) +#define ARDUINO_A6 ADC_LINE(6) +#define ARDUINO_A7 ADC_LINE(7) +/** @} */ + #ifdef __cplusplus } #endif diff --git a/boards/stm32f4discovery/include/arduino_board.h b/boards/stm32f4discovery/include/arduino_board.h index dd0a3169b0..1376f9bd9a 100644 --- a/boards/stm32f4discovery/include/arduino_board.h +++ b/boards/stm32f4discovery/include/arduino_board.h @@ -19,7 +19,7 @@ #ifndef ARDUINO_BOARD_H #define ARDUINO_BOARD_H -#include "periph/gpio.h" +#include "arduino_pinmap.h" #ifdef __cplusplus extern "C" { @@ -28,14 +28,24 @@ extern "C" { #define ARDUINO_LED (2) static const gpio_t arduino_pinmap[] = { - GPIO_PIN(PORT_D, 12), - GPIO_PIN(PORT_D, 13), - GPIO_PIN(PORT_D, 14), - GPIO_PIN(PORT_D, 15), - GPIO_PIN(PORT_A, 12), - GPIO_PIN(PORT_A, 15), - GPIO_PIN(PORT_B, 1), - GPIO_PIN(PORT_B, 2), + ARDUINO_PIN_0, + ARDUINO_PIN_1, + ARDUINO_PIN_2, + ARDUINO_PIN_3, + ARDUINO_PIN_4, + ARDUINO_PIN_5, + ARDUINO_PIN_6, + ARDUINO_PIN_7, +}; + +/** + * @brief Look-up table for the Arduino's analog pins + */ +static const adc_t arduino_analog_map[] = { + ARDUINO_A0, + ARDUINO_A1, + ARDUINO_A2, + ARDUINO_A3, }; #ifdef __cplusplus diff --git a/boards/stm32f4discovery/include/arduino_pinmap.h b/boards/stm32f4discovery/include/arduino_pinmap.h new file mode 100644 index 0000000000..dfa24aac6b --- /dev/null +++ b/boards/stm32f4discovery/include/arduino_pinmap.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2017 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_stm32f4discovery + * @{ + * + * @file + * @brief Mapping from MCU pins to Arduino pins + * + * You can use the defines in this file for simplified interaction with the + * Arduino specific pin numbers. + * + * @author Sebastian Meiling + */ + +#ifndef ARDUINO_PINMAP_H +#define ARDUINO_PINMAP_H + +#include "periph/gpio.h" +#include "periph/adc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Mapping of MCU pins to Arduino pins + * @{ + */ +#define ARDUINO_PIN_0 GPIO_PIN(PORT_D, 12) +#define ARDUINO_PIN_1 GPIO_PIN(PORT_D, 13) +#define ARDUINO_PIN_2 GPIO_PIN(PORT_D, 14) +#define ARDUINO_PIN_3 GPIO_PIN(PORT_D, 15) +#define ARDUINO_PIN_4 GPIO_PIN(PORT_A, 12) +#define ARDUINO_PIN_5 GPIO_PIN(PORT_A, 15) +#define ARDUINO_PIN_6 GPIO_PIN(PORT_B, 1) +#define ARDUINO_PIN_7 GPIO_PIN(PORT_B, 2) +/** @ */ + +/** + * @name Mapping of Ardunino analog pins to RIOT ADC lines + * @{ + */ +#define ARDUINO_A0 ADC_LINE(0) +#define ARDUINO_A1 ADC_LINE(1) +#define ARDUINO_A2 ADC_LINE(2) +#define ARDUINO_A3 ADC_LINE(3) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* ARDUINO_PINMAP_H */ +/** @} */ diff --git a/boards/waspmote-pro/Makefile.features b/boards/waspmote-pro/Makefile.features index 4e3851d2b6..abcd9925d9 100644 --- a/boards/waspmote-pro/Makefile.features +++ b/boards/waspmote-pro/Makefile.features @@ -1,4 +1,5 @@ # Put defined MCU peripherals here (in alphabetical order) +FEATURES_PROVIDED += periph_adc FEATURES_PROVIDED += periph_gpio FEATURES_PROVIDED += periph_i2c FEATURES_PROVIDED += periph_spi diff --git a/boards/waspmote-pro/include/periph_conf.h b/boards/waspmote-pro/include/periph_conf.h index 8c2476c53d..dd97b1ecc3 100644 --- a/boards/waspmote-pro/include/periph_conf.h +++ b/boards/waspmote-pro/include/periph_conf.h @@ -104,9 +104,18 @@ extern "C" { /** @} */ /** - * @brief I2C configuration + * @name I2C configuration + * @{ */ #define I2C_NUMOF 1 +/** @} */ + +/** + * @name ADC configuration + * @{ + */ +#define ADC_NUMOF (8U) +/** @} */ #ifdef __cplusplus } diff --git a/cpu/atmega_common/periph/adc.c b/cpu/atmega_common/periph/adc.c new file mode 100644 index 0000000000..fac2ad8918 --- /dev/null +++ b/cpu/atmega_common/periph/adc.c @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2016 Laurent Navet + * 2017 HAW Hamburg, Dimitri Nahm + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup drivers_periph + * @{ + * + * @file + * @brief Low-level ADC driver implementation for ATmega family + * + * @author Laurent Navet + * @author Dimitri Nahm + * @author Sebastian Meiling + * @} + */ + +#include "cpu.h" +#include "mutex.h" +#include "assert.h" +#include "periph/adc.h" +#include "periph_conf.h" + +#define ADC_MAX_CLK (200000U) + +static mutex_t lock = MUTEX_INIT; + +static inline void _prep(void) +{ + mutex_lock(&lock); + /* Enable ADC */ + ADCSRA |= (1 << ADEN); +} + +static inline void _done(void) +{ + /* Disable ADC */ + ADCSRA &= ~(1 << ADEN); + mutex_unlock(&lock); +} + +int adc_init(adc_t line) +{ + /* check if the line is valid */ + if (line >= ADC_NUMOF) { + return -1; + } + + _prep(); + + /* Disable corresponding Digital input */ + if (line < 8) { + DIDR0 |= (1 << line); + } +#if defined(CPU_ATMEGA2560) + else { + DIDR2 |= (1 << (line - 8)); + } +#endif + + /* Set ADC-pin as input */ +#if defined(CPU_ATMEGA328P) + DDRC &= ~(1 << line); + PORTC &= ~(1 << line); +#elif defined(CPU_ATMEGA2560) || defined(CPU_ATMEGA1281) + if (line < 8) { + DDRF &= ~(1 << line); + PORTF &= ~(1 << line); + } +#if defined(CPU_ATMEGA2560) + else { + DDRK &= ~(1 << (line-8)); + PORTK &= ~(1 << (line-8)); + } +#endif /* CPU_ATMEGA2560 */ +#endif /* CPU_ATMEGA328P */ + + /* set clock prescaler to get the maximal possible ADC clock value */ + for (uint32_t clk_div = 1; clk_div < 8; ++clk_div) { + if ((CLOCK_CORECLOCK / (1 << clk_div)) <= ADC_MAX_CLK) { + ADCSRA |= clk_div; + break; + } + } + + /* Ref Voltage is Vcc(5V) */ + ADMUX |= (1 << REFS0); + + _done(); + + return 0; +} + +int adc_sample(adc_t line, adc_res_t res) +{ + int sample = 0; + + /* check if resolution is applicable */ + if (res != ADC_RES_10BIT) { + return -1; + } + + _prep(); + + /* set conversion channel */ +#if defined(CPU_ATMEGA328P) || defined(CPU_ATMEGA1281) + ADMUX &= 0xf0; + ADMUX |= line; +#elif defined(CPU_ATMEGA2560) + if (line < 8) { + ADCSRB &= ~(1 << MUX5); + ADMUX &= 0xf0; + ADMUX |= line; + } + else { + ADCSRB |= (1 << MUX5); + ADMUX &= 0xf0; + ADMUX |= (line-8); + } +#endif + + /* Start a new conversion. By default, this conversion will + be performed in single conversion mode. */ + ADCSRA |= (1 << ADSC); + + /* Wait until the conversion is complete */ + while (ADCSRA & (1 << ADSC)) {} + + /* Get conversion result */ + sample = ADC; + + /* Clear the ADIF flag */ + ADCSRA |= (1 << ADIF); + + _done(); + + return sample; +} diff --git a/sys/arduino/base.cpp b/sys/arduino/base.cpp index 4f61a81c4c..4c800018ab 100644 --- a/sys/arduino/base.cpp +++ b/sys/arduino/base.cpp @@ -21,10 +21,13 @@ extern "C" { #include "xtimer.h" #include "periph/gpio.h" +#include "periph/adc.h" } #include "arduino.hpp" +#define ANALOG_PIN_NUMOF (sizeof(arduino_analog_map) / sizeof(arduino_analog_map[0])) + void pinMode(int pin, int mode) { gpio_mode_t m = GPIO_OUT; @@ -58,3 +61,32 @@ void delay(unsigned long msec) { xtimer_usleep(1000 * msec); } + +/* + * Bitfield for the state of the ADC-channels. + * 0: Not initialized + * 1: Successfully initialized + */ +static uint16_t adc_line_state = 0; + +int analogRead(int arduino_pin) +{ + int adc_value; + + /* Check if the ADC line is valid */ + assert((arduino_pin >= 0) && (arduino_pin < (int)ANALOG_PIN_NUMOF)); + + /* Initialization of given ADC channel */ + if (!(adc_line_state & (1 << arduino_pin))) { + if (adc_init(arduino_analog_map[arduino_pin]) != 0) { + return -1; + } + /* The ADC channel is initialized */ + adc_line_state |= 1 << arduino_pin; + } + + /* Read the ADC channel */ + adc_value = adc_sample(arduino_analog_map[arduino_pin], ADC_RES_10BIT); + + return adc_value; +} diff --git a/sys/arduino/include/arduino.hpp b/sys/arduino/include/arduino.hpp index 5323012ad5..b94f17519f 100644 --- a/sys/arduino/include/arduino.hpp +++ b/sys/arduino/include/arduino.hpp @@ -82,5 +82,15 @@ int digitalRead(int pin); */ void delay(unsigned long msec); +/** + * @brief Read the current value of the given analog pin + * + * @param[in] pin pin to read + * + * @return a value between 0 to 1023 that is proportionnal + * to the voltage applied to the pin + */ +int analogRead(int pin); + #endif /* ARDUINO_H */ /** @} */