Hello NXP developers, I am an NXP, I am using LPC55S28 to implement DMA to transmit I2S data, I found that the I2S of NXP's official SDK uses DMA to transmit 16 bits, I don't know how to modify it to 24 bits, please guide us. Thank you (bow). A portion of the code is also attached.
//Configuration of I2S
I2S_TxGetDefaultConfig(&s_TxConfig);
s_TxConfig.divider = DEMO_I2S_CLOCK_DIVIDER;
s_TxConfig.masterSlave = DEMO_I2S_TX_MODE;
s_TxConfig.dataLength = DataLenth;
s_TxConfig.frameLength = FrameLength;
s_TxConfig.leftJust = false;
I2S_TxInit(DEMO_I2S_TX, &s_TxConfig);
I2S_RxGetDefaultConfig(&s_RxConfig);
s_RxConfig.divider = DEMO_I2S_CLOCK_DIVIDER;
s_RxConfig.masterSlave = DEMO_I2S_RX_MODE;
s_RxConfig.dataLength = DataLenth;
s_RxConfig.frameLength = FrameLength;
s_RxConfig.leftJust = false;
I2S_RxInit(DEMO_I2S_RX, &s_RxConfig);
PRINTF("AUDIO Loopback started!\r\n");
PRINTF("Headphones will play what is input into Audio Line-In connector.\r\n");
// PRINTF("CLOCK_GetPll0OutFreq = %d\r\n", CLOCK_GetPll0OutFreq);
s_RxTransfer.data = &s_Buffer[0];
s_RxTransfer.dataSize = sizeof(s_Buffer);
// s_TxTransfer.data = &s_Buffer[0];
// s_TxTransfer.dataSize = sizeof(s_Buffer);
#if I2S_24BIT
// 24bit
s_TxTransfer.data = &sin_24bit[0];
s_TxTransfer.dataSize = sizeof(sin_24bit);
#else
// 16bit
s_TxTransfer.data = &sin_16bit[0];
s_TxTransfer.dataSize = sizeof(sin_16bit);
#endif
//Configuration of DMA0
#if DMA_Transfer
DMA_Init(DEMO_DMA);
DMA_EnableChannel(DEMO_DMA, DEMO_I2S_TX_CHANNEL);
DMA_EnableChannel(DEMO_DMA, DEMO_I2S_RX_CHANNEL);
DMA_SetChannelPriority(DEMO_DMA, DEMO_I2S_TX_CHANNEL, kDMA_ChannelPriority2);
DMA_SetChannelPriority(DEMO_DMA, DEMO_I2S_RX_CHANNEL, kDMA_ChannelPriority3);
DMA_CreateHandle(&s_DmaTxHandle, DEMO_DMA, DEMO_I2S_TX_CHANNEL);
DMA_CreateHandle(&s_DmaRxHandle, DEMO_DMA, DEMO_I2S_RX_CHANNEL);
I2S_TxTransferCreateHandleDMA(DEMO_I2S_TX, &s_TxHandle, &s_DmaTxHandle, TxCallback, (void *)&s_TxTransfer);
I2S_TxTransferCreateHandleDMA(DEMO_I2S_RX, &s_RxHandle, &s_DmaRxHandle, RxCallback, (void *)&s_RxTransfer);
/* need to queue two transmit buffers so when the first one
* finishes transfer, the other immediatelly starts */
I2S_TxTransferSendDMA(DEMO_I2S_TX, &s_TxHandle, s_TxTransfer);
I2S_TxTransferSendDMA(DEMO_I2S_TX, &s_TxHandle, s_TxTransfer);
//I2S_TxTransferSendDMA(DEMO_I2S_TX, &s_TxHandle, s_TxTransfer);
I2S_RxTransferReceiveDMA(DEMO_I2S_RX, &s_RxHandle, s_RxTransfer);
I2S_RxTransferReceiveDMA(DEMO_I2S_RX, &s_RxHandle, s_RxTransfer);
#else //I2STransfer
I2S_TxTransferCreateHandle(DEMO_I2S_TX, &s_TxHandle, TxCallback, (void *)&s_TxTransfer);
I2S_RxTransferCreateHandle(DEMO_I2S_RX, &s_RxHandle, RxCallback, (void *)&s_RxTransfer);
I2S_RxTransferNonBlocking(DEMO_I2S_RX, &s_RxHandle, s_RxTransfer);
I2S_TxTransferNonBlocking(DEMO_I2S_TX, &s_TxHandle, s_TxTransfer);
#endif
//Also attach my project code
Hi @MHY_0878
About the I2S Configuration Adjustments.
#define DataLenth 24 // 24 bits per channel
#define FrameLength 64 // 64 bits per frame (32 bits per channel)
About the DMA Configuration,
You need to configure DMA for 32-bit transfers since each sample is stored in a 32-bit word.
You need to check this function.
BR
Harry
Hello, I've seen this function, I found that it seems that only the modified I2S is used, I generate 16-bit and 24-bit positive sine waves in MCU lpc55S28 for testing, the 16-bit positive sine wave data is normal to transmit with I2S and DMA, but the 24-bit positive sine wave data is transmitted, only the I2S transmission waveform is correct, and the DMA transmission waveform is abnormal, I don't know what the reason is, please help me.
Hi @MHY_0878
I checked the i2s DMA code,
bytesPerFrame is determined based on the width of i2s, so there is no need to modify it.
"the DMA transmission waveform is abnormal"
How do you test DMA waveforms? Can you send photos of the relevant waveforms?
BR
Harry