Improve watch_tcc to decouple leds and buzzer as much as allowed
As a positive side effect, the led will stop emitting the faintiest of blinks when the buzzer starts playing.
This commit is contained in:
@@ -151,7 +151,8 @@ static void _watch_disable_all_pins_except_rtc(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void _watch_disable_all_peripherals_except_slcd(void) {
|
static void _watch_disable_all_peripherals_except_slcd(void) {
|
||||||
_watch_disable_tcc();
|
watch_disable_leds();
|
||||||
|
watch_disable_buzzer();
|
||||||
watch_disable_adc();
|
watch_disable_adc();
|
||||||
watch_disable_external_interrupts();
|
watch_disable_external_interrupts();
|
||||||
|
|
||||||
|
|||||||
@@ -27,10 +27,15 @@
|
|||||||
#include "tcc.h"
|
#include "tcc.h"
|
||||||
#include "tc.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;
|
static void (*_cb_tc0)(void) = NULL;
|
||||||
void cb_watch_buzzer_seq(void);
|
static void cb_watch_buzzer_seq(void);
|
||||||
void cb_watch_buzzer_raw_source(void);
|
static void cb_watch_buzzer_raw_source(void);
|
||||||
|
|
||||||
static uint16_t _seq_position;
|
static uint16_t _seq_position;
|
||||||
static int8_t _tone_ticks, _repeat_counter;
|
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
|
// Abort any previous sequence
|
||||||
watch_buzzer_abort_sequence();
|
watch_buzzer_abort_sequence();
|
||||||
|
|
||||||
_buzzer_is_active = true;
|
|
||||||
|
|
||||||
if (_cb_start_global) {
|
if (_cb_start_global) {
|
||||||
_cb_start_global();
|
_cb_start_global();
|
||||||
}
|
}
|
||||||
|
|
||||||
watch_enable_buzzer_and_leds();
|
watch_enable_buzzer();
|
||||||
|
|
||||||
watch_set_buzzer_off();
|
watch_set_buzzer_off();
|
||||||
_sequence = note_sequence;
|
_sequence = note_sequence;
|
||||||
_cb_finished = callback_on_end;
|
_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
|
// Abort any previous sequence
|
||||||
watch_buzzer_abort_sequence();
|
watch_buzzer_abort_sequence();
|
||||||
|
|
||||||
_buzzer_is_active = true;
|
|
||||||
|
|
||||||
if (_cb_start_global) {
|
if (_cb_start_global) {
|
||||||
_cb_start_global();
|
_cb_start_global();
|
||||||
}
|
}
|
||||||
|
|
||||||
watch_enable_buzzer_and_leds();
|
watch_enable_buzzer();
|
||||||
|
|
||||||
watch_set_buzzer_off();
|
watch_set_buzzer_off();
|
||||||
_raw_source = raw_source;
|
_raw_source = raw_source;
|
||||||
@@ -213,14 +213,12 @@ void watch_buzzer_abort_sequence(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_buzzer_is_active = false;
|
|
||||||
|
|
||||||
_tc0_stop();
|
_tc0_stop();
|
||||||
|
|
||||||
watch_set_buzzer_off();
|
watch_set_buzzer_off();
|
||||||
|
|
||||||
// disable TCC
|
// disable TCC
|
||||||
watch_maybe_disable_buzzer_and_leds();
|
watch_disable_buzzer();
|
||||||
|
|
||||||
if (_cb_stop_global) {
|
if (_cb_stop_global) {
|
||||||
_cb_stop_global();
|
_cb_stop_global();
|
||||||
@@ -244,11 +242,11 @@ void irq_handler_tc0(void) {
|
|||||||
TC0->COUNT8.INTFLAG.reg |= TC_INTFLAG_OVF;
|
TC0->COUNT8.INTFLAG.reg |= TC_INTFLAG_OVF;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool watch_is_buzzer_or_led_enabled(void){
|
void _watch_maybe_enable_tcc(void) {
|
||||||
return tcc_is_enabled(0);
|
if (!_buzzer_is_active && !_led_is_active) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void watch_enable_buzzer_and_leds(void) {
|
|
||||||
if (!tcc_is_enabled(0)) {
|
if (!tcc_is_enabled(0)) {
|
||||||
// tcc_set_run_in_standby(0, true);
|
// tcc_set_run_in_standby(0, true);
|
||||||
_watch_enable_tcc();
|
_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)) {
|
if (tcc_is_enabled(0)) {
|
||||||
_tcc_write_RUNSTDBY(false);
|
_tcc_write_RUNSTDBY(false);
|
||||||
_watch_disable_tcc();
|
_watch_disable_tcc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void watch_maybe_disable_buzzer_and_leds(void) {
|
void watch_enable_buzzer(void) {
|
||||||
if (_buzzer_is_active || _led_is_active) {
|
_buzzer_is_active = true;
|
||||||
return;
|
_watch_maybe_enable_tcc();
|
||||||
}
|
|
||||||
|
|
||||||
watch_disable_buzzer_and_leds();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void watch_enable_buzzer(void) {
|
void watch_disable_buzzer(void) {
|
||||||
watch_enable_buzzer_and_leds();
|
_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_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) {
|
inline void watch_set_buzzer_on(void) {
|
||||||
HAL_GPIO_BUZZER_out();
|
HAL_GPIO_BUZZER_out();
|
||||||
HAL_GPIO_BUZZER_pmuxen(HAL_GPIO_PMUX_TCC_ALT);
|
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);
|
tcc_set_cc(0, (WATCH_BLUE_TCC_CHANNEL) % 4, 0, false);
|
||||||
#endif
|
#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
|
// Enable the TCC
|
||||||
tcc_enable(0);
|
tcc_enable(0);
|
||||||
}
|
}
|
||||||
@@ -393,11 +375,45 @@ void _watch_disable_tcc(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void watch_enable_leds(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) {
|
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) {
|
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[0] = red;
|
||||||
_current_led_color[1] = green;
|
_current_led_color[1] = green;
|
||||||
_current_led_color[2] = blue;
|
_current_led_color[2] = blue;
|
||||||
_led_is_active = true;
|
watch_enable_leds();
|
||||||
watch_enable_buzzer_and_leds();
|
|
||||||
} else {
|
|
||||||
_led_is_active = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tcc_is_enabled(0)) {
|
|
||||||
uint32_t period = tcc_get_period(0);
|
uint32_t period = tcc_get_period(0);
|
||||||
_watch_set_led_duty_cycle(period, red, green, blue);
|
_watch_set_led_duty_cycle(period, red, green, blue);
|
||||||
}
|
} else {
|
||||||
|
if (tcc_is_enabled(0)) {
|
||||||
if (!turning_on) {
|
_watch_set_led_duty_cycle(1, red, green, blue);
|
||||||
watch_maybe_disable_buzzer_and_leds();
|
}
|
||||||
|
watch_disable_leds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -130,13 +130,6 @@ typedef enum {
|
|||||||
|
|
||||||
typedef bool (*watch_buzzer_raw_source_t)(uint16_t position, void* userdata, uint16_t* period, uint16_t* duration);
|
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)
|
/** @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
|
* @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.
|
* 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);
|
void watch_set_buzzer_period_and_duty_cycle(uint32_t period, uint8_t duty);
|
||||||
|
|
||||||
/** @brief Disables the TCC peripheral that drives the buzzer.
|
/** @brief Disables the TCC peripheral that drives the buzzer (if LED not active).
|
||||||
* @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.
|
|
||||||
*/
|
*/
|
||||||
void watch_disable_buzzer(void);
|
void watch_disable_buzzer(void);
|
||||||
|
|
||||||
/** @brief Turns the buzzer output on. It will emit a continuous sound at the given frequency.
|
/** @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
|
* @note The TCC peripheral that drives the buzzer does run in standby mode; if you wish for buzzer
|
||||||
* output to continue, you should prevent your app from going to sleep.
|
* output to continue, you don't need to prevent your app from going to sleep.
|
||||||
*/
|
*/
|
||||||
void watch_set_buzzer_on(void);
|
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);
|
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__
|
#ifndef __EMSCRIPTEN__
|
||||||
void irq_handler_tc0(void);
|
void irq_handler_tc0(void);
|
||||||
#endif
|
#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.
|
* 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.
|
/** @brief Enables the TCC peripheral, which drives the LEDs.
|
||||||
* @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.
|
|
||||||
*/
|
*/
|
||||||
void watch_enable_leds(void);
|
void watch_enable_leds(void);
|
||||||
|
|
||||||
/** @brief Disables the LEDs.
|
/** @brief Disables the TCC peripheral that drives the LEDs (if buzzer not active).
|
||||||
* @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.
|
|
||||||
*/
|
*/
|
||||||
void watch_disable_leds(void);
|
void watch_disable_leds(void);
|
||||||
|
|
||||||
/** @brief Sets the LED to a custom color by modulating each output's duty cycle.
|
/** @brief Sets the LED to a custom color by modulating each output's duty cycle.
|
||||||
* @param red The red value from 0-255.
|
* @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.
|
* @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);
|
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 red The red value from 0-255.
|
||||||
* @param green The green value from 0-255.
|
* @param green The green value from 0-255.
|
||||||
* @param blue The blue 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);
|
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. */
|
/** @brief Turns both the red and the green LEDs off. */
|
||||||
void watch_set_led_off(void);
|
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.
|
/// @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];
|
extern const uint16_t NotePeriods[108];
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
#include "watch.h"
|
#include "watch.h"
|
||||||
|
|
||||||
bool watch_is_buzzer_or_led_enabled(void) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool watch_is_usb_enabled(void) {
|
bool watch_is_usb_enabled(void) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,8 +51,6 @@ int _gettimeofday(struct timeval *tv, void *tzvp) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _watch_disable_tcc(void) {}
|
|
||||||
|
|
||||||
void _watch_enable_usb(void) {}
|
void _watch_enable_usb(void) {}
|
||||||
|
|
||||||
void watch_disable_TRNG() {}
|
void watch_disable_TRNG() {}
|
||||||
|
|||||||
@@ -46,8 +46,6 @@ static watch_cb_t _cb_start_global = NULL;
|
|||||||
static watch_cb_t _cb_stop_global = NULL;
|
static watch_cb_t _cb_stop_global = NULL;
|
||||||
static volatile bool _buzzer_is_active = false;
|
static volatile bool _buzzer_is_active = false;
|
||||||
|
|
||||||
void _watch_enable_tcc(void) {}
|
|
||||||
|
|
||||||
static inline void _em_interval_stop() {
|
static inline void _em_interval_stop() {
|
||||||
emscripten_clear_interval(_em_interval_id);
|
emscripten_clear_interval(_em_interval_id);
|
||||||
_em_interval_id = 0;
|
_em_interval_id = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user