Hello there,
I am currently working on an application in which i am using the DMA to drive my DAC to create an analog signal. At low frequencies i am able to use the single transfer DMA and a call back function to reload the DMA. At higher frequencies there is a problem with the callback as they introduce a certain delay while making the subsequent DMA transfers.
I tried to use the ping pong buffer and the DMA values are not refreshed as i expected. I am using the following code and not sure what i am doing wrong in setting up the ping pong scheme for DMA. The software runs on a LPC845. Any suggestions please.
dma_descriptor_t nextDesc[2];
dma_channel_config_t dma_channel_config;
#define DAC_DATA_REG_ADDR 0x40014000
dma_handle_t DMA0_CH0_Handle;
#define DMA0_CH0_DMA_CHANNEL 22
void Start_DAC_1Khz_signal(void)
{
uint32_t numOftransferBytes = sizeof(g_waveform);
DMA_EnableChannel(DMA0_DMA_BASEADDR, DMA0_CH0_DMA_CHANNEL);
DMA_ALLOCATE_LINK_DESCRIPTORS(nextDesc,2);
DMA_SetupDescriptor(&nextDesc[0],
DMA_CHANNEL_XFER(1, 0, 0, 0, 4, kDMA_AddressInterleave4xWidth, kDMA_AddressInterleave4xWidth, numOftransferBytes),
(void *)g_waveform, (void *)DAC_DATA_REG_ADDR,&nextDesc[1]);
DMA_SetupDescriptor(&nextDesc[1],
DMA_CHANNEL_XFER(1, 0, 0, 0, 4, kDMA_AddressInterleave4xWidth, kDMA_AddressInterleave4xWidth, numOftransferBytes),
(void *)g_waveform, (void *)DAC_DATA_REG_ADDR, &nextDesc[0]);
DMA_CreateHandle(&DMA0_CH0_Handle, DMA0_DMA_BASEADDR, DMA0_CH0_DMA_CHANNEL);
DMA_PrepareChannelTransfer(&dma_channel_config, (void *)g_waveform,
(void *)DAC_DATA_REG_ADDR,
DMA_CHANNEL_XFER(1, 0, 0, 0, 4, kDMA_AddressInterleave4xWidth, kDMA_AddressInterleave4xWidth, numOftransferBytes),kDMA_MemoryToPeripheral,0,&nextDesc[0]);
DMA_SubmitChannelTransfer(&DMA0_CH0_Handle, &dma_channel_config);
DMA_StartTransfer(&DMA0_CH0_Handle);
}
const dac_config_t DAC0_config = {
.settlingTime = kDAC_SettlingTimeIs1us
};
#define DAC0_BUFFER_VALUE 1
#define DAC0_COUNTER_VALUE 234
static void DAC0_init(void) {
/* DAC0 initiation */
DAC_Init(DAC0_PERIPHERAL, &DAC0_config);
/* DAC0 double buffering enabled */
DAC_EnableDoubleBuffering(DAC0_PERIPHERAL, true);
/* DAC0 set buffer value */
DAC_SetBufferValue(DAC0_PERIPHERAL, DAC0_BUFFER_VALUE);
/* DAC0 set counter value */
DAC_SetCounterValue(DAC0_PERIPHERAL, DAC0_COUNTER_VALUE);
/* DAC0 DMA access enabled */
DAC_EnableDMA(DAC0_PERIPHERAL, true);
/* DAC0 enable counter */
DAC_EnableCounter(DAC0_PERIPHERAL, true);
}
int main()
{
DMA_Init(DMA0_DMA_BASEADDR);
/* Initialize components */
DAC0_init();
Start_DAC_1Khz_signal();
while(1){};
}