123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- #include "audio.h"
- #include "ch.h"
- #include "hal.h"
- #if !defined(AUDIO_PIN)
- # pragma message "Audio feature enabled, but no suitable pin selected as AUDIO_PIN - see docs/feature_audio under 'ARM (DAC basic)' for available options."
- # define AUDIO_PIN A5
- #endif
- #if defined(AUDIO_PIN_ALT_AS_NEGATIVE) && !defined(AUDIO_PIN_ALT)
- # error "Audio feature: AUDIO_PIN_ALT_AS_NEGATIVE set, but no pin configured as AUDIO_PIN_ALT"
- #endif
- #ifndef AUDIO_PIN_ALT
- # define AUDIO_PIN_ALT -1
- #endif
- #if !defined(AUDIO_STATE_TIMER)
- # define AUDIO_STATE_TIMER GPTD8
- #endif
- static const dacsample_t dac_buffer_1[AUDIO_DAC_BUFFER_SIZE] = {
-
- [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = AUDIO_DAC_SAMPLE_MAX,
- [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = 0,
- };
- static const dacsample_t dac_buffer_2[AUDIO_DAC_BUFFER_SIZE] = {
-
- [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = 0,
- [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = AUDIO_DAC_SAMPLE_MAX,
- };
- GPTConfig gpt6cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE,
- .callback = NULL,
- .cr2 = TIM_CR2_MMS_1,
- .dier = 0U};
- GPTConfig gpt7cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE,
- .callback = NULL,
- .cr2 = TIM_CR2_MMS_1,
- .dier = 0U};
- static void gpt_audio_state_cb(GPTDriver *gptp);
- GPTConfig gptStateUpdateCfg = {.frequency = 10,
- .callback = gpt_audio_state_cb,
- .cr2 = TIM_CR2_MMS_1,
- .dier = 0U};
- static const DACConfig dac_conf_ch1 = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_DHRM_12BIT_RIGHT};
- static const DACConfig dac_conf_ch2 = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_DHRM_12BIT_RIGHT};
- static const DACConversionGroup dac_conv_grp_ch1 = {.num_channels = 1U, .trigger = DAC_TRG(0b000)};
- static const DACConversionGroup dac_conv_grp_ch2 = {.num_channels = 1U, .trigger = DAC_TRG(0b010)};
- void channel_1_start(void) {
- gptStart(&GPTD6, &gpt6cfg1);
- gptStartContinuous(&GPTD6, 2U);
- palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG);
- }
- void channel_1_stop(void) {
- gptStopTimer(&GPTD6);
- palSetPadMode(GPIOA, 4, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPad(GPIOA, 4);
- }
- static float channel_1_frequency = 0.0f;
- void channel_1_set_frequency(float freq) {
- channel_1_frequency = freq;
- channel_1_stop();
- if (freq <= 0.0)
- return;
- gpt6cfg1.frequency = 2 * freq * AUDIO_DAC_BUFFER_SIZE;
- channel_1_start();
- }
- float channel_1_get_frequency(void) { return channel_1_frequency; }
- void channel_2_start(void) {
- gptStart(&GPTD7, &gpt7cfg1);
- gptStartContinuous(&GPTD7, 2U);
- palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG);
- }
- void channel_2_stop(void) {
- gptStopTimer(&GPTD7);
- palSetPadMode(GPIOA, 5, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPad(GPIOA, 5);
- }
- static float channel_2_frequency = 0.0f;
- void channel_2_set_frequency(float freq) {
- channel_2_frequency = freq;
- channel_2_stop();
- if (freq <= 0.0)
- return;
- gpt7cfg1.frequency = 2 * freq * AUDIO_DAC_BUFFER_SIZE;
- channel_2_start();
- }
- float channel_2_get_frequency(void) { return channel_2_frequency; }
- static void gpt_audio_state_cb(GPTDriver *gptp) {
- if (audio_update_state()) {
- #if defined(AUDIO_PIN_ALT_AS_NEGATIVE)
-
- channel_1_set_frequency(audio_get_processed_frequency(0));
- channel_2_set_frequency(audio_get_processed_frequency(0));
- #else
-
- if (AUDIO_PIN == A4) {
- channel_1_set_frequency(audio_get_processed_frequency(0));
- if (AUDIO_PIN_ALT == A5) {
- if (audio_get_number_of_active_tones() > 1) {
- channel_2_set_frequency(audio_get_processed_frequency(1));
- } else {
- channel_2_stop();
- }
- }
- }
-
- if (AUDIO_PIN == A5) {
- channel_2_set_frequency(audio_get_processed_frequency(0));
- if (AUDIO_PIN_ALT == A4) {
- if (audio_get_number_of_active_tones() > 1) {
- channel_1_set_frequency(audio_get_processed_frequency(1));
- } else {
- channel_1_stop();
- }
- }
- }
- #endif
- }
- }
- void audio_driver_initialize() {
- if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) {
- palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG);
- dacStart(&DACD1, &dac_conf_ch1);
-
-
- gptStart(&GPTD6, &gpt6cfg1);
- }
- if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) {
- palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG);
- dacStart(&DACD2, &dac_conf_ch2);
- gptStart(&GPTD7, &gpt7cfg1);
- }
-
- DACD1.params->dac->CR &= ~DAC_CR_BOFF1;
- DACD2.params->dac->CR &= ~DAC_CR_BOFF2;
-
- gptStart(&AUDIO_STATE_TIMER, &gptStateUpdateCfg);
- }
- void audio_driver_stop(void) {
- if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) {
- gptStopTimer(&GPTD6);
-
- dacStopConversion(&DACD1);
- dacPutChannelX(&DACD1, 0, AUDIO_DAC_OFF_VALUE);
- }
- if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) {
- gptStopTimer(&GPTD7);
- dacStopConversion(&DACD2);
- dacPutChannelX(&DACD2, 0, AUDIO_DAC_OFF_VALUE);
- }
- gptStopTimer(&AUDIO_STATE_TIMER);
- }
- void audio_driver_start(void) {
- if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) {
- dacStartConversion(&DACD1, &dac_conv_grp_ch1, (dacsample_t *)dac_buffer_1, AUDIO_DAC_BUFFER_SIZE);
- }
- if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) {
- dacStartConversion(&DACD2, &dac_conv_grp_ch2, (dacsample_t *)dac_buffer_2, AUDIO_DAC_BUFFER_SIZE);
- }
- gptStartContinuous(&AUDIO_STATE_TIMER, 2U);
- }
|