add API for playing sounds from the buzzer

This commit is contained in:
Joey Castillo 2021-08-08 19:56:33 -04:00
parent ca96db1ef5
commit 616e4fb105
7 changed files with 483 additions and 3 deletions

View File

@ -0,0 +1,137 @@
#include <stdio.h>
#include <string.h>
#include "watch.h"
typedef struct ApplicationState {
bool play;
bool debounce_wait;
} ApplicationState;
ApplicationState application_state;
void cb_alarm_pressed() {
if (application_state.debounce_wait) return;
application_state.debounce_wait = true;
application_state.play = true;
}
void app_init() {
memset(&application_state, 0, sizeof(application_state));
}
void app_wake_from_deep_sleep() {
}
void app_setup() {
watch_register_button_callback(BTN_ALARM, cb_alarm_pressed);
watch_enable_display();
watch_enable_buzzer();
}
void app_prepare_for_sleep() {
watch_display_string(" rains ", 2);
}
void app_wake_from_sleep() {
}
bool app_loop() {
if (application_state.play) {
const BuzzerNote rains[] = {
BUZZER_NOTE_A4,
BUZZER_NOTE_F5,
BUZZER_NOTE_REST,
BUZZER_NOTE_A4,
BUZZER_NOTE_E5,
BUZZER_NOTE_REST,
BUZZER_NOTE_A4,
BUZZER_NOTE_F5,
BUZZER_NOTE_G5,
BUZZER_NOTE_E5,
BUZZER_NOTE_REST,
BUZZER_NOTE_A4,
BUZZER_NOTE_G5,
BUZZER_NOTE_F5,
BUZZER_NOTE_E5,
BUZZER_NOTE_D5,
BUZZER_NOTE_E5,
BUZZER_NOTE_REST,
BUZZER_NOTE_A5,
BUZZER_NOTE_REST,
BUZZER_NOTE_A5,
BUZZER_NOTE_A5SHARP_B5FLAT,
BUZZER_NOTE_G5,
BUZZER_NOTE_REST,
BUZZER_NOTE_C5,
BUZZER_NOTE_A5,
BUZZER_NOTE_A5SHARP_B5FLAT,
BUZZER_NOTE_G5,
BUZZER_NOTE_REST,
BUZZER_NOTE_D5,
BUZZER_NOTE_A5SHARP_B5FLAT,
BUZZER_NOTE_A5,
BUZZER_NOTE_G5,
BUZZER_NOTE_F5,
BUZZER_NOTE_E5,
};
const uint16_t durations[] = {
200,
600,
100,
200,
600,
100,
200,
400,
400,
600,
100,
200,
400,
400,
400,
400,
800,
600,
200,
50,
400,
200,
400,
100,
200,
400,
400,
400,
200,
200,
400,
400,
400,
400,
900,
};
application_state.play = false;
for(size_t i = 0; i < sizeof(rains); i++) {
char buf[9] = {0};
if (rains[i] == BUZZER_NOTE_REST) {
sprintf(buf, "%2drESt ", i);
} else {
sprintf(buf, "%2d%6d", i, NotePeriods[rains[i]]);
}
watch_display_string(buf, 2);
watch_buzzer_play_note(rains[i], durations[i]);
}
}
// Wait a moment to debounce button input
delay_ms(250);
application_state.debounce_wait = false;
return true;
}

1
Sensor Watch Buzzer Demo/make/.gitignore vendored Executable file
View File

@ -0,0 +1 @@
build/

View File

