diff --git a/drivers/plasma/apa102.cpp b/drivers/plasma/apa102.cpp index 7f1c7e2d..bb60a972 100644 --- a/drivers/plasma/apa102.cpp +++ b/drivers/plasma/apa102.cpp @@ -3,14 +3,14 @@ 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) { - uint offset = pio_add_program(pio, &apa102_program); + 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_gpio_init(pio, pin_clk); pio_gpio_init(pio, pin_dat); - pio_sm_config c = apa102_program_get_default_config(offset); + pio_sm_config c = apa102_program_get_default_config(pio_program_offset); sm_config_set_out_pins(&c, pin_dat, 1); sm_config_set_sideset_pins(&c, pin_clk); @@ -21,7 +21,7 @@ APA102::APA102(uint num_leds, PIO pio, uint sm, uint pin_dat, uint pin_clk, uint float div = (float)clock_get_hz(clk_sys) / (2 * freq); sm_config_set_clkdiv(&c, div); - pio_sm_init(pio, sm, offset, &c); + pio_sm_init(pio, sm, pio_program_offset, &c); pio_sm_set_enabled(pio, sm, true); dma_channel = dma_claim_unused_channel(true); diff --git a/drivers/plasma/apa102.hpp b/drivers/plasma/apa102.hpp index accdcbcc..094c3e6e 100644 --- a/drivers/plasma/apa102.hpp +++ b/drivers/plasma/apa102.hpp @@ -60,7 +60,12 @@ namespace plasma { clear(); update(true); dma_channel_unclaim(dma_channel); + pio_sm_set_enabled(pio, sm, false); + pio_remove_program(pio, &apa102_program, pio_program_offset); +#ifndef MICROPY_BUILD_TYPE + // pio_sm_unclaim seems to hardfault in MicroPython pio_sm_unclaim(pio, sm); +#endif delete[] buffer; } bool start(uint fps=60); @@ -78,6 +83,7 @@ namespace plasma { uint32_t fps; PIO pio; uint sm; + uint pio_program_offset; int dma_channel; struct repeating_timer timer; }; diff --git a/drivers/plasma/ws2812.cpp b/drivers/plasma/ws2812.cpp index 92a1b0b0..3c49f618 100644 --- a/drivers/plasma/ws2812.cpp +++ b/drivers/plasma/ws2812.cpp @@ -3,12 +3,12 @@ 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) { - uint offset = pio_add_program(pio, &ws2812_program); + pio_program_offset = pio_add_program(pio, &ws2812_program); pio_gpio_init(pio, pin); pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true); - pio_sm_config c = ws2812_program_get_default_config(offset); + pio_sm_config c = ws2812_program_get_default_config(pio_program_offset); sm_config_set_sideset_pins(&c, pin); sm_config_set_out_shift(&c, false, true, rgbw ? 32 : 24); // Discard first (APA102 global brightness) byte. TODO support RGBW WS281X LEDs @@ -18,7 +18,7 @@ WS2812::WS2812(uint num_leds, PIO pio, uint sm, uint pin, uint freq, bool rgbw, float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit); sm_config_set_clkdiv(&c, div); - pio_sm_init(pio, sm, offset, &c); + pio_sm_init(pio, sm, pio_program_offset, &c); pio_sm_set_enabled(pio, sm, true); dma_channel = dma_claim_unused_channel(true); diff --git a/drivers/plasma/ws2812.hpp b/drivers/plasma/ws2812.hpp index 3d57cabb..4f503c3a 100644 --- a/drivers/plasma/ws2812.hpp +++ b/drivers/plasma/ws2812.hpp @@ -69,7 +69,12 @@ namespace plasma { clear(); update(true); dma_channel_unclaim(dma_channel); + pio_sm_set_enabled(pio, sm, false); + pio_remove_program(pio, &ws2812_program, pio_program_offset); +#ifndef MICROPY_BUILD_TYPE + // pio_sm_unclaim seems to hardfault in MicroPython pio_sm_unclaim(pio, sm); +#endif delete[] buffer; } bool start(uint fps=60); @@ -87,6 +92,7 @@ namespace plasma { uint32_t fps; PIO pio; uint sm; + uint pio_program_offset; int dma_channel; struct repeating_timer timer; };