lpcware

DMA ADC sync

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by rouxfederico on Sat Jul 12 10:03:52 MST 2014
Hello, this is my first post here. I always find the answer to my programming problems but I haven't found for this.

The problem is with the LPCOpen example periph_adc, so there's no need to upload the project.In the function App_DMA_Test is written:


static void App_DMA_Test(void)
{
uint16_t dataADC;

/* Initialize GPDMA controller */
Chip_GPDMA_Init(LPC_GPDMA);
/* Setting GPDMA interrupt */
NVIC_DisableIRQ(DMA_IRQn);
NVIC_SetPriority(DMA_IRQn, ((0x01 << 3) | 0x01));
NVIC_EnableIRQ(DMA_IRQn);
/* Setting ADC interrupt, ADC Interrupt must be disable in DMA mode */
NVIC_DisableIRQ(_LPC_ADC_IRQ);
Chip_ADC_Int_SetChannelCmd(_LPC_ADC_ID, _ADC_CHANNLE, ENABLE);
/* Get the free channel for DMA transfer */
dmaChannelNum = Chip_GPDMA_GetFreeChannel(LPC_GPDMA, _GPDMA_CONN_ADC);
/* Enable burst mode if any, the AD converter does repeated conversions
   at the rate selected by the CLKS field in burst mode automatically */
if (Burst_Mode_Flag) {
Chip_ADC_SetBurstCmd(_LPC_ADC_ID, ENABLE);
}
/* Get  adc value until get 'x' character */
while (DEBUGIN() != 'x') {
/* Start A/D conversion if not using burst mode */

if (!Burst_Mode_Flag) {
Chip_ADC_SetStartMode(_LPC_ADC_ID, ADC_START_NOW, ADC_TRIGGERMODE_RISING);
}
channelTC = 0;
Chip_GPDMA_Transfer(LPC_GPDMA, dmaChannelNum,
  _GPDMA_CONN_ADC,
  (uint32_t) &DMAbuffer,
  GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA,
  1);


/* Waiting for reading ADC value completed */
while (channelTC == 0) {}

/* Get the ADC value fron Data register*/
dataADC = ADC_DR_RESULT(DMAbuffer);
                App_print_ADC_value(dataADC);
}
/* Disable interrupts, release DMA channel */
Chip_GPDMA_Stop(LPC_GPDMA, dmaChannelNum);
NVIC_DisableIRQ(DMA_IRQn);
/* Disable burst mode if any */
if (Burst_Mode_Flag) {
Chip_ADC_SetBurstCmd(_LPC_ADC_ID, DISABLE);
}
}



I've some problems with this code:

[list=1]
  [*] DMA transfer is not sync with the ADC conversion. I've found that the DMA transfer the result from ADGDR before the ADC makes the conversion. It's only sync the first time. If you put a breakpoint in the line Chip_ADC_SetStartMode(...) (that's inmediately before starting the ADC conversion) and you change the input voltage from, for example, 0V to 1V, the DMA transfers a 0x00 from the last conversion of 0V, and then, the subsequents conversions are OK. Why is this?


[*] In the User Manual (UM10360 page 618. Table 567) says:

Transfer Direction :  Peripheral-to-memory 
Request Generator : Peripheral 
Flow Controller : DMA Controller

Reading this, I understand that when you config a P2M DMA transfer, the request generator and the flow controller are fixed to these I read in the table.
So, in the LPCOpen function, why you have [color=#30f]GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA[/color] and [color=#30f]GPDMA_TRANSFERTYPE_P2M_CONTROLLER_PERIPHERAL [/color]transfer type? I've read all the function that uses this constants and there's no difference between them. The switch/case uses both constants to do the same things. But I still have a problem, when I put transfer type to [color=#30f]GPDMA_TRANSFERTYPE_P2M_CONTROLLER_PERIPHERAL[/color], the DMA returns an ERROR from the ISR handler.
[/list]

Well, that's all!
I'll be waiting anxious for the answer :).
Thank's a lot and sorry for my English.



Outcomes