Skip to content

Commit

Permalink
Add RP2040 support
Browse files Browse the repository at this point in the history
This adds support for RP2040 based boards such as the Pico and the Pico W.
I have tested this on a Pico W.
  • Loading branch information
adisbladis committed Mar 30, 2023
1 parent c780331 commit d9e0410
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 14 deletions.
10 changes: 8 additions & 2 deletions .github/workflows/LibraryBuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ jobs:

# define each specific configuration
include:

# if the current configuration contains the parameter "config-name" and it is equal to "esp8266-v2",
# add the following parameters to this configuration. If board-type is never matched,
# add the following parameters to this configuration. If board-type is never matched,
# a new singular configuration is created
- config-name: esp8266-v2
platform-url: https://arduino.esp8266.com/stable/package_esp8266com_index.json
Expand Down Expand Up @@ -65,6 +65,12 @@ jobs:
arduino-boards-fqbn: arduino:samd:nano_33_iot
sketches-exclude: 3_dimmable_light_5_light, 5_dimmable_manager_n_lights

- config-name: rpi-pico
platform-url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
arduino-platform: pico:[email protected]
arduino-boards-fqbn: pico:rp2040:rpipico
sketches-exclude: 3_dimmable_light_5_light, 5_dimmable_manager_n_lights

# Do not cancel all jobs / architectures if one job fails
fail-fast: false

