Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
/*
* Copyright (c) 2023-2024 TiaC Systems
* Copyright (c) 2022 Golioth, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#include "buzzer.h"
#include <zephyr/kernel.h>
#include <zephyr/init.h>
/* Logging */
#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(buzzersh, CONFIG_BUZZER_SHELL_LOG_LEVEL);
/* Buzzer thread structs */
static k_tid_t buzzer_tid;
static struct k_thread buzzer_thread;
static struct buzzer_instance *buzzer_instance;
K_THREAD_STACK_DEFINE(buzzer_stack, 1024);
K_SEM_DEFINE(buzzer_initialized_sem, 0, 1); /* wait until buzzer is ready */
#define BUZZER_MAX_FREQ 2500
#define BUZZER_MIN_FREQ 10
/* extern */ void buzzer_entry(void *p0, void *p1, void *p2)
{
buzzer_instance = (struct buzzer_instance *)(p0);
/* block until buzzer is available */
k_sem_take(&buzzer_initialized_sem, K_FOREVER);
while (1) {
const struct pwm_dt_spec *pwm = &(buzzer_instance->dt_spec);
const note_t *replay; /* the song with ... */
size_t notes; /* ... number of notes in replay */
switch (buzzer_instance->song) {
case beep:
LOG_DBG("beep");
replay = song_beep;
notes = song_beep_notes;
break;
case folksong:
LOG_DBG("folksong");
replay = song_folksong;
notes = song_folksong_notes;
break;
case xmastime:
LOG_DBG("xmastime");
replay = song_xmastime;
notes = song_xmastime_notes;
break;
case funkytown:
LOG_DBG("funkytown");
replay = song_funkytown;
notes = song_funkytown_notes;
break;
case mario:
LOG_DBG("mario");
replay = song_mario;
notes = song_mario_notes;
break;
case golioth:
LOG_DBG("golioth");
replay = song_golioth;
notes = song_golioth_notes;
break;
case tiacsys:
LOG_DBG("tiacsys");
replay = song_tiacsys;
notes = song_tiacsys_notes;
break;
default:
LOG_WRN("Warning: invalid song selection");
replay = NULL;
notes = 0;
break;
}
/* if song, then ... */
if (replay && notes) {
/* ... replay the song */
for (int i = 0; i < notes; i++) {
note_pitch_t pitch = replay[i].pitch;
note_duration_t duration = replay[i].duration;
if (pitch < BUZZER_MIN_FREQ) {
/* 'pause' on frequency notes */
pwm_set_pulse_dt(pwm, 0);
k_msleep(duration);
} else {
pwm_set_dt(pwm, PWM_HZ(pitch), PWM_HZ(pitch) / 2);
k_msleep(duration);
}
}
}
/* turn buzzer off (pulse duty to 0) */
pwm_set_pulse_dt(pwm, 0);
/* sleep thread again until awoken externally */
k_sleep(K_FOREVER);
}
}
int app_buzzer_init(struct buzzer_instance *buzzer)
{
if (!device_is_ready(buzzer->dt_spec.dev)) {
return -ENODEV;
}
buzzer_tid = k_thread_create(&buzzer_thread, buzzer_stack,
K_THREAD_STACK_SIZEOF(buzzer_stack), buzzer_entry, buzzer,
NULL, NULL, K_LOWEST_APPLICATION_THREAD_PRIO, 0, K_SECONDS(2));
k_sem_give(&buzzer_initialized_sem);
return 0;
}
void app_buzzer_play_song(enum song_choice song)
{
if (buzzer_instance) {
buzzer_instance->song = song;
}
k_wakeup(buzzer_tid);
}
efd4b04f2This file is pinned to the selected release. Download the original to open it in your design tool.