Allow uP allocated buffer for Plasma LEDs

This commit is contained in:
Phil Howard 2021-08-02 10:28:43 +01:00
parent 59d3c91f1b
commit 693e84c73d
5 changed files with 44 additions and 10 deletions

View File

@ -2,7 +2,7 @@
namespace plasma {
APA102::APA102(uint num_leds, PIO pio, uint sm, uint pin_dat, uint pin_clk, uint freq) : num_leds(num_leds), pio(pio), sm(sm) {
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_sm_set_pins_with_mask(pio, sm, 0, (1u << pin_clk) | (1u << pin_dat));
@ -32,7 +32,9 @@ APA102::APA102(uint num_leds, PIO pio, uint sm, uint pin_dat, uint pin_clk, uint
channel_config_set_read_increment(&config, true);
dma_channel_configure(dma_channel, &config, &pio->txf[sm], NULL, 0, false);
buffer = new RGB[num_leds];
if(this->buffer == nullptr) {
this->buffer = new RGB[num_leds];
}
}
bool APA102::dma_timer_callback(struct repeating_timer *t) {

View File

@ -54,7 +54,7 @@ namespace plasma {
RGB *buffer;
uint32_t num_leds;
APA102(uint num_leds, PIO pio, uint sm, uint pin_dat, uint pin_clk, uint freq=DEFAULT_SERIAL_FREQ);
APA102(uint num_leds, PIO pio, uint sm, uint pin_dat, uint pin_clk, uint freq=DEFAULT_SERIAL_FREQ, RGB* buffer=nullptr);
~APA102() {
stop();
clear();

View File

@ -2,7 +2,7 @@
namespace plasma {
WS2812::WS2812(uint num_leds, PIO pio, uint sm, uint pin, uint freq) : num_leds(num_leds), pio(pio), sm(sm) {
WS2812::WS2812(uint num_leds, PIO pio, uint sm, uint pin, uint freq, RGB* buffer) : buffer(buffer), num_leds(num_leds), pio(pio), sm(sm) {
uint offset = pio_add_program(pio, &ws2812_program);
pio_gpio_init(pio, pin);
@ -31,7 +31,9 @@ WS2812::WS2812(uint num_leds, PIO pio, uint sm, uint pin, uint freq) : num_leds(
dma_channel_set_read_addr(dma_channel, (uint32_t *)buffer, false);
dma_channel_configure(dma_channel, &config, &pio->txf[sm], NULL, 0, false);
buffer = new RGB[num_leds];
if(!this->buffer) {
this->buffer = new RGB[num_leds];
}
}
bool WS2812::dma_timer_callback(struct repeating_timer *t) {

View File

@ -54,7 +54,7 @@ namespace plasma {
RGB *buffer;
uint32_t num_leds;
WS2812(uint num_leds, PIO pio, uint sm, uint pin, uint freq=DEFAULT_SERIAL_FREQ);
WS2812(uint num_leds, PIO pio, uint sm, uint pin, uint freq=DEFAULT_SERIAL_FREQ, RGB* buffer=nullptr);
~WS2812() {
stop();
clear();

View File

@ -27,6 +27,7 @@ const mp_obj_float_t const_float_1 = {{&mp_type_float}, 1.0f};
typedef struct _PlasmaWS2812_obj_t {
mp_obj_base_t base;
WS2812* ws2812;
void *buf;
} _PlasmaWS2812_obj_t;
@ -58,7 +59,8 @@ mp_obj_t PlasmaWS2812_make_new(const mp_obj_type_t *type, size_t n_args, size_t
ARG_pio,
ARG_sm,
ARG_dat,
ARG_freq
ARG_freq,
ARG_buffer
};
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_num_leds, MP_ARG_REQUIRED | MP_ARG_INT },
@ -66,6 +68,7 @@ mp_obj_t PlasmaWS2812_make_new(const mp_obj_type_t *type, size_t n_args, size_t
{ MP_QSTR_sm, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_dat, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_freq, MP_ARG_INT, {.u_int = WS2812::DEFAULT_SERIAL_FREQ} },
{ MP_QSTR_buffer, MP_ARG_OBJ, {.u_obj = nullptr} },
};
// Parse args.
@ -78,10 +81,22 @@ mp_obj_t PlasmaWS2812_make_new(const mp_obj_type_t *type, size_t n_args, size_t
int dat = args[ARG_dat].u_int;
int freq = args[ARG_freq].u_int;
void *buffer = nullptr;
if (args[ARG_buffer].u_obj) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_RW);
buffer = bufinfo.buf;
if(bufinfo.len < (size_t)(num_leds * 4)) {
mp_raise_ValueError("Supplied buffer is too small for LED count!");
}
}
self = m_new_obj_with_finaliser(_PlasmaWS2812_obj_t);
self->base.type = &PlasmaWS2812_type;
self->buf = buffer;
self->ws2812 = new WS2812(num_leds, pio, sm, dat, freq);
self->ws2812 = new WS2812(num_leds, pio, sm, dat, freq, (WS2812::RGB *)buffer);
return MP_OBJ_FROM_PTR(self);
}
@ -166,6 +181,7 @@ mp_obj_t PlasmaWS2812_set_hsv(size_t n_args, const mp_obj_t *pos_args, mp_map_t
typedef struct _PlasmaAPA102_obj_t {
mp_obj_base_t base;
APA102* apa102;
void *buf;
} _PlasmaAPA102_obj_t;
@ -198,7 +214,8 @@ mp_obj_t PlasmaAPA102_make_new(const mp_obj_type_t *type, size_t n_args, size_t
ARG_sm,
ARG_dat,
ARG_clk,
ARG_freq
ARG_freq,
ARG_buffer
};
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_num_leds, MP_ARG_REQUIRED | MP_ARG_INT },
@ -207,6 +224,7 @@ mp_obj_t PlasmaAPA102_make_new(const mp_obj_type_t *type, size_t n_args, size_t
{ MP_QSTR_dat, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_clk, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_freq, MP_ARG_INT, {.u_int = APA102::DEFAULT_SERIAL_FREQ} },
{ MP_QSTR_buffer, MP_ARG_OBJ, {.u_obj = nullptr} },
};
// Parse args.
@ -220,10 +238,22 @@ mp_obj_t PlasmaAPA102_make_new(const mp_obj_type_t *type, size_t n_args, size_t
int clk = args[ARG_clk].u_int;
int freq = args[ARG_freq].u_int;
void *buffer = nullptr;
if (args[ARG_buffer].u_obj) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_RW);
buffer = bufinfo.buf;
if(bufinfo.len < (size_t)(num_leds * 4)) {
mp_raise_ValueError("Supplied buffer is too small for LED count!");
}
}
self = m_new_obj_with_finaliser(_PlasmaAPA102_obj_t);
self->base.type = &PlasmaAPA102_type;
self->buf = buffer;
self->apa102 = new APA102(num_leds, pio, sm, dat, clk, freq);
self->apa102 = new APA102(num_leds, pio, sm, dat, clk, freq, (APA102::RGB *)buffer);
return MP_OBJ_FROM_PTR(self);
}