Hello,
I have DMA set up to move data from the HSADC FIFO to memory. This seems to work correctly, however there is some unexpected behavior.
The number of samples transferred is far larger than the 16 words expected. From my understanding, the DMA transfer is initiated when the HSADC FIFO_FULL flag is set. I have set the FIFIO fill level to 15. So after 15 samples, the DMA should trigger and move 16 samples out of the FIFO and into the destination address.
In the DMA handler, I reset the channel to get it ready for another transfer. From my understanding, the next time the DMA transfer occurs, the destination address should be the same (eg: dest[0]), however, it seems as though the destination address is the next address after the last transfer (eg: dest[16]).
This results in the DMA filling up memory incredibly rapidly.
What is going on here?
void DMA_IRQHandler(void)
{
Chip_GPDMA_Interrupt(LPC_GPDMA, dmaCh); //clears it
LPC_GPDMA->CH[dmaCh].SRCADDR = (uint32_t) &LPC_ADCHS->FIFO_OUTPUT[0];
LPC_GPDMA->CH[dmaCh].DESTADDR = ((uint32_t) &dest[0]);
LPC_GPDMA->CH[dmaCh].CONFIG |= 1;
}
void adchs_dma_setup(void)
{
Chip_GPDMA_Init(LPC_GPDMA);
dmaCh = Chip_GPDMA_GetFreeChannel(LPC_GPDMA, GPDMA_CONN_ADCHS_READ);
Chip_GPDMA_Transfer(LPC_GPDMA, dmaCh,
GPDMA_CONN_ADCHS_READ, (uint32_t) &dest[0],
GPDMA_TRANSFERTYPE_P2M_CONTROLLER_PERIPHERAL,
NULL);
/* Enable GPDMA interrupt */
NVIC_SetPriority(DMA_IRQn, 0);
NVIC_ClearPendingIRQ(DMA_IRQn);
NVIC_EnableIRQ(DMA_IRQn);
}
void adchs_setup(void)
{
Chip_HSADC_Init(LPC_ADCHS);
Chip_HSADC_SetupFIFO(LPC_ADCHS, 15, false);
Chip_HSADC_ConfigureTrigger(LPC_ADCHS, HSADC_CONFIG_TRIGGER_SW,
HSADC_CONFIG_TRIGGER_RISEEXT, HSADC_CONFIG_TRIGGER_NOEXTSYNC,
HSADC_CHANNEL_ID_EN_NONE, 0x90);
Chip_HSADC_SetACDCBias(LPC_ADCHS, 0, HSADC_CHANNEL_DCBIAS, HSADC_CHANNEL_NODCBIAS);
Chip_HSADC_SetPowerSpeed(LPC_ADCHS, false);
Chip_HSADC_EnablePower(LPC_ADCHS);
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 0, (HSADC_DESC_CH(0) | HSADC_DESC_BRANCH_FIRST | HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE | HSADC_DESC_RESET_TIMER));
Chip_HSADC_EnableInts(LPC_ADCHS, 0, (HSADC_INT0_FIFO_FULL));
Chip_HSADC_UpdateDescTable(LPC_ADCHS, 0);
NVIC_EnableIRQ(ADCHS_IRQn);
}