I'd like to use the ad converter with a dma support.
In the specific case the ad converter is triggered by a PIT's channel every 2 ms.
Then the ad converter must trigger the dma channel.
It works but, as you can see, in the code, I was expecting to see the ad converter data in a buffer previously set in the dma DAR register. I can see the data only in the first 2 buffer position. In the first two. Seem that the destination increment doesn't work correctly or something continue to clear the counter. Ther's something wrong in the firmware.
For more detail I can post the ad converter init in the case.
Thanks.
Claudio
/*!
*********************************************************************************************************************************************************************************
*** @fn : void Init_Dma(void)
*** @brief : dma initialization
***
*** @param : channel to be initialized
*** @ return: none
***
*** @details: initialize dma module
***
*********************************************************************************************************************************************************************************
*/
void Init_Dma(UINT8 channel)
{
DMA_Type *dma;
DMAMUX_Type *dma_mux;
UINT32 *destination;
UINT8 dma_int[] =
{
DMA0_IRQn,
DMA1_IRQn,
DMA2_IRQn,
DMA3_IRQn
};
if(channel > 0x00) // just for debug is 0. Then will be 3
return;
// clock gating on dmux & dma modules
SIM->SCGC6 |= SIM_SCGC6_DMAMUX_MASK; // dma mux clock gating
SIM->SCGC7 |= SIM_SCGC7_DMA_MASK; // dma clock gating
dma_mux = DMAMUX0;
dma = DMA0;
switch(channel)
{
case 0: destination = (UINT32*)&Buffer_A; break;
case 1: destination = (UINT32*)&Buffer_B; break;
case 2: destination = NULL; break;
case 3: destination = NULL; break;
default:
return;
}
// dma mux
dma_mux->CHCFG[channel] = 0x00; // clear register
// dma
dma->DMA[channel].SAR = (UINT32)&ADC0[0].R; // dma source register (where dma takes data)
dma->DMA[channel].DAR = (UINT32)destination; // dma destination register (where dma write data)
dma->DMA[channel].DSR_BCR |= DMA_DSR_BCR_DONE_MASK; // clear BCR reg
dma->DMA[channel].DSR_BCR = DMA_DSR_BCR_BCR(16); // bcr = 16
dma->DMA[channel].DCR |= DMA_DCR_EINT_MASK + // enable interrupt
DMA_DCR_ERQ_MASK + // Enable peripheral requestDMA_DCR_SSIZE(2)
0 + // CS
0 + // AA
0 + // EADREQ
0 + // SINC
DMA_DCR_SSIZE(0x02) + // source size = 16 bit
DMA_DCR_DINC_MASK + // set increments to destination address
0 + // DINC
DMA_DCR_DSIZE(0x02) + // destination size = 16 bit
0 + // START
0 + // SMOD
DMA_DCR_DMOD(0x01) + // destination circular buffer = 16 bytes
0 + // D_REQ
0 + // LINKCC
0 + // LCH1
0; // LCH2
DMAMUX0->CHCFG[channel] |= kDmaRequestMux0ADC0 + // dma source pheripheral
DMAMUX_CHCFG_ENBL_MASK; // no trigg, then dma is in normal mode
ConnectInterruptToCortex(dma_int[channel]); // set dma channel 0 interrupts
}
void DMA0_IRQHandler(void)
{
DMA_Type *dma;
dma = DMA0;
dma->DMA[0].DSR_BCR |= DMA_DSR_BCR_DONE_MASK; // Clear Done Flag
dma->DMA[0].DSR_BCR |= DMA_DSR_BCR_BCR(16); // Set byte count register
}