cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F429I I2S Rx/Tx simultaneously

gevmar
Associate III

Hello everyone, I'm asking for your advice. I use STM32F429I-DISCO1  board, I want to use I2S so that the reception and transmission occurred simultaneously, on different lines and only one frame on each <WS> signal, and I think in order to quickly implement it with DMA , how can I implement this.

thanks in advance.

16 REPLIES 16
gevmar
Associate III

Thank you very much, you shed a lot of light on the overall picture.
But I have a second question. when and how the <WS> signal coming from outside(I am slave) ,
comes into play, in the I2S interface.

We need to synchronize all this , with signal <WS>.
for example, 16 bit data 32 bit frame, clk = 2 MHz, => one_frame = 32*500 nSec = 16 μs, and my array with 8 elements  => my_tx_buf[8]={payload_data , 0,0,0,0,0,0,0} it turns out cycle = 8*16=128 μs, and I have a <WS> signal coming from outside every 125 μs.
That is, my full cycle has not yet ended, and the synchronizing signal <WS> comes from outside.

1) At this time the I2S interface itself will reset the array elements counter ?, (I doubt that)
2) or should I implement it myself, say with an external interrupt ?,
3) if every time I call a function <HAL_I2SEx_TransmitReceive_DMA(...)> in the external interrupt function <EXTIn_IRQHandler()> ,
will the counter of my array be reset to zero , at this moment.

Sorry - but did you follow my suggestion >> 3. Because the I2S stream is continuous ... <<

You can use your buffer with only 8 samples, if you like this so much. :)

BUT start circular dma only once !!!!! Believe me, it will run then forever...

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

I understood the concept of your proposal and I will definitely try it.
I don’t understand whether it makes sense in the cubemx settings, in SLAVE mode, full-duplex, transmission mode = <mod slave receive> ? .

As I understand , the arrival time of the signal <WS> will certainly be equal to ( integer_number * frame_length_time ).
How do I properly use the arrived signal <WS> ?.

I understand that along with this <WS> signal I receive useful 16-bit data.

I understand that this data will be written to my <Rx_buf> buffer, but to which element number( Rx_buf [ ? ] ) specifically? .

How can I implement this correctly?

Seems, you dont understand it : audio is the sum of continuous data - not just one sample.

One sample is just a number , one number - no audio signal.

>How do I properly use the arrived signal <WS> ?

Nope. On circular DMA , you get blocks of data; what you do with the data - i dont know, you didnt say.

So do whatever you want to do.

>How can I implement this correctly?

What is "correctly" ? You dont want to tell, what you wanna do - so what ?

Sorry, but its late , and i don't want to have to guess , what you want to do.

I showed you, how to get and send a sound data-stream - what you want then ?

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

Your help was really very valuable, and I tried both PCM-s (I2S2 and I2S3) on the STM32F429I-DISCO1 board
in practice, a lot became clear in practice. But there are hardware nuances that are not fully understood.
At first, PORTB PIN_13 (clk) did not work on I2S2; it turned out that it was connected to USB_OTG and capacitor C53
and microcircuit U8 were interfering, after removing C53 and applying a HIGH level to PORTC_pin4 (or just the input - OTG_FS_PSO),
everything started working.
Separately, both I2S2 and I2S3 work normally, by the way, for normal operation of the DMA, we must definitely
keep the NVIC I2S2 and I2S3 turned on.
And when I set I2S2=SLAVE and full_duplex;
I2S3=SLAVE and half_duplex and transmit mode;
and from some source (pin) I apply PCM_CLOCK to both interfaces (I2S2 and I2S3), then I2S2 works normally,
synchronously with the WS signal and each bit is correctly output, in its place and with the correct duration.
And the I2S3 data output begins to go dull.

___ the wrong number of bits and their duration are output,
and the wrong data, and it is synchronized (only on I2S3), and the data is output much more often.
By the way, the green LED=ON on the USB_OTG port, which is not turned on for no reason.
---it is enough to remove the clock signal from I2S2, then the falsely output data on I2S3 disappears,
but it does not work synchronously with the WS signal, and after RESET (button) the operation of I2S3 is normalized.
How can this problem be solved?

Why now on 2 x I2S same time ?  Two codecs connected ??

1. Use only one I2S -> one codec .

2. Dont use some pins, that already connected on your board - this wont work.

Look in board schematic , if I2S3 pins are unused, so we try with this .

https://www.st.com/en/evaluation-tools/32f429idiscovery.html#cad-resources

3. Set the I2S to full-duplex-slave , connect bck, wck, miso, mosi to your codec NAU8810 .

4. Set two DMA channels in circular mode, one receive and one transmit .

Now we need to set the format: you have I2C connected , to program the NAU8810 ?

I would recommend: set to I2S , 16 bit, both channel used (is anyway mono codec) .

You can set this ? 

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

Yes, I made these settings, it’s just that my system is like this, sim7600 and NAU8810 codec are connected to
each other, I want to cut off the lines to fit with stm32 between them, make my own digital additional filtering,
for this I must connect one stm32_I2S2 to the sim7600, and the other stm32_I2S3 to NAU8810 , so that everything
works in parallel. Just because everything was parallel, I want to run both I2S in slave mode(for example Master is only sim7600) ,
now I created a hardware PCM simulator in stm32 with Timers (PCM in master mode), and from some pin the physical clock signal was sent to clock_ I2S2 and clock_ I2S3, which was causing the problem .

 

But right now I physically defined the same clock on two pins, and applied separate pins to clock_I2S2 and clock_I2S3, and the problem was solved.


But this is a partial and incorrect solution method.

Moreover, I think such a problem should not have arisen at all.
I think the problem may be related to the pin settings (pull_up, pull_down, ...)?