lpcware

20 ADC Chanel0 vakues to Memory, DMA driven?

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by elgarbe on Sun Apr 13 08:20:39 MST 2014
Hi, I need to continuosly read ADC chanel 0 and transfer the result to an array. I need to make 20 readings befor DMA make an interrupt. So I write this code:

adc.c

void ADCInit(void){
LPC_SC->PCONP |= (1 << 12);// Enable CLOCK into ADC controller */

LPC_PINCON->PINSEL1 &= ~(2<<14);// P0.23 -> AD0.0, function 01
LPC_PINCON->PINSEL1 |= 1<<14;

LPC_ADC->ADCR = ( 1 << 0 ) | // SEL=1,select channel 0 on ADC0
( 4 << 8 ) |  // 100MHz/4 (PCKL_ADC default) = 25MHz / 5 = 5MHz
( 1 << 16 ) | // BURST = 1, BURST mode, continuos covertion
( 1 << 21 ) |  // PDN = 1, normal operation
( 0 << 24 ) |  // START = 0 A/D conversion stops
( 0 << 27 );// EDGE = 0 (CAP/MAT singal falling,trigger A/D conversion)
LPC_ADC->ADINTEN |= 1<<0;// Enable Chanel 0 interrupt request
NVIC_DisableIRQ(ADC_IRQn);            // Register ADC Interrupt Handler
}


dma.c

void DMAInit(){
LPC_SC->PCONP |= 1 << 29; // Power up DMA

LPC_GPDMACH0->DMACCConfig = 0; // stop ch0 dma

LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) &(LPC_ADC->ADDR0); // ADC Chanel 0
LPC_GPDMACH0->DMACCDestAddr = (uint32_t) &arrRSSI; // Array
LPC_GPDMACH0->DMACCLLI = 0;
LPC_GPDMACH0->DMACCControl = ADC_CANT_SAMPLE // Transferencia de 20 word
| (0 << 12) // 1 burst
| (0 << 15) // 1 burst
| (2 << 18) // Word width
| (2<< 21) // Word width
| (0 << 26 ) // Source no increment.
| (1 << 27 ) // Destination increment.
| (1 << 31 );// Enable Terminal Count Interrupt

LPC_GPDMACH0->DMACCConfig = ( 4 << 1 )// Set ADC as source DMA request
| ( 2 << 11 ) // Peripheral to Memory
| ( 1 << 15 ); // Terminal count interrupt mask. 1 = unmasked

LPC_GPDMA->DMACIntErrClr |= 0xff;//Clear all DMA interrupts
LPC_GPDMA->DMACIntTCClear |= 0xff;
NVIC_EnableIRQ(DMA_IRQn);// Register DMA Interrupt Handler

//LPC_GPDMACH0->DMACCConfig |= 1; // enable ch0
LPC_GPDMA->DMACConfig |= 1; // enable DMA
}

void DMA_IRQHandler (void){
uint8_t i;
int adcSuma=0;
for (i=0;i<=ADC_CANT_SAMPLE;i++){
adcSuma += (arrRSSI[0] >> 4) & 0xFFF;
}
adcRSSI = (float)adcSuma / ADC_CANT_SAMPLE;
adcRSSI = adcRSSI * 3.3 / 4096;
LPC_GPDMA->DMACIntTCClear |= 0xff;
}

void DMACh0_Ena(){
LPC_GPDMACH0->DMACCConfig |= 1; //enable ch0
}
void DMACh0_Dis(){
LPC_GPDMACH0->DMACCConfig = 0; // stop ch0 dma
}


and main.c


#include <cr_section_macros.h>
#include "adc.h"
#include "dma.h"

volatile float adcRSSI;

int main(void) {

DMAInit();
ADCInit();

DMACh0_Ena();

    while(1) {
    }
}


With this code I pause on DMA_IRQ and see what arrRSSI have. I see this:

arrRSSI[0]uint32_t2147516752
arrRSSI[1]uint32_t33104
arrRSSI[2]uint32_t33104
arrRSSI[3]uint32_t33104
arrRSSI[4]uint32_t33104
arrRSSI[5]uint32_t33104
arrRSSI[6]uint32_t33104
arrRSSI[7]uint32_t33104
arrRSSI[8]uint32_t33104
arrRSSI[9]uint32_t33104
arrRSSI[10]uint32_t33104
arrRSSI[11]uint32_t33104
arrRSSI[12]uint32_t33104
arrRSSI[13]uint32_t33104
arrRSSI[14]uint32_t33104
arrRSSI[15]uint32_t33104
arrRSSI[16]uint32_t33104
arrRSSI[17]uint32_t33104
arrRSSI[18]uint32_t33104
arrRSSI[19]uint32_t33104


as you can see only first convertion as an 1 on DONE bit so I think the other values are not correct.

So how do I configure DMA chanel to read 20 adc chanel 0 readings after a TC interrupt fire?

Regards!

Outcomes