SAI example "bug" in edma_record_playback (SDK 2.7)

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

SAI example "bug" in edma_record_playback (SDK 2.7)

1,289 Views
scott1
Contributor I

Hello community,

I was wondering whether anyone had come across a similar situation. I am examining the edma_record_playback driver example in SDK 2.7, on a FRDMK66F board. With it's default settings (16kHz, 16-bit) it seems to work fine, however if you extend the word width to 24-bit (modifying #define DEMO_AUDIO_BIT_WIDTH kSAI_WordWidth24bits and setting the DA7212 config to a bitWidth of 24), the application plays static.

Modifying the sample word width to 32-bits or 8 bits the application works OK. It appears to be an issue with only the 24-bit sample size.

I have debugged sufficiently to eliminate the problem being with the configuration of the audio codec (although there are a number of minor problems with the 7212 driver and the device configuration, none of them would result in this specific issue). I have been examining the SAI APIs and I suspect the SAI clock configuration, however I can't say definitively.

Interestingly, I have got the SAI interface to work correctly in 24-bit sample size using the legacy style APIs. I am including the code below for reference (note, I have commented out the provided SAI code).

Has anyone come across a similar issue?

Thanks,

/Scott

// ----- Working SAI init code for 24-bit sample size, note only tested with 48KHz sample rate) ----
 /* SAI init */
    /*
    SAI_Init(DEMO_SAI);
    */
    memset(&sai_format, 0U, sizeof(sai_transfer_format_t));
    SAI_TxGetDefaultConfig(&sai_config);
    sai_config.masterSlave = kSAI_Master;
    SAI_TxInit(DEMO_SAI, &sai_config);
    SAI_RxGetDefaultConfig(&sai_config);
    SAI_RxInit(DEMO_SAI, &sai_config);

    sai_format.bitWidth = DEMO_AUDIO_BIT_WIDTH;
    sai_format.channel = 0U;
    sai_format.sampleRate_Hz = DEMO_AUDIO_SAMPLE_RATE;
    sai_format.masterClockHz = OVER_SAMPLE_RATE * sai_format.sampleRate_Hz;
    sai_format.protocol = sai_config.protocol;
    sai_format.stereo = kSAI_Stereo;
    sai_format.watermark = FSL_FEATURE_SAI_FIFO_COUNT / 2U;

    SAI_TransferTxCreateHandleEDMA(DEMO_SAI, &txHandle, tx_callback, NULL, &dmaTxHandle);
    SAI_TransferRxCreateHandleEDMA(DEMO_SAI, &rxHandle, rx_callback, NULL, &dmaRxHandle);

    /*
    // I2S mode configurations
    SAI_GetClassicI2SConfig(&config, DEMO_AUDIO_BIT_WIDTH, kSAI_Stereo, kSAI_Channel0Mask);
    config.syncMode = DEMO_SAI_TX_SYNC_MODE;
    SAI_TransferTxSetConfigEDMA(DEMO_SAI, &txHandle, &config);
    config.syncMode = DEMO_SAI_RX_SYNC_MODE;
    SAI_TransferRxSetConfigEDMA(DEMO_SAI, &rxHandle, &config);

    // set bit clock divider
    SAI_TxSetBitClockRate(DEMO_SAI, DEMO_AUDIO_MASTER_CLOCK, DEMO_AUDIO_SAMPLE_RATE, DEMO_AUDIO_BIT_WIDTH,
                          DEMO_AUDIO_DATA_CHANNEL);
    SAI_RxSetBitClockRate(DEMO_SAI, DEMO_AUDIO_MASTER_CLOCK, DEMO_AUDIO_SAMPLE_RATE, DEMO_AUDIO_BIT_WIDTH,
                          DEMO_AUDIO_DATA_CHANNEL);
// master clock configurations
#if (defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)) || \
    (defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER))
#if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)
    mclkConfig.mclkHz          = DEMO_AUDIO_MASTER_CLOCK;
    mclkConfig.mclkSourceClkHz = DEMO_SAI_CLK_FREQ;
#endif
    SAI_SetMasterClockConfig(DEMO_SAI, &mclkConfig);
#endif
    */

   SAI_TransferTxSetFormatEDMA(DEMO_SAI, &txHandle, &sai_format,
                               CLOCK_GetFreq(kCLOCK_CoreSysClk),
                               sai_format.masterClockHz);
   SAI_TransferRxSetFormatEDMA(DEMO_SAI, &rxHandle, &sai_format,
                               CLOCK_GetFreq(kCLOCK_CoreSysClk),
                               sai_format.masterClockHz);
Tags (1)
0 Kudos
8 Replies

1,088 Views
scott1
Contributor I

