How to configure SAI3 Tx for audio output?

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

How to configure SAI3 Tx for audio output?

Jump to solution
3,422 Views
antoniohsu888
Contributor II

I am trying to configure the SAI3 Tx setting for audio output, but seems miss something it doesn't work.

Do not measure the I2S mclk output.

What settings I missed ?

 

Here is my pins mux settings:

//Audio Amp I2S
//AMP_SAI3_MCLK:GPIO_SD_B1_04
//AMP_SAI3_TX_DATA:GPIO_SD_B1_01
//AMP_SAI3_TX_BCLK: GPIO_SD_B1_03
//AMP_SAI3_TX_SYNC: GPIO_SD_B1_02

IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_04_SAI3_MCLK,1U);
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_01_SAI3_TX_DATA,1U);
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_03_SAI3_TX_BCLK,1U);
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_02_SAI3_TX_SYNC,1U);

IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_04_SAI3_MCLK, 0x10B0u);

IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_01_SAI3_TX_DATA, 0x10B0u);

IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_03_SAI3_TX_BCLK, 0x10B0u);

IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_02_SAI3_TX_SYNC, 0x10B0u);

My define:

/* SAI instance and clock */
#define DEMO_CODEC_WM8960
#define DEMO_SAI SAI1
#define DEMO_SAI_CHANNEL (0)
#define DEMO_SAI_BITWIDTH (kSAI_WordWidth16bits)
#define DEMO_SAI_IRQ SAI1_IRQn
#define SAI_UserIRQHandler SAI1_IRQHandler
#define DEMO_CHANNEL_NUM 2
#define DEMO_CODEC_CHANNEL kCODEC_PlayChannelHeadphoneLeft | kCODEC_PlayChannelHeadphoneRight

//Speaker TX SAI3
#define DEMO_SAI3 SAI3
#define DEMO_SAI3_CHANNEL (0)
#define DEMO_SAI3_IRQ SAI3_TX_IRQn
#define SAI3_UserIRQHandler SAI1_IRQHandler

/* IRQ */
#define DEMO_SAI_TX_IRQ SAI1_IRQn
#define DEMO_SAI_RX_IRQ SAI1_IRQn
#define DEMO_SAI3_TX_IRQ SAI3_TX_IRQn

/* DMA */
#define DEMO_DMA DMA0
#define DEMO_DMAMUX DMAMUX
#define DEMO_TX_CHANNEL (0U) //(0U)
#define DEMO_RX_CHANNEL (1U)
#define DEMO_SAI_TX_SOURCE kDmaRequestMuxSai3Tx //kDmaRequestMuxSai1Tx
#define DEMO_SAI_RX_SOURCE kDmaRequestMuxSai1Rx

in main()

CLOCK_SetMux(kCLOCK_Sai3Mux, DEMO_SAI1_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_Sai3PreDiv, DEMO_SAI1_CLOCK_SOURCE_PRE_DIVIDER);
CLOCK_SetDiv(kCLOCK_Sai3Div, DEMO_SAI1_CLOCK_SOURCE_DIVIDER);

DMAMUX_Init(DEMO_DMAMUX);
DMAMUX_SetSource(DEMO_DMAMUX, DEMO_TX_CHANNEL, (uint8_t)DEMO_SAI_TX_SOURCE);
DMAMUX_EnableChannel(DEMO_DMAMUX, DEMO_TX_CHANNEL);
DMAMUX_SetSource(DEMO_DMAMUX, DEMO_RX_CHANNEL, (uint8_t)DEMO_SAI_RX_SOURCE);
DMAMUX_EnableChannel(DEMO_DMAMUX, DEMO_RX_CHANNEL);

 

void BOARD_EnableSaiMclkOutput(bool enable)
{
if (enable)
{
IOMUXC_GPR->GPR1 |= IOMUXC_GPR_GPR1_SAI1_MCLK_DIR_MASK;
}
else
{
IOMUXC_GPR->GPR1 &= (~IOMUXC_GPR_GPR1_SAI1_MCLK_DIR_MASK);
}

#if PCBA_SAI3_TX_ENABLE
if (enable)
{
IOMUXC_GPR->GPR1 |= IOMUXC_GPR_GPR1_SAI3_MCLK_DIR_MASK;
}
else
{
IOMUXC_GPR->GPR1 &= (~IOMUXC_GPR_GPR1_SAI3_MCLK_DIR_MASK);
}

#endif
}

