diff --git a/watch-library/hardware/watch/watch_tcc.c b/watch-library/hardware/watch/watch_tcc.c index 8624ffcc..fa81d074 100644 --- a/watch-library/hardware/watch/watch_tcc.c +++ b/watch-library/hardware/watch/watch_tcc.c @@ -43,6 +43,9 @@ static watch_cb_t _cb_start_global = NULL; static watch_cb_t _cb_stop_global = NULL; static volatile bool _led_is_active = false; static volatile bool _buzzer_is_active = false; +static volatile uint8_t _current_led_color[3] = {0, 0, 0}; + +static void _watch_set_led_duty_cycle(uint32_t period, uint8_t red, uint8_t green, uint8_t blue); static void _tcc_write_RUNSTDBY(bool value) { // enables or disables RUNSTDBY of the tcc @@ -276,6 +279,11 @@ void watch_enable_buzzer(void) { void watch_set_buzzer_period_and_duty_cycle(uint32_t period, uint8_t duty) { tcc_set_period(0, period, true); tcc_set_cc(0, (WATCH_BUZZER_TCC_CHANNEL) % 4, period / (100 / duty), true); + // The buzzer determines the period, which means that if the LED was active before it will flicker + // Update the LED duty cycle to match the new period required by the buzzer. + if (_led_is_active) { + _watch_set_led_duty_cycle(period, _current_led_color[0], _current_led_color[1], _current_led_color[2]); + } } void watch_disable_buzzer(void) { @@ -400,10 +408,27 @@ void watch_set_led_color(uint8_t red, uint8_t green) { #endif } +static void _watch_set_led_duty_cycle(uint32_t period, uint8_t red, uint8_t green, uint8_t blue) { + tcc_set_cc(0, (WATCH_RED_TCC_CHANNEL) % 4, ((period * (uint32_t)red * 1000ull) / 255000ull), true); +#ifdef WATCH_GREEN_TCC_CHANNEL + tcc_set_cc(0, (WATCH_GREEN_TCC_CHANNEL) % 4, ((period * (uint32_t)green * 1000ull) / 255000ull), true); +#else + (void) green; // silence warning +#endif +#ifdef WATCH_BLUE_TCC_CHANNEL + tcc_set_cc(0, (WATCH_BLUE_TCC_CHANNEL) % 4, ((period * (uint32_t)blue * 1000ull) / 255000ull), true); +#else + (void) blue; // silence warning +#endif +} + void watch_set_led_color_rgb(uint8_t red, uint8_t green, uint8_t blue) { bool turning_on = (red | green | blue) != 0; if (turning_on) { + _current_led_color[0] = red; + _current_led_color[1] = green; + _current_led_color[2] = blue; _led_is_active = true; watch_enable_buzzer_and_leds(); } else { @@ -412,17 +437,7 @@ void watch_set_led_color_rgb(uint8_t red, uint8_t green, uint8_t blue) { if (tcc_is_enabled(0)) { uint32_t period = tcc_get_period(0); - tcc_set_cc(0, (WATCH_RED_TCC_CHANNEL) % 4, ((period * (uint32_t)red * 1000ull) / 255000ull), true); -#ifdef WATCH_GREEN_TCC_CHANNEL - tcc_set_cc(0, (WATCH_GREEN_TCC_CHANNEL) % 4, ((period * (uint32_t)green * 1000ull) / 255000ull), true); -#else - (void) green; // silence warning -#endif -#ifdef WATCH_BLUE_TCC_CHANNEL - tcc_set_cc(0, (WATCH_BLUE_TCC_CHANNEL) % 4, ((period * (uint32_t)blue * 1000ull) / 255000ull), true); -#else - (void) blue; // silence warning -#endif + _watch_set_led_duty_cycle(period, red, green, blue); } if (!turning_on) {