@ -0,0 +1,151 @@
##############################################################################
BUILD = build
BIN = watch
##############################################################################
.PHONY: all directory clean size
CC = arm-none-eabi-gcc
OBJCOPY = arm-none-eabi-objcopy
SIZE = arm-none-eabi-size
UF2 = python ../../utils/uf2conv.py
ifeq ($(OS), Windows_NT)
MKDIR = gmkdir
else
MKDIR = mkdir
endif
CFLAGS += -W -Wall --std=gnu99 -Os
CFLAGS += -fno-diagnostics-show-caret
CFLAGS += -fdata-sections -ffunction-sections
CFLAGS += -funsigned-char -funsigned-bitfields
CFLAGS += -mcpu=cortex-m0plus -mthumb
CFLAGS += -MD -MP -MT $(BUILD)/$(*F).o -MF $(BUILD)/$(@F).d
LDFLAGS += -mcpu=cortex-m0plus -mthumb
LDFLAGS += -Wl,--gc-sections
LDFLAGS += -Wl,--script=../../watch-library/linker/saml22j18.ld
# If you add any additional directories with headers, add them to this list, e.g.
# ../drivers/
INCLUDES += \
-I../ \
-I../../watch-library/include \
-I../../watch-library/hal/ \
-I../../watch-library/hal/documentation/ \
-I../../watch-library/hal/include/ \
-I../../watch-library/hal/src/ \
-I../../watch-library/hal/utils/ \
-I../../watch-library/hal/utils/include/ \
-I../../watch-library/hal/utils/src/ \
-I../../watch-library/hpl/ \
-I../../watch-library/hpl/adc/ \
-I../../watch-library/hpl/core/ \
-I../../watch-library/hpl/dmac/ \
-I../../watch-library/hpl/eic/ \
-I../../watch-library/hpl/gclk/ \
-I../../watch-library/hpl/mclk/ \
-I../../watch-library/hpl/osc32kctrl/ \
-I../../watch-library/hpl/oscctrl/ \
-I../../watch-library/hpl/pm/ \
-I../../watch-library/hpl/port/ \
-I../../watch-library/hpl/rtc/ \
-I../../watch-library/hpl/sercom/ \
-I../../watch-library/hpl/slcd/ \
-I../../watch-library/hpl/systick/ \
-I../../watch-library/hpl/tcc/ \
-I../../watch-library/hpl/tc/ \
-I../../watch-library/hri/ \
-I../../watch-library/config/ \
-I../../watch-library/hw/ \
-I../../watch-library/watch/ \
-I../../watch-library
# If you add any additional C files to your project, add them each to this list, e.g.
# ../drivers/st25dv.c
SRCS += \
../app.c \
../../watch-library/main.c \
../../watch-library/startup_saml22.c \
../../watch-library/hw/driver_init.c \
../../watch-library/watch/watch.c \
../../watch-library/hal/src/hal_adc_sync.c \
../../watch-library/hal/src/hal_atomic.c \
../../watch-library/hal/src/hal_calendar.c \
../../watch-library/hal/src/hal_delay.c \
../../watch-library/hal/src/hal_ext_irq.c \
../../watch-library/hal/src/hal_gpio.c \
../../watch-library/hal/src/hal_i2c_m_sync.c \
../../watch-library/hal/src/hal_init.c \
../../watch-library/hal/src/hal_io.c \
../../watch-library/hal/src/hal_pwm.c \
../../watch-library/hal/src/hal_slcd_sync.c \
../../watch-library/hal/src/hal_sleep.c \
../../watch-library/hal/utils/src/utils_assert.c \
../../watch-library/hal/utils/src/utils_event.c \
../../watch-library/hal/utils/src/utils_list.c \
../../watch-library/hal/utils/src/utils_syscalls.c \
../../watch-library/hpl/adc/hpl_adc.c \
../../watch-library/hpl/core/hpl_core_m0plus_base.c \
../../watch-library/hpl/core/hpl_init.c \
../../watch-library/hpl/dmac/hpl_dmac.c \
../../watch-library/hpl/eic/hpl_eic.c \
../../watch-library/hpl/gclk/hpl_gclk.c \
../../watch-library/hpl/mclk/hpl_mclk.c \
../../watch-library/hpl/osc32kctrl/hpl_osc32kctrl.c \
../../watch-library/hpl/oscctrl/hpl_oscctrl.c \
../../watch-library/hpl/pm/hpl_pm.c \
../../watch-library/hpl/rtc/hpl_rtc.c \
../../watch-library/hpl/sercom/hpl_sercom.c \
../../watch-library/hpl/slcd/hpl_slcd.c \
../../watch-library/hpl/systick/hpl_systick.c \
../../watch-library/hpl/tcc/hpl_tcc.c \
../../watch-library/hpl/tc/hpl_tc.c
DEFINES += \
-D__SAML22J18A__ \
-DDONT_USE_CMSIS_INIT
CFLAGS += $(INCLUDES) $(DEFINES)
OBJS = $(addprefix $(BUILD)/, $(notdir %/$(subst .c,.o, $(SRCS))))
all: directory $(BUILD)/$(BIN).elf $(BUILD)/$(BIN).hex $(BUILD)/$(BIN).bin $(BUILD)/$(BIN).uf2 size
$(BUILD)/$(BIN).elf: $(OBJS)
@echo LD $@
@$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
$(BUILD)/$(BIN).hex: $(BUILD)/$(BIN).elf
@echo OBJCOPY $@
@$(OBJCOPY) -O ihex $^ $@
$(BUILD)/$(BIN).bin: $(BUILD)/$(BIN).elf
@echo OBJCOPY $@
@$(OBJCOPY) -O binary $^ $@
$(BUILD)/$(BIN).uf2: $(BUILD)/$(BIN).bin
@echo UF2CONV $@
@$(UF2) $^ -co $@
install:
@$(UF2) -D $(BUILD)/$(BIN).uf2
%.o:
@echo CC $@
@$(CC) $(CFLAGS) $(filter %/$(subst .o,.c,$(notdir $@)), $(SRCS)) -c -o $@
directory:
@$(MKDIR) -p $(BUILD)
size: $(BUILD)/$(BIN).elf
@echo size:
@$(SIZE) -t $^
clean:
@echo clean
@-rm -rf $(BUILD)
-include $(wildcard $(BUILD)/*.d)

View File

@ -173,7 +173,7 @@
// <i> Select the clock source for TCC. // <i> Select the clock source for TCC.
#ifndef CONF_GCLK_TCC0_SRC #ifndef CONF_GCLK_TCC0_SRC
#define CONF_GCLK_TCC0_SRC GCLK_PCHCTRL_GEN_GCLK3_Val #define CONF_GCLK_TCC0_SRC GCLK_PCHCTRL_GEN_GCLK0_Val
#endif #endif
/** /**
@ -181,7 +181,7 @@
* \brief TCC0's Clock frequency * \brief TCC0's Clock frequency
*/ */
#ifndef CONF_GCLK_TCC0_FREQUENCY #ifndef CONF_GCLK_TCC0_FREQUENCY
#define CONF_GCLK_TCC0_FREQUENCY 32768 #define CONF_GCLK_TCC0_FREQUENCY 16000000
#endif #endif
#include <hpl_osc32kctrl_config.h> #include <hpl_osc32kctrl_config.h>

114
watch-library/watch/notes.h Normal file
View File

@ -0,0 +1,114 @@
////< @file notes.h
/// @brief 108 notes for use with watch_buzzer_play_note
typedef enum BuzzerNote {
BUZZER_NOTE_C0 = 0, ///< 16.35 Hz
BUZZER_NOTE_C0SHARP_D0FLAT, ///< 17.32 Hz
BUZZER_NOTE_D0, ///< 18.35 Hz
BUZZER_NOTE_D0SHARP_E0FLAT, ///< 19.45 Hz
BUZZER_NOTE_E0, ///< 20.60 Hz
BUZZER_NOTE_F0, ///< 21.83 Hz
BUZZER_NOTE_F0SHARP_G0FLAT, ///< 23.12 Hz
BUZZER_NOTE_G0, ///< 24.50 Hz
BUZZER_NOTE_G0SHARP_A0FLAT, ///< 25.96 Hz
BUZZER_NOTE_A0, ///< 27.50 Hz
BUZZER_NOTE_A0SHARP_B0FLAT, ///< 29.14 Hz
BUZZER_NOTE_B0, ///< 30.87 Hz
BUZZER_NOTE_C1, ///< 32.70 Hz
BUZZER_NOTE_C1SHARP_D1FLAT, ///< 34.65 Hz
BUZZER_NOTE_D1, ///< 36.71 Hz
BUZZER_NOTE_D1SHARP_E1FLAT, ///< 38.89 Hz
BUZZER_NOTE_E1, ///< 41.20 Hz
BUZZER_NOTE_F1, ///< 43.65 Hz
BUZZER_NOTE_F1SHARP_G1FLAT, ///< 46.25 Hz
BUZZER_NOTE_G1, ///< 49.00 Hz
BUZZER_NOTE_G1SHARP_A1FLAT, ///< 51.91 Hz
BUZZER_NOTE_A1, ///< 55.00 Hz
BUZZER_NOTE_A1SHARP_B1FLAT, ///< 58.27 Hz
BUZZER_NOTE_B1, ///< 61.74 Hz
BUZZER_NOTE_C2, ///< 65.41 Hz
BUZZER_NOTE_C2SHARP_D2FLAT, ///< 69.30 Hz
BUZZER_NOTE_D2, ///< 73.42 Hz
BUZZER_NOTE_D2SHARP_E2FLAT, ///< 77.78 Hz
BUZZER_NOTE_E2, ///< 82.41 Hz
BUZZER_NOTE_F2, ///< 87.31 Hz
BUZZER_NOTE_F2SHARP_G2FLAT, ///< 92.50 Hz
BUZZER_NOTE_G2, ///< 98.00 Hz
BUZZER_NOTE_G2SHARP_A2FLAT, ///< 103.83 Hz
BUZZER_NOTE_A2, ///< 110.00 Hz
BUZZER_NOTE_A2SHARP_B2FLAT, ///< 116.54 Hz
BUZZER_NOTE_B2, ///< 123.47 Hz
BUZZER_NOTE_C3, ///< 130.81 Hz
BUZZER_NOTE_C3SHARP_D3FLAT, ///< 138.59 Hz
BUZZER_NOTE_D3, ///< 146.83 Hz
BUZZER_NOTE_D3SHARP_E3FLAT, ///< 155.56 Hz
BUZZER_NOTE_E3, ///< 164.81 Hz
BUZZER_NOTE_F3, ///< 174.61 Hz
BUZZER_NOTE_F3SHARP_G3FLAT, ///< 185.00 Hz
BUZZER_NOTE_G3, ///< 196.00 Hz
BUZZER_NOTE_G3SHARP_A3FLAT, ///< 207.65 Hz
BUZZER_NOTE_A3, ///< 220.00 Hz
BUZZER_NOTE_A3SHARP_B3FLAT, ///< 233.08 Hz
BUZZER_NOTE_B3, ///< 246.94 Hz
BUZZER_NOTE_C4, ///< 261.63 Hz
BUZZER_NOTE_C4SHARP_D4FLAT, ///< 277.18 Hz
BUZZER_NOTE_D4, ///< 293.66 Hz
BUZZER_NOTE_D4SHARP_E4FLAT, ///< 311.13 Hz
BUZZER_NOTE_E4, ///< 329.63 Hz
BUZZER_NOTE_F4, ///< 349.23 Hz
BUZZER_NOTE_F4SHARP_G4FLAT, ///< 369.99 Hz
BUZZER_NOTE_G4, ///< 392.00 Hz
BUZZER_NOTE_G4SHARP_A4FLAT, ///< 415.30 Hz
BUZZER_NOTE_A4, ///< 440.00 Hz
BUZZER_NOTE_A4SHARP_B4FLAT, ///< 466.16 Hz
BUZZER_NOTE_B4, ///< 493.88 Hz
BUZZER_NOTE_C5, ///< 523.25 Hz
BUZZER_NOTE_C5SHARP_D5FLAT, ///< 554.37 Hz
BUZZER_NOTE_D5, ///< 587.33 Hz
BUZZER_NOTE_D5SHARP_E5FLAT, ///< 622.25 Hz
BUZZER_NOTE_E5, ///< 659.25 Hz
BUZZER_NOTE_F5, ///< 698.46 Hz
BUZZER_NOTE_F5SHARP_G5FLAT, ///< 739.99 Hz
BUZZER_NOTE_G5, ///< 783.99 Hz
BUZZER_NOTE_G5SHARP_A5FLAT, ///< 830.61 Hz
BUZZER_NOTE_A5, ///< 880.00 Hz
BUZZER_NOTE_A5SHARP_B5FLAT, ///< 932.33 Hz
BUZZER_NOTE_B5, ///< 987.77 Hz
BUZZER_NOTE_C6, ///< 1046.50 Hz
BUZZER_NOTE_C6SHARP_D6FLAT, ///< 1108.73 Hz
BUZZER_NOTE_D6, ///< 1174.66 Hz
BUZZER_NOTE_D6SHARP_E6FLAT, ///< 1244.51 Hz
BUZZER_NOTE_E6, ///< 1318.51 Hz
BUZZER_NOTE_F6, ///< 1396.91 Hz
BUZZER_NOTE_F6SHARP_G6FLAT, ///< 1479.98 Hz
BUZZER_NOTE_G6, ///< 1567.98 Hz
BUZZER_NOTE_G6SHARP_A6FLAT, ///< 1661.22 Hz
BUZZER_NOTE_A6, ///< 1760.00 Hz
BUZZER_NOTE_A6SHARP_B6FLAT, ///< 1864.66 Hz
BUZZER_NOTE_B6, ///< 1975.53 Hz
BUZZER_NOTE_C7, ///< 2093.00 Hz
BUZZER_NOTE_C7SHARP_D7FLAT, ///< 2217.46 Hz
BUZZER_NOTE_D7, ///< 2349.32 Hz
BUZZER_NOTE_D7SHARP_E7FLAT, ///< 2489.02 Hz
BUZZER_NOTE_E7, ///< 2637.02 Hz
BUZZER_NOTE_F7, ///< 2793.83 Hz
BUZZER_NOTE_F7SHARP_G7FLAT, ///< 2959.96 Hz
BUZZER_NOTE_G7, ///< 3135.96 Hz
BUZZER_NOTE_G7SHARP_A7FLAT, ///< 3322.44 Hz
BUZZER_NOTE_A7, ///< 3520.00 Hz
BUZZER_NOTE_A7SHARP_B7FLAT, ///< 3729.31 Hz
BUZZER_NOTE_B7, ///< 3951.07 Hz
BUZZER_NOTE_C8, ///< 4186.01 Hz
BUZZER_NOTE_C8SHARP_D8FLAT, ///< 4434.92 Hz
BUZZER_NOTE_D8, ///< 4698.63 Hz
BUZZER_NOTE_D8SHARP_E8FLAT, ///< 4978.03 Hz
BUZZER_NOTE_E8, ///< 5274.04 Hz
BUZZER_NOTE_F8, ///< 5587.65 Hz
BUZZER_NOTE_F8SHARP_G8FLAT, ///< 5919.91 Hz
BUZZER_NOTE_G8, ///< 6271.93 Hz
BUZZER_NOTE_G8SHARP_A8FLAT, ///< 6644.88 Hz
BUZZER_NOTE_A8, ///< 7040.00 Hz
BUZZER_NOTE_A8SHARP_B8FLAT, ///< 7458.62 Hz
BUZZER_NOTE_B8, ///< 7902.13 Hz
BUZZER_NOTE_REST ///< no sound
} BuzzerNote;

View File

@ -172,6 +172,9 @@ inline void watch_clear_pixel(uint8_t com, uint8_t seg) {
} }
void watch_display_character(uint8_t character, uint8_t position) { void watch_display_character(uint8_t character, uint8_t position) {
// handle lowercase 7 if needed
if (character == '7' && (position == 4 || position == 6)) character = '&';
uint64_t segmap = Segment_Map[position]; uint64_t segmap = Segment_Map[position];
uint64_t segdata = Character_Set[character - 0x20]; uint64_t segdata = Character_Set[character - 0x20];
@ -319,6 +322,39 @@ void watch_set_led_off() {
} }
} }
//////////////////////////////////////////////////////////////////////////////////////////
// Buzzer
inline void watch_enable_buzzer() {
PWM_1_init();
}
inline void watch_set_buzzer_period(uint32_t period) {
pwm_set_parameters(&PWM_1, period, period / 2);
}
inline void watch_set_buzzer_on() {
pwm_enable(&PWM_1);
}
inline void watch_set_buzzer_off() {
pwm_disable(&PWM_1);
}
const uint16_t NotePeriods[108] = {31047, 29301, 27649, 26079, 24617, 23224, 21923, 20683, 19515, 18418, 17377, 16399, 15477, 14603, 13780, 13004, 12272, 11580, 10926, 10311, 9730, 9181, 8664, 8175, 7714, 7280, 6869, 6483, 6117, 5772, 5447, 5140, 4850, 4577, 4319, 4076, 3846, 3629, 3425, 3232, 3050, 2878, 2715, 2562, 2418, 2282, 2153, 2032, 1917, 1809, 1707, 1611, 1520, 1435, 1354, 1277, 1205, 1137, 1073, 1013, 956, 902, 851, 803, 758, 715, 675, 637, 601, 567, 535, 505, 476, 450, 424, 400, 378, 357, 336, 317, 300, 283, 267, 252, 238, 224, 212, 200, 188, 178, 168, 158, 149, 141, 133, 125, 118, 112, 105, 99, 94, 89, 84, 79, 74, 70, 66, 63};
void watch_buzzer_play_note(BuzzerNote note, uint16_t duration_ms) {
if (note == BUZZER_NOTE_REST) {
watch_set_buzzer_off();
} else {
pwm_set_parameters(&PWM_1, NotePeriods[note], NotePeriods[note] / 2);
watch_set_buzzer_on();
}
delay_ms(duration_ms);
watch_set_buzzer_off();
}
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Real-time Clock // Real-time Clock

