diff --git a/drivers/plasma/apa102.cpp b/drivers/plasma/apa102.cpp index 87bdf328..75326067 100644 --- a/drivers/plasma/apa102.cpp +++ b/drivers/plasma/apa102.cpp @@ -60,14 +60,18 @@ bool APA102::dma_timer_callback(struct repeating_timer *t) { return true; } +bool APA102::is_busy() { + return dma_channel_is_busy(dma_channel); +} + void APA102::update(bool blocking) { - if(dma_channel_is_busy(dma_channel) && !blocking) return; - while(dma_channel_is_busy(dma_channel)) {}; // Block waiting for DMA finish + if(is_busy() && !blocking) return; + while(is_busy()) {}; // Block waiting for DMA finish pio->txf[sm] = 0x00000000; // Output the APA102 start-of-frame bytes dma_channel_set_trans_count(dma_channel, num_leds, false); dma_channel_set_read_addr(dma_channel, buffer, true); if (!blocking) return; - while(dma_channel_is_busy(dma_channel)) {}; // Block waiting for DMA finish + while(is_busy()) {}; // Block waiting for DMA finish // This is necessary to prevent a single LED remaining lit when clearing and updating. // This code will only run in *blocking* mode since it's assumed non-blocking will be continuously updating anyway. // Yes this will slow down LED updates... don't use blocking mode unless you're clearing LEDs before shutdown, diff --git a/drivers/plasma/apa102.hpp b/drivers/plasma/apa102.hpp index 944ceb6c..97bedf6a 100644 --- a/drivers/plasma/apa102.hpp +++ b/drivers/plasma/apa102.hpp @@ -76,6 +76,7 @@ namespace plasma { bool start(uint fps=60); bool stop(); void update(bool blocking=false); + bool is_busy(); void clear(); void set_hsv(uint32_t index, float h, float s, float v); void set_rgb(uint32_t index, uint8_t r, uint8_t g, uint8_t b, bool gamma=true); diff --git a/drivers/plasma/ws2812.cpp b/drivers/plasma/ws2812.cpp index 4da6d932..f3d3a2b5 100644 --- a/drivers/plasma/ws2812.cpp +++ b/drivers/plasma/ws2812.cpp @@ -46,13 +46,17 @@ bool WS2812::dma_timer_callback(struct repeating_timer *t) { return true; } +bool WS2812::is_busy() { + return dma_channel_is_busy(dma_channel); +} + void WS2812::update(bool blocking) { - if(dma_channel_is_busy(dma_channel) && !blocking) return; - while(dma_channel_is_busy(dma_channel)) {}; // Block waiting for DMA finish + if(is_busy() && !blocking) return; + while(is_busy()) {}; // Block waiting for DMA finish dma_channel_set_trans_count(dma_channel, num_leds, false); dma_channel_set_read_addr(dma_channel, buffer, true); if (!blocking) return; - while(dma_channel_is_busy(dma_channel)) {}; // Block waiting for DMA finish + while(is_busy()) {}; // Block waiting for DMA finish } bool WS2812::start(uint fps) { diff --git a/drivers/plasma/ws2812.hpp b/drivers/plasma/ws2812.hpp index 0c507db4..044c7b80 100644 --- a/drivers/plasma/ws2812.hpp +++ b/drivers/plasma/ws2812.hpp @@ -85,6 +85,7 @@ namespace plasma { bool start(uint fps=60); bool stop(); void update(bool blocking=false); + bool is_busy(); void clear(); void set_hsv(uint32_t index, float h, float s, float v, uint8_t w=0); void set_rgb(uint32_t index, uint8_t r, uint8_t g, uint8_t b, uint8_t w=0, bool gamma=true); diff --git a/micropython/modules/plasma/plasma.c b/micropython/modules/plasma/plasma.c index 6c7982c3..d4a93e74 100644 --- a/micropython/modules/plasma/plasma.c +++ b/micropython/modules/plasma/plasma.c @@ -10,6 +10,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(PlasmaAPA102_start_obj, 1, PlasmaAPA102_start); MP_DEFINE_CONST_FUN_OBJ_KW(PlasmaAPA102_get_obj, 2, PlasmaAPA102_get); MP_DEFINE_CONST_FUN_OBJ_1(PlasmaAPA102_clear_obj, PlasmaAPA102_clear); MP_DEFINE_CONST_FUN_OBJ_1(PlasmaAPA102_update_obj, PlasmaAPA102_update); +MP_DEFINE_CONST_FUN_OBJ_2(PlasmaAPA102_set_blocking_obj, PlasmaAPA102_set_blocking); MP_DEFINE_CONST_FUN_OBJ_1(PlasmaWS2812___del___obj, PlasmaWS2812___del__); MP_DEFINE_CONST_FUN_OBJ_KW(PlasmaWS2812_set_rgb_obj, 5, PlasmaWS2812_set_rgb); @@ -18,6 +19,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(PlasmaWS2812_start_obj, 1, PlasmaWS2812_start); MP_DEFINE_CONST_FUN_OBJ_KW(PlasmaWS2812_get_obj, 2, PlasmaWS2812_get); MP_DEFINE_CONST_FUN_OBJ_1(PlasmaWS2812_clear_obj, PlasmaWS2812_clear); MP_DEFINE_CONST_FUN_OBJ_1(PlasmaWS2812_update_obj, PlasmaWS2812_update); +MP_DEFINE_CONST_FUN_OBJ_2(PlasmaWS2812_set_blocking_obj, PlasmaWS2812_set_blocking); /***** Binding of Methods *****/ static const mp_rom_map_elem_t PlasmaAPA102_locals_dict_table[] = { @@ -29,6 +31,7 @@ static const mp_rom_map_elem_t PlasmaAPA102_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_get), MP_ROM_PTR(&PlasmaAPA102_get_obj) }, { MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&PlasmaAPA102_clear_obj) }, { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&PlasmaAPA102_update_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_blocking), MP_ROM_PTR(&PlasmaAPA102_set_blocking_obj) }, }; static const mp_rom_map_elem_t PlasmaWS2812_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&PlasmaWS2812___del___obj) }, @@ -38,6 +41,7 @@ static const mp_rom_map_elem_t PlasmaWS2812_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_get), MP_ROM_PTR(&PlasmaWS2812_get_obj) }, { MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&PlasmaWS2812_clear_obj) }, { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&PlasmaWS2812_update_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_blocking), MP_ROM_PTR(&PlasmaWS2812_set_blocking_obj) }, }; static MP_DEFINE_CONST_DICT(PlasmaAPA102_locals_dict, PlasmaAPA102_locals_dict_table); diff --git a/micropython/modules/plasma/plasma.cpp b/micropython/modules/plasma/plasma.cpp index 349a6755..b55e8eb5 100644 --- a/micropython/modules/plasma/plasma.cpp +++ b/micropython/modules/plasma/plasma.cpp @@ -24,6 +24,7 @@ typedef struct _PlasmaWS2812_obj_t { mp_obj_base_t base; WS2812* ws2812; void *buf; + bool blocking; } _PlasmaWS2812_obj_t; @@ -98,6 +99,7 @@ mp_obj_t PlasmaWS2812_make_new(const mp_obj_type_t *type, size_t n_args, size_t self = mp_obj_malloc_with_finaliser(_PlasmaWS2812_obj_t, &PlasmaWS2812_type); self->buf = buffer; + self->blocking = false; self->ws2812 = m_new_class(WS2812, num_leds, pio, sm, dat, freq, rgbw, color_order, (WS2812::RGB *)buffer); @@ -112,7 +114,13 @@ mp_obj_t PlasmaWS2812_clear(mp_obj_t self_in) { mp_obj_t PlasmaWS2812_update(mp_obj_t self_in) { _PlasmaWS2812_obj_t *self = MP_OBJ_TO_PTR2(self_in, _PlasmaWS2812_obj_t); - self->ws2812->update(true); + self->ws2812->update(self->blocking); + return mp_const_none; +} + +mp_obj_t PlasmaWS2812_set_blocking(mp_obj_t self_in, mp_obj_t blocking_in) { + _PlasmaWS2812_obj_t *self = MP_OBJ_TO_PTR2(self_in, _PlasmaWS2812_obj_t); + self->blocking = blocking_in == mp_const_true; return mp_const_none; } @@ -230,6 +238,7 @@ typedef struct _PlasmaAPA102_obj_t { mp_obj_base_t base; APA102* apa102; void *buf; + bool blocking; } _PlasmaAPA102_obj_t; @@ -308,6 +317,7 @@ mp_obj_t PlasmaAPA102_make_new(const mp_obj_type_t *type, size_t n_args, size_t self = mp_obj_malloc_with_finaliser(_PlasmaAPA102_obj_t, &PlasmaAPA102_type); self->buf = buffer; + self->blocking = false; self->apa102 = m_new_class(APA102, num_leds, pio, sm, dat, clk, freq, buffer); @@ -322,7 +332,13 @@ mp_obj_t PlasmaAPA102_clear(mp_obj_t self_in) { mp_obj_t PlasmaAPA102_update(mp_obj_t self_in) { _PlasmaAPA102_obj_t *self = MP_OBJ_TO_PTR2(self_in, _PlasmaAPA102_obj_t); - self->apa102->update(true); + self->apa102->update(self->blocking); + return mp_const_none; +} + +mp_obj_t PlasmaAPA102_set_blocking(mp_obj_t self_in, mp_obj_t blocking_in) { + _PlasmaAPA102_obj_t *self = MP_OBJ_TO_PTR2(self_in, _PlasmaAPA102_obj_t); + self->blocking = blocking_in == mp_const_true; return mp_const_none; } diff --git a/micropython/modules/plasma/plasma.h b/micropython/modules/plasma/plasma.h index 4483e6b4..39e73329 100644 --- a/micropython/modules/plasma/plasma.h +++ b/micropython/modules/plasma/plasma.h @@ -16,6 +16,7 @@ extern mp_obj_t PlasmaAPA102_set_brightness(size_t n_args, const mp_obj_t *pos_a extern mp_obj_t PlasmaAPA102_get(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); extern mp_obj_t PlasmaAPA102_clear(mp_obj_t self_in); extern mp_obj_t PlasmaAPA102_update(mp_obj_t self_in); +extern mp_obj_t PlasmaAPA102_set_blocking(mp_obj_t self_in, mp_obj_t blocking_in); extern void PlasmaWS2812_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); extern mp_obj_t PlasmaWS2812_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args); @@ -26,5 +27,6 @@ extern mp_obj_t PlasmaWS2812_set_hsv(size_t n_args, const mp_obj_t *pos_args, mp extern mp_obj_t PlasmaWS2812_get(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); extern mp_obj_t PlasmaWS2812_clear(mp_obj_t self_in); extern mp_obj_t PlasmaWS2812_update(mp_obj_t self_in); +extern mp_obj_t PlasmaWS2812_set_blocking(mp_obj_t self_in, mp_obj_t blocking_in); extern bool Pimoroni_mp_obj_to_i2c(mp_obj_t in, void *out); \ No newline at end of file