diff --git a/watch-library/hardware/watch/watch_deepsleep.c b/watch-library/hardware/watch/watch_deepsleep.c index e90150ee..20254df4 100644 --- a/watch-library/hardware/watch/watch_deepsleep.c +++ b/watch-library/hardware/watch/watch_deepsleep.c @@ -151,7 +151,8 @@ static void _watch_disable_all_pins_except_rtc(void) { } static void _watch_disable_all_peripherals_except_slcd(void) { - _watch_disable_tcc(); + watch_disable_leds(); + watch_disable_buzzer(); watch_disable_adc(); watch_disable_external_interrupts(); diff --git a/watch-library/hardware/watch/watch_tcc.c b/watch-library/hardware/watch/watch_tcc.c index fa81d074..cde3c0dd 100644 --- a/watch-library/hardware/watch/watch_tcc.c +++ b/watch-library/hardware/watch/watch_tcc.c @@ -27,10 +27,15 @@ #include "tcc.h" #include "tc.h" -void _watch_enable_tcc(void); +static void _watch_enable_tcc(void); +static void _watch_disable_tcc(void); +static void _watch_maybe_enable_tcc(void); +static void _watch_maybe_disable_tcc(void); +static void _watch_enable_led_pins(void); +static void _watch_disable_led_pins(void); static void (*_cb_tc0)(void) = NULL; -void cb_watch_buzzer_seq(void); -void cb_watch_buzzer_raw_source(void); +static void cb_watch_buzzer_seq(void); +static void cb_watch_buzzer_raw_source(void); static uint16_t _seq_position; static int8_t _tone_ticks, _repeat_counter; @@ -84,14 +89,11 @@ void watch_buzzer_play_sequence_with_volume(int8_t *note_sequence, void (*callba // Abort any previous sequence watch_buzzer_abort_sequence(); - _buzzer_is_active = true; - if (_cb_start_global) { _cb_start_global(); } - watch_enable_buzzer_and_leds(); - + watch_enable_buzzer(); watch_set_buzzer_off(); _sequence = note_sequence; _cb_finished = callback_on_end; @@ -154,13 +156,11 @@ void watch_buzzer_play_raw_source_with_volume(watch_buzzer_raw_source_t raw_sour // Abort any previous sequence watch_buzzer_abort_sequence(); - _buzzer_is_active = true; - if (_cb_start_global) { _cb_start_global(); } - watch_enable_buzzer_and_leds(); + watch_enable_buzzer(); watch_set_buzzer_off(); _raw_source = raw_source; @@ -213,14 +213,12 @@ void watch_buzzer_abort_sequence(void) { return; } - _buzzer_is_active = false; - _tc0_stop(); watch_set_buzzer_off(); // disable TCC - watch_maybe_disable_buzzer_and_leds(); + watch_disable_buzzer(); if (_cb_stop_global) { _cb_stop_global(); @@ -244,11 +242,11 @@ void irq_handler_tc0(void) { TC0->COUNT8.INTFLAG.reg |= TC_INTFLAG_OVF; } -bool watch_is_buzzer_or_led_enabled(void){ - return tcc_is_enabled(0); -} +void _watch_maybe_enable_tcc(void) { + if (!_buzzer_is_active && !_led_is_active) { + return; + } -void watch_enable_buzzer_and_leds(void) { if (!tcc_is_enabled(0)) { // tcc_set_run_in_standby(0, true); _watch_enable_tcc(); @@ -257,23 +255,26 @@ void watch_enable_buzzer_and_leds(void) { } } -void watch_disable_buzzer_and_leds(void) { +void _watch_maybe_disable_tcc(void) { + if (_buzzer_is_active || _led_is_active) { + return; + } + if (tcc_is_enabled(0)) { _tcc_write_RUNSTDBY(false); _watch_disable_tcc(); } } -void watch_maybe_disable_buzzer_and_leds(void) { - if (_buzzer_is_active || _led_is_active) { - return; - } - - watch_disable_buzzer_and_leds(); +void watch_enable_buzzer(void) { + _buzzer_is_active = true; + _watch_maybe_enable_tcc(); } -void watch_enable_buzzer(void) { - watch_enable_buzzer_and_leds(); +void watch_disable_buzzer(void) { + _buzzer_is_active = false; + watch_set_buzzer_off(); + _watch_maybe_disable_tcc(); } void watch_set_buzzer_period_and_duty_cycle(uint32_t period, uint8_t duty) { @@ -286,10 +287,6 @@ void watch_set_buzzer_period_and_duty_cycle(uint32_t period, uint8_t duty) { } } -void watch_disable_buzzer(void) { - watch_maybe_disable_buzzer_and_leds(); -} - inline void watch_set_buzzer_on(void) { HAL_GPIO_BUZZER_out(); HAL_GPIO_BUZZER_pmuxen(HAL_GPIO_PMUX_TCC_ALT); @@ -356,21 +353,6 @@ void _watch_enable_tcc(void) { tcc_set_cc(0, (WATCH_BLUE_TCC_CHANNEL) % 4, 0, false); #endif - // enable LED PWM pins (the LED driver assumes if the TCC is on, the pins are enabled) - HAL_GPIO_RED_pmuxen(HAL_GPIO_PMUX_TCC_ALT); - HAL_GPIO_RED_drvstr(1); - HAL_GPIO_RED_out(); -#ifdef WATCH_GREEN_TCC_CHANNEL - HAL_GPIO_GREEN_pmuxen(HAL_GPIO_PMUX_TCC_ALT); - HAL_GPIO_GREEN_drvstr(1); - HAL_GPIO_GREEN_out(); -#endif -#ifdef WATCH_BLUE_TCC_CHANNEL - HAL_GPIO_BLUE_pmuxen(HAL_GPIO_PMUX_TCC_ALT); - HAL_GPIO_BLUE_drvstr(1); - HAL_GPIO_BLUE_out(); -#endif - // Enable the TCC tcc_enable(0); } @@ -393,11 +375,45 @@ void _watch_disable_tcc(void) { } void watch_enable_leds(void) { - watch_enable_buzzer_and_leds(); + _led_is_active = true; + _watch_enable_led_pins(); + _watch_maybe_enable_tcc(); } void watch_disable_leds(void) { - watch_maybe_disable_buzzer_and_leds(); + _led_is_active = false; + _watch_disable_led_pins(); + _watch_maybe_disable_tcc(); +} + +void _watch_enable_led_pins(void) { + // enable LED PWM pins (the LED driver assumes if the TCC is on, the pins are enabled) + HAL_GPIO_RED_pmuxen(HAL_GPIO_PMUX_TCC_ALT); + HAL_GPIO_RED_drvstr(1); + HAL_GPIO_RED_out(); +#ifdef WATCH_GREEN_TCC_CHANNEL + HAL_GPIO_GREEN_pmuxen(HAL_GPIO_PMUX_TCC_ALT); + HAL_GPIO_GREEN_drvstr(1); + HAL_GPIO_GREEN_out(); +#endif +#ifdef WATCH_BLUE_TCC_CHANNEL + HAL_GPIO_BLUE_pmuxen(HAL_GPIO_PMUX_TCC_ALT); + HAL_GPIO_BLUE_drvstr(1); + HAL_GPIO_BLUE_out(); +#endif +} + +void _watch_disable_led_pins(void) { + HAL_GPIO_RED_pmuxdis(); + HAL_GPIO_RED_off(); +#ifdef WATCH_GREEN_TCC_CHANNEL + HAL_GPIO_GREEN_pmuxdis(); + HAL_GPIO_GREEN_off(); +#endif +#ifdef WATCH_BLUE_TCC_CHANNEL + HAL_GPIO_BLUE_pmuxdis(); + HAL_GPIO_BLUE_off(); +#endif } void watch_set_led_color(uint8_t red, uint8_t green) { @@ -429,19 +445,14 @@ void watch_set_led_color_rgb(uint8_t red, uint8_t green, uint8_t blue) { _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 { - _led_is_active = false; - } - - if (tcc_is_enabled(0)) { + watch_enable_leds(); uint32_t period = tcc_get_period(0); _watch_set_led_duty_cycle(period, red, green, blue); - } - - if (!turning_on) { - watch_maybe_disable_buzzer_and_leds(); + } else { + if (tcc_is_enabled(0)) { + _watch_set_led_duty_cycle(1, red, green, blue); + } + watch_disable_leds(); } } diff --git a/watch-library/shared/watch/watch_tcc.h b/watch-library/shared/watch/watch_tcc.h index e87e53bf..056844b3 100644 --- a/watch-library/shared/watch/watch_tcc.h +++ b/watch-library/shared/watch/watch_tcc.h @@ -130,13 +130,6 @@ typedef enum { typedef bool (*watch_buzzer_raw_source_t)(uint16_t position, void* userdata, uint16_t* period, uint16_t* duration); -/** @brief Returns true if either the buzzer or the LED driver is enabled. - * @details Both the buzzer and the LED use the TCC peripheral to drive their behavior. This function returns true if that - * peripheral is enabled. You can use this function to determine whether you need to call the watch_enable_leds or - * or watch_enable_buzzer functions before using these peripherals. - */ -bool watch_is_buzzer_or_led_enabled(void); - /** @addtogroup tcc Buzzer and LED Control (via the TCC peripheral) * @brief This section covers functions related to Timer Counter for Control peripheral, which drives the piezo buzzer * embedded in the F-91W's back plate as well as the LED that backlights the display. @@ -155,15 +148,13 @@ void watch_enable_buzzer(void); */ void watch_set_buzzer_period_and_duty_cycle(uint32_t period, uint8_t duty); -/** @brief Disables the TCC peripheral that drives the buzzer. - * @note If you are using PWM to set custom LED colors, this method will also disable the LED PWM driver, - * since the buzzer and LED both make use of the same peripheral to drive their PWM behavior. +/** @brief Disables the TCC peripheral that drives the buzzer (if LED not active). */ void watch_disable_buzzer(void); /** @brief Turns the buzzer output on. It will emit a continuous sound at the given frequency. - * @note The TCC peripheral that drives the buzzer does not run in standby mode; if you wish for buzzer - * output to continue, you should prevent your app from going to sleep. + * @note The TCC peripheral that drives the buzzer does run in standby mode; if you wish for buzzer + * output to continue, you don't need to prevent your app from going to sleep. */ void watch_set_buzzer_on(void); @@ -265,18 +256,6 @@ void watch_buzzer_abort_sequence(void); void watch_buzzer_register_global_callbacks(watch_cb_t cb_start, watch_cb_t cb_stop); -/** @brief Enables the TCC peripheral, which drives the buzzer and the leds. -*/ -void watch_enable_buzzer_and_leds(void); - -/** @brief Disables the TCC peripheral that drives the buzzer and the leds. - */ -void watch_disable_buzzer_and_leds(void); - -/** @brief Disables the TCC peripheral that drives the buzzer and the leds if neither is currently active - */ -void watch_maybe_disable_buzzer_and_leds(void); - #ifndef __EMSCRIPTEN__ void irq_handler_tc0(void); #endif @@ -294,26 +273,17 @@ void irq_handler_tc0(void); * so that watch_set_led_red sets the red LED, and watch_set_led_green sets the blue one. */ /// @{ -/** @brief Enables the bi-color LED. - * @note The TCC peripheral that drives the LEDs does not run in STANDBY mode — but the outputs do! This - * means that if you set either red, green or both LEDs to full power, they will shine even when - * your app is asleep. If, however, you set a custom color using watch_set_led_color, the color will - * not display correctly in STANDBY mode. You will need to keep your app running while the LED is on. +/** @brief Enables the TCC peripheral, which drives the LEDs. */ void watch_enable_leds(void); -/** @brief Disables the LEDs. - * @note This method will also disable the buzzer, since the buzzer and LED both make use of the same - * peripheral to drive their PWM behavior. +/** @brief Disables the TCC peripheral that drives the LEDs (if buzzer not active). */ void watch_disable_leds(void); /** @brief Sets the LED to a custom color by modulating each output's duty cycle. * @param red The red value from 0-255. * @param green The green value from 0-255. If your watch has a red/blue LED, this will be the blue value. - * @note If you are displaying a custom color, you will need to prevent your app from going to sleep - * while the LED is on; otherwise, the color will not display correctly. You can do this by - * returning false in your app_loop method. */ void watch_set_led_color(uint8_t red, uint8_t green); @@ -321,9 +291,6 @@ void watch_set_led_color(uint8_t red, uint8_t green); * @param red The red value from 0-255. * @param green The green value from 0-255. * @param blue The blue value from 0-255. - * @note If you are displaying a custom color, you will need to prevent your app from going to sleep - * while the LED is on; otherwise, the color will not display correctly. You can do this by - * returning false in your app_loop method. */ void watch_set_led_color_rgb(uint8_t red, uint8_t green, uint8_t blue); @@ -348,9 +315,6 @@ void watch_set_led_yellow(void); /** @brief Turns both the red and the green LEDs off. */ void watch_set_led_off(void); -/** @brief Disables the TCC peripheral. Should only be called internally. */ -void _watch_disable_tcc(void); - /// @brief An array of periods for all the notes on a piano, corresponding to the names in watch_buzzer_note_t. extern const uint16_t NotePeriods[108]; diff --git a/watch-library/simulator/watch/watch.c b/watch-library/simulator/watch/watch.c index 4e89f3d3..7584cd38 100644 --- a/watch-library/simulator/watch/watch.c +++ b/watch-library/simulator/watch/watch.c @@ -1,9 +1,5 @@ #include "watch.h" -bool watch_is_buzzer_or_led_enabled(void) { - return false; -} - bool watch_is_usb_enabled(void) { return true; } diff --git a/watch-library/simulator/watch/watch_private.c b/watch-library/simulator/watch/watch_private.c index 6f97490b..b94fbf12 100644 --- a/watch-library/simulator/watch/watch_private.c +++ b/watch-library/simulator/watch/watch_private.c @@ -51,8 +51,6 @@ int _gettimeofday(struct timeval *tv, void *tzvp) { return 0; } -void _watch_disable_tcc(void) {} - void _watch_enable_usb(void) {} void watch_disable_TRNG() {} diff --git a/watch-library/simulator/watch/watch_tcc.c b/watch-library/simulator/watch/watch_tcc.c index 1ca4bbf0..6cbf9822 100644 --- a/watch-library/simulator/watch/watch_tcc.c +++ b/watch-library/simulator/watch/watch_tcc.c @@ -46,8 +46,6 @@ static watch_cb_t _cb_start_global = NULL; static watch_cb_t _cb_stop_global = NULL; static volatile bool _buzzer_is_active = false; -void _watch_enable_tcc(void) {} - static inline void _em_interval_stop() { emscripten_clear_interval(_em_interval_id); _em_interval_id = 0;