cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 H743/H753 with pmod I2S2 Stereo Audio

SamT
Associate II

TL;DR – Does anyone know how get the STM H7 series boards to do what Phil showed how do to in [#5] IIR Filters - Audio DSP On STM32 with I2S (24 Bit / 96 kHz) for the STM32 F4 series?  The H7 appears to be lots faster, and its floating point unit does double precision. Been learning a lot (trying out the I2S and SAI on the board), but not getting there.  Given the 80,000 views of Phil’s videos and all the references, seems like others would be interested too. Would like to be able to configure other aspects of the project using the STM32CUBEIDE GUI (i.e have it work as an .ioc project), but don’t care if the audio interface not use the GUI (i.e. HAL or LL). But that’s beyond my present skill level.

(And yes, seen and been studying other posts where people are working with audio on the H7).

Additional Background.

Many of you know about Phil of YetAnotherElectronicsChannel's video "Realtime Audio DSP on STM32" ( https://www.youtube.com/watch?v=lNBrGOk0XzE ) which shows how to use the STM32CubeIDE GUI to configure an STM32 F4 series board to read the ADC channels and send the data back to the DAC with some filtering.

Learned a lot from the video, and have been using it as the basis of doing some communications DSP labs found on line. Based on great advice from the community here, have done a number of things, including the following:

  • Demonstrated good 2 way comms using the SAI interface by connection SDO into SDI.
  • Made the output look (to my eye on an inexpensive logic analyzer anyway) look like the F4 output to the pmod I2S
  • Been reading the Reference Manual
  • Learned about the DMA issue (haven’t got it to work with DCache enabled yet, but have seen and tried the examples).

This is a long term hobby, so am enjoying the STM32 H7 learning process, while continuing to use the F4 to do the DSP communications labs.

So the request: Does anyone have this working who might be willing to share screen shots of how they got it configured, or even better a skeleton .ioc and main.c that shows how to make this work?

Thank you all.

4 REPLIES 4
SamT
Associate II

Got it working!  Mostly, sort of...

  1. Couldn't make any of the I2S work, so switched to SAI 1 with a buffer of 8 uint16 using RX TX DMA half and full complete approach (as in the F4).
  2. The audio is OK, not what it was on the F4 though. SAI audio frequency has to be set to 192 KHz (say real frequency is 260.4 KHz!) to get 41 KHz. This results  MCLK = 12 MHz, SCLK=2.7 MHz and FS=41 KHz.
  3. SAI_ACR1 settings are Mode=0,PRTCFG=0, DS=6,LBSFIRST=0,KSTR=1, SYNCEN=0, MONO=0, OUTDRIV=1, SAIXEN=1, DMAEN=1,NOMCK=0,MCKDIV=2 (maybe a culprit?), and OSR=0.
  4. Not sure which clock parameters to share, but I followed the approach in the F4 video as best I could. Am getting 133.33 MHZ "to SAI1" from PLL1Q by using HSE=50 MH, with  SYSCLK=400 MHz
  5. The processor is working so hard at these settings that neither a button push or a break point in the main infinite loop are hit unless the audio frequency is dropped by a factor of two.Seems likely the cause of the distortion - it just can't keep up.
  6. Icache is enabled.  Haven't succeeded in enabling Dcache yet, but I've been reading all the good material you all have posted on cleaning and inhibiting the cache. Maybe that will give it the boost needed.

    I'm very encouraged, but clearly have a ways to go.

    And yes, I understand from responses on other threads that I'm essentially getting what I deserved by using the GUI, but that's where I'm at with this. I'll keep reading the RM and posts here, and trying things out. My old mentor used to say "even a blind squirrel occasionally finds a nut".  He wasn't (usually) talking about me, but it describes my situation here pretty well!

SamT
Associate II

edit to the above: I incorrectly said " RX TX DMA half and full".  I'm redoing a near minimal implemenation of the code completely from scratch in hopes of finding my clock problem and having a sharable .ioc and main.c, and realized that in fact the HAL_SAI_RxHalfCpltCallback and HAL_SAI_RxCpltCallback functions are used.

Sorry for the confusion.

SamT
Associate II

Great Progress!
1) Found the solution to the difference between the specified SAI Gui Audio frequency and what it ran at (had to set it 3x higher than what it produced).  https://community.st.com/t5/stm32-mcus-products/problem-with-i2s-tx-rx-circular-dma-on-stm32h743zi2-board/td-p/155128/page/2  JOatl (the OP) said "I took its default cube value of 25 MHz when it should have been 8 which explains the 1/3 speeds." - did the same.  I see it now in UM2407: "This frequency cannot be changed. It is fixed at 8 MHz". Didn't sink in the first time I read it. Apparently it can be changed in the GUI, it just doesn't end well.

