diff options
Diffstat (limited to 'platforms/chibios/drivers/audio_pwm_hardware.c')
-rw-r--r-- | platforms/chibios/drivers/audio_pwm_hardware.c | 115 |
1 files changed, 0 insertions, 115 deletions
diff --git a/platforms/chibios/drivers/audio_pwm_hardware.c b/platforms/chibios/drivers/audio_pwm_hardware.c deleted file mode 100644 index 40d891326f..0000000000 --- a/platforms/chibios/drivers/audio_pwm_hardware.c +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2022 Stefan Kerkmann -// Copyright 2020 Jack Humbert -// Copyright 2020 JohSchneider -// SPDX-License-Identifier: GPL-2.0-or-later - -// Audio Driver: PWM the duty-cycle is always kept at 50%, and the pwm-period is -// adjusted to match the frequency of a note to be played back. This driver uses -// the chibios-PWM system to produce a square-wave on specific output pins that -// are connected to the PWM hardware. The hardware directly toggles the pin via -// its alternate function. see your MCUs data-sheet for which pin can be driven -// by what timer - looking for TIMx_CHy and the corresponding alternate -// function. - -#include "audio.h" -#include "gpio.h" - -#if !defined(AUDIO_PIN) -# error "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM PWM settings" -#endif - -#if !defined(AUDIO_PWM_COUNTER_FREQUENCY) -# define AUDIO_PWM_COUNTER_FREQUENCY 100000 -#endif - -extern bool playing_note; -extern bool playing_melody; -extern uint8_t note_timbre; - -static PWMConfig pwmCFG = {.frequency = AUDIO_PWM_COUNTER_FREQUENCY, /* PWM clock frequency */ - .period = 2, - .callback = NULL, - .channels = {[(AUDIO_PWM_CHANNEL - 1)] = {.mode = PWM_OUTPUT_ACTIVE_HIGH, .callback = NULL}}}; - -static float channel_1_frequency = 0.0f; - -void channel_1_set_frequency(float freq) { - channel_1_frequency = freq; - - if (freq <= 0.0) { - // a pause/rest has freq=0 - return; - } - - pwmcnt_t period = (pwmCFG.frequency / freq); - chSysLockFromISR(); - pwmChangePeriodI(&AUDIO_PWM_DRIVER, period); - pwmEnableChannelI(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1, - // adjust the duty-cycle so that the output is for 'note_timbre' duration HIGH - PWM_PERCENTAGE_TO_WIDTH(&AUDIO_PWM_DRIVER, (100 - note_timbre) * 100)); - chSysUnlockFromISR(); -} - -float channel_1_get_frequency(void) { - return channel_1_frequency; -} - -void channel_1_start(void) { - pwmStop(&AUDIO_PWM_DRIVER); - pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); -} - -void channel_1_stop(void) { - pwmStop(&AUDIO_PWM_DRIVER); -} - -static virtual_timer_t audio_vt; -static void audio_callback(virtual_timer_t *vtp, void *p); - -// a regular timer task, that checks the note to be currently played and updates -// the pwm to output that frequency. -static void audio_callback(virtual_timer_t *vtp, void *p) { - float freq; // TODO: freq_alt - - if (audio_update_state()) { - freq = audio_get_processed_frequency(0); // freq_alt would be index=1 - channel_1_set_frequency(freq); - } - - chSysLockFromISR(); - chVTSetI(&audio_vt, TIME_MS2I(16), audio_callback, NULL); - chSysUnlockFromISR(); -} - -void audio_driver_initialize(void) { - pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); - - // connect the AUDIO_PIN to the PWM hardware -#if defined(USE_GPIOV1) // STM32F103C8, RP2040 - palSetLineMode(AUDIO_PIN, AUDIO_PWM_PAL_MODE); -#else // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command) - palSetLineMode(AUDIO_PIN, PAL_MODE_ALTERNATE(AUDIO_PWM_PAL_MODE)); -#endif - - chVTObjectInit(&audio_vt); -} - -void audio_driver_start(void) { - channel_1_stop(); - channel_1_start(); - - if ((playing_note || playing_melody) && !chVTIsArmed(&audio_vt)) { - // a whole note is one beat, which is - per definition in - // musical_notes.h - set to 64 the longest note is - // BREAVE_DOT=128+64=192, the shortest SIXTEENTH=4 the tempo (which - // might vary!) is in bpm (beats per minute) therefore: if the timer - // ticks away at 64Hz (~16.6ms) audio_update_state is called just often - // enough to not miss any notes - chVTSet(&audio_vt, TIME_MS2I(16), audio_callback, NULL); - } -} - -void audio_driver_stop(void) { - channel_1_stop(); - chVTReset(&audio_vt); -} |