Content originally posted in LPCWare by andrea.giuffrida1 on Wed May 25 05:37:12 MST 2016
Hello everybody!
I'm trying to read three ADC channel with DMA.
If I disable the DMA controller the ADC works correctly but i don't understand where is the error in the DMA code.
Could someone help me to find the error?
volatile uint32_t ADCBuff[3] = {0,0,0};
void initDMA(void) {
LPC_GPDMA->DMACConfig = 0; /* Disable DMA */
LPC_GPDMA->DMACIntTCClear |= 0xFF;
LPC_GPDMA->DMACIntErrClr |= 0xFF;
LPC_GPDMACH0->DMACCLLI = (unsigned int)(LPC_GPDMACH1);
LPC_GPDMACH0->DMACCSrcAddr = (unsigned int)&(LPC_ADC->ADDR3);
LPC_GPDMACH0->DMACCDestAddr = (unsigned int)ADCBuff;
LPC_GPDMACH0->DMACCControl = (1u << 0 )|/* TransferSize */
(0u << 12)|/* Source Burst Size */
(0u << 15)|/* Dest Burst Size */
(2u << 18)|/* Source transfer width = 32bit */
(2u << 21)|/* Dest transfer width = 32bit */
(1u << 27)|/* the destination address is incremented after each transfer */
(1u << 31);/* the terminal count interrupt is enabled. */
LPC_GPDMACH0->DMACCConfig = (1u << 0)|/* Channel enabled */
(4u << 1)|/* SrcPeripheral ADC */
(2u << 11)|/* Transfer Type Periph to Memory */
(1u << 14)|/* IE Mask */
(1u << 15);/* ITC Mask */
LPC_GPDMACH1->DMACCLLI = (unsigned int)(LPC_GPDMACH2);
LPC_GPDMACH1->DMACCSrcAddr = (unsigned int)&(LPC_ADC->ADDR6);
LPC_GPDMACH1->DMACCDestAddr = (unsigned int)(ADCBuff + 1);
LPC_GPDMACH1->DMACCControl = (1u << 0 )|/* TransferSize */
(0u << 12)|/* Source Burst Size */
(0u << 15)|/* Dest Burst Size */
(2u << 18)|/* Source transfer width = 32bit */
(2u << 21)|/* Dest transfer width = 32bit */
(1u << 27)|/* the destination address is incremented after each transfer */
(1u << 31);/* the terminal count interrupt is enabled. */
LPC_GPDMACH1->DMACCConfig = (1u << 0)|/* Channel enabled */
(4u << 1)|/* SrcPeripheral ADC */
(2u << 11)|/* Transfer Type Periph to Memory */
(1u << 14)|/* IE Mask */
(1u << 15);/* ITC Mask */
LPC_GPDMACH2->DMACCLLI = 0;
LPC_GPDMACH2->DMACCSrcAddr = (unsigned int)&(LPC_ADC->ADDR7);
LPC_GPDMACH2->DMACCDestAddr = (unsigned int)(ADCBuff + 2);
LPC_GPDMACH2->DMACCControl = (1u << 0 )|/* TransferSize */
(0u << 12)|/* Source Burst Size */
(0u << 15)|/* Dest Burst Size */
(2u << 18)|/* Source transfer width = 32bit */
(2u << 21)|/* Dest transfer width = 32bit */
(1u << 27)|/* the destination address is incremented after each transfer */
(1u << 31);/* the terminal count interrupt is enabled. */
LPC_GPDMACH2->DMACCConfig = (1u << 0)|/* Channel enabled */
(4u << 1)|/* SrcPeripheral ADC */
(2u << 11)|/* Transfer Type Periph to Memory */
(1u << 14)|/* IE Mask */
(1u << 15);/* ITC Mask */
NVIC_EnableIRQ(DMA_IRQn);
LPC_GPDMA->DMACConfig |= 1; /* Enable DMA */
}
void DMA_IRQHandler(void){
NVIC_DisableIRQ(DMA_IRQn);
if (DMA_done == 0) {
CSdata.VBATT = (ADCBuff[0] >> 4) & ADC_VALUE_MAX;
CSdata.CSREF = (ADCBuff[1] >> 4) & ADC_VALUE_MAX;
CSdata.CSOUT = (ADCBuff[2] >> 4) & ADC_VALUE_MAX;
DMA_done = 1;
}
}
/*----------------------------------------------------------------------------
Function that initializes ADC
*----------------------------------------------------------------------------*/
void initADC (void) {
LPC_ADC->ADCR = ( 1 << 3) | /* select AD0.3 pin */
( 1 << 6) | /* select AD0.6 pin */
( 1 << 7) | /* select AD0.7 pin */
( 1 << 8) | /* ADC clock is 25MHz/(n+1) */
( 1 << 16) | /* BURST. Remark: START bits must be 000 when BURST = 1 or conversions will not start.*/
( 1 << 21); /* enable ADC */
LPC_ADC->ADINTEN = ( 0 << 3) |/* CH.3 conversion interr dis */
( 0 << 6) |/* CH.6 conversion interr dis */
( 1 << 7);/* CH.7 conversion interr en */
LPC_ADC->ADINTEN &= ~(1 << 8);/*Global Interrupt*/
NVIC_DisableIRQ(ADC_IRQn);/* Disable ADC Interrupt*/
}