2) Also noticed that one of the two H753ZI boards is much more susceptible to stray capacitance (or ?)  than the other. So much so that audio sometimes doesn't start (especially with the too high clock rate), or is very noisy.  Found https://www.diyaudio.com/community/threads/i2s-problems.236932/ describing much the same thing. Touching the solder points on the bottom of the pmod I2S2 clean things up nicely. Eventually the novelty of hearing really clean sound wore off, and tried connecting some capacitors to ground on the I2S lines, and discovered the Frame Select was the cause.  Oddly while the capacitor intermittently helped, it didn't really solve it - noise would come back if the board was moved or a hand came near it. No idea why, but found that if the loop connecting Frame Select of the ADC to the DAC is 6 inches or longer, the noise goes away.  Tried the second board again (same model, bought at the same time), and it's fine with a jumper between the two pins (on the pmod breakout board). Suspect this is why some of the things tried before didn't seem to work.

So very happy, and pretty close to a full up system!

The  next challenge seems to be enabling Dcache.  Been reading the write ups, but not there yet.  Tried some things, but the HAL code fit the approach described (discrete calls to the DMA transfer. :
In the HAL generated code, these are the only calls to the DMA, in main before the infinite loop:

 

  HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t*)txBuf, HALF_BUF_SIZE);
  HAL_SAI_Receive_DMA(&hsai_BlockB1, (uint8_t*)rxBuf, HALF_BUF_SIZE);

 

 

After that, the Rx half and full callback routines are  getting called with RX and TX continuing.

The great write up at https://community.st.com/t5/stm32-mcus/dma-is-not-working-on-stm32h7-devices/ta-p/49498 says the clean goes before the transmit, so tried it before the memcpy to the transmit buffer, but no luck.

So where to put the invalidate and clean calls go?

 

		memcpy(inCircBuf,rxBuf,sizeof(txBuf)/2);
		SCB_InvalidateDCache_by_Addr((uint32_t*)(((uint32_t)rxBuf) & ~(uint32_t)0x1F), 4*HALF_BUF_SIZE*+32);
		inReadyFromRx1=1;

		// copy results of processing in main loop (if available)
		if (outReadyForTx==1) {
			SCB_CleanDCache_by_Addr((uint32_t*)(((uint32_t)txBuf) & ~(uint32_t)0x1F), 4*HALF_BUF_SIZE*+32);
			memcpy(txBuf,outCircBuf,HALF_BUF_SIZE*sizeof(uint16_t));
			outReadyForTx=0;
		}

 


Attempted to align the buffers per the write up, but not sure this achieves what's required:

 

static uint16_t __attribute__((section(".sai_rx_dma_buffer_section"))) __attribute__((aligned(32))) rxBuf[2*HALF_BUF_SIZE] = {0};
static uint16_t __attribute__((section(".sai_tx_dma_buffer_section"))) __attribute__((aligned(32))) txBuf[2*HALF_BUF_SIZE] = {0};

 

And yes, I read the comment about blindly using calls to functions I don't understand.  Guilty as charged I guess. Points for perseverance? Any help would be appreciated!









 

Hi,

So you found most of your basic errors yourself, ... wrong HSE clock setting etc.

The problem with the touch sensitive I2S lines is curious - you set the SAI to I2S standard?

Then maybe try some other speed settings for the used pins: if speed settings too high, you get much ringing and this disturbs the receiving DAC. So try - probably lower speed settings.

And about d-cache: clean cache is the last thing to do! After copying or any other action by the CPU. Then it's doing what you expect.

And using the HAL library isn't anything bad!

It's just the fastest way to get a system working. Doing it better by writing hard core to the hardware/ registers is still something you can do on some rainy Friday evening, If you think you can do it better... it's possible, for sure, but not for anyone beginning with this stuff.

Btw I made an audio player with H743 CPU and 3 DACs, plays from SD card and USB stick, wave, flac and MP3, just using the Cube/HAL and STM32IDE; working really fine.

So no big problem to do it.

If you feel a post has answered your question, please click "Accept as Solution".