From c5bfc4cb73634989a219e284f8db0e06335b1eda Mon Sep 17 00:00:00 2001 From: true Date: Wed, 7 Aug 2024 13:38:15 -0700 Subject: [PATCH] add and modify flame programs, work around i2c lockup, other bugfixes added a flashing program, fixed up rainbow program, fixed program bugs. added an iterate program, which iterates over the existing programs with random delays. I've had i2c lock up with AF bit set while writing data, so now I look for that error and just bail buttons were not being handled at the correct input update rate. this has been fixed. led data wasn't initialized at power on. this has been fixed. --- firmware/flames_fw.launch | 6 +- firmware/user/ch32v20x_it.c | 11 +- firmware/user/main.c | 4 + firmware/user/src/i2c.c | 6 + firmware/user/src/led.h | 2 +- firmware/user/src/ledprog_boeing.c | 1 - firmware/user/src/ledprog_flame.c | 136 ----------- firmware/user/src/ledprog_flames.c | 216 ++++++++++++++++++ .../src/{ledprog_flame.h => ledprog_flames.h} | 2 +- firmware/user/src/ui.c | 8 +- 10 files changed, 241 insertions(+), 151 deletions(-) delete mode 100644 firmware/user/src/ledprog_flame.c create mode 100644 firmware/user/src/ledprog_flames.c rename firmware/user/src/{ledprog_flame.h => ledprog_flames.h} (80%) diff --git a/firmware/flames_fw.launch b/firmware/flames_fw.launch index 57b9edc..12c2f24 100644 --- a/firmware/flames_fw.launch +++ b/firmware/flames_fw.launch @@ -1,6 +1,6 @@ - + @@ -17,7 +17,7 @@ - + @@ -50,7 +50,7 @@ - + diff --git a/firmware/user/ch32v20x_it.c b/firmware/user/ch32v20x_it.c index d3a900e..c4613e5 100644 --- a/firmware/user/ch32v20x_it.c +++ b/firmware/user/ch32v20x_it.c @@ -64,17 +64,18 @@ void SysTick_Handler(void) // light sensor updates at ~1ms adc_process_lsens(); - // general processes update at 1/128 duty + // general processes update at 128Hz switch (ticnt & 0x7) { case 0: { // send new LEDs led_boeing_update(); led_matrix_send(); break; } - case 1: { // process buttons - btn_poll(); - break; - } + } + + // process buttons at 512Hz + if (ticnt & 1) { + btn_poll(); } // clear comparison flag diff --git a/firmware/user/main.c b/firmware/user/main.c index e74e824..69a4f74 100644 --- a/firmware/user/main.c +++ b/firmware/user/main.c @@ -128,6 +128,10 @@ int main(void) // configure UI ui_init(); + // initialize led programs + ledprog_top_init(); + ledprog_bot_init(); + // configure systick interrupt systick_init(); diff --git a/firmware/user/src/i2c.c b/firmware/user/src/i2c.c index cdcbf77..68eb6d8 100644 --- a/firmware/user/src/i2c.c +++ b/firmware/user/src/i2c.c @@ -125,6 +125,12 @@ int8_t i2c_write_addr1b(uint8_t addr, uint8_t reg, const uint8_t *data, uint8_t len--; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); } + // failed to acknowledge... reset bus + if (I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)) { + I2C1->STAR1 = 0; + I2C_GenerateSTOP(I2C1, ENABLE); + break; + } } I2C_GenerateSTOP(I2C1, ENABLE); diff --git a/firmware/user/src/led.h b/firmware/user/src/led.h index c438cf8..d965ef7 100644 --- a/firmware/user/src/led.h +++ b/firmware/user/src/led.h @@ -12,7 +12,7 @@ #include "aw20xxx.h" #include "ledprog_boeing.h" -#include "ledprog_flame.h" +#include "ledprog_flames.h" diff --git a/firmware/user/src/ledprog_boeing.c b/firmware/user/src/ledprog_boeing.c index b7b230d..1113c42 100644 --- a/firmware/user/src/ledprog_boeing.c +++ b/firmware/user/src/ledprog_boeing.c @@ -5,7 +5,6 @@ #include -#include "hsv2rgb.h" #include "led.h" #include "rand.h" diff --git a/firmware/user/src/ledprog_flame.c b/firmware/user/src/ledprog_flame.c deleted file mode 100644 index eb9e7bc..0000000 --- a/firmware/user/src/ledprog_flame.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Created on: Aug 7, 2024 - */ - -#include - -#include "hsv2rgb.h" -#include "led.h" -#include "rand.h" - - - -static uint16_t rnd; -static uint16_t work[4]; - - - -/* - * - */ -static void prog_0_flames(uint8_t tick) -{ - uint8_t i; - uint16_t j; - - uint16_t hue = 0; // straight red - - if ((tick & 0x3) == 0) { - for (i = 0; i < 5; i++) { - work[0] = 8; - j = prng_get8(); - if (j > 128) { - work[0] += j >> 1; - } - - if (j > 64) { - // put some orange-green hue in there sometimes - j = (j >= 0xfd) ? (5*6) : 0; - - hsv2rgb_8b(hue + j, 255, work[0] & 0xff, - &led.ind.rgb[i][0], &led.ind.rgb[i][1], &led.ind.rgb[i][2]); - } - } - - led_matrix_is_updated(); - } - - // update orange more slowly (why? dunno) - if ((tick & 0x7) == 3) { - for (i = 0; i < 3; i++) { - work[0] = 32; - j = prng_get8(); - if (j > 0x7f) { - work[0] += j >> 1; - } - - led.ind.led[i] = work[0]; - } - - led_matrix_is_updated(); - } -} - -/* - * flames - */ -static void prog_1_rainbow(uint8_t tick) -{ - uint8_t i; - uint16_t hue; - - work[0] += 1; - work[0] &= 0xff; - hue = work[0] * 6; - - if (tick & 1) { - for (i = 0; i < 5; i++) { - hsv2rgb_8b(hue, 255, 255, &led.ind.rgb[i][0], &led.ind.rgb[i][1], &led.ind.rgb[i][2]); - - hue += 32; - hue %= 1536; - } - - for (i = 0; i < 3; i++) { - led.ind.led[i] = 0; - } - - led_matrix_is_updated(); - } -} - -/* - * iterate over previous programs after random delays - */ -static void prog_2_iterate(uint8_t tick) -{ - -} - -static void prog_3_off(uint8_t tick) -{ - uint8_t i; - - // blank it - for (i = 0; i < sizeof(led.all); i++) { - led.all[i] = 0; - } - - if (!work[0]) { - led_matrix_is_updated(); - work[0] = 1; - } -} - - - -void (*ledprog_flame[4])(uint8_t) = { - prog_0_flames, - prog_1_rainbow, - prog_2_iterate, - prog_3_off -}; - - - -void ledprog_top_init() -{ - uint8_t i; - - rnd = prng_get16(); - - // global program initialization - for (i = 0; i < 4; i++) { - work[i] = 0; - } -} diff --git a/firmware/user/src/ledprog_flames.c b/firmware/user/src/ledprog_flames.c new file mode 100644 index 0000000..d06e4ea --- /dev/null +++ b/firmware/user/src/ledprog_flames.c @@ -0,0 +1,216 @@ +/* + * Created on: Aug 7, 2024 + */ + +#include + +#include "hsv2rgb.h" +#include "led.h" +#include "rand.h" + +#include "ledprog_flames.h" + + + +static uint16_t rnd; +static uint16_t work[4]; + + + +/* + * + */ +static void prog_0_flames(uint8_t tick) +{ + uint8_t i; + uint16_t j; + + uint16_t hue = 0; // straight red + + if ((tick & 0x3) == 0) { + for (i = 0; i < 5; i++) { + work[0] = 8; + j = prng_get8(); + if (j > 128) { + work[0] += j >> 1; + } + + if (j > 64) { + // put some orange-green hue in there sometimes + j = (j >= 0xfd) ? (5*6) : 0; + + hsv2rgb_8b(hue + j, 255, work[0] & 0xff, + &led.ind.rgb[i][0], &led.ind.rgb[i][1], &led.ind.rgb[i][2]); + } + } + + led_matrix_is_updated(); + } + + // update orange more slowly (why? dunno) + if ((tick & 0x7) == 3) { + for (i = 0; i < 3; i++) { + work[0] = 32; + j = prng_get8(); + if (j > 0x7f) { + work[0] += j >> 1; + } + + led.ind.led[i] = work[0]; + } + + led_matrix_is_updated(); + } +} + +/* + * flames + */ +static void prog_1_rainbow(uint8_t tick) +{ + uint8_t i; + uint16_t hue; + + if ((tick & 0x3) == 0) { + work[0] += 1; + work[0] &= 0xff; + hue = (255 - work[0]) * 6; + + for (i = 0; i < 5; i++) { + hsv2rgb_8b(hue, 255, 255, &led.ind.rgb[i][0], &led.ind.rgb[i][1], &led.ind.rgb[i][2]); + + hue += 100; + hue %= 1536; + } + + for (i = 0; i < 3; i++) { + led.ind.led[i] = 0; + } + + led_matrix_is_updated(); + } +} + + +static void prog_2_flash(uint8_t tick) +{ + uint8_t i; + + uint16_t hue = 0; + uint8_t val; + + if (!work[1]) { + // reset flash timer + work[1] = 32; + work[1] += prng_get8() >> 2; + + // do a flash + work[0] ^= 1; + + if (!work[0]) { + led.ind.rgb[0][0] = 0; + led.ind.rgb[0][1] = 0; + led.ind.rgb[0][2] = 0; + + led.ind.led[0] = led.ind.led[1] = led.ind.led[2] = 0; + } else { + hue += prng_get8() >> 4; + val = (255 - 63) + (prng_get8() >> 2); + + hsv2rgb_8b(hue, 255, val, &led.ind.rgb[0][0], &led.ind.rgb[0][1], &led.ind.rgb[0][2]); + + led.ind.led[0] = led.ind.led[1] = led.ind.led[2] = 255; + } + + for (i = 1; i < 5; i++) { + led.ind.rgb[i][0] = led.ind.rgb[0][0]; + led.ind.rgb[i][1] = led.ind.rgb[0][1]; + led.ind.rgb[i][2] = led.ind.rgb[0][2]; + } + + led_matrix_is_updated(); + } + + work[1]--; +} + +/* + * iterate over previous programs after random delays + */ +static uint8_t iterate_tmr; +static uint8_t iterate_prg; +static void prog_3_iterate(uint8_t tick) +{ + uint8_t w[2]; + + if (!iterate_tmr) { + // between 26 - 90 seconds per program + iterate_tmr = prng_get8() >> 2; + iterate_tmr += 26; + + iterate_prg++; + + // this resets our counters so save then restore them + w[0] = iterate_tmr; + w[1] = iterate_prg; + ledprog_top_init(); + iterate_tmr = w[0]; + iterate_prg = w[1]; + } + + if (!tick) { + iterate_tmr--; + } + + // run all but the last two programs (this program, and off program) + if (iterate_prg > (sizeof(ledprog_flames) / 4) - 2) { + iterate_prg = 1; + } + + if (ledprog_flames[iterate_prg - 1]) { + ledprog_flames[iterate_prg - 1](tick); + } +} + +static void prog_4_off(uint8_t tick) +{ + uint8_t i; + + // blank it + for (i = 0; i < sizeof(led.all); i++) { + led.all[i] = 0; + } + + if (!work[0]) { + led_matrix_is_updated(); + work[0] = 1; + } +} + + + +void (*ledprog_flames[5])(uint8_t) = { + prog_0_flames, + prog_1_rainbow, + prog_2_flash, + prog_3_iterate, + prog_4_off +}; + + + +void ledprog_top_init() +{ + uint8_t i; + + rnd = prng_get16(); + + // global program initialization + for (i = 0; i < 4; i++) { + work[i] = 0; + } + + // program specific init + iterate_tmr = 0; + iterate_prg = 0; +} diff --git a/firmware/user/src/ledprog_flame.h b/firmware/user/src/ledprog_flames.h similarity index 80% rename from firmware/user/src/ledprog_flame.h rename to firmware/user/src/ledprog_flames.h index b565a00..b635c4c 100644 --- a/firmware/user/src/ledprog_flame.h +++ b/firmware/user/src/ledprog_flames.h @@ -7,7 +7,7 @@ -extern void (*ledprog_flame[4])(uint8_t); +extern void (*ledprog_flames[5])(uint8_t); diff --git a/firmware/user/src/ui.c b/firmware/user/src/ui.c index d088f93..db70e5e 100644 --- a/firmware/user/src/ui.c +++ b/firmware/user/src/ui.c @@ -62,7 +62,7 @@ void ui_btn_release_cb(uint8_t idx) case 0: { // BTN_UP, upper programs update = userconf.top_prog_ena_map & ~(PROG_RANDOM); update++; - if (update > 3) update = 0; + if (update >= (sizeof(ledprog_flames) / 4)) update = 0; userconf.top_prog_ena_map = update | (userconf.top_prog_ena_map & PROG_RANDOM); ledprog_top_init(); break; @@ -70,7 +70,7 @@ void ui_btn_release_cb(uint8_t idx) case 1: { // BTN_DN, lower programs update = userconf.bot_prog_ena_map & ~(PROG_RANDOM); update++; - if (update > 3) update = 0; + if (update >= (sizeof(ledprog_boeing) / 4)) update = 0; userconf.bot_prog_ena_map = update | (userconf.bot_prog_ena_map & PROG_RANDOM); ledprog_bot_init(); break; @@ -110,8 +110,8 @@ void ui_render() switch (mode) { case MODE_RUN: { // run programs - if (ledprog_flame[prog_top_idx]) { - ledprog_flame[prog_top_idx](tick); + if (ledprog_flames[prog_top_idx]) { + ledprog_flames[prog_top_idx](tick); } if (ledprog_boeing[prog_bot_idx]) { ledprog_boeing[prog_bot_idx](tick);