add buzzer volume control
This commit is contained in:
parent
6e0d9270b5
commit
2e738db673
@ -334,7 +334,7 @@ static void _activity_chirp_tick_transmit(void *context) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint16_t period = chirpy_get_tone_period(tone);
|
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();
|
watch_set_buzzer_on();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,7 +351,7 @@ static void _activity_chirp_tick_countdown(void *context) {
|
|||||||
}
|
}
|
||||||
// Sound or turn off buzzer
|
// Sound or turn off buzzer
|
||||||
if ((state->chirpy_tick_state.seq_pos % 8) == 0) {
|
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();
|
watch_set_buzzer_on();
|
||||||
if (state->chirpy_tick_state.seq_pos == 0) {
|
if (state->chirpy_tick_state.seq_pos == 0) {
|
||||||
watch_display_string(" --- ", 4);
|
watch_display_string(" --- ", 4);
|
||||||
|
|||||||
@ -84,7 +84,7 @@ static void update_buzzer(const tuning_tones_state_t *state)
|
|||||||
{
|
{
|
||||||
if (state->playing) {
|
if (state->playing) {
|
||||||
watch_set_buzzer_off();
|
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();
|
watch_set_buzzer_on();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -168,7 +168,7 @@ static void _cdf_scale_tick(void *context) {
|
|||||||
}
|
}
|
||||||
uint32_t freq = 700 + tick_state->seq_pos * 200;
|
uint32_t freq = 700 + tick_state->seq_pos * 200;
|
||||||
uint32_t period = 1000000 / freq;
|
uint32_t period = 1000000 / freq;
|
||||||
watch_set_buzzer_period(period);
|
watch_set_buzzer_period_and_duty_cycle(period, 25);
|
||||||
watch_set_buzzer_on();
|
watch_set_buzzer_on();
|
||||||
++tick_state->seq_pos;
|
++tick_state->seq_pos;
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ static void _cdf_data_tick(void *context) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint16_t period = chirpy_get_tone_period(tone);
|
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();
|
watch_set_buzzer_on();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +234,7 @@ static void _cdf_countdown_tick(void *context) {
|
|||||||
}
|
}
|
||||||
// Sound or turn off buzzer
|
// Sound or turn off buzzer
|
||||||
if ((tick_state->seq_pos % 8) == 0) {
|
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();
|
watch_set_buzzer_on();
|
||||||
} else if ((tick_state->seq_pos % 8) == 1) {
|
} else if ((tick_state->seq_pos % 8) == 1) {
|
||||||
watch_set_buzzer_off();
|
watch_set_buzzer_off();
|
||||||
|
|||||||
@ -110,7 +110,7 @@ void cb_watch_buzzer_seq(void) {
|
|||||||
// read note
|
// read note
|
||||||
BuzzerNote note = _sequence[_seq_position];
|
BuzzerNote note = _sequence[_seq_position];
|
||||||
if (note != BUZZER_NOTE_REST) {
|
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();
|
watch_set_buzzer_on();
|
||||||
} else watch_set_buzzer_off();
|
} else watch_set_buzzer_off();
|
||||||
// set duration ticks and move to next tone
|
// 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_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) {
|
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) {
|
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) {
|
if (note == BUZZER_NOTE_REST) {
|
||||||
watch_set_buzzer_off();
|
watch_set_buzzer_off();
|
||||||
} else {
|
} else {
|
||||||
watch_set_buzzer_period(NotePeriods[note]);
|
watch_set_buzzer_period_and_duty_cycle(NotePeriods[note], volume == WATCH_BUZZER_VOLUME_SOFT ? 5 : 25);
|
||||||
watch_set_buzzer_on();
|
watch_set_buzzer_on();
|
||||||
}
|
}
|
||||||
delay_ms(duration_ms);
|
delay_ms(duration_ms);
|
||||||
|
|||||||
@ -36,7 +36,8 @@
|
|||||||
bool watch_is_buzzer_or_led_enabled(void);
|
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 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.
|
/** @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.
|
/** @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
|
* @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
|
* 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.
|
/** @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,
|
* @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);
|
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
|
/// @brief 87 notes for use with watch_buzzer_play_note
|
||||||
typedef enum BuzzerNote {
|
typedef enum BuzzerNote {
|
||||||
BUZZER_NOTE_A1, ///< 55.00 Hz
|
BUZZER_NOTE_A1, ///< 55.00 Hz
|
||||||
@ -157,7 +167,7 @@ typedef enum BuzzerNote {
|
|||||||
BUZZER_NOTE_REST ///< no sound
|
BUZZER_NOTE_REST ///< no sound
|
||||||
} BuzzerNote;
|
} 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 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 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
|
* @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);
|
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.
|
/// @brief An array of periods for all the notes on a piano, corresponding to the names in BuzzerNote.
|
||||||
extern const uint16_t NotePeriods[108];
|
extern const uint16_t NotePeriods[108];
|
||||||
|
|
||||||
|
|||||||
@ -89,7 +89,7 @@ void cb_watch_buzzer_seq(void *userData) {
|
|||||||
if (note == BUZZER_NOTE_REST) {
|
if (note == BUZZER_NOTE_REST) {
|
||||||
watch_set_buzzer_off();
|
watch_set_buzzer_off();
|
||||||
} else {
|
} else {
|
||||||
watch_set_buzzer_period(NotePeriods[note]);
|
watch_set_buzzer_period_and_duty_cycle(NotePeriods[note], 25);
|
||||||
watch_set_buzzer_on();
|
watch_set_buzzer_on();
|
||||||
}
|
}
|
||||||
// set duration ticks and move to next tone
|
// 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;
|
if (!buzzer_enabled) return;
|
||||||
buzzer_period = period;
|
buzzer_period = period;
|
||||||
}
|
}
|
||||||
@ -174,7 +175,7 @@ void watch_buzzer_play_note(BuzzerNote note, uint16_t duration_ms) {
|
|||||||
if (note == BUZZER_NOTE_REST) {
|
if (note == BUZZER_NOTE_REST) {
|
||||||
watch_set_buzzer_off();
|
watch_set_buzzer_off();
|
||||||
} else {
|
} else {
|
||||||
watch_set_buzzer_period(NotePeriods[note]);
|
watch_set_buzzer_period_and_duty_cycle(NotePeriods[note], 25);
|
||||||
watch_set_buzzer_on();
|
watch_set_buzzer_on();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user