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

\$\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\$
    – brhans
    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\$
    – brhans
    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\$
    – brhans
    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\$
    – atomd
    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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.