Labels (1)
0 Kudos
Reply
1 Solution
3,392 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @antoniohsu888 

  Glad to hear you find the new inclue, from your description, it should related to the SYNC for the RX and TX:

kerryzhou_0-1660268410897.png

You may set the RX: ASYNC, TX: SYNC

kerryzhou_1-1660268471301.png

kerryzhou_2-1660268477102.png

Then, even your TX also use the RX BCLK and SYNC.

kerryzhou_3-1660268508720.png

kerryzhou_4-1660268514035.png

So, you can debug your code to check it, make sure you set:

saiConfig.syncMode = kSAI_ModeAsync;

Then, even no RX, TX should also work.

Best Regards,

Kerry

 

 

 

View solution in original post

0 Kudos
Reply
6 Replies
3,411 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @antoniohsu888 ,

   Thank you for your interest in the NXP MIMXRT product, I would like to provide service for you.

  Just check your post code, I didn't find the special abnormal code, just this one:

#define SAI3_UserIRQHandler SAI1_IRQHandler

 But seems you didn't use it.

  So, how do you test it find it can't work?

  Do you test the BCLK, SYNC, DATA pin, whether it has any wave or not? What about the hardware test point, whether it is correct?

  About the code, I highly recommend you test it based on this SAI code directly:

SDK_2_12_0_EVK-MIMXRT1060\boards\evkmimxrt1060\driver_examples\sai\edma_transfer

Then modify the SAI interface to SAI3, and check the wave, it will help you to check whether TX_DATA is correct or not, after this works OK, then you can add the related code to your maestro again, it will be more easy to find the issues, just make sure not other code prevent the SAI3 working.

Best Regards,

kerry

0 Kudos
Reply
3,403 Views
antoniohsu888
Contributor II

Hi, Kerry:

I checked the sai_edma_transfer project settings compare to my maestro_record settings.

Seems I already set all settings.

I checked it dose call streamer_pcm_open()->SAI_TransferTxCreateHandleEDMA(DEMO_SAI3,... )

then call streamer_pcm_setparams()

final it call streamer_pcm_write(), but it lock on below wait semaphore and no saiTxCallback()

/* Wait for the previous transfer to finish */
if (xSemaphoreTake(pcm->semaphoreTX, portMAX_DELAY) != pdTRUE)

Does it look like my EDMA settings still not right?

would you please take a look for my settings. 

I can't measure data signal on IOMUXC_GPIO_SD_B1_01_SAI3_TX_DATA, 

I guess EDMA do not write data to sai3 tx data pin.

 

Bye the way, would you please confirm these setting is right or not.

1. pin mux

I follow the SAI1 settings, change to SAI3

IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_04_SAI3_MCLK, 1U);  
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_01_SAI3_TX_DATA, 1U); 
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_03_SAI3_TX_BCLK, 1U); 
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_02_SAI3_TX_SYNC,1U);

IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_04_SAI3_MCLK,0x10B0u);

IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_01_SAI3_TX_DATA,0x10B0u);

IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_03_SAI3_TX_BCLK,0x10B0u);

IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_02_SAI3_TX_SYNC,0x10B0u);

 

2.Could enable sai1 and sai3 at the same time ?

SAI_Init(DEMO_SAI);
SAI_Init(DEMO_SAI3);

 

3. Define.

/* SAI instance and clock */
#define DEMO_CODEC_WM8960
#define DEMO_SAI SAI1
#define DEMO_SAI_CHANNEL (0)
#define DEMO_SAI_BITWIDTH (kSAI_WordWidth16bits)
#define DEMO_SAI_IRQ SAI1_IRQn
#define SAI_UserIRQHandler SAI1_IRQHandler
#define DEMO_CHANNEL_NUM 2
#define DEMO_CODEC_CHANNEL kCODEC_PlayChannelHeadphoneLeft | kCODEC_PlayChannelHeadphoneRight

