diff --git a/components/badge23/espan.c b/components/badge23/espan.c index 0375ab5b45a957a0bf53af9d80148df7f00a9aba..c7b2be6dad26f360dc049ae67dcb32110f22dd11 100644 --- a/components/badge23/espan.c +++ b/components/badge23/espan.c @@ -58,7 +58,7 @@ static esp_err_t i2c_master_init(void) } #define CAPTOUCH_POLLING_PERIOD 10 -#define SLOW_SYSTEM_STATUS_PERIOD 200 +#define SLOW_SYSTEM_STATUS_PERIOD 100 static uint8_t hw_init_done = 0; void i2c_timer(TimerHandle_t data){ @@ -82,11 +82,13 @@ void slow_system_status_task(void * data){ xQueueReceive(slow_system_status_queue, &dummy_data, portMAX_DELAY); //read out stuff like jack detection, battery status, usb connection etc. audio_update_jacksense(); + leds_update_hardware(); } } void locks_init(){ mutex_i2c = xSemaphoreCreateMutex(); + mutex_LED = xSemaphoreCreateMutex(); } void os_app_main(void) @@ -101,7 +103,6 @@ void os_app_main(void) init_buttons(); captouch_init(); - //vTaskDelay(2000 / portTICK_PERIOD_MS); captouch_force_calibration(); display_init(); diff --git a/components/badge23/include/badge23/leds.h b/components/badge23/include/badge23/leds.h index 361f4ab1ae1bc1c146a5702e1aca6bc720b0c0d8..e36b430a4b9e712cd6f29c1767c235abd43f5fd8 100644 --- a/components/badge23/include/badge23/leds.h +++ b/components/badge23/include/badge23/leds.h @@ -1,8 +1,18 @@ #pragma once #include <stdint.h> +#include <stdbool.h> void leds_init(); void leds_set_single_rgb(uint8_t index, uint8_t red, uint8_t green, uint8_t blue); void leds_set_single_hsv(uint8_t index, float hue, float sat, float value); +void leds_set_all_rgb(uint8_t red, uint8_t green, uint8_t blue); +void leds_set_all_hsv(float hue, float sat, float value); +void leds_set_brightness(uint8_t brightness); +uint8_t leds_get_brightness(); +void leds_set_slew_rate(uint8_t slew_rate); +uint8_t leds_get_slew_rate(); void leds_update(); - +void leds_update_hardware(); +void leds_set_gamma(float red, float green, float blue); +void leds_set_auto_update(bool on); +bool leds_get_auto_update(); diff --git a/components/badge23/include/badge23/lock.h b/components/badge23/include/badge23/lock.h index eb52077c7b349d8819a1cec0d181b73ea3f4cd2c..4e597f675651f207f26b11c4b883668957dd8c64 100644 --- a/components/badge23/include/badge23/lock.h +++ b/components/badge23/include/badge23/lock.h @@ -4,3 +4,4 @@ #include <freertos/semphr.h> SemaphoreHandle_t mutex_i2c; +SemaphoreHandle_t mutex_LED; diff --git a/components/badge23/leds.c b/components/badge23/leds.c index ccd56d565a77d8f40c86cba2d733a2a8f75daf1d..630c91d835c2757f69d380016b73efa69343359f 100644 --- a/components/badge23/leds.c +++ b/components/badge23/leds.c @@ -6,14 +6,21 @@ #include <math.h> #include "esp_system.h" #include "badge23/leds.h" +#include "badge23/lock.h" #include "badge23_hwconfig.h" +static uint8_t leds_brightness = 69;; +static uint8_t leds_slew_rate = 255; +static bool leds_auto_update = 0; + +static uint8_t gamma_red[256]; +static uint8_t gamma_green[256]; +static uint8_t gamma_blue[256]; + #if defined(CONFIG_BADGE23_HW_GEN_P1) #define LED_SPI_PORT - -#elif defined(CONFIG_BADGE23_HW_GEN_P3) || defined(CONFIG_BADGE23_HW_GEN_P4) +#elif defined(CONFIG_BADGE23_HW_GEN_P3) || defined(CONFIG_BADGE23_HW_GEN_P4) || defined(CONFIG_BADGE23_HW_GEN_P6) #define LED_ASYNC_PORT - #else #error "leds not implemented for this badge generation" #endif @@ -35,6 +42,10 @@ struct RGB unsigned char B; }; +struct RGB led_target[40] = {0,}; +struct RGB led_target_buffer[40] = {0,}; +struct RGB led_hardware_value[40] = {0,}; + struct HSV { double H; @@ -164,7 +175,7 @@ static int setupSPI() return ret; } -void set_single_led(uint8_t index, uint8_t c[3]){ +static void set_single_led(uint8_t index, uint8_t c[3]){ setPixel(&leds, index, c); } @@ -180,7 +191,7 @@ static void _leds_init() { spiTransObject.tx_buffer = leds.LEDs; - TaskHandle_t handle; + //TaskHandle_t handle; //xTaskCreate(&leds_task, "LEDs player", 4096, NULL, configMAX_PRIORITIES - 2, &handle); } #endif @@ -210,12 +221,53 @@ static void renderLEDs(){ #endif +uint8_t led_get_slew(int16_t old, int16_t new, int16_t slew){ + if(new > old + slew){ + return old + slew; + } else if(new > old) { + return new; + } + if(new < old - slew){ + return old - slew; + } else if(new < old) { + return new; + } + return old; +} + +static void leds_update_target(){ + for(int i = 0; i < 40; i++){ + led_target[i].R = led_target_buffer[i].R; + led_target[i].G = led_target_buffer[i].G; + led_target[i].B = led_target_buffer[i].B; + } +} + +void leds_update_hardware(){ + if(leds_auto_update) leds_update_target(); + xSemaphoreTake(mutex_LED, portMAX_DELAY); + for(int i = 0; i < 40; i++){ + uint8_t c[3]; + c[0] = led_target[i].R * leds_brightness/255; + c[1] = led_target[i].G * leds_brightness/255; + c[2] = led_target[i].B * leds_brightness/255; + c[0] = led_get_slew(led_hardware_value[i].R, c[0], leds_slew_rate); + c[1] = led_get_slew(led_hardware_value[i].G, c[1], leds_slew_rate); + c[2] = led_get_slew(led_hardware_value[i].B, c[2], leds_slew_rate); + led_hardware_value[i].R = gamma_red[c[0]]; + led_hardware_value[i].G = gamma_green[c[1]]; + led_hardware_value[i].B = gamma_blue[c[2]]; + int8_t index = i + 3 % 40; + set_single_led(index, c); + } + renderLEDs(); + xSemaphoreGive(mutex_LED); +} + void leds_set_single_rgb(uint8_t index, uint8_t red, uint8_t green, uint8_t blue){ - uint8_t c[3]; - c[0] = red; - c[1] = green; - c[2] = blue; - set_single_led(index, c); + led_target_buffer[index].R = red; + led_target_buffer[index].G = green; + led_target_buffer[index].B = blue; } void leds_set_single_hsv(uint8_t index, float hue, float sat, float val){ @@ -227,17 +279,71 @@ void leds_set_single_hsv(uint8_t index, float hue, float sat, float val){ rgb = HSVToRGB(hsv); - uint8_t c[3]; - c[0] = rgb.R; - c[1] = rgb.G; - c[2] = rgb.B; - set_single_led(index, c); + led_target_buffer[index].R = rgb.R; + led_target_buffer[index].G = rgb.G; + led_target_buffer[index].B = rgb.B; +} + +void leds_set_all_rgb(uint8_t red, uint8_t green, uint8_t blue){ + for(int i = 0; i<40; i++){ + leds_set_single_rgb(i, red, green, blue); + } +} + +void leds_set_all_hsv(float h, float s, float v){ + for(int i = 0; i<40; i++){ + leds_set_single_hsv(i, h, s, v); + } } void leds_update(){ - vTaskDelay(10 / portTICK_PERIOD_MS); //do we... - renderLEDs(); - vTaskDelay(10 / portTICK_PERIOD_MS); //...need these? + leds_update_target(); + leds_update_hardware(); +} + +void leds_init(){ + for(uint16_t i = 0; i<256; i++){ + gamma_red[i] = i; + gamma_green[i] = i; + gamma_blue[i] = i; + } + _leds_init(); } -void leds_init() { _leds_init(); } +void leds_set_brightness(uint8_t b){ + leds_brightness = b; +} + +uint8_t leds_get_brightness(){ + return leds_brightness; +} + +void leds_set_slew_rate(uint8_t s){ + leds_slew_rate = s; +} + +uint8_t leds_get_slew_rate(){ + return leds_slew_rate; +} + +void leds_set_auto_update(bool on){ + leds_auto_update = on; +} + +bool leds_get_auto_update(){ + return leds_auto_update; +} + +void leds_set_gamma(float red, float green, float blue){ + for(uint16_t i = 0; i<256; i++){ + if(i == 0){ + gamma_red[i] = 0; + gamma_green[i] = 0; + gamma_blue[i] = 0; + } + float step = ((float) i) / 255.; + gamma_red[i] = (uint8_t) (254.*(pow(step, red))+1); + gamma_green[i] = (uint8_t) (254.*(pow(step, green))+1); + gamma_blue[i] = (uint8_t) (254.*(pow(step, blue))+1); + } +} diff --git a/usermodule/micropython.cmake b/usermodule/micropython.cmake index 2912379039ec6c1a2f51d127fac5dd12a0c1ee3b..326524e3bb510b6bfa6ff877ab30b44e14eadb3a 100644 --- a/usermodule/micropython.cmake +++ b/usermodule/micropython.cmake @@ -6,6 +6,7 @@ add_library(usermod_badge23 INTERFACE) target_sources(usermod_badge23 INTERFACE ${CMAKE_CURRENT_LIST_DIR}/mp_hardware.c + ${CMAKE_CURRENT_LIST_DIR}/mp_leds.c ${CMAKE_CURRENT_LIST_DIR}/mp_audio.c ${CMAKE_CURRENT_LIST_DIR}/mp_badge_link.c ${CMAKE_CURRENT_LIST_DIR}/mp_synth.c diff --git a/usermodule/mp_hardware.c b/usermodule/mp_hardware.c index 836a7804d4b05e272a6b5eadde715a2169aff5ad..fa7dec9ffb64fc5122e73fa8278314987eb9ef9f 100644 --- a/usermodule/mp_hardware.c +++ b/usermodule/mp_hardware.c @@ -12,7 +12,6 @@ #include "py/runtime.h" #include "badge23/audio.h" -#include "badge23/leds.h" #include "badge23/captouch.h" #include "badge23/display.h" #include "badge23/spio.h" @@ -166,32 +165,6 @@ STATIC mp_obj_t mp_dump_all_sources(size_t n_args, const mp_obj_t *args) { STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_dump_all_sources_obj, 0, 2, mp_dump_all_sources); -STATIC mp_obj_t mp_set_led_rgb(size_t n_args, const mp_obj_t *args) { - uint8_t index = mp_obj_get_int(args[0]); - uint8_t red = mp_obj_get_int(args[1]); - uint8_t green = mp_obj_get_int(args[2]); - uint8_t blue = mp_obj_get_int(args[3]); - leds_set_single_rgb(index, red, green, blue); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_set_led_rgb_obj, 4, 5, mp_set_led_rgb); - -STATIC mp_obj_t mp_set_led_hsv(size_t n_args, const mp_obj_t *args) { - uint8_t index = mp_obj_get_int(args[0]); - float hue = mp_obj_get_float(args[1]); - float sat = mp_obj_get_float(args[2]); - float val = mp_obj_get_float(args[3]); - leds_set_single_hsv(index, hue, sat, val); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_set_led_hsv_obj, 4, 5, mp_set_led_hsv); - -STATIC mp_obj_t mp_update_leds(size_t n_args, const mp_obj_t *args) { - leds_update(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_update_leds_obj, 0, 2, mp_update_leds); - STATIC mp_obj_t mp_version(void) { mp_obj_t str = mp_obj_new_str(badge23_hw_name, strlen(badge23_hw_name)); return str; @@ -233,9 +206,6 @@ STATIC const mp_rom_map_elem_t mp_module_hardware_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_set_global_volume_dB), MP_ROM_PTR(&mp_set_global_volume_dB_obj) }, { MP_ROM_QSTR(MP_QSTR_count_sources), MP_ROM_PTR(&mp_count_sources_obj) }, { MP_ROM_QSTR(MP_QSTR_dump_all_sources), MP_ROM_PTR(&mp_dump_all_sources_obj) }, - { MP_ROM_QSTR(MP_QSTR_set_led_rgb), MP_ROM_PTR(&mp_set_led_rgb_obj) }, - { MP_ROM_QSTR(MP_QSTR_set_led_hsv), MP_ROM_PTR(&mp_set_led_hsv_obj) }, - { MP_ROM_QSTR(MP_QSTR_update_leds), MP_ROM_PTR(&mp_update_leds_obj) }, { MP_ROM_QSTR(MP_QSTR_display_update), MP_ROM_PTR(&mp_display_update_obj) }, { MP_ROM_QSTR(MP_QSTR_display_set_backlight), MP_ROM_PTR(&mp_display_set_backlight_obj) }, { MP_ROM_QSTR(MP_QSTR_version), MP_ROM_PTR(&mp_version_obj) }, diff --git a/usermodule/mp_leds.c b/usermodule/mp_leds.c new file mode 100644 index 0000000000000000000000000000000000000000..4d9baf698e3dc461386ad5c53f7000253a5c2b3c --- /dev/null +++ b/usermodule/mp_leds.c @@ -0,0 +1,125 @@ +// probably doesn't need all of these idk +#include <stdio.h> +#include <string.h> + +#include "py/runtime.h" +#include "py/mphal.h" +#include "mphalport.h" +#include "modmachine.h" +#include "extmod/virtpin.h" +#include "machine_rtc.h" +#include "py/builtin.h" +#include "py/runtime.h" + +#include "badge23/leds.h" +#include "badge23/espan.h" +#include "badge23_hwconfig.h" + +STATIC mp_obj_t mp_leds_set_brightness(mp_obj_t b) { + leds_set_brightness(mp_obj_get_int(b)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_leds_set_brightness_obj, mp_leds_set_brightness); + +STATIC mp_obj_t mp_leds_get_brightness() { + return mp_obj_new_int(leds_get_brightness()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_leds_get_brightness_obj, mp_leds_get_brightness); + +STATIC mp_obj_t mp_leds_set_auto_update(mp_obj_t on) { + leds_set_auto_update(mp_obj_get_int(on)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_leds_set_auto_update_obj, mp_leds_set_auto_update); + +STATIC mp_obj_t mp_leds_get_auto_update() { + return mp_obj_new_int(leds_get_auto_update()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_leds_get_auto_update_obj, mp_leds_get_auto_update); + +STATIC mp_obj_t mp_leds_set_gamma(mp_obj_t r, mp_obj_t g, mp_obj_t b) { + leds_set_gamma(mp_obj_get_float(r), mp_obj_get_float(g), mp_obj_get_float(b)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(mp_leds_set_gamma_obj, mp_leds_set_gamma); + +STATIC mp_obj_t mp_leds_set_slew_rate(mp_obj_t b) { + leds_set_slew_rate(mp_obj_get_int(b)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_leds_set_slew_rate_obj, mp_leds_set_slew_rate); + +STATIC mp_obj_t mp_leds_get_slew_rate() { + return mp_obj_new_int(leds_get_slew_rate()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_leds_get_slew_rate_obj, mp_leds_get_slew_rate); + +STATIC mp_obj_t mp_led_set_rgb(size_t n_args, const mp_obj_t *args) { + uint8_t index = mp_obj_get_int(args[0]); + uint8_t red = mp_obj_get_int(args[1]); + uint8_t green = mp_obj_get_int(args[2]); + uint8_t blue = mp_obj_get_int(args[3]); + leds_set_single_rgb(index, red, green, blue); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_led_set_rgb_obj, 4, 4, mp_led_set_rgb); + +STATIC mp_obj_t mp_led_set_hsv(size_t n_args, const mp_obj_t *args) { + uint8_t index = mp_obj_get_int(args[0]); + float hue = mp_obj_get_float(args[1]); + float sat = mp_obj_get_float(args[2]); + float val = mp_obj_get_float(args[3]); + leds_set_single_hsv(index, hue, sat, val); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_led_set_hsv_obj,4,4, mp_led_set_hsv); + +STATIC mp_obj_t mp_led_set_all_rgb(mp_obj_t r, mp_obj_t g, mp_obj_t b) { + uint8_t red = mp_obj_get_int(r); + uint8_t green = mp_obj_get_int(g); + uint8_t blue = mp_obj_get_int(b); + leds_set_all_rgb(red, green, blue); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(mp_led_set_all_rgb_obj, mp_led_set_all_rgb); + +STATIC mp_obj_t mp_led_set_all_hsv(mp_obj_t h, mp_obj_t s, mp_obj_t v) { + float hue = mp_obj_get_float(h); + float sat = mp_obj_get_float(s); + float val = mp_obj_get_float(v); + leds_set_all_hsv(hue, sat, val); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_3(mp_led_set_all_hsv_obj, mp_led_set_all_hsv); + +STATIC mp_obj_t mp_leds_update() { + leds_update(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_leds_update_obj, mp_leds_update); + +STATIC const mp_rom_map_elem_t mp_module_leds_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_badge_audio) }, + { MP_ROM_QSTR(MP_QSTR_set_rgb), MP_ROM_PTR(&mp_led_set_rgb_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_hsv), MP_ROM_PTR(&mp_led_set_hsv_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_all_rgb), MP_ROM_PTR(&mp_led_set_all_rgb_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_all_hsv), MP_ROM_PTR(&mp_led_set_all_hsv_obj) }, + { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mp_leds_update_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_brightness), MP_ROM_PTR(&mp_leds_get_brightness_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_brightness), MP_ROM_PTR(&mp_leds_set_brightness_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_auto_update), MP_ROM_PTR(&mp_leds_get_auto_update_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_auto_update), MP_ROM_PTR(&mp_leds_set_auto_update_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_gamma), MP_ROM_PTR(&mp_leds_set_gamma_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_slew_rate), MP_ROM_PTR(&mp_leds_get_slew_rate_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_slew_rate), MP_ROM_PTR(&mp_leds_set_slew_rate_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(mp_module_leds_globals, mp_module_leds_globals_table); + +const mp_obj_module_t mp_module_leds = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&mp_module_leds_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_leds, mp_module_leds); +