How can I go about learning to output audio to a speaker using the STM32F7?
I am hoping someone can point me in the right direction as so far I haven't been able to get help on other forums. I am trying to learn how to output audio on a STM32 board. The board I have is the STM32F746ZG NUCLEO board.
I have small (1-3) second audio files I have stored on the internal flash of my STM32, so there is no external SD card or anything. They have 16 bit data @44.1kHz. I was able to convert to 8bit so I tried both 8 and 16 bit. I plan to output the audio to a PAM8302a amplifier which is connected to a speaker. I was following along with the AN3126 (Waveform generation using DAC). I was able to successfully generate waveforms and view them on my oscilloscope. But when I send audio data, it's just static. I tried to follow along this video, but it just sounds like static for the most part with a hint of sound in the background. Not sure what I'm doing wrong but I feel this is not the way to go about this.
So does anyone know what I should be using on the board or reading on? I see SAI, I2S, SPI, etc and honestly just don't know where to start. Am I missing components? I'm not interested in filtering and what not at the moment, that's something I feel can come after. I just want to at least be able to output something audible for now.
I have the code I used to generate the sine wave according to the doc along with my scope pic
uint8_t samples = 100;
void getSineVal(){
for(int i = 0; i < samples; i++){
sineVal[i] = (sin(2*i*PI/samples)+1)*((0xFFF+1)/2);
}
}
getSineVal();
HAL_TIM_Base_Start(&htim6);
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, sineVal, 100, DAC_ALIGN_12B_R);
// sineVal being the data, 100 being the # of data pointsThe clock for TIM6 is at 80Mhz. The prescalar is 80-1, the period is 100-1, and the #samples is 100. So 80Mhz/(80 * 100 * 100) = 100Hz.
Here is the picture of the sine wave I generated at 100 Hz
Here is code I made for the audio
uint8_t *p = (uint8_t *)&audioArray;
... // I didn't paste here but I move the pointer to the data section
if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13) == GPIO_PIN_SET){
uint16_t *pp = (uint16_t *)p;
uint32_t wavBuffer1[512];
uint32_t wavBuffer2[512];
flg_dma_done = 1;
int count = 65536;
while(count > 0){
for(int i = 0; i < 512; i++){
wavBuffer2[i] = *pp;
pp++;
}
while(!flg_dma_done){ // check if the flag is done
__NOP();
}
flg_dma_done = 0; // clear/reset the flag
count = count - 512; // 512 bytes decrease
HAL_DAC_Stop_DMA(&hdac, DAC_CHANNEL_1); // Stop the transfer
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*)wavBuffer2, 512, DAC_ALIGN_12B_R); // Start transmission
for(int i = 0; i < 512; i++){
wavBuffer1[i] = pp;
pp++;
}
while(!flg_dma_done){ // check if the flag is done
__NOP();
}
flg_dma_done = 0; // Clear/reset the flag
count = count - 512;
HAL_DAC_Stop_DMA(&hdac, DAC_CHANNEL_1); // Stop the transfer
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*)wavBuffer1, 512, DAC_ALIGN_12B_R); // Start transmission
}
}
...
void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef* hdac)
{
flg_dma_done = 1;
}With this code I made, it sounds like two sections of audio play and they're both just garbled sound.
Here is a image of the schematic.
I hope you can help out. Thanks
