14#include "ws2812_rp2040.h"
15#include "pio/ws2812.pio.h"
20using namespace _IO_BANK0_;
25void ws2812_rp2040::LED::on() {
27 _ws2812_rp2040->update(_index);
30void ws2812_rp2040::LED::off() {
32 _ws2812_rp2040->update(_index);
35void ws2812_rp2040::LED::toggle() {
36 _color = _color ? 0 : _on_color;
37 _ws2812_rp2040->update(_index);
40bool ws2812_rp2040::LED::is_on() {
44void ws2812_rp2040::LED::set_color(uint32_t rgb) {
45 _color = _ws2812_rp2040->xRGB_to_GRBx(rgb);
46 _ws2812_rp2040->update(_index);
49void ws2812_rp2040::LED::set_on_color(uint32_t rgb) {
50 _on_color = _ws2812_rp2040->xRGB_to_GRBx(rgb);
55ws2812_rp2040::ws2812_rp2040(gpio_pin_t pin,
57: _gpio(pin), _size(size) {
59 _leds =
new LED[_size];
60 for(uint16_t i=0; i < _size; ++i) {
61 _leds[i]._ws2812_rp2040 =
this;
66ws2812_rp2040::~ws2812_rp2040() {
69 _gpio.setSEL(GPIO_CTRL_FUNCSEL__null);
72void ws2812_rp2040::init() {
74 _gpio.setSEL(GPIO_CTRL_FUNCSEL__pio0);
76 _sm = pio_rp2040::pio0.loadProgram(ws2812_program);
77 configure_SM(_sm, _gpio.getGpio() );
83void ws2812_rp2040::set_colors(uint32_t * values, uint16_t size) {
84 assert(size <= _size);
85 for(uint16_t i=0; i < size; ++i) {
86 _leds[i]._color = xRGB_to_GRBx(values[i]);
91uint32_t ws2812_rp2040::xRGB_to_GRBx(uint32_t rgb) {
95 rgb |= (rgb & 0x0000ff00) << 16;
99 rgb |= (rgb & 0x000000ff) << 8;
103void ws2812_rp2040::update(uint16_t index) {
111 task::enterCritical();
113 uint64_t now = task::millis();
114 while (task::millis() < now+1) ;
116 IO_BANK0_SET.GPIO18_CTRL.OEOVER <<= GPIO_CTRL_OEOVER__ENABLE;
117 IO_BANK0_SET.GPIO18_CTRL.OUTOVER <<= GPIO_CTRL_OUTOVER__HIGH;
119 for(uint16_t i=0; i <= index; ++i) {
120 _sm->writeTxFifo(_leds[i]._color);
123 task::leaveCritical();
125 IO_BANK0_CLR.GPIO18_CTRL.OEOVER <<= GPIO_CTRL_OEOVER__ENABLE;
126 IO_BANK0_CLR.GPIO18_CTRL.OUTOVER <<= GPIO_CTRL_OUTOVER__HIGH;
CMSIS-Core(M) Device Peripheral Access Layer Header File for Device RP2040.