View File

@ -6,6 +6,7 @@
#include "driver_init.h" #include "driver_init.h"
#include "hpl_calendar.h" #include "hpl_calendar.h"
#include "hal_ext_irq.h" #include "hal_ext_irq.h"
#include "notes.h"
/** @mainpage Sensor Watch Documentation /** @mainpage Sensor Watch Documentation
* @brief This documentation covers most of the functions you will use to interact with the Sensor Watch * @brief This documentation covers most of the functions you will use to interact with the Sensor Watch
@ -14,12 +15,13 @@
Sensor Watch app. Sensor Watch app.
- @ref slcd - This section covers functions related to the Segment LCD display driver, which is responsible - @ref slcd - This section covers functions related to the Segment LCD display driver, which is responsible
for displaying strings of characters and indicators on the main watch display. for displaying strings of characters and indicators on the main watch display.
- @ref buttons - This section covers functions related to the three buttons: Light, Mode and Alarm.
- @ref led - This section covers functions related to the bi-color red/green LED mounted behind the LCD. - @ref led - This section covers functions related to the bi-color red/green LED mounted behind the LCD.
- @ref buzzer - This section covers functions related to the piezo buzzer.
- @ref rtc - This section covers functions related to the SAM L22's real-time clock peripheral, including - @ref rtc - This section covers functions related to the SAM L22's real-time clock peripheral, including
date, time and alarm functions. date, time and alarm functions.
- @ref adc - This section covers functions related to the SAM L22's analog-to-digital converter, as well as - @ref adc - This section covers functions related to the SAM L22's analog-to-digital converter, as well as
configuring and reading values from the three analog-capable pins on the 9-pin connector. configuring and reading values from the three analog-capable pins on the 9-pin connector.
- @ref buttons - This section covers functions related to the three buttons: Light, Mode and Alarm.
- @ref gpio - This section covers functions related to general-purpose input and output signals. - @ref gpio - This section covers functions related to general-purpose input and output signals.
- @ref i2c - This section covers functions related to the SAM L22's built-I2C driver, including configuring - @ref i2c - This section covers functions related to the SAM L22's built-I2C driver, including configuring
the I2C bus, putting values directly on the bus and reading data from registers on I2C devices. the I2C bus, putting values directly on the bus and reading data from registers on I2C devices.
@ -215,6 +217,45 @@ void watch_set_led_off();
/// @} /// @}
/** @addtogroup buzzer Buzzer
* @brief This section covers functions related to the piezo buzzer embedded in the F-91W's back plate.
*/
/// @{
/** @brief Enables the TCC peripheral, which drives the buzzer.
*/
void watch_enable_buzzer();
/** @brief Sets the period of the buzzer.
* @param period The period of a single cycle for the PWM peripheral. You can use the following formula to
* convert a desired frequency to a period for this function: period = 513751 * (freq^1.0043)
*/
void watch_set_buzzer_period(uint32_t period);
/** @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.
*/
void watch_set_buzzer_on();
/** @brief Turns the buzzer output off.
*/
void watch_set_buzzer_off();
/** @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.
* @note Note that this will block your UI for the duration of the note's play time, and it will
* after this call, the buzzer period will be set to the period of this note.
*/
void watch_buzzer_play_note(BuzzerNote note, uint16_t duration_ms);
/** @brief An array of periods for all the notes on a piano, corresponding to the names in BuzzerNote.
*/
extern const uint16_t NotePeriods[108];
/// @}
/** @addtogroup rtc Real-Time Clock /** @addtogroup rtc Real-Time Clock
* @brief This section covers functions related to the SAM L22's real-time clock peripheral, including * @brief This section covers functions related to the SAM L22's real-time clock peripheral, including
* date, time and alarm functions. * date, time and alarm functions.