Skip to content

Commit

Permalink
drivers: sai: the 1st frame synchronization signal lost in slave side
Browse files Browse the repository at this point in the history
According the RM document, RT1170 58.3.3 (should be same for other MCU
which has a similiar SAI IP):
"A valid frame sync is also ignored (slave mode) or not generated (master
mode) for the first four bit clock cycles after enabling the transmitter
or receiver."
but in fact, we found master side send out a valid frame sync at the 3rd
bit clock cycles which cause this frame sync is ignored by the slave
side and frame data lost.
To workaround this issue, bit clock is enabled before TE/RE.

Signed-off-by: Raymond Lei <[email protected]>
  • Loading branch information
Raymond0225 committed Dec 19, 2024
1 parent 0ac8302 commit a505c5b
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions mcux/mcux-sdk/drivers/sai/fsl_sai.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,8 +509,15 @@ void SAI_TxEnable(I2S_Type *base, bool enable)
/* If clock is sync with Rx, should enable RE bit. */
if (((base->TCR2 & I2S_TCR2_SYNC_MASK) >> I2S_TCR2_SYNC_SHIFT) == 0x1U)
{
base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_BCE_MASK);
base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK);
}
/* Sometimes, bit clock starts just 3 clocks before frame synchronization
* signal, which cause the 1st frame sync is ignored by the RX side as
* described in RT1170 RM 58.3.3. To make bit clock at least 4 clocks earlier,
* here, we enable bit clock firstly.
*/
base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_BCE_MASK);
base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK);
/* Also need to clear the FIFO error flag before start */
SAI_TxClearStatusFlags(base, kSAI_FIFOErrorFlag);
Expand Down Expand Up @@ -539,8 +546,15 @@ void SAI_RxEnable(I2S_Type *base, bool enable)
/* If clock is sync with Tx, should enable TE bit. */
if (((base->RCR2 & I2S_RCR2_SYNC_MASK) >> I2S_RCR2_SYNC_SHIFT) == 0x1U)
{
base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_BCE_MASK);
base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK);
}
/* Sometimes, bit clock starts just 3 clocks before frame synchronization
* signal, which cause the 1st frame sync is ignored by the RX side as
* described in RT1170 RM 58.3.3. To make bit clock at least 4 clocks earlier,
* here, we enable bit clock firstly.
*/
base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_BCE_MASK);
base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK);
/* Also need to clear the FIFO error flag before start */
SAI_RxClearStatusFlags(base, kSAI_FIFOErrorFlag);
Expand Down Expand Up @@ -851,7 +865,8 @@ void SAI_TxSetBitclockConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai
}
else
{
tcr2 &= ~(I2S_TCR2_BCD_MASK);
/* Clear BCP bit before set it. */
tcr2 &= ~(I2S_TCR2_BCD_MASK | I2S_TCR2_BCP_MASK);
tcr2 |= I2S_TCR2_BCP(config->bclkPolarity);
}

Expand Down Expand Up @@ -879,7 +894,8 @@ void SAI_RxSetBitclockConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai
}
else
{
rcr2 &= ~(I2S_RCR2_BCD_MASK);
/* Clear BCP bit before set it. */
rcr2 &= ~(I2S_RCR2_BCD_MASK | I2S_RCR2_BCP_MASK);
rcr2 |= I2S_RCR2_BCP(config->bclkPolarity);
}

Expand Down

0 comments on commit a505c5b

Please sign in to comment.