HAL_SAI_Transmit() does not stop the I2S clocks when complete
Hello,
Some background:
STM32CubeIDE 1.6.1
MCU: STM32L4R9ZGJ6
SDK: STM32Cube_FW_L4_V1.14.0 (Yes I know it's old ~ 2019) Project is too large to update at the moment.
I am currently debugging external DAC audio issues. I reverted to using simple SAI blocking functions for testing purposes. In doing so, I have discovered that HAL_SAI_Transmit() keeps all I2S clocks running after the specified amount of data is transmitted.
Question 1: Are the I2S clocks supposed to stop after HAL_SAI_Transmit() returns, or is it up to the user to call __HAL_SAI_DISABLE() to stop the clocks manually?
Looking at the STM32L4R9 reference manual (RM0432 Rev 5), I found the following on pg 1678:
"In master TX mode, enabling the audio block immediately generates the bit clock for the
external slaves even if there is no data in the FIFO, However FS signal generation is
conditioned by the presence of data in the FIFO. After the FIFO receives the first data to
transmit, this data is output to external slaves. If there is no data to transmit in the FIFO, 0
values are then sent in the audio frame with an underrun flag generation."
My concerns is with the statement "However FS signal generation is
conditioned by the presence of data in the FIFO". Looking at a logic analyzer, I see the FS signal (or WCLK) always toggling even after the FIFO is flushed onto the I2S bus. See screenshot below:
Question 2: Is this a bug in the STM MCU / driver, or is the reference manual incorrect?
I am attempting to transmit a small portion of an audio file as a test. The audio file is 44.1 KHz, stereo (2 channels), 16-bits per channel. Since the clocks keep running after HAL_SAI_Transmit() returns, garbage is sent to the DAC on the data line beyond the end of the specified buffer length as seen below:
Question 3: If the clocks do keep running after HAL_SAI_Transmit() returns, why am I seeing garbage output on the data line instead of 0x00 as defined in the reference manual? Is the only explanation that it could be coupling to the other clock lines and picking up noise?
Edit: I tried calling __HAL_SAI_DISABLE() after HAL_SAI_Transmit() returns and some garbage data is still output before the SAI clocks actually stop as seen below:
Interestingly the garbage data looks the same across multiple captures so this makes me think the SAI driver / hardware is incrementing beyond the end of the transmit buffer and outputting random data from RAM. I have verified the 'Size' value passed into HAL_SAI_Transmit() is the length of my buffer so I don't see why data beyond this would be output.
Thanks,
Derek