Hey Felipe, Thanks for getting back so quickly. Sure, I will take a look at these differences tomorrow and let you know if I find out anything.

Best,

Scott

0 Kudos

1,088 Views
scott1
Contributor I

Thank you Felipe. Do you have any timeline you may share?

Best regards,
Scott

0 Kudos

1,088 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Scott,

 

I am sorry for the late reply. We have been under a big workload. So far I have replicated your issue and realized that the classic APIs are not setting the same registers as the latest SDK APIs. Please check the below snippets.

pastedImage_2.png

pastedImage_4.png

I will still need to check which of these differences is making I2S not work. If you have time you could also help me to check this on your side.

Best regards,

Felipe

0 Kudos

1,088 Views
scott1
Contributor I

Hello Felipe,

I am back in the office now and I tried what you suggested.

So just changing the the bitWidth & DEMO_AUDIO_BIT_WIDTH to 24 bits while keeping everything the same does indeed work. We get 24-bit samples at 16KHz just fine.

The issue is related to 48KHz sampling. When I change the demo program to 48KHz sample rate by changing the following:

#define OVER_SAMPLE_RATE (256U)

#define DEMO_AUDIO_SAMPLE_RATE (kSAI_SampleRate48KHz)

#define DEMO_AUDIO_BIT_WIDTH kSAI_WordWidth16bits

da7212_config_t da7212Config = {

    .i2cConfig    = {.codecI2CInstance = BOARD_CODEC_I2C_INSTANCE, .codecI2CSourceClock = 60000000},

    .dacSource    = kDA7212_DACSourceInputStream,

    .slaveAddress = DA7212_ADDRESS,

    .protocol     = kDA7212_BusI2S,

    .format       = {.mclk_HZ = 12288000U, .sampleRate = 48000, .bitWidth = 16},

    .isMaster     = false,

};

The application only works with 16-bit and 32-bit bit widths; 24-bit does not work, static is produced. However with the "legacy" configuration code, it does work with all valid bit widths (16, 24 and 32-bit).

Can you reproduce this issue?

I can confirm I am using SDK 2.7.0 and IDE 11.1.1.

Thank you for your continued assistance with this matter.

Sincerely,

Scott

0 Kudos

1,088 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Scott,

 

I have reproduced your issue. Please allow me to do more tests on my side and I will inform you whenever I have an update.

 

Best regards,

Felipe

0 Kudos

1,088 Views
scott1
Contributor I

Hey Felipe, Thanks for trying this on my behalf. I am currently not at my desk, so I can't verify at this moment, but I will be able to verify later today or tomorrow.

However, from memory, the changes you made were the same as I made. There is one additional change I made as well - I increased the sample rate to 48KHz, which meant that I needed to change the .format.mclk_Hz to 12288000U. So I am not sure whether it's a 24-bit word size issue or a 48KHz + 24-bit word size.

Thank you again, and I'll update this thread when I can recheck.

/scott

0 Kudos

1,088 Views
FelipeGarcia
NXP Employee
NXP Employee

Hello Scott,

 

I have just tried the same example that you mentioned with 24 bit word with and it worked correctly. The only modifications that I did to the frdmk66f_sai_edma_record_playback example were the following:

 

#define DEMO_AUDIO_BIT_WIDTH kSAI_WordWidth24bits

da7212_config_t da7212Config = {

    .i2cConfig    = {.codecI2CInstance = BOARD_CODEC_I2C_INSTANCE, .codecI2CSourceClock = 60000000},

    .dacSource    = kDA7212_DACSourceInputStream,

    .slaveAddress = DA7212_ADDRESS,

    .protocol     = kDA7212_BusI2S,

    .format       = {.mclk_HZ = 6144000U, .sampleRate = 16000, .bitWidth = 24},

    .isMaster     = false,

};

Please let me know if the modifications you made on your side were different. I used MCUXpresso 11.1.1 and SDK 2.7.0.

 

Best regards,

Felipe

0 Kudos

1,088 Views
aaronminner
Contributor III

Hi Felipe. I don't want to steal this thread, but I'm curious how these manual configurations for the da7212_config_t variable fit together with the selections we make in the Config Tools -> Peripherals screen.  It seems like if we're selecting values in the Peripherals screen, and promulgating those to the peripherals.c/h code, setting them manually in the da7212_config_t variable kind of defeats the purpose.  In my case, I tried to use the defines that MCUXpresso came up with, like .mclk_HZ = I2S0_USER_MCLK_HZ, and .sampleRate = I2S0_TX_SAMPLE_RATE

 but it seems like it should be automated somehow, if we're going to select values in the Peripherals screen.  Or am I just unclear on this works?  Thanks - and sorry for the diversion.

0 Kudos