Skip to content

Commit

Permalink
Plasma: Add support for GPIOs >=32.
Browse files Browse the repository at this point in the history
For both APA102 and WS2812 the pins used on the same PIO must be in the same range.
The GPIO base offset applies to the whole PIO and not individual state machines.

This means that for APA102 both data and clock must be in the same pin range,
ie: either 16-48 inclusive or 0-31 inclusive.
  • Loading branch information
Gadgetoid committed Oct 31, 2024
1 parent 4518de2 commit 5b2e806
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
20 changes: 18 additions & 2 deletions drivers/plasma/apa102.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,26 @@
namespace plasma {

APA102::APA102(uint num_leds, PIO pio, uint sm, uint pin_dat, uint pin_clk, uint freq, RGB* buffer) : buffer(buffer), num_leds(num_leds), pio(pio), sm(sm) {
// NOTE: This sets the gpio_base for *the entire PIO* not just this state machine
uint range_max = std::max(pin_dat, pin_clk);
uint range_min = std::min(pin_dat, pin_clk);

// Both pins in 16-48 range
if(range_max >= 32 && range_min >= 16) {
pio_set_gpio_base(pio, 16);
// Both pins in 0-31 range
} else if(range_max <= 31) {
pio_set_gpio_base(pio, 0);
// Pins in different ranges: invalid combo!
} else {
// TODO: Need some means to notify the caller
pio_set_gpio_base(pio, 0);
}

pio_program_offset = pio_add_program(pio, &apa102_program);

pio_sm_set_pins_with_mask(pio, sm, 0, (1u << pin_clk) | (1u << pin_dat));
pio_sm_set_pindirs_with_mask(pio, sm, ~0u, (1u << pin_clk) | (1u << pin_dat));
pio_sm_set_pins_with_mask(pio, sm, 0, (1u << (pin_clk - pio_get_gpio_base(pio))) | (1u << (pin_dat - pio_get_gpio_base(pio))));
pio_sm_set_pindirs_with_mask(pio, sm, ~0u, (1u << (pin_clk - pio_get_gpio_base(pio))) | (1u << (pin_dat - pio_get_gpio_base(pio))));
pio_gpio_init(pio, pin_clk);
pio_gpio_init(pio, pin_dat);

Expand Down
3 changes: 3 additions & 0 deletions drivers/plasma/ws2812.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
namespace plasma {

WS2812::WS2812(uint num_leds, PIO pio, uint sm, uint pin, uint freq, bool rgbw, COLOR_ORDER color_order, RGB* buffer) : buffer(buffer), num_leds(num_leds), color_order(color_order), pio(pio), sm(sm) {
// NOTE: This sets the gpio_base for *the entire PIO* not just this state machine
pio_set_gpio_base(pio, pin >= 32 ? 16 : 0);

pio_program_offset = pio_add_program(pio, &ws2812_program);

pio_gpio_init(pio, pin);
Expand Down

0 comments on commit 5b2e806

Please sign in to comment.