add buzzer volume control

This commit is contained in:
joeycastillo 2024-09-22 13:34:46 -04:00
parent 6e0d9270b5
commit 2e738db673
6 changed files with 41 additions and 17 deletions

View File

@ -334,7 +334,7 @@ static void _activity_chirp_tick_transmit(void *context) {
return;
}
uint16_t period = chirpy_get_tone_period(tone);
watch_set_buzzer_period(period);
watch_set_buzzer_period_and_duty_cycle(period, 25);
watch_set_buzzer_on();
}
@ -351,7 +351,7 @@ static void _activity_chirp_tick_countdown(void *context) {
}
// Sound or turn off buzzer
if ((state->chirpy_tick_state.seq_pos % 8) == 0) {
watch_set_buzzer_period(NotePeriods[BUZZER_NOTE_A5]);
watch_set_buzzer_period_and_duty_cycle(NotePeriods[BUZZER_NOTE_A5], 25);
watch_set_buzzer_on();
if (state->chirpy_tick_state.seq_pos == 0) {
watch_display_string(" --- ", 4);

View File

@ -84,7 +84,7 @@ static void update_buzzer(const tuning_tones_state_t *state)
{
if (state->playing) {
watch_set_buzzer_off();
watch_set_buzzer_period(NotePeriods[notes[state->note_ind].note]);
watch_set_buzzer_period_and_duty_cycle(NotePeriods[notes[state->note_ind].note], 25);
watch_set_buzzer_on();
}
}

View File

@ -168,7 +168,7 @@ static void _cdf_scale_tick(void *context) {
}
uint32_t freq = 700 + tick_state->seq_pos * 200;
uint32_t period = 1000000 / freq;
watch_set_buzzer_period(period);
watch_set_buzzer_period_and_duty_cycle(period, 25);
watch_set_buzzer_on();
++tick_state->seq_pos;
}
@ -183,7 +183,7 @@ static void _cdf_data_tick(void *context) {
return;
}
uint16_t period = chirpy_get_tone_period(tone);
watch_set_buzzer_period(period);
watch_set_buzzer_period_and_duty_cycle(period, 25);
watch_set_buzzer_on();
}
@ -234,7 +234,7 @@ static void _cdf_countdown_tick(void *context) {
}
// Sound or turn off buzzer
if ((tick_state->seq_pos % 8) == 0) {
watch_set_buzzer_period(NotePeriods[BUZZER_NOTE_A5]);
watch_set_buzzer_period_and_duty_cycle(NotePeriods[BUZZER_NOTE_A5], 25);
watch_set_buzzer_on();
} else if ((tick_state->seq_pos % 8) == 1) {
watch_set_buzzer_off();

View File

@ -110,7 +110,7 @@ void cb_watch_buzzer_seq(void) {
// read note
BuzzerNote note = _sequence[_seq_position];
if (note != BUZZER_NOTE_REST) {
watch_set_buzzer_period(NotePeriods[note]);
watch_set_buzzer_period_and_duty_cycle(NotePeriods[note], 25);
watch_set_buzzer_on();
} else watch_set_buzzer_off();
// set duration ticks and move to next tone
@ -148,9 +148,9 @@ inline void watch_enable_buzzer(void) {
}
}
inline void watch_set_buzzer_period(uint32_t period) {
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 / 2, true);
tcc_set_cc(0, (WATCH_BUZZER_TCC_CHANNEL) % 4, period / (100 / duty), true);
}
void watch_disable_buzzer(void) {
@ -168,10 +168,14 @@ inline void watch_set_buzzer_off(void) {
}
void watch_buzzer_play_note(BuzzerNote note, uint16_t duration_ms) {
watch_buzzer_play_note_with_volume(note, duration_ms, WATCH_BUZZER_VOLUME_LOUD);
}
void watch_buzzer_play_note_with_volume(BuzzerNote note, uint16_t duration_ms, watch_buzzer_volume_t volume) {
if (note == BUZZER_NOTE_REST) {
watch_set_buzzer_off();
} else {
watch_set_buzzer_period(NotePeriods[note]);
} else {
watch_set_buzzer_period_and_duty_cycle(NotePeriods[note], volume == WATCH_BUZZER_VOLUME_SOFT ? 5 : 25);
watch_set_buzzer_on();
}
delay_ms(duration_ms);

View File

@ -36,7 +36,8 @@
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 the piezo buzzer embedded in the F-91W's back plate.
* @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.
*/
/// @{
/** @brief Enables the TCC peripheral, which drives the buzzer.
@ -46,8 +47,11 @@ void watch_enable_buzzer(void);
/** @brief Sets the period of the buzzer.
* @param period The period of a single cycle for the TCC peripheral. You can determine the period for
* a desired frequency with the following formula: period = 1000000 / freq
* @param duty The duty cycle of the buzzer, from 0 to 50 (percent ON time). Do not use values over 50.
* @note Unless you _really_ know what you're doing, use 25% for the duty cycle. If you're just aiming
* to play a tone at a given volume, use watch_buzzer_play_note_with_volume instead.
*/
void watch_set_buzzer_period(uint32_t period);
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,
@ -65,6 +69,12 @@ void watch_set_buzzer_on(void);
*/
void watch_set_buzzer_off(void);
/// @brief An enum for controlling the volume of the buzzer.
typedef enum {
WATCH_BUZZER_VOLUME_SOFT = 0,
WATCH_BUZZER_VOLUME_LOUD
} watch_buzzer_volume_t;
/// @brief 87 notes for use with watch_buzzer_play_note
typedef enum BuzzerNote {
BUZZER_NOTE_A1, ///< 55.00 Hz
@ -157,7 +167,7 @@ typedef enum BuzzerNote {
BUZZER_NOTE_REST ///< no sound
} BuzzerNote;
/** @brief Plays the given note for a set duration.
/** @brief Plays the given note for a set duration at the loudest possible volume.
* @param note The note you wish to play, or BUZZER_NOTE_REST to disable output for the given duration.
* @param duration_ms The duration of the note.
* @note Note that this will block your UI for the duration of the note's play time, and it will
@ -165,6 +175,15 @@ typedef enum BuzzerNote {
*/
void watch_buzzer_play_note(BuzzerNote note, uint16_t duration_ms);
/** @brief Plays the given note for a set duration.
* @param note The note you wish to play, or BUZZER_NOTE_REST to disable output for the given duration.
* @param duration_ms The duration of the note.
* @param volume either WATCH_BUZZER_VOLUME_SOFT or WATCH_BUZZER_VOLUME_LOUD
* @note This will block your UI for the duration of the note's play time, and after this call, the
* buzzer will stop sounding, but the TCC period will remain set to the period of this note.
*/
void watch_buzzer_play_note_with_volume(BuzzerNote note, uint16_t duration_ms, watch_buzzer_volume_t volume);
/// @brief An array of periods for all the notes on a piano, corresponding to the names in BuzzerNote.
extern const uint16_t NotePeriods[108];

View File

@ -89,7 +89,7 @@ void cb_watch_buzzer_seq(void *userData) {
if (note == BUZZER_NOTE_REST) {
watch_set_buzzer_off();
} else {
watch_set_buzzer_period(NotePeriods[note]);
watch_set_buzzer_period_and_duty_cycle(NotePeriods[note], 25);
watch_set_buzzer_on();
}
// set duration ticks and move to next tone
@ -118,7 +118,8 @@ void watch_enable_buzzer(void) {
});
}
void watch_set_buzzer_period(uint32_t period) {
void watch_set_buzzer_period_and_duty_cycle(uint32_t period, uint8_t duty_cycle) {
(void) duty_cycle;
if (!buzzer_enabled) return;
buzzer_period = period;
}
@ -174,7 +175,7 @@ void watch_buzzer_play_note(BuzzerNote note, uint16_t duration_ms) {
if (note == BUZZER_NOTE_REST) {
watch_set_buzzer_off();
} else {
watch_set_buzzer_period(NotePeriods[note]);
watch_set_buzzer_period_and_duty_cycle(NotePeriods[note], 25);
watch_set_buzzer_on();
}