//Speaker TX SAI3
#define DEMO_SAI3 SAI3
#define DEMO_SAI3_CHANNEL (0) //0
#define DEMO_SAI3_IRQ SAI3_TX_IRQn
#define SAI3_UserIRQHandler SAI3_TX_IRQHandler

/* IRQ */
#define DEMO_SAI_TX_IRQ SAI3_TX_IRQn 
#define DEMO_SAI_RX_IRQ SAI1_IRQn
#define DEMO_SAI3_TX_IRQ

/* DMA */
#define DEMO_DMA DMA0
#define DEMO_DMAMUX DMAMUX
#define DEMO_TX_CHANNEL (0U) //(0U)
#define DEMO_RX_CHANNEL (1U) //1
#define DEMO_SAI_TX_SOURCE kDmaRequestMuxSai3Tx
#define DEMO_SAI_RX_SOURCE kDmaRequestMuxSai1Rx

0 Kudos
Reply
3,402 Views
antoniohsu888
Contributor II

Hi,Kerry:

I notice that the original settings for SAI1.

#define DEMO_SAI_CHANNEL (0)

For SAI3, still set to 0 or need to set other value?

 

Tags (1)
0 Kudos
Reply
3,399 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @antoniohsu888 ,

  SAI3 just have one channel, so it's OK to use Channel 0, as you don't have other channels.

  I didn't find the detail code issues, that's why I recommend you use the SDK code, modify it to the SAI3 and test it directly, after it works, then compare with your maestro code, just make sure, your maestro project directly SAI3 modification is not influenced by other code.

 

Best Regards,

Kerry

0 Kudos
Reply
3,395 Views
antoniohsu888
Contributor II

Hi, Kerry:

I meet a very strange thing.

Now I try to set all tx/rx to SAI3, when I play audio output, it works.

I can measure data signal output from sai3 tx data pin.

So, could EDMA(DMA0) set for sai1-rx and sai3-tx at the same time ?

 

The defines are:

/* SAI instance and clock */
#define DEMO_CODEC_WM8960
#define DEMO_SAI SAI3
#define DEMO_SAI_CHANNEL (0)
#define DEMO_SAI_BITWIDTH (kSAI_WordWidth16bits)
#define DEMO_SAI_IRQ SAI3_RX_IRQn
#define SAI_UserIRQHandler SAI1_IRQHandler
#define DEMO_CHANNEL_NUM 2
#define DEMO_CODEC_CHANNEL kCODEC_PlayChannelHeadphoneLeft | kCODEC_PlayChannelHeadphoneRight

//Speaker TX SAI3
#define DEMO_SAI3 SAI3
#define DEMO_SAI3_CHANNEL (0)
#define DEMO_SAI3_IRQ SAI3_TX_IRQn
#define SAI3_UserIRQHandler SAI3_TX_IRQHandler

/* IRQ */
#define DEMO_SAI_TX_IRQ SAI3_TX_IRQn
#define DEMO_SAI_RX_IRQ SAI3_RX_IRQn
#define DEMO_SAI3_TX_IRQ SAI3_TX_IRQn

/* DMA */
#define DEMO_DMA DMA0
#define DEMO_DMAMUX DMAMUX
#define DEMO_TX_CHANNEL (0U) //(0U)
#define DEMO_RX_CHANNEL (1U)
#define DEMO_SAI_TX_SOURCE kDmaRequestMuxSai3Tx //kDmaRequestMuxSai1Tx
#define DEMO_SAI_RX_SOURCE kDmaRequestMuxSai3Rx

0 Kudos
Reply
3,393 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @antoniohsu888 

  Glad to hear you find the new inclue, from your description, it should related to the SYNC for the RX and TX:

kerryzhou_0-1660268410897.png

You may set the RX: ASYNC, TX: SYNC

kerryzhou_1-1660268471301.png

kerryzhou_2-1660268477102.png

Then, even your TX also use the RX BCLK and SYNC.

kerryzhou_3-1660268508720.png

kerryzhou_4-1660268514035.png

So, you can debug your code to check it, make sure you set:

saiConfig.syncMode = kSAI_ModeAsync;

Then, even no RX, TX should also work.

Best Regards,

Kerry

 

 

 

0 Kudos
Reply