cancel
Showing results for 
Search instead for 
Did you mean: 

Weirdest thing happening with STM32H7 I2S hardware

CLeo.1
Senior II

Hi guys! I am having the biggest issue with the I2S right now

What is happening: For whatever reason the I2S does not want to transmit any samples VIA DMA. Doesnt matter what I do what I try.

The weird thing happening: The I2S WS, SCLK wont work. Only if the DMA associated with the Tx part is enable (DMA1_Stream1) which I find so weird. All it does it set the WS pin to HIGH

What I have tried:

  • Verified the registers are correctly setup
  • Ensure with measuring tools the right signals are shooting out (WS, MCLK, SCLK) when the DMA1_Stream1 is enable
  • Swapped out the ADC/DAC for another one
  • Ensured the ADC is sending out its digital signal
  • Ensured the STM32 is receiving samples and transmitting to the Tx Buffer associated with the DMA

How the code works.

The code waits around till an UART signal is received VIA the DMA, once received in goes into a super loop where it process UART signals

Depending on what UART signal was received it will enable not only the I2S peripheral but setup the clock, Interrupt, anything to make the I2S running with DMA etc...

Then the stm32 should now be ready to take in I2S signals and spit them out

Code: (Using PasteBin as code is too long here)

Main.c

https://pastebin.com/GZCTs8Sd

I2S_Factory.c (Setups GPIO, and DMA)

https://pastebin.com/tDXjzVaX

Audio_Selector.c (Setups the I2S Clock, interrupt, and DMA)

https://pastebin.com/mHjDgZaX

DSP_FACTORY.c (Where in takes in the Rx Samples and transfer it to the Tx Buffer for transitmission)

https://pastebin.com/WNt9TSrA

Any help would be amazing, I am stumped right now its not even funny.

25 REPLIES 25
TDK
Guru
GPIOA->MODER |= (GPIO_MODER_MODE4_AF) |
                (GPIO_MODER_MODE5_AF) |
                (GPIO_MODER_MODE6_AF) |
                (GPIO_MODER_MODE7_AF);

What is GPIO_MODER_MODE4_AF? It's not defined anywhere in the CubeH7 repo. Google also reports 0 hits.

https://github.com/STMicroelectronics/STM32CubeH7/search?q=GPIO_MODER_MODE4_AF

Do HAL I2S examples work?

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

Sorry thats my doing

Here are the definitions:

GPIOA->MODER |= (GPIO_MODER_MODE4_AF) | = (0x2UL << GPIO_MODER_MODE4_Pos) 

(GPIO_MODER_MODE5_AF) | = (0x2UL << GPIO_MODER_MODE5_Pos) 

(GPIO_MODER_MODE6_AF) | = (0x2UL << GPIO_MODER_MODE6_Pos) 

(GPIO_MODER_MODE7_AF) ; = (0x2UL << GPIO_MODER_MODE7_Pos) 

Never used HAL so I couldn't tell you. My guy feeling is telling me something is wrong with the DMA and the TxBuffer, does static put it in a piece of memory where the DMA can't reach?

Depends on your linker script. Debug and find out the address of the data you're putting in there and cross reference with the memory map.

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

Yeah, wouldnt know how to do this, I have never ever dealt with the linker or anything along these lines. But for someone who didnt mess with the linker why is memory being put there while other memory isnt? I would assume my array "I2S1_RxBUFF" is fine but why not "I2S1_TxBUFF".

Also do you think it could be cause of the static keyword? Maybe when static is called it places in memory where the DMA can't reach it?

TDK
Guru

> But for someone who didnt mess with the linker why is memory being put there while other memory isnt?

You haven't even verified that this is the case, so who knows? I didn't write your linker and you didn't include it.

> Also do you think it could be cause of the static keyword? Maybe when static is called it places in memory where the DMA can't reach it?

Why do you think the static keyword is causing things to be placed somewhere else?

Instead of grasping at straws, do a more systematic debugging process. When DMA fails to trigger, examine the registers for error codes. Find out where your data is located and ensure DMA can access that region. Create a minimal working example which displays the error or issue you're seeing so you can debug it easier.

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

That all make sense and Ill do it, but first can you kindly explain to me how does the DMA Tx work with the I2S peripheral. I got a few questions that's been bugging and can be integral for me solving this problem

  1. Unlike DMA Rx where data gets sent to, how does the DMA know to transferred out data from Memory to the peripheral ? Is it when you write into the Tx Buffer and it knows when the Tx Buffer gets full and its then it ships out to the shadow Register (SPI->TXDR) ?
  2. Would it make sense to have DMA_Tx for I2S on a "non-circ" mode and have it only execute when the Buffer is full?

The 'H7 SPI/I2S module is an overcomplicated beast and I don't use it so maybe I'm unaware of some detail, but generally in communication peripherals, there's a TXE (Tx Empty) flag/signal, which - when this signal is routed properly through DMAMUX - triggers a DMA transfer. This transfer is supposed to move a frame from memory to the Tx data register of I2S/SPI, thus clearing the TXE flag and starting transmission. After the frame is transmitted, TXE gets set and the cycle repeats.

JW

Thank you king, would you mind taking a looking at my code and see if the DMA is setup correctly and its just a linker issue?

CLeo.1
Senior II

Kept digging and found this in my map file

.bss.I2S1_TxBUFF
                0x00000000240004ac       0x10 Core/Src/driver/I2S_FACTORY.o
 .bss.I2S1_RxBUFF
                0x00000000240004bc       0x10 Core/Src/driver/I2S_FACTORY.o
 .bss.UART4_RxBUFF
                0x00000000240004cc        0x1 Core/Src/driver/UART_FACTORY.o
 
.text.getUART4_RxBUFF
                0x0000000008000f60       0x14 Core/Src/driver/UART_FACTORY.o
                0x0000000008000f60                getUART4_RxBUFF
    .text.getI2S1_TxBUFF
                0x0000000008000cd0       0x14 Core/Src/driver/I2S_FACTORY.o
                0x0000000008000cd0                getI2S1_TxBUFF
 .text.getI2S1_RxBUFF
                0x0000000008000ce4       0x14 Core/Src/driver/I2S_FACTORY.o
                0x0000000008000ce4                getI2S1_RxBUFF

All the DMA variables are located in the ITCM memory region, could this be the problem? If so how come the DMA doesnt return any errors?