#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;
// 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;
// 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;
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();
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();
}
}
-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) {
}
}
-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);
tcc_set_cc(0, (WATCH_BLUE_TCC_CHANNEL) % 4, 0, false);
#endif
+ // Enable the TCC
+ tcc_enable(0);
+}
+
+void _watch_disable_tcc(void) {
+ // disable all PWM pins
+ HAL_GPIO_BUZZER_pmuxdis();
+ HAL_GPIO_BUZZER_off();
+ 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
+ tcc_disable(0);
+}
+
+void watch_enable_leds(void) {
+ _led_is_active = true;
+ _watch_enable_led_pins();
+ _watch_maybe_enable_tcc();
+}
+
+void watch_disable_leds(void) {
+ _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_BLUE_drvstr(1);
HAL_GPIO_BLUE_out();
#endif
-
- // Enable the TCC
- tcc_enable(0);
}
-void _watch_disable_tcc(void) {
- // disable all PWM pins
- HAL_GPIO_BUZZER_pmuxdis();
- HAL_GPIO_BUZZER_off();
+void _watch_disable_led_pins(void) {
HAL_GPIO_RED_pmuxdis();
HAL_GPIO_RED_off();
#ifdef WATCH_GREEN_TCC_CHANNEL
HAL_GPIO_BLUE_pmuxdis();
HAL_GPIO_BLUE_off();
#endif
- tcc_disable(0);
-}
-
-void watch_enable_leds(void) {
- watch_enable_buzzer_and_leds();
-}
-
-void watch_disable_leds(void) {
- watch_maybe_disable_buzzer_and_leds();
}
void watch_set_led_color(uint8_t red, uint8_t green) {
_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();
}
}
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.
*/
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);
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
* 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);
* @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);
/** @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];