2023-01-13 08:32 AM
The stm32u5xx_hal_sai.c sets up the I2S clock strobing like this:
static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
{
HAL_StatusTypeDef status = HAL_OK;
hsai->Init.Protocol = SAI_FREE_PROTOCOL;
hsai->Init.FirstBit = SAI_FIRSTBIT_MSB;
/* Compute ClockStrobing according AudioMode */
if ((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
{
/* Transmit */
hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
}
else
{
/* Receive */
hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
}
Notice the dependency on the TX or RX direction. However, the I2S standard uses a fixed definition: setup on falling for the transmitter, sample on rising for the receiver.
The reference manual states:
Bit 9 CKSTR: Clock strobing edge
This bit is set and cleared by software. It must be configured when the audio block is disabled. This
bit has no meaning in SPDIF audio protocol.
0: Signals generated by the SAI change on SCK rising edge, while signals received by the SAI are
sampled on the SCK falling edge.
1: Signals generated by the SAI change on SCK falling edge, while signals received by the SAI are
sampled on the SCK rising edge.
So the only valid setting is 1 (SAI_CLOCKSTROBING_RISINGEDGE) for conform I2S.
Why does the HAL implementation deviate?
2023-01-13 05:30 PM
It appears that it is confusing but correct. The code you showed just initializes the configuration structure. The peripheral is initialized by HAL_SAI_Init().
https://community.st.com/s/question/0D50X00009XkaCCSAZ/f446-cubedocumentation-saixycr1ckstr
2023-01-15 10:23 AM
2023-01-16 07:56 AM
Ok - the init code turns everything back again:
/* Compute CKSTR bits of SAI CR1 according ClockStrobing and AudioMode */
if ((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
{
/* Transmit */
ckstr_bits = (hsai->Init.ClockStrobing == SAI_CLOCKSTROBING_RISINGEDGE) ? 0U : SAI_xCR1_CKSTR;
}
else
{
/* Receive */
ckstr_bits = (hsai->Init.ClockStrobing == SAI_CLOCKSTROBING_RISINGEDGE) ? SAI_xCR1_CKSTR : 0U;
}