Hi there,
I am trying to send sine wave data over I2S DMA to an audio amplifier, 16 bit samples @48kHz.
I have based my software on the SDK for the LPC54608 microcontroller.
The sine wave data is one channel, so i have configured the I2S to operate in mono mode.
What i have found is that when i play the audio data over normal I2S without DMA everything is as expected on the output.
However when i switch to a DMA setup, the data plays twice as fast, and when i try to counter this with reducing the clock speeds the output is distorted.
My theory is, that the I2S DMA, although is set up as 2 bytes per frame, the DMA is cycling through the data at twice the speed that it should. Below are the setups for both I2S, and I2S DMA setups i am using.
Below is a setup of our I2S DMA, which is modelled after the NXP SDK examples.
static dma_handle_t s_DmaTxHandle;
static i2s_config_t s_TxConfig;
static i2s_dma_handle_t s_TxHandle;
static i2s_transfer_t s_TxTransfer;
I2S_TxGetDefaultConfig(&s_TxConfig);
s_TxConfig.divider = 16; // BCLK @ 1.536MHz
s_TxConfig.oneChannel = true; // mono mode
s_TxConfig.masterSlave = kI2S_MasterSlaveNormalMaster;
I2S_TxInit(I2S0, &s_TxConfig);
DMA_Init(DMA0);
DMA_EnableChannel(DMA0, 13U);
DMA_SetChannelPriority(DMA0, 13U, kDMA_ChannelPriority3);
DMA_CreateHandle(&s_DmaTxHandle, DMA0, 13U);
s_TxTransfer.data = (uint8_t*)messageSourceAddress; // pointer to source address
s_TxTransfer.dataSize = messageSourceSizeBytes;
I2S_TxTransferCreateHandleDMA(I2S0, &s_TxHandle, &s_DmaTxHandle, TxCallback, (void *)&s_TxTransfer);
I2S_TxTransferSendDMA(I2S0, &s_TxHandle, s_TxTransfer);
When I run this code (above) my audio plays at twice the speed. When I reduce the clock speeds to counter this the sine wave output is distorted.
However when I run this code (below) without DMA, everything runs as expected, and the sine wave output is as expected.
static i2s_config_t s_TxConfig;
static i2s_transfer_t s_TxTransfer;
static i2s_handle_t s_TxHandle;
I2S_TxGetDefaultConfig(&s_TxConfig);
s_TxConfig.divider = 16; // BCLK @ 1.536MHz
s_TxConfig.oneChannel = true; // mono mode
s_TxConfig.masterSlave = kI2S_MasterSlaveNormalMaster;
I2S_TxInit(I2S0, &s_TxConfig);
s_TxTransfer.data = (uint8_t*)messageSourceAddress;
s_TxTransfer.dataSize = messageSourceSizeBytes;
I2S_TxTransferCreateHandle(I2S0, &s_TxHandle, TxCallback, (void *)&s_TxTransfer);
I2S_TxTransferNonBlocking(I2S0, & s_TxHandle, s_I2S_TxTransfer);
The I2S clock speeds are set up as:
MCLK = 12.288MHz
WCLK = 48kHz
BCLK = 1.536MHz
Any help on this is greatly appreciated.
Blair