2024-12-11 12:59 PM
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:
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.
2024-12-20 07:41 PM - edited 2024-12-20 07:42 PM
Got it working! Mostly, sort of...
2024-12-21 08:45 AM - edited 2024-12-21 09:14 AM
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.
2024-12-22 09:45 PM
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!
2024-12-23 01:37 AM
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.