0
\$\begingroup\$

So I tried to power up codec (CS4272) together with my F401 board. After a lot of tweaking I got I2S to work and send data, but there were gaps. Upon further investigation it looks like HAL_I2SEx_TransmitReceive_IT doesn't return until it sends all of it's data.

for(int i=0;;i++)
 {
 for(int j=0;j<256;j++)
 data[2*j]=16843009*(i%256);
 HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,1);
 HAL_I2SEx_TransmitReceive_IT(&hi2s2,(uint16_t*)data,(uint16_t*)ret,128);
 HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,0);
 //printf("dupa: %d\r\n",i);
 }

Here is main loop from my test code. The rest is just cubeMX output. Logic analyser shows that I2S activity is only when C13 is HIGH. Why is so? How can it be fixed?

Here's is logic analyser trace of signals. On top there's C13 and I2S below. top C13, under data, LRCLk and SCLK respectively

As you can see the I2S transmit doesn't return until it's done. And no, C13 is not CS for codec but simply debug utility to track why I2S transmission executes so slowly

asked Aug 3, 2020 at 22:19
\$\endgroup\$
4
  • \$\begingroup\$ HAL_I2SEx_TransmitReceive_IT does return almost immediately. All it does is set up and start the interrupt-driven transfer. As such, your PC13 will only be high for a very brief period of time. \$\endgroup\$ Commented Aug 3, 2020 at 23:02
  • \$\begingroup\$ Assuming PC13 is your chip-select line to the CS4272, then you're also driving it with the wrong polarity. According to the datasheet (page 6), CS (pin 13) is active LOW. \$\endgroup\$ Commented Aug 3, 2020 at 23:04
  • \$\begingroup\$ So swap the polarity of your HAL_GPIO_WritePin() calls, and use HAL_I2SEx_TransmitReceive() (the non-interrupt version) instead. \$\endgroup\$ Commented Aug 3, 2020 at 23:06
  • \$\begingroup\$ As I written in the edit, the edit C13 is debug only and shows that Transmit_Receive_IT doesn't return until it's done \$\endgroup\$ Commented Aug 4, 2020 at 8:44

1 Answer 1

1
\$\begingroup\$

The calls ending with IT start a transfer that happens in the background and calls the transfer complete callback when done. Obviously, since you call it in a for loop, it starts one transfer and the HAL is busy, so further calls to it will fail until done or timeout elapses. You don't check the return value which would tell you it failed. Start a new transfer in the callback or use DMA with double or ring buffer.

answered Aug 3, 2020 at 22:28
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.