cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with HAL_I2S_Receive_IT

I need to receive I2S from from a device which digitises microphone audio and acts as an I2S master

I have use the STM32 Cube configuation tool to set I2S3 as a Half-Duplex Slave

When I call

HAL_I2S_Receive_IT()

I the code receives the callback into

void SPI3_IRQHandler(void)

And I use this to update some buffer pointers, before calling HAL_I2S_Receive_IT() again, to continue to receive the audio stream.

However even though the I2S master is still sending data, which I have verified using a logic analyser on the I2S bus.

void SPI3_IRQHandler(void) is not called again.

I looked to see if I needed to clear any flags which were perhaps preventing subsequent calls to the ISR,but I can't see anything in the I2S HAL to do this, and I don't know even whether that is the cause of the problem

Effecively I'm calling HAL_I2S_Receive_IT() from inside the SPI3_IRQHandler() ISR, and I don't know whether that is not allowed?

Or whethere is something else I need or do after the callback.

Also.

There seem to be 2 different non-blocking I2S receieve, and transmit, functions

HAL_I2S_Receive_IT() and HAL_I2S_Receive_DMA()

The "DMA" version does not not include "IT" in its function title, but I presume that there must be an interrupt generated when the DMA transfer is complete ???

Which one of these 2 functions should I be using for non-blocking reception of I2S data as a slave device ?

And does anyone have any idea's why I'm only getting an interrupt in response to the first call to HAL_I2S_Receive_IT()

2 REPLIES 2
TDK
Guru

Do you have HAL_I2S_IRQHandler being called within SPI3_IRQHandler?

Calling HAL_I2S_Receive_IT within an ISR is fine. Although you need to ensure the peripheral state is ready and not still servicing the previous call before calling. Verify that it is returning HAL_OK.

_IT and_DMA are both options. _IT generates an interrupt on every word received while DMA will shove everything into a buffer and trigger an interrupt on half- and full transfer complete.

Please include your chip number in your post.

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

Ah.

That explains a lot.

If the SPI3_IRQHandler() is getting called for every byte, then I can see that my code is not going to work, because I presumed that the ISR was only being called on completion of the entire transfer

I'll need to change the code to use the DMA version, because I'm porting code that has been running on a NXP processor, which only calls the interrupt when the entire transfer is complete.