mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-25 06:23:53 +01:00
Merge pull request #12523 from aabadie/pr/sys/arduino_pwm
sys/arduino: add implementation for analogWrite
This commit is contained in:
commit
a05027cdba
@ -635,11 +635,16 @@ endif
|
||||
|
||||
ifneq (,$(filter arduino,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += arduino
|
||||
FEATURES_OPTIONAL += arduino_pwm
|
||||
FEATURES_OPTIONAL += periph_adc
|
||||
FEATURES_REQUIRED += periph_gpio
|
||||
USEMODULE += xtimer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter arduino_pwm,$(FEATURES_USED)))
|
||||
FEATURES_REQUIRED += periph_pwm
|
||||
endif
|
||||
|
||||
ifneq (,$(filter xtimer,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_timer
|
||||
USEMODULE += div
|
||||
|
||||
@ -14,3 +14,4 @@ FEATURES_PROVIDED += periph_usbdev
|
||||
|
||||
# Various other features (if any)
|
||||
FEATURES_PROVIDED += arduino
|
||||
FEATURES_PROVIDED += arduino_pwm
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#define ARDUINO_BOARD_H
|
||||
|
||||
#include "arduino_pinmap.h"
|
||||
#include "periph/pwm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -70,6 +71,21 @@ static const adc_t arduino_analog_map[] = {
|
||||
ARDUINO_A5,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief PWM frequency
|
||||
*/
|
||||
#define ARDUINO_PWM_FREQU (732U)
|
||||
|
||||
/**
|
||||
* @brief List of PWM GPIO mappings
|
||||
*/
|
||||
static const arduino_pwm_t arduino_pwm_list[] = {
|
||||
{ .pin = 3, .dev = PWM_DEV(0), .chan = 1 },
|
||||
{ .pin = 4, .dev = PWM_DEV(0), .chan = 0 },
|
||||
{ .pin = 8, .dev = PWM_DEV(1), .chan = 0 },
|
||||
{ .pin = 9, .dev = PWM_DEV(1), .chan = 1 },
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
# Put defined MCU peripherals here (in alphabetical order)
|
||||
FEATURES_PROVIDED += periph_adc
|
||||
FEATURES_PROVIDED += periph_i2c
|
||||
FEATURES_PROVIDED += periph_pwm
|
||||
FEATURES_PROVIDED += periph_spi
|
||||
FEATURES_PROVIDED += periph_timer
|
||||
FEATURES_PROVIDED += periph_uart
|
||||
|
||||
# Various other features (if any)
|
||||
FEATURES_PROVIDED += arduino
|
||||
FEATURES_PROVIDED += periph_pwm
|
||||
FEATURES_PROVIDED += arduino_pwm
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#define ARDUINO_BOARD_H
|
||||
|
||||
#include "arduino_pinmap.h"
|
||||
#include "periph/pwm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -141,6 +142,34 @@ static const adc_t arduino_analog_map[] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief PWM frequency
|
||||
*/
|
||||
#define ARDUINO_PWM_FREQU (490U)
|
||||
|
||||
/**
|
||||
* @brief List of PWM GPIO mappings
|
||||
*/
|
||||
static const arduino_pwm_t arduino_pwm_list[] = {
|
||||
#if defined(CPU_ATMEGA2560)
|
||||
{ .pin = 13, .dev = PWM_DEV(0), .chan = 0 },
|
||||
{ .pin = 4, .dev = PWM_DEV(0), .chan = 1 },
|
||||
#elif defined(CPU_ATMEGA32U4)
|
||||
{ .pin = 11, .dev = PWM_DEV(0), .chan = 0 },
|
||||
{ .pin = 3, .dev = PWM_DEV(0), .chan = 1 },
|
||||
#else /* CPU_ATMEGA328p */
|
||||
{ .pin = 6, .dev = PWM_DEV(0), .chan = 0 },
|
||||
{ .pin = 5, .dev = PWM_DEV(0), .chan = 1 },
|
||||
#endif
|
||||
#if defined(CPU_ATMEGA2560)
|
||||
{ .pin = 10, .dev = PWM_DEV(1), .chan = 0 },
|
||||
{ .pin = 9, .dev = PWM_DEV(1), .chan = 1 },
|
||||
#else /* CPU_ATMEGA328p */
|
||||
{ .pin = 11, .dev = PWM_DEV(1), .chan = 0 },
|
||||
{ .pin = 3, .dev = PWM_DEV(1), .chan = 1 },
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -15,3 +15,4 @@ FEATURES_PROVIDED += periph_usbdev
|
||||
|
||||
# Various other features (if any)
|
||||
FEATURES_PROVIDED += arduino
|
||||
FEATURES_PROVIDED += arduino_pwm
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#define ARDUINO_BOARD_H
|
||||
|
||||
#include "arduino_pinmap.h"
|
||||
#include "periph/pwm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -68,6 +69,19 @@ static const adc_t arduino_analog_map[] = {
|
||||
ARDUINO_A6,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief PWM frequency
|
||||
*/
|
||||
#define ARDUINO_PWM_FREQU (732U)
|
||||
|
||||
/**
|
||||
* @brief List of PWM GPIO mappings
|
||||
*/
|
||||
static const arduino_pwm_t arduino_pwm_list[] = {
|
||||
{ .pin = 2, .dev = PWM_DEV(0), .chan = 0 },
|
||||
{ .pin = 3, .dev = PWM_DEV(0), .chan = 1 },
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2,4 +2,7 @@ CPU_MODEL = samd21j18a
|
||||
|
||||
FEATURES_PROVIDED += periph_pwm
|
||||
|
||||
# Various other features (if any)
|
||||
FEATURES_PROVIDED += arduino_pwm
|
||||
|
||||
include $(RIOTBOARD)/common/sodaq/Makefile.features
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
|
||||
#include "periph/gpio.h"
|
||||
#include "periph/adc.h"
|
||||
#include "periph/pwm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -145,6 +146,22 @@ static const adc_t arduino_analog_map[] = {
|
||||
ADC_LINE(14),
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief PWM frequency
|
||||
*/
|
||||
#define ARDUINO_PWM_FREQU (732U)
|
||||
|
||||
/**
|
||||
* @brief List of PWM GPIO mappings
|
||||
*/
|
||||
static const arduino_pwm_t arduino_pwm_list[] = {
|
||||
{ .pin = 20, .dev = PWM_DEV(0), .chan = 0 },
|
||||
{ .pin = 29, .dev = PWM_DEV(0), .chan = 1 },
|
||||
{ .pin = 11, .dev = PWM_DEV(1), .chan = 0 },
|
||||
{ .pin = 13, .dev = PWM_DEV(1), .chan = 1 },
|
||||
{ .pin = 14, .dev = PWM_DEV(1), .chan = 2 },
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -103,6 +103,17 @@ typedef enum {
|
||||
} pwm_mode_t;
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_ARDUINO
|
||||
/**
|
||||
* @brief RIOT GPIO mapping between Arduino pin, PWM device and channel
|
||||
*/
|
||||
typedef struct {
|
||||
int pin; /**< Arduino pin number */
|
||||
int dev; /**< PWM device index of pin */
|
||||
int chan; /**< PWM channel index */
|
||||
} arduino_pwm_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize a PWM device
|
||||
*
|
||||
|
||||
@ -22,6 +22,7 @@ extern "C" {
|
||||
#include "xtimer.h"
|
||||
#include "periph/gpio.h"
|
||||
#include "periph/adc.h"
|
||||
#include "periph/pwm.h"
|
||||
}
|
||||
|
||||
#include "arduino.hpp"
|
||||
@ -106,3 +107,55 @@ int analogRead(int arduino_pin)
|
||||
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 */
|
||||
|
||||
@ -122,5 +122,37 @@ unsigned long millis();
|
||||
int analogRead(int pin);
|
||||
#endif
|
||||
|
||||
#if MODULE_PERIPH_PWM || DOXYGEN
|
||||
/**
|
||||
* @brief PWM default frequency
|
||||
*
|
||||
* Can be overridden at board level in arduino_board.h.
|
||||
*
|
||||
* See table from https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/
|
||||
* for reference values.
|
||||
*/
|
||||
#ifndef ARDUINO_PWM_FREQU
|
||||
#define ARDUINO_PWM_FREQU (1000U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWM mode
|
||||
*/
|
||||
#define ARDUINO_PWM_MODE PWM_LEFT
|
||||
|
||||
/**
|
||||
* @brief PWM steps
|
||||
*/
|
||||
#define ARDUINO_PWM_STEPS (256U)
|
||||
|
||||
/**
|
||||
* @brief Write an analog value to a pin
|
||||
*
|
||||
* @param[in] pin pin to write
|
||||
* @param[in] value duty cycle value, between 0 and 255
|
||||
*/
|
||||
void analogWrite(int pin, int value);
|
||||
#endif
|
||||
|
||||
#endif /* ARDUINO_HPP */
|
||||
/** @} */
|
||||
|
||||
15
tests/sys_arduino_analog/Makefile
Normal file
15
tests/sys_arduino_analog/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
BOARD ?= arduino-zero
|
||||
|
||||
include ../Makefile.tests_common
|
||||
|
||||
LED_PIN ?= 3
|
||||
|
||||
USEMODULE += arduino
|
||||
|
||||
# Features used by Arduino analogRead/analogWrite functions are required
|
||||
FEATURES_REQUIRED += arduino_pwm
|
||||
FEATURES_REQUIRED += periph_adc
|
||||
|
||||
CFLAGS += -DLED_PIN=$(LED_PIN)
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
15
tests/sys_arduino_analog/arduino-test.sketch
Normal file
15
tests/sys_arduino_analog/arduino-test.sketch
Normal file
@ -0,0 +1,15 @@
|
||||
// Example sketch given in analogWrite documentation
|
||||
// https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/
|
||||
|
||||
int ledPin = LED_PIN; // LED connected to digital pin 3 by default
|
||||
int analogPin = 1; // potentiometer connected to analog pin 1
|
||||
int val = 0; // variable to store the read value
|
||||
|
||||
void setup() {
|
||||
pinMode(ledPin, OUTPUT); // sets the pin as output
|
||||
}
|
||||
|
||||
void loop() {
|
||||
val = analogRead(analogPin); // read the input pin
|
||||
analogWrite(ledPin, val / 4); // analogRead values go from 0 to 1023, analogWrite values from 0 to 255
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user