Project Overview
I am building a real-time ANC system on FRDM-MCXN947 with the following audio hardware:
- 4× INMP441 MEMS microphones — feedforward and error microphones for the FxLMS algorithm
- 2× MAX98357A I2S amplifiers — anti-noise speaker output via SAI1 TXD0 (P3_20)
- Dual-core split: Core0 handles all I/O (SAI DMA, LCD, shell), Core1 runs the FxLMS
DSP algorithm. IPC via MCMGR mailbox, 16 ms frame rate (256 samples @ 16 kHz).
The system requires capturing all 4 microphones simultaneously on every 16 ms frame.
Because MCXN947 provides only one DMA request line for SAI1 RX
(kDma0RequestMuxSai1Rx = 101U), FIFO combine mode (RCR4.FCOMB) is the only
SDK-supported path to receive from both RXD0 and RXD1 with a single DMA channel.
Bug Found
SDK version: MCUXpresso SDK (mcuxsdk-core, commit 0455af2)
Driver versions: fsl_sai v2.4.11 / fsl_sai_edma v2.7.4
File: drivers/sai/fsl_sai.c
The problem
SAI_RxSetConfig() unconditionally clears RCR4.FCOMB whenever channelNums > 1,
even when the caller explicitly set fifoCombine = kSAI_RXFifoCombineModeEnabledOnRead.
The call chain is:
SAI_RxSetFifoConfig() (fsl_sai.c lines 1103–1105) — correctly sets RCR4.FCOMB
from config->fifoCombine:
rcr4 &= ~I2S_RCR4_FCOMB_MASK;
rcr4 |= I2S_RCR4_FCOMB(config->fifoCombine); // ← set correctly
base->RCR4 = rcr4;
SAI_RxSetConfig() (fsl_sai.c lines 1439–1444) — runs after step 1 and
unconditionally clears it:
/* make sure combine mode disabled while multipe channel is used */
if (config->channelNums > 1U)
{
base->RCR4 &= ~I2S_RCR4_FCOMB_MASK; // ← always clears, ignores fifoCombine
}SAI_TransferRxSetConfigEDMA() (fsl_sai_edma.c lines 362–368) — has an assert()
that correctly requires fifoCombine to be non-zero when channelNums > 1, but it
validates the config struct, not the hardware register. The assert passes while
RCR4.FCOMB is already 0 in the hardware.
The comment at step 2 says "make sure combine mode disabled while multiple channel is used"
— this appears to be a copy of the TX-side logic incorrectly applied to RX. For RX, FIFO
combine mode is required for multi-channel DMA, as documented in the example code
in fsl_sai_edma.c lines 340–350.
Observed symptom
After calling SAI_TransferRxSetConfigEDMA() with channelMask = kSAI_Channel0Mask | kSAI_Channel1Mask
and fifoCombine = kSAI_RXFifoCombineModeEnabledOnRead:
- SAI1->RCR4 & I2S_RCR4_FCOMB_MASK == 0 (should be 2)
- SAI RX FIFO overflow errors fire immediately on AUDIO_CaptureStart()
- kStatus_SAI_RxError callbacks flood the system (hundreds per second)
- The FreeRTOS UART shell task (priority 2) becomes completely unresponsive
- No valid audio data is received
Reverting to single-channel (kSAI_Channel0Mask only, channelNums=1) restores
full system operation immediately.
Secondary issue — confusing enum values
The _sai_fifo_combine enum in fsl_sai.h (lines 272–277) uses swapped numeric values
for TX vs RX directions:
kSAI_FifoCombineModeEnabledOnRead = 1U, // TX only
kSAI_RXFifoCombineModeEnabledOnRead = 2U, // RX only
The example code in fsl_sai_edma.c line 348 uses kSAI_FifoCombineModeEnabledOnRead
(the TX enum, value=1) for an RX configuration. On devices with
FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE=1 this silently configures write-combine instead
of read-combine for RX.
Current Workaround
I currently work around this by manually restoring RCR4.FCOMB after SAI_TransferRxSetConfigEDMA()
returns:
SAI_TransferRxSetConfigEDMA(SAI1, &s_saiRxHandle, &rxConfig);
/* Workaround: fsl_sai.c:1443 clears RCR4.FCOMB unconditionally when channelNums>1 */
SAI1->RCR4 = (SAI1->RCR4 & ~I2S_RCR4_FCOMB_MASK) | I2S_RCR4_FCOMB(2U);
This is fragile and requires direct register access bypassing the SDK API.
Questions
- Is this a confirmed bug in fsl_sai v2.4.11?
- Is there a known fix or patched version available?
- Is the example code at fsl_sai_edma.c:348 (kSAI_FifoCombineModeEnabledOnRead used
for RX) intentional or also a documentation error? - Is there an official supported way to capture from SAI1 RXD0 + RXD1 simultaneously
on MCXN947 using the public SDK API that I may have missed?
A full bug report with the complete call chain analysis is attached.
Thank you for your time and support.
Best regards,
Huynh Mao
huynhmaook@gmail.com