98 lines
2.1 KiB
C
98 lines
2.1 KiB
C
/*
|
|
* This creates sound tones by outputting a square wave on a DAC pin. The
|
|
* volume of the tone is the level of the DAC pin.
|
|
*
|
|
* The square wave is created by a timer. The timer runs at 2x the freq, because
|
|
* it needs to transition high and then low.
|
|
*
|
|
*
|
|
*/
|
|
#ifndef SOUND_H
|
|
#define SOUND_H
|
|
|
|
#include "esp32-hal-timer.h";
|
|
|
|
#define ESP32_F_CPU 80000000 // the speed of the processor
|
|
#define AUDIO_INTERRUPT_PRESCALER 80
|
|
#define SOUND_TIMER_NO 0
|
|
//#define AUDIO_PIN 25
|
|
#define MIN_FREQ 20
|
|
#define MAX_FREQ 16000
|
|
|
|
hw_timer_t * sndTimer = NULL;
|
|
|
|
bool sound_on = true;
|
|
bool sound_wave_high = true; // this toggles to create the high/low transitions of the wave
|
|
uint8_t sound_volume = 0;
|
|
|
|
void sound_init(int pin);
|
|
bool sound(uint16_t freq, uint8_t volume);
|
|
void soundOff();
|
|
|
|
int dac_pin;
|
|
|
|
|
|
|
|
void IRAM_ATTR onSoundTimer()
|
|
{
|
|
if (sound_on) {
|
|
dacWrite(dac_pin, (sound_wave_high?sound_volume:0));
|
|
sound_wave_high = ! sound_wave_high;
|
|
|
|
}
|
|
else
|
|
dacWrite(dac_pin, 0);
|
|
}
|
|
|
|
void sound_init(int pin){ // pin must be a DAC pin number !! (typically 25 or 26)
|
|
dac_pin = pin;
|
|
sound_on = false;
|
|
pinMode(dac_pin, OUTPUT);
|
|
sound_volume = 0;
|
|
|
|
sndTimer = timerBegin(SOUND_TIMER_NO, AUDIO_INTERRUPT_PRESCALER, true);
|
|
timerAttachInterrupt(sndTimer, &onSoundTimer, true);
|
|
timerAlarmWrite(sndTimer, ESP32_F_CPU/AUDIO_INTERRUPT_PRESCALER/MIN_FREQ, true); // lower timer freq
|
|
timerAlarmEnable(sndTimer);
|
|
}
|
|
|
|
void sound_pause() // this prevents the interrupt from firing ... use during eeprom write
|
|
{
|
|
timerStop(sndTimer);
|
|
}
|
|
|
|
void sound_resume() // resume from pause ... after eeprom write
|
|
{
|
|
timerRestart(sndTimer);
|
|
}
|
|
|
|
bool sound(uint16_t freq, uint8_t volume){
|
|
if (volume == 0) {
|
|
soundOff();
|
|
return false;
|
|
}
|
|
if (freq < MIN_FREQ || freq > MAX_FREQ) {
|
|
return false;
|
|
}
|
|
sound_on = true;
|
|
sound_volume = volume;
|
|
timerAlarmWrite(sndTimer, ESP32_F_CPU/AUDIO_INTERRUPT_PRESCALER/(freq * 2), true);
|
|
return true;
|
|
}
|
|
|
|
void soundOff(){
|
|
sound_on = false;
|
|
sound_volume = 0;
|
|
timerAlarmWrite(sndTimer, ESP32_F_CPU/AUDIO_INTERRUPT_PRESCALER/(MIN_FREQ), true); // lower timer freq
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|