[MCXN947] SAI_RxSetConfig() clears RCR4.FCOMB for multi-channel RX — bug confirmation request

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

[MCXN947] SAI_RxSetConfig() clears RCR4.FCOMB for multi-channel RX — bug confirmation request

127 Views
maohuynh
Contributor II
Dear NXP Support Team,

I am writing to report a potential bug I found in the MCUXpresso SDK SAI driver (`fsl_sai.c`)
while developing an **Active Noise Cancellation (ANC)** system on the **FRDM-MCXN947**
evaluation board. I would appreciate your confirmation of whether this is a known issue
and whether a fix is planned.

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:

  1. 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;
  2. 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
    }
  3. 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

  1. Is this a confirmed bug in fsl_sai v2.4.11?
  2. Is there a known fix or patched version available?
  3. Is the example code at fsl_sai_edma.c:348 (kSAI_FifoCombineModeEnabledOnRead used
    for RX) intentional or also a documentation error?
  4. 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

Labels (2)
Tags (1)
0 Kudos
Reply
1 Reply

4 Views
Celeste_Liu
NXP Employee
NXP Employee

Hello @maohuynh ,

Thanks for your post. I am currently investigating the issue you raised and will get back to you as soon as possible.

BR

Celeste

0 Kudos
Reply