From 82a32b39484d5541e387119cf6001420207fb506 Mon Sep 17 00:00:00 2001 From: Sara Date: Thu, 21 Sep 2023 12:01:02 +0200 Subject: [PATCH] calling leds_set_gradient with a valid set of gradient structs followed by send_leds will now work --- .gitignore | 1 + main/leds.h | 141 ++++++++++++++++++++++++++++---------------- main/potion_party.c | 70 +++++++++++++++------- main/server.h | 8 ++- main/shared.h | 2 + sdkconfig | 19 +++--- 6 files changed, 159 insertions(+), 82 deletions(-) diff --git a/.gitignore b/.gitignore index 378eac2..ce47324 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ build +sdkconfig.backup diff --git a/main/leds.h b/main/leds.h index 5dd05f3..16b2a7d 100644 --- a/main/leds.h +++ b/main/leds.h @@ -10,17 +10,19 @@ #include #include #include +#include "esp8266/gpio_register.h" +#include "esp_system.h" #include "rom/ets_sys.h" #include "shared.h" #include "driver/gpio.h" // pack the struct to match exactly 8 * 4 = 32bits struct __attribute__((__packed__)) led_components_t { - uint8_t global; // global baseline brightness, highest 3 bits should always be ones // RGB component values uint8_t red; uint8_t green; uint8_t blue; + uint8_t global; // global baseline brightness, highest 3 bits should always be ones }; // union of components and their representation as a u32 @@ -37,54 +39,16 @@ struct gradient_point_t { }; // buffer that will be written out to the led strip over serial -// for leds to work, the uint32_t g_serial_out_buffer[62]; // 60-long slice of the out buffer that represents the first few leds -union led_t* g_leds = (uint32_t*)(g_serial_out_buffer + 1); +union led_t* g_leds = ((union led_t*)g_serial_out_buffer + 1); + #define CLOCK 4 #define DATA 5 static -void send_leds() { - LOGLN("Writing to leds"); - // index of the bit being written - // the first 5 bits represent the bit of the byte represented by the rest of the int - int write_bit = 0; - int write_next = 0; - - gpio_set_level(CLOCK, 0); - - while(write_bit < sizeof(g_serial_out_buffer) * 8) { - // fetch the bit being adressed - write_next = 0x1 & (g_serial_out_buffer[write_bit >> 5] >> (write_bit & 0x1F)); - // set clock out to high, triggering a rising edge - gpio_set_level(CLOCK, 1); - // write bit to data out - gpio_set_level(DATA, write_next); - - os_delay_us(10); - // set clock to low, triggering a falling edge, flushing the LEDs shift registers - gpio_set_level(CLOCK, 0); - os_delay_us(10); - - write_bit++; - } -} - -static -void leds_init() { - g_serial_out_buffer[0] = 0; - g_serial_out_buffer[61] = 0xFFFFFFFF; - for(int i = 0; i < 60; ++i) { - g_leds[i].components = (struct led_components_t) { - .red = 255, - .green = 10, - .blue = 255, - .global = 0xE0 | 0 - }; - } - +void leds_config_gpio() { gpio_config_t config = { .intr_type = GPIO_INTR_DISABLE, .mode = GPIO_MODE_OUTPUT, @@ -93,12 +57,58 @@ void leds_init() { .pull_down_en = 0, }; gpio_config(&config); + +} + +static +void serial_write(int high) { + // set clock out to high, triggering a rising edge + gpio_set_level(CLOCK, 1); + // write bit to data out + gpio_set_level(DATA, high); + + os_delay_us(2); + // set clock to low, triggering a falling edge, shifting the LEDs shift register + gpio_set_level(CLOCK, 0); +} + +static +void send_leds() { + LOGLN("entering send_leds()"); + // index of the bit being written + // fixed point number where the first 5 bits are the bit of a 32bit integger, and the rest is the integer + int write_bit = 0; + int write_next = 0; + + + LOGLN("Setting clock low"); + + gpio_set_level(CLOCK, 0); + + LOGLN("Writing to leds"); + + while(write_bit < sizeof(g_serial_out_buffer) * 8) { + // fetch the bit being addressed + write_next = 0x1 & (g_serial_out_buffer[write_bit >> 5] >> (32 - (write_bit & 0x1F))); + + serial_write(write_next); + + write_bit++; + } + + gpio_set_level(CLOCK, 0); + gpio_set_level(DATA, 0); + } static inline uint8_t lerp_uint8(uint8_t a, uint8_t b, float t) { - int dir = b - a; - return a + t * dir; + if(t <= 0) return a; + else if(t >= 1.0) return b; + else { + int dir = b - a; + return a + dir * t; + } } static inline @@ -106,33 +116,62 @@ void lerp_led(union led_t* out, const union led_t* from, const union led_t* to, out->components.red = lerp_uint8(from->components.red, to->components.red, t); out->components.green = lerp_uint8(from->components.green, to->components.green, t); out->components.blue = lerp_uint8(from->components.blue, to->components.blue, t); - uint8_t glob_from = from->components.global & 0x1F; - uint8_t glob_to = to->components.global & 0x1F; - out->components.global = 0xE0 | lerp_uint8(glob_from, glob_to, t); + uint8_t glob_from = from->components.global & ~0xE0; + uint8_t glob_to = to->components.global & ~0xE0; + out->components.global = GLOBAL(lerp_uint8(glob_from, glob_to, t)); } static inline void lerp_points_between(const struct gradient_point_t from, const struct gradient_point_t to) { const int dif = to.offset - from.offset; float t = 0.f; - for(int led = from.offset; led < to.offset; ++led) { + for(int led = from.offset; led <= to.offset; ++led) { t = (float)(led - from.offset) / (float)dif; lerp_led(g_leds + led, &from.led, &to.led, t); - LOGLN("%f", t); } } static -void leds_set_gradient(struct gradient_point_t* points, size_t points_len) { +void set_led_range(int start, int end, union led_t value) { + for(int i = start; i < end; ++i) { + g_leds[i] = value; + } +} + +static +void leds_set_gradient(struct gradient_point_t* points, size_t points_len, int send) { struct gradient_point_t from = points[0]; struct gradient_point_t to; + + // set_led_range(0, points[0].offset, points[0].led); + // set_led_range(points[points_len-1].offset, 60, points[points_len-1].led); + for(int i = 1; i < points_len; ++i) { to = points[i]; lerp_points_between(from, to); from = to; } - send_leds(); + if(send) { + send_leds(); + } +} + +static +void leds_init() { + g_serial_out_buffer[0] = 0u; + g_serial_out_buffer[61] = ~0u; + set_led_range(0, 60, + (union led_t){.components = + (struct led_components_t) { + .red = 0, + .green = 0, + .blue = 0, + .global = GLOBAL(5) + }} + ); + + leds_config_gpio(); } #endif // !_leds_h diff --git a/main/potion_party.c b/main/potion_party.c index 2c15e8e..14ca94b 100644 --- a/main/potion_party.c +++ b/main/potion_party.c @@ -16,6 +16,55 @@ void init_esp(void) { ESP_ERROR_CHECK(esp_event_loop_create_default()); } +static +void TEST_leds() { + // TEST: after a delay, set the leds to a gradient of red - black + sleep(1); + + union led_t led = { + .components = { + .red = 0, + .green = 255, + .blue = 0, + .global = GLOBAL(10) + } + }; + + set_led_range(0, 60, led); + led.components.blue = 255; + set_led_range(30, 60, led); + send_leds(); + + sleep(1); + + struct gradient_point_t points[3]; + points[0].offset = 0; + points[0].led.components = (struct led_components_t) { + .global = GLOBAL(10), + .red = 200, + .green = 0, + .blue = 40, + }; + + points[1].offset = 30; + points[1].led.components = (struct led_components_t){ + .global = GLOBAL(10), + .red = 40, + .green = 30, + .blue = 40, + }; + + points[2].offset = 60; + points[2].led.components = (struct led_components_t){ + .global = GLOBAL(10), + .red = 200, + .green = 255, + .blue = 255, + }; + + leds_set_gradient(points, 3, 1); +} + void app_main(void) { LOGLN("---- starting"); @@ -31,27 +80,8 @@ void app_main(void) { // start listening for HTTP signals server_init(); - // TEST: after a delay, set the leds to a gradient of red - black - os_delay_us(1000); + TEST_leds(); - struct gradient_point_t points[2]; - points[0].offset = 0; - points[0].led.components = (struct led_components_t) { - .global = 0xE | 10, - .red = 255, - .green = 10, - .blue = 10, - }; - - points[1].offset = 60; - points[1].led.components = (struct led_components_t){ - .global = 0xE0, - .red = 0, - .green = 0, - .blue = 0, - }; - - leds_set_gradient(points, 2); LOGLN("---- finished setting up"); } diff --git a/main/server.h b/main/server.h index 39044c2..0a1e584 100644 --- a/main/server.h +++ b/main/server.h @@ -21,6 +21,8 @@ #include "esp_http_server.h" #include "esp_system.h" #include "esp_netif.h" +#include "sys_arch.h" + static httpd_handle_t g_http_server = NULL; @@ -55,7 +57,7 @@ void parse_leds_query(char* query_string, size_t query_size) { } sprintf(query_key, "a%d", point); if(httpd_query_key_value(query_string, query_key, query_value, sizeof(query_value)) == ESP_OK) { - points[point].led.components.global = atoi(query_value) | 0xE0; + points[point].led.components.global = GLOBAL(atoi(query_value)); } sprintf(query_key, "t%d", point); if(httpd_query_key_value(query_string, query_key, query_value, sizeof(query_value)) == ESP_OK) { @@ -66,12 +68,12 @@ void parse_leds_query(char* query_string, size_t query_size) { LOGLN(" r %d", points[point].led.components.red); LOGLN(" g %d", points[point].led.components.green); LOGLN(" b %d", points[point].led.components.blue); - LOGLN(" global %d", points[point].led.components.global); + LOGLN(" global %d", points[point].led.components.global >> 3); LOGLN(" t %d", (int)points[point].offset); } - leds_set_gradient(points, gradient_point_count); + leds_set_gradient(points, gradient_point_count, 0); } // receives HTTP POST requests on root diff --git a/main/shared.h b/main/shared.h index d271aee..7fee108 100644 --- a/main/shared.h +++ b/main/shared.h @@ -25,4 +25,6 @@ static const char* APP_TAG="CINEKID_LEDS"; printf("\n");\ } while(0) +#define GLOBAL(__a) (uint8_t)(__a|0xE0) + #endif // !_shared_h diff --git a/sdkconfig b/sdkconfig index dd9affd..d7878a3 100644 --- a/sdkconfig +++ b/sdkconfig @@ -61,14 +61,14 @@ CONFIG_ESPTOOLPY_AFTER_HARD_RESET=y CONFIG_ESPTOOLPY_AFTER="hard_reset" # CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set # CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_74880B is not set -CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y +CONFIG_ESPTOOLPY_MONITOR_BAUD_74880B=y +# CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B is not set # CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set # CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B is not set # CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set # CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=74880 -CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +CONFIG_ESPTOOLPY_MONITOR_BAUD=74880 CONFIG_PARTITION_TABLE_SINGLE_APP=y # CONFIG_PARTITION_TABLE_TWO_OTA is not set # CONFIG_PARTITION_TABLE_CUSTOM is not set @@ -118,9 +118,9 @@ CONFIG_ETS_PRINTF_EXIT_WHEN_FLASH_RW=y CONFIG_SOC_IRAM_SIZE=0xC000 # CONFIG_DISABLE_ROM_UART_PRINT is not set # CONFIG_ESP_PANIC_PRINT_HALT is not set -CONFIG_ESP_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_PANIC_PRINT_REBOOT is not set # CONFIG_ESP_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP_PANIC_GDBSTUB is not set +CONFIG_ESP_PANIC_GDBSTUB=y CONFIG_RESET_REASON=y CONFIG_WIFI_PPT_TASKSTACK_SIZE=5120 CONFIG_ESP8266_CORE_GLOBAL_DATA_LINK_IRAM=y @@ -166,6 +166,9 @@ CONFIG_ESP_TASK_WDT_TIMEOUT_15N=y CONFIG_ESP_TASK_WDT_TIMEOUT_S=15 # CONFIG_ESP_EVENT_LOOP_PROFILING is not set CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_GDBSTUB_ENABLED=y +CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y +CONFIG_ESP_GDBSTUB_MAX_TASKS=32 CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set CONFIG_HTTP_BUF_SIZE=512 @@ -452,14 +455,14 @@ CONFIG_FLASHMODE_QIO=y # CONFIG_FLASHMODE_DOUT is not set # CONFIG_MONITOR_BAUD_9600B is not set # CONFIG_MONITOR_BAUD_57600B is not set -# CONFIG_MONITOR_BAUD_74880B is not set -CONFIG_MONITOR_BAUD_115200B=y +CONFIG_MONITOR_BAUD_74880B=y +# CONFIG_MONITOR_BAUD_115200B is not set # CONFIG_MONITOR_BAUD_230400B is not set # CONFIG_MONITOR_BAUD_921600B is not set # CONFIG_MONITOR_BAUD_2MB is not set # CONFIG_MONITOR_BAUD_OTHER is not set CONFIG_MONITOR_BAUD_OTHER_VAL=74880 -CONFIG_MONITOR_BAUD=115200 +CONFIG_MONITOR_BAUD=74880 CONFIG_OPTIMIZATION_LEVEL_DEBUG=y # CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y