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
AScha.3
Chief III

Hi,

Setup in Cube an I2S to: full duplex master ; (set Fs speed, format etc.)

Then start in main : 

HAL_I2SEx_TransmitReceive_DMA (...) ;

I2S then running reception and transmission...

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

I config it as a full duplex slave, the transmission mode as <mode slave receiver>.
16 bit data per 32 bit frame. PCM short frame mode . DMA is < normal > without increment,
all interrupts are <set> by default, <WS>= 8 kHz , in the my digital analyzer I see , regardless of the c signal,
transmission is always carried out sequentially. And the impression is that this <WS> signal does not give anything
to the interface, and if the interface wants to transmit data, regardless of the presence of <WS> the signal,
it produces data ... I think this is not true . I'm from the outside, with each <WS> signal I enter one frame into the interface.


HAL_I2SEx_TransmitReceive_DMA(&hi2s2, (uint16_t*) &my_tmp_I2S_2_Tx , (uint16_t*) &my_tmp_I2S_2_Rx , 1) ;

>I config it as a full duplex slave

?? and who is master then ??

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

any external PCM master device, for example, say SIM7600, or NAU8810 codec, or my own PCM master generator created in STM32F429i using TIMERs , PWMs..., where the input date and output date are physically on different pins (lines), clock = 2mHz, and with the arrival each <WS>. signal , my microcontroller simultaneously must read the data_IN and give data_OUT to the master, using different lines (Tx/Px),

As I understand ,  the full duplex means that there must be two different lines ( I2Sx_SD
, and I2Sx_extSD ), but the document says that

< Note: I2S2_ext an I2S3_ext are used only in full-duplex mode>

page 901/1751

I2Sx can operate in master mode. As a result:
• Only I2Sx can output SCK and WS in half duplex mode
• Only I2Sx can deliver SCK and WS to I2S2_ext and I2S3_ext in full duplex mode.
The extended I2Ss (I2Sx_ext) can be used only in full duplex mode. The I2Sx_ext operate
always in slave mode.
Both I2Sx and I2Sx_ext can be configured as transmitters or receivers

>

in master mode  ---> I2S2_ext and I2S3_ext in full duplex mode

The I2Sx_ext operate always ---> in slave mode.

here one contradicts the other ?

or how configure I2Sx_ext as ---> transmitters

or how configure I2Sx_ext as ---> receivers

 

Is it possible in master mode to simultaneously (on different lines ---> I2Sx_SD
, and I2Sx_extSD) transmit and receive data?

 

Thanks in advance

 

 

Sorry, i dont understand all your statements mixed assumptions .

Just tell me: what you want ?  Which ADC or codec... and what you want to do.

And yes, TransmitReceive as master  transmit and receive data , on one sync (ws + bcl) on two lines , rx + tx , if you accept my identifiers.

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

1) Do I understand correctly?, if the slave, full duplex works in the transmission mode = <mod slave receive> mode,
then I can transmit data only when there is data reception? . if so, why, as soon as I update the DMA,
the data immediately goes out, regardless of whether there is reception at that moment or not. 

 

2) Is it possible in master mode to launch full duplex mode with simultaneous operation of the SD and SD_ext lines
(that is, receive data during transmission and vice versa, I have a board STM32F429I-DISCO1).

 

3) I have an array of 10 elements uint16_t my_arr[10], I want to transmit these elements separately (only one element)
in SLAVE and full duplex mode with each input short signal <WS -> period = 125 μsec (8 kHz), signal duration 500 nsec > .
With each <WS> signal, only one 16-bit frame (duration 8 μsec) come to the STM32F429i,
then the main interval between the two <ws> signals (125-8 μsec) remains simply empty.
I need to pass one element from my array, simultaneously synchronous with the arrival of <WS> and the input 16-bit frame.
how to implement this ?
I have this settings

 

Full Duplex SLAVE
transmission mode = <mod slave receive>
16 bit data on 32 bit Frame
PCM with short synchro frame
Audio Freq = 8 kHz

NVIC = all interrupts is set default
DMA -> I2S2_EXT_TX = mem to periph. ; normal ; half word ; not increment
DMA -> SPI2_RX = periph. to mem ; normal ; half word ; not increment

 

Thanks in advance

Wait -- you still didnt say : Which ADC or codec... you have - and i don't want to have to guess. 

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

I have a  NAU8810 codec

 

Ok, now i see, why you try with slave mode on F429 . 

 

>1) Do I understand correctly?, if the slave, full duplex works in the transmission mode = <mod slave receive> mode, then I can transmit data only when there is data reception?

No. This "master - slave" thing is just : who is generating the clocks (wck , bck) = the master. And usually the master doing this permanently , with or without data ; if no data, its just "0000" data, send + receive , always.

So now you understand, why also on the slave data is going out as soon as you put it to output register; as clocks are running , its always sending : 0-0-0-your data - 0-0-...

2. If you have the NAU8810 in master mode, F429 has to be slave,  in full duplex mode; 

 

3. Because the I2S stream is continuous, you should serve it in a matching mode : circular dma mode.

+ with some size of these send + receive buffers, to have some time to do something with the data.

On the F429 you have > 100kB ram, so i would use (at first) maybe 4KB+4KB, 2K int16 as in-buf and 2K int16 as out-buf.

Set in Cube circular dma, all on 16b (half-word) sizes, enable callbacks in Project Manager -> Advanced Settings.

Now in your main.c , start I2S+DMA :

HAL_DMA_Init(...

HAL_I2SEx_TransmitReceive_DMA(...

Now (if you set this correct) you have a running I2S system, permanently all received data coming to the in-buf and out-buf is sending out synchronous its data. 

In the half and full buffer callbacks now you have about (1K samples * sample_rate) time, to use the incoming data and put new data to the 1K samples in out-buf. (or 00 data, if you want silence = "pause" )

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