Expand Down
5 changes: 3 additions & 2 deletions library.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"espressif8266",
"espressif32",
"atmelavr",
"atmelsam"
"atmelsam",
"raspberrypi"
],
"dependencies": [
{
Expand Down Expand Up @@ -97,4 +98,4 @@
]
}
]
}
}
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ sentence=This library allows to easily control dimmers (also known as thyristors
paragraph=This library was born to control dimmable light bulbs, but actually dimmers are fully compatible with other AC loads like electrical heaters and motors (be aware of what you are doing!). Actually it works on ESP8266, ESP32, AVR and SAMD.
category=Device Control
url=https://github.com/fabianoriccardi/dimmable-light
architectures=esp8266,esp32,avr,samd
architectures=esp8266,esp32,avr,samd,rp2040
depends=ArduinoSTL
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This brief overview gives a glimpse of the variety of timers embedded in microco
## Features

1. Control multiple thyristors at the same time
2. Compatible with multiple platforms (ESP8266/ESP32/AVR/SAMD)
2. Compatible with multiple platforms (ESP8266/ESP32/AVR/SAMD/RP2040)
3. Interrupt optimization (trigger interrupts only if necessary, no periodic interrupt)
4. Control the load via gate activation time or relative power

Expand All @@ -28,7 +28,7 @@ Here a comparison against 2 similar and popular libraries:
|------------------------------------------|---------------------------------------------|-----------------------------------------------------------------------------|---------------------------------------------------------|
| Multiple dimmers | yes | yes | yes |
| Supported Frequencies | 50/60Hz | 50Hz | 50/60Hz |
| Supported architectures | AVR, SAMD, ESP8266, ESP32 | AVR, SAMD, ESP8266, ESP32, STM32F1, STM32F4, SAM | AVR |
| Supported architectures | AVR, SAMD, ESP8266, ESP32, RP2040 | AVR, SAMD, ESP8266, ESP32, STM32F1, STM32F4, SAM | AVR |
| Control *effective* delivered power | yes, dynamic calculation | no | yes, static lookup table |
| Predefined effects | no | yes, automatic fade to new value | yes, swipe effect |
| Optional zero-crossing mode | no | no | yes |
Expand Down
6 changes: 3 additions & 3 deletions src/dimmable_light_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

bool DimmableLightManager::add(String lightName, uint8_t pin) {
const char* temp = lightName.c_str();
#if defined(ESP8266) || defined(ESP32) || defined(ARDUINO_ARCH_SAMD)
#if defined(ESP8266) || defined(ESP32) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_RP2040)
std::unordered_map<std::string, DimmableLight*>::const_iterator it = dla.find(temp);
#elif defined(AVR)
std::map<std::string, DimmableLight*>::const_iterator it = dla.find(temp);
Expand All @@ -37,7 +37,7 @@ bool DimmableLightManager::add(String lightName, uint8_t pin) {

DimmableLight* DimmableLightManager::get(String lightName) {
const char* temp = lightName.c_str();
#if defined(ESP8266) || defined(ESP32) || defined(ARDUINO_ARCH_SAMD)
#if defined(ESP8266) || defined(ESP32) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_RP2040)
std::unordered_map<std::string, DimmableLight*>::const_iterator it = dla.find(temp);
#elif defined(AVR)
std::map<std::string, DimmableLight*>::const_iterator it = dla.find(temp);
Expand All @@ -50,7 +50,7 @@ DimmableLight* DimmableLightManager::get(String lightName) {
}

std::pair<String, DimmableLight*> DimmableLightManager::get() {
#if defined(ESP8266) || defined(ESP32) || defined(ARDUINO_ARCH_SAMD)
#if defined(ESP8266) || defined(ESP32) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_RP2040)
static std::unordered_map<std::string, DimmableLight*>::const_iterator it = dla.begin();
#elif defined(AVR)
static std::map<std::string, DimmableLight*>::const_iterator it = dla.begin();
Expand Down
4 changes: 2 additions & 2 deletions src/dimmable_light_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

#include "dimmable_light.h"

#if defined(ESP8266) || defined(ESP32) || defined(ARDUINO_ARCH_SAMD)
#if defined(ESP8266) || defined(ESP32) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_RP2040)
// Unfortunately Arduino defines max/min macros, those create conflicts with the one
// defined by C++/STL environment
#undef max
Expand Down Expand Up @@ -68,7 +68,7 @@ class DimmableLightManager {
}

private:
#if defined(ESP8266) || defined(ESP32) || defined(ARDUINO_ARCH_SAMD)
#if defined(ESP8266) || defined(ESP32) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_RP2040)
std::unordered_map<std::string, DimmableLight*> dla;
#elif defined(AVR)
std::map<std::string, DimmableLight*> dla;
Expand Down
53 changes: 53 additions & 0 deletions src/hw_timer_rp2040.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/***************************************************************************
* This file is part of Dimmable Light for Arduino, a library to *
* control dimmers. *
* *
* Copyright (C) 2018-2022 Fabiano Riccardi *
* *
* Dimmable Light for Arduino is free software; you can redistribute *
* it and/or modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/

#ifdef ARDUINO_ARCH_RP2040

#include "hw_timer_rp2040.h"
#include <Arduino.h>

static void (*timer_callback)() = nullptr;
static alarm_id_t alarm_id;
static alarm_pool_t *alarm_pool;

void timerBegin() {
alarm_pool = alarm_pool_get_default();
}

void timerSetCallback(void (*callback)()) {
timer_callback = callback;
}

void timerStart(uint16_t t) {
if (t <= 1) { return; }

if (alarm_id) { cancel_alarm(alarm_id); }

alarm_id = alarm_pool_add_alarm_in_us(
alarm_pool, t,
[](alarm_id_t id, void *user_data) -> int64_t {
timer_callback();
alarm_id = 0;
return 0; // Do not reschedule alarm
},
NULL, true);
}

#endif // END ARDUINO_ARCH_RP2040
47 changes: 47 additions & 0 deletions src/hw_timer_rp2040.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/***************************************************************************
* This file is part of Dimmable Light for Arduino, a library to *
* control dimmers. *
* *
* Copyright (C) 2018-2022 Fabiano Riccardi *
* *
* Dimmable Light for Arduino is free software; you can redistribute *
* it and/or modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/

#ifdef ARDUINO_ARCH_RP2040

#ifndef HW_RP2040_H
#define HW_RP2040_H

#include <stdint.h>

/**
* Initialize the timer.
*/
void timerBegin();

/**
* Set callback function on timer triggers
*/
void timerSetCallback(void (*callback)());

/**
* Start the timer to trigger after the specified number of ticks.
*
* NOTE: 0 or 1 values are not accepted
*/
void timerStart(uint16_t tick);

#endif // HW_TIMER_SAMD_H

#endif // ARDUINO_ARCH_SAMD
26 changes: 24 additions & 2 deletions src/thyristor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
#include "hw_timer_avr.h"
#elif defined(ARDUINO_ARCH_SAMD)
#include "hw_timer_samd.h"
#elif defined(ARDUINO_ARCH_RP2040)
#include "hw_timer_rp2040.h"
#else
#error "only ESP8266, ESP32, AVR, SAMD architectures are supported"
#error "only ESP8266, ESP32, AVR, SAMD & RP2040 architectures are supported"
#endif

// Check if zero cross interrupts are evenly time-spaced (i.e. no spurious interrupt)
Expand Down Expand Up @@ -200,6 +202,10 @@ void activate_thyristors() {
}
#elif defined(ARDUINO_ARCH_SAMD)
timerStart(microsecond2Tick(delay));
#elif defined(ARDUINO_ARCH_RP2040)
timerStart(delay);
#else
#error "Not implemented"
#endif
} else {

Expand All @@ -213,6 +219,8 @@ void activate_thyristors() {
stopTimer();
#elif defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_SAMD)
// Given actual HAL, AVR and SAMD counter automatically stops on interrupt
#elif defined(ARDUINO_ARCH_RP2040)
// Timer callback is not rescheduled
#endif
#else
// If there are not more thyristors to serve, set timer to turn off gates' signal
Expand All @@ -231,6 +239,11 @@ void activate_thyristors() {
#elif defined(ARDUINO_ARCH_SAMD)
timerSetCallback(turn_off_gates_int);
timerStart(microsecond2Tick(delay));
#elif defined(ARDUINO_ARCH_RP2040)
timerSetCallback(turn_off_gates_int);
timerStart(delay);
#else
#error "Not implemented"
#endif
#endif
}
Expand Down Expand Up @@ -396,6 +409,11 @@ void zero_cross_int() {
#elif defined(ARDUINO_ARCH_SAMD)
timerSetCallback(activate_thyristors);
timerStart(microsecond2Tick(pinDelay[thyristorManaged].delay));
#elif defined(ARDUINO_ARCH_RP2040)
timerSetCallback(activate_thyristors);
timerStart(pinDelay[thyristorManaged].delay);
#else
# error "Not implemented"
#endif
} else {
#if defined(ARDUINO_ARCH_ESP8266)
Expand All @@ -406,6 +424,8 @@ void zero_cross_int() {
stopTimer();
#elif defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_SAMD)
// Given actual HAL, AVR and SAMD counter automatically stops on interrupt
#elif defined(ARDUINO_ARCH_RP2040)
// Timer callback is not rescheduled
#endif
}
}
Expand Down Expand Up @@ -534,9 +554,11 @@ void Thyristor::begin() {
T1I = 0;
#elif defined(ARDUINO_ARCH_ESP32)
timerInit(activate_thyristors);
#elif defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_SAMD)
#elif defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_RP2040)
timerSetCallback(activate_thyristors);
timerBegin();
#else
#error "Not implemented"
#endif

#ifdef MONITOR_FREQUENCY
Expand Down

0 comments on commit d9e0410

Please sign in to comment.