mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
043e8cc88e
- Rename all `arduino_pinmap.h` to `arduino_iomap.h` - An empty `arduino_pinmap.h` that just includes `arduino_iomap.h` is provided for backward compatibility - Move all info from `arduino_board.h` into the new file as trivial macros, so that they can also be used outside of sketches - The new name reflects the fact not just pin mappings, but also other I/O features such as PWMs are mapped - Drop all `arduino_board.h` - `arduino_board.h` and `arduino_iomap.h` now provide the exact same information, just in a different format - a generic `arduino_board.h` is provided instead that just uses the info in `arduinio_iomap.h` and provides them in the format the code in `sys/arduino` expects it - Add fine grained features to indicate for mappings - availability of mappings for analog pins, DAC pins, PWM pins, UART devices, SPI/I2C buses to the corresponding RIOT identification can now be expressed: - `arduino_pins`: `ARDUINO_PIN_0` etc. are available - `arduino_analog`: `ARDUINO_A0` etc. are available - `arduino_pwm`: `ARDUINO_PIN_13_PWM_DEV` etc. are available - `arduino_dac`: `ARDUINO_DAC0` etc. are available - `arduino_uart`: `ARDUINO_UART_D0D1` or similar are available - `arduino_spi`: `ARDUINO_SPI_ISP` or similar are available - `arduino_i2c`: `ARDUINO_I2C_UNO` or similar are available - mechanical/electrical compatibility with specific form factors can now be expressed as features: - `aruino_shield_nano`: Arduino NANO compatible headers - `aruino_shield_uno`: Arduino UNO compatible headers - `aruino_shield_mega`: Arduino MEGA compatible headers - `aruino_shield_isp`: ISP header is available This provides the groundwork to implement shield support as modules that can rely on the I/O mappings, rather than having to provide a configuration per board.
170 lines
3.8 KiB
C++
170 lines
3.8 KiB
C++
/*
|
|
* Copyright (C) 2015 Freie Universität Berlin
|
|
*
|
|
* 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 sys_arduino
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief Implementation of Arduino core functionality
|
|
*
|
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
|
*
|
|
* @}
|
|
*/
|
|
|
|
#include "arduino_board.h"
|
|
#include "assert.h"
|
|
#include "periph/adc.h"
|
|
#include "periph/gpio.h"
|
|
#include "periph/pwm.h"
|
|
#include "ztimer.h"
|
|
|
|
#include "arduino.hpp"
|
|
|
|
void pinMode(int pin, int mode)
|
|
{
|
|
if ((pin > ARDUINO_PIN_LAST) || (pin < 0) ||
|
|
!gpio_is_valid(arduino_pinmap[pin])) {
|
|
assert(0);
|
|
return;
|
|
}
|
|
gpio_mode_t m = GPIO_OUT;
|
|
|
|
if (mode == INPUT) {
|
|
m = GPIO_IN;
|
|
}
|
|
else if (mode == INPUT_PULLUP) {
|
|
m = GPIO_IN_PU;
|
|
}
|
|
|
|
gpio_init(arduino_pinmap[pin], m);
|
|
}
|
|
|
|
void digitalWrite(int pin, int state)
|
|
{
|
|
assert(gpio_is_valid(arduino_pinmap[pin]));
|
|
gpio_write(arduino_pinmap[pin], state);
|
|
}
|
|
|
|
int digitalRead(int pin)
|
|
{
|
|
assert(gpio_is_valid(arduino_pinmap[pin]));
|
|
if (gpio_read(arduino_pinmap[pin])) {
|
|
return HIGH;
|
|
}
|
|
else {
|
|
return LOW;
|
|
}
|
|
}
|
|
|
|
void delay(unsigned long msec)
|
|
{
|
|
ztimer_sleep(ZTIMER_MSEC, msec);
|
|
}
|
|
|
|
void delayMicroseconds(unsigned long usec)
|
|
{
|
|
ztimer_sleep(ZTIMER_USEC, usec);
|
|
}
|
|
|
|
unsigned long micros()
|
|
{
|
|
return ztimer_now(ZTIMER_USEC);
|
|
}
|
|
|
|
unsigned long millis()
|
|
{
|
|
return ztimer_now(ZTIMER_MSEC);
|
|
}
|
|
|
|
#if IS_USED(MODULE_PERIPH_ADC) && defined(ARDUINO_ANALOG_PIN_LAST)
|
|
int analogRead(int arduino_pin)
|
|
{
|
|
/*
|
|
* Bitfield for the state of the ADC-channels.
|
|
* 0: Not initialized
|
|
* 1: Successfully initialized
|
|
*/
|
|
static uint16_t adc_line_state;
|
|
#if ARDUINO_ANALOG_PIN_LAST > 15
|
|
# error "Implementation currently not compatible with more than 16 analog pins"
|
|
#endif
|
|
int adc_value;
|
|
|
|
/* Check if the ADC line is valid */
|
|
assert((arduino_pin >= 0) && (arduino_pin <= (int)ARDUINO_ANALOG_PIN_LAST));
|
|
|
|
/* Initialization of given ADC channel */
|
|
if (!(adc_line_state & (1UL << 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;
|
|
}
|
|
#endif
|
|
|
|
#if MODULE_PERIPH_PWM
|
|
static int _get_pwm_pin_idx(int pin)
|
|
{
|
|
for (uint8_t i = 0; i < ARRAY_SIZE(arduino_pwm_list); ++i) {
|
|
if (arduino_pwm_list[i].pin == pin) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void analogWrite(int pin, int value)
|
|
{
|
|
/*
|
|
* Bitfield for the state of the PWM devices.
|
|
* 0: Not initialized
|
|
* 1: Successfully initialized
|
|
*/
|
|
static uint8_t pwm_dev_state;
|
|
|
|
/* Clamp given value within bounds */
|
|
if (value < 0) {
|
|
value = 0;
|
|
}
|
|
if ((unsigned)value >= ARDUINO_PWM_STEPS) {
|
|
value = ARDUINO_PWM_STEPS - 1;
|
|
}
|
|
|
|
/* Check if the PWM pin is valid */
|
|
int pin_idx = _get_pwm_pin_idx(pin);
|
|
if (pin_idx == -1) {
|
|
/* Set to digital write if not a PWM pin */
|
|
pinMode(pin, OUTPUT);
|
|
return;
|
|
}
|
|
|
|
/* Initialization of given PWM pin */
|
|
if (!(pwm_dev_state & (1 << arduino_pwm_list[pin_idx].dev))) {
|
|
if (pwm_init(arduino_pwm_list[pin_idx].dev,
|
|
ARDUINO_PWM_MODE, ARDUINO_PWM_FREQU, ARDUINO_PWM_STEPS) == 0) {
|
|
return;
|
|
}
|
|
/* The PWM channel is initialized */
|
|
pwm_dev_state |= (1 << arduino_pwm_list[pin_idx].dev);
|
|
}
|
|
|
|
/* Write analog value */
|
|
pwm_set(arduino_pwm_list[pin_idx].dev, arduino_pwm_list[pin_idx].chan, value);
|
|
}
|
|
#endif /* MODULE_PERIPH_PWM */
|