This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2540 ADC/DMA question

Hi all, i am using ADC in sequence to to a 4 channel adc conversion at 1k samples/s. Result is read out using dma channel 3. When i am writing code, i have some doubts:

1.  I use only 1 channel of DMA and the trigger is ADC_CHALL, which means a sequence sampling is ready. But where is the result? As i know, ADCH is a fixed register.

2. I only want to read the result from ADCH, 8 bit, i set the dma to read 8 bit each timer and total transfer before a interrupt is 4(4 channel.) What should i do?because each time adc there will be a result of 16bit from ADCH and ADCL.

3. To achieve this, i need to do check the interrupt and read out 4byte of data every 1ms. Is there a way to store the data in a larger buffer in DMA(DMA will write to the buffer with increment), so i can lower the time to check the interrupt and tansfer the data.     DMA is in block transfer mode trigger by timer1 channel 0, the frequency of the trigger is 1k.

Below is my code :

#include "adc_dma.h"
#include "hal_dma.h"


static __xdata uint8 result[4];

//init adc, dma, timer1
void initAll(void)
{
//***************** init timer1************************/
// bit[7-4] 0000 reserved
// bit[3-2] 11   32Mhz/128 = 0.25Mhz ~ 0.004ms
//                          0.004ms * 250 = 1ms
// bit[1-0] 10   modulo, from 0x0000 to T1CCO (250)
T1CTL = 0x0E;
// timer1 channel 0 compare control
// bit[7  ] 0    regular capture mode
// bit[6  ] 0    disable interrupt
// bit[5-3] 010  toggle output on compare
// bit[2  ] 1    compare mode
// bit[1-0] 00   no capture
T1CCTL0 = 0x14;
T1CC0L = 0xFA;   //250 times 0.004ms
T1CC0H = 0x00;

T1CCTL0 |= 0x40; //enable interrupt

T1CNTL = 0x01;   // write T1CC0 and start the timer from 0x0000

//***************** init ADC**************************/
APCFG = 0xFF;    // ADC inputs

//ADCCON1  0(conversion not complete)  0?????????????
// 10 timer 1 channel 0 will start a new conversion sequence
// 1111 stops random number generator
ADCCON1 = 0x3F;
//ADCCON2 10 ACDD5 REFRENCE  01 9bits ENOB setting
// 0011 AIN0 TO AIN3 (4 channel)
ADCCON2 = 0x93;
//**ADCCON1 &= ~(0x30); //Clear STSEL bits
//**ADCCON1 |= 0x20; //Set STSEL to Timer 1 channel 0

//***************** init DMA**************************/
//using dma channel 3 to do reading
halDMADesc_t *ch;
ch = HAL_DMA_GET_DESC1234(3);    //adress of dma register
dmaSetDataStructure(ch,result);

//arm dma 
DMAARM3 = 1;
}



void dmaSetDataStructure ( halDMADesc_t  *dma_p,
                        uint16  *dest_adr)
{
    // Setup DMA configuration.
	//source address
    dma_p->srcAddrH  = (uint16)(&X_ADCH) >> 8;
    dma_p->srcAddrL  = (uint16)(&X_ADCH) & 0x00FF;
	//destination adress
    dma_p->dstAddrH = ((uint16)dest_adr) >> 8;
    dma_p->dstAddrL = ((uint16)dest_adr);
	// 000 use len for transfer countr
	// 00000
    dma_p->xferLenV      = 0x00;
	//lenl is the length of transfer byte
    dma_p->xferLenL      = 4;                   // Tranfer Count 4 byte
    // wordsize 8bit   repeated block, every time read out all then interrupt
	// 20 10100 means ADC_ALL_READY
	dma_p->ctrlA = 0x74;
	//source no increment , dest increment, enable interrupt , high proi
	dma_p->ctrlB = 0x1A;
}