cancel
Showing results for 
Search instead for 
Did you mean: 

How can I go about learning to output audio to a speaker using the STM32F7?

TC2
Associate II

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 points

The 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

0693W00000AOxXgQAL.jpgHere 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.0693W00000AOxYAQA1.pngI hope you can help out. Thanks

5 REPLIES 5
Ons KOOLI
Senior III

Hi @TC2​ ,

You can inspire from the Audio_playback_and_record application, under directory: STM32Cube_FW_F7_V1.16.0\Projects\STM32746G-Discovery\Applications\Audio of the STM32CubeF7. This application explores the content of USB disk and play wave files that are stored on the USB disk.

Hope this is helpful.

Best Regards,

Ons.

Note: If the problem is resolved, please mark this topic as answered by selecting Select as best. This will help other users find that answer faster.

Ozone
Lead II

> 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.

Sounds reasonable.

But take the DAC output impedance into account.

In unbuffered mode, this is about 1 MOhm, which is most probably not enough to drive the amplifier.

The PAM8302 datasheet does not specify an input impedance, but try to enable the "BUFFERED" mode of the DAC, with 15kOhm output impedance.

And, I think you are not supposed to leave the A- input pin unconnected.

TC2
Associate II

Hi. Thanks for the response. I should mention the sine wave was able to produce an audible tone.

I forgot to mention it is already in buffered mode. You are right, I shouldn't have left A- floating, I connected it to GND as it's ground or a 2nd output line which I don't have in this case. It basically just made the speaker louder.

Piranha
Chief II
wavBuffer1[i] = pp;

At line 22 you forgot to dereference the pointer.

Producing static sound typically means a wrong bit/byte order, alignment, address etc.

As you are using Cortex-M7, the D-cache management is also be relevant. At development stage just do not turn it on. For a proper solution read my answer here:

https://community.st.com/s/question/0D53W00000oXSzySAG/different-cache-behavior-between-stm32h7-and-stm32f7

Hi thanks for the response. Good catch, I fixed it which got rid of the "two sections" of static sound, but still static obviously. I also changed the pointer to be 8 bits as 16 bits was making it skip over a byte each increment.

I disabled the Dcache and it causes a HardFault.