From c04d6b52573a141e2b7f67b0b1e263dde004438d Mon Sep 17 00:00:00 2001 From: true Date: Tue, 6 Aug 2024 13:12:11 -0700 Subject: [PATCH] change fade method to use channel current scaling --- firmware/retro_tech_fw/user/src/btn.c | 2 +- firmware/retro_tech_fw/user/src/led_rgbprog.h | 2 + firmware/retro_tech_fw/user/src/ui.c | 216 ++++++++---------- 3 files changed, 99 insertions(+), 121 deletions(-) diff --git a/firmware/retro_tech_fw/user/src/btn.c b/firmware/retro_tech_fw/user/src/btn.c index 820007b..c4dade2 100644 --- a/firmware/retro_tech_fw/user/src/btn.c +++ b/firmware/retro_tech_fw/user/src/btn.c @@ -60,7 +60,7 @@ void btn_poll() // hold counter if (btn[i]._count < 0xffff) btn[i]._count++; - // pushed long ennough? + // pushed long enough? if (btn[i]._count < BTN_DEBOUNCE) continue; // first push? diff --git a/firmware/retro_tech_fw/user/src/led_rgbprog.h b/firmware/retro_tech_fw/user/src/led_rgbprog.h index 4297fac..236b655 100644 --- a/firmware/retro_tech_fw/user/src/led_rgbprog.h +++ b/firmware/retro_tech_fw/user/src/led_rgbprog.h @@ -13,6 +13,8 @@ #define LED_RGBPROG_NORMAL 0 #define LED_RGBPROG_PREVIEW 0x80 +#define LED_RGBPROG_COUNT 5 + extern void ((*led_rgbprog[5])(uint8_t, uint8_t)); diff --git a/firmware/retro_tech_fw/user/src/ui.c b/firmware/retro_tech_fw/user/src/ui.c index 2923f7f..ac1c8b2 100644 --- a/firmware/retro_tech_fw/user/src/ui.c +++ b/firmware/retro_tech_fw/user/src/ui.c @@ -25,8 +25,8 @@ #define UI_CONF_SAVE_TIMEOUT 192 -#define UI_PROG_RUNTIME_MIN (128*15) // 15 seconds -#define UI_PROG_RUNTIME_MAX (128*120) // 120 seconds +#define UI_PROG_RUNTIME_MIN (15) // 15 seconds +#define UI_PROG_RUNTIME_MAX (120) // 120 seconds static uint8_t mode = MODE_RUN; @@ -49,7 +49,7 @@ const uint16_t cursor_flash_rates[8] = { // off-to-on flash rates in 1/256 29, // PC VGA text mode (4.38 on-off/second) }; -static uint8_t rgb_prog_idx = 0; // currently running rgbled program index +static uint8_t rgb_prog_idx = 0xff; // currently running rgbled program index static uint16_t rgb_prog_timer = 9; // timeout until this program is done and switches static uint8_t rgb_prog_is_editing = 0; // currently editing a program's parameters static uint8_t preview_idx = 0; // currently selected program preview index @@ -121,59 +121,11 @@ void ui_btn_push_cb(uint8_t idx) } } - // do normal button actions + // there are no on-push events. switch (mode) { - /* button logic flow: - * - * - * mode changes happen by pressing both buttons. - * - * - * NORMAL MODE: cursor is flashing. - * - * cursor changes are committed to EEPROM a couple of seconds after changing is done. - * - * if cursor is off, programming mode cannot be entered. - * - * - top button: changes cursor color (white, green, orange, off) - * - bot button: changes cursor flash rate. press and hold while not off to - * enter program change mode. - */ + case MODE_RUN: { - - /* - * PROGRAM CHANGE MODE: cursor is off. - * - * - * letters in RETRO show enabled programs. by default, none are enabled. - * enabled programs are bright. disabled ones are dim. - * selected program will flash. if on, will flash brightly. if off, it will flash dimly. - * - * any program which is enabled can run. the active program randomly changes after random delays. - * - * letters in TECH preview the currently selected program. - * letters in RETRO will each preview their own program (any flash / twinkle will always have idle light) - * - * - top button: tap enables or disables the program. push and hold does nothing. - * - bot button: tap selects the next program index. push and hold enters parameter change mode. - * - * - * PARAMETER CHANGE MODE: cursor is on. - * - * letters in RETRO flash to show currently selected program. - * selected program will flash. if a program has been disabled, nothing will light for that letter. - * - * letters in TECH preview the current program, at some fixed brightness. - * - * - top button: increment some parameter, with loop (speed, etc) - * - bot button: selects the next program - * - knob: changes some parameter (color/hue, etc) - * - * settings are saved when the cursor returns to flashing from any other mode. - * - * settings are restored to default if the top button is held while powering on. - * restored settings are not committed until entering programming mode - */ + } } } @@ -199,9 +151,11 @@ void ui_btn_release_cb(uint8_t idx) switch (mode) { /* button logic flow: - * * * mode changes happen by pressing both buttons. + * this is handled in the push event handler. + * + * if cursor is off, mode changing cannot occur. */ /* @@ -209,8 +163,6 @@ void ui_btn_release_cb(uint8_t idx) * * cursor changes are committed to EEPROM about a second after changing is done. * - * if cursor is off, programming mode cannot be entered. - * * any program which is enabled will run. the active program randomly changes after random delays. */ case MODE_RUN: { @@ -245,8 +197,8 @@ void ui_btn_release_cb(uint8_t idx) /* * PROGRAM CHANGE MODE: cursor is on. * - * letters in RETRO show programs. by default, all are disabled. - * selected program will flash. + * by default, all are disabled. selected program will flash. + * cursor will light on the selected program if it is enabled. * * letters in TECH preview the currently selected program. * letters in RETRO will each preview their own program (any flash / twinkle will always have idle light) @@ -282,9 +234,8 @@ void ui_btn_release_cb(uint8_t idx) * * letters in TECH preview the current program, at some fixed brightness. * - * - * - * - knob: changes some parameter (color/hue, etc) + * - top button: change some parameter + * - knob: change some parameter (color/hue, etc) */ case MODE_PARAMETER: { switch (idx) { @@ -400,14 +351,40 @@ void ui_init() btn[1].cb_release = ui_btn_release_cb; } -static void rgb_prog_timer_generate() { +static void rgb_prog_random_timer_generate() { uint32_t t; t = prng_get16(); - t *= (UI_PROG_RUNTIME_MAX - UI_PROG_RUNTIME_MIN); + t *= (UI_PROG_RUNTIME_MAX - UI_PROG_RUNTIME_MIN) * 32; t >>= 16; + t += UI_PROG_RUNTIME_MIN * 32; - rgb_prog_timer = t + UI_PROG_RUNTIME_MIN; + rgb_prog_timer = t; +} + +static uint8_t rgb_prog_random_select() +{ + uint8_t i; + uint8_t w; + + uint8_t new; + + w = prng_get8(); + w &= 0x7; + for (i = 0; i < 8; i++) { + new = (w + i) & 0x7; + if (userconf.ledprog_ena_mask & (1 << new)) { + // bias selecting a new program + if (rgb_prog_idx != new) { + rgb_prog_idx = new; + led_rgb_firstrun(); + break; + } + } + } + + if (i == 8) return 0; + return 1; } void ui_render() @@ -417,7 +394,8 @@ void ui_render() uint16_t w; uint8_t flash; - uint8_t new; + + uint8_t out[16]; // deal with eeprom @@ -473,74 +451,72 @@ void ui_render() if (userconf.ledprog_ena_mask) { // fade and change programs depending on the timer - rgb_prog_timer--; + // actually run the program if (rgb_prog_timer) { - // actually run the program - led_rgbprog[rgb_prog_idx](LED_RGBPROG_NORMAL, tick); + if (led_rgbprog[rgb_prog_idx] && (rgb_prog_idx < LED_RGBPROG_COUNT)) { + led_rgbprog[rgb_prog_idx](LED_RGBPROG_NORMAL, tick); + } } - // todo: the fade goes way too fast and looks bad - // make it look nicer - if (rgb_prog_timer <= 17) { - led_is_updated(); + if ((tick >> 2) & 1) { + rgb_prog_timer--; - if (rgb_prog_timer == 17) { - w = prng_get8(); - w &= 0x7; - for (i = 0; i < 8; i++) { - new = (w + i) & 0x7; - if (userconf.ledprog_ena_mask & (1 << new)) { - // bias selecting a new program - if (rgb_prog_idx != new) { - rgb_prog_idx = new; - led_rgb_firstrun(); - break; - } + if (rgb_prog_timer <= 17) { + led_is_updated(); + + if (rgb_prog_timer == 17) { + // if no new program was selected (likely only one program selected?) + // just reset the timer + if (!rgb_prog_random_select()) { + rgb_prog_random_timer_generate(); } } - // no new program was selected (likely only one program selected?) - // so just reset the timer - if (i == 8) { - rgb_prog_timer_generate(); + else if (rgb_prog_timer >= 9) { + // fade out current program + w = 7 - (rgb_prog_timer - 9); + for (i = 0; i < 16; i++) { + out[i] = 0xff >> w; + } + is31fl3729_set_scaling_current_multi(FL3729_ADDR, out, 15); } - } - else if (rgb_prog_timer > 9) { - // fade out current program - w = 7 - (rgb_prog_timer - 10); - for (i = 0; i < 9; i++) { - rgb[i][0] >>= w; - rgb[i][1] >>= w; - rgb[i][2] >>= w; - } - } else if (rgb_prog_timer > 7) { - // clear out for now, since new program hasn't actually been run - for (i = 0; i < 9; i++) { - rgb[i][0] = 0; - rgb[i][1] = 0; - rgb[i][2] = 0; - } - } else if (rgb_prog_timer >= 1) { - // fade in new program - w = (rgb_prog_timer & 0x7); - for (i = 0; i < 9; i++) { - rgb[i][0] >>= w; - rgb[i][1] >>= w; - rgb[i][2] >>= w; - } - } else { // 0 - // randomize next program timing - rgb_prog_timer_generate(); + else if (rgb_prog_timer > 7) { + // clear out for now, since new program hasn't actually been run + for (i = 0; i < 9; i++) { + rgb[i][0] = 0; + rgb[i][1] = 0; + rgb[i][2] = 0; + } + // try to select a new program if we haven't set one before + if (rgb_prog_idx == 0xff) { + rgb_prog_random_select(); + } + } + + else if (rgb_prog_timer > 0) { + // fade in new program + w = (rgb_prog_timer & 0x7); + for (i = 0; i < 16; i++) { + out[i] = 0xff >> w; + } + is31fl3729_set_scaling_current_multi(FL3729_ADDR, out, 15); + } + + else { // 0 + // randomize next program timing + for (i = 0; i < 16; i++) { + out[i] = 0xff; + } + is31fl3729_set_scaling_current_multi(FL3729_ADDR, out, 15); + + rgb_prog_random_timer_generate(); + } } } } - // temp: remove me once buttons are tested and working - //rgb_prog_idx = 0; - //led_rgbprog[rgb_prog_idx](LED_RGBPROG_NORMAL, tick); - break; }