Plasma: Expose non-blocking update to MicroPython.

pull/1053/head
Phil Howard 2025-01-22 11:18:36 +00:00
rodzic a9a18c3c9e
commit fee0e5674b
7 zmienionych plików z 40 dodań i 8 usunięć

Wyświetl plik

@ -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,

Wyświetl plik

@ -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);

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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);

Wyświetl plik

@ -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);

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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);