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.

Read ADC conversion sequence with DMA and Timer1 on CC2530

Other Parts Discussed in Thread: CC2530

I am trying to read 6 sensor values from the ADC at specific time intervals using compare mode on Timer 1 channel 0 along with the DMA on a CC2530. My current code is below. Unfortunately, the ADC values appear to be gibberish, mostly FF and 00.

I have previously tested the ADC using code without the DMA so I know the sensors are working correctly. I also know that the DMA is working properly because I tested it by moving values from one place in memory to another. I am at a loss as to what is wrong with this code. I am assuming it must be something with the setup of the ADC, but I have looked through the user guide and can't figure it out. In addition I have compared the code to this (http://e2e.ti.com/support/low_power_rf/f/156/t/143710.aspx#520330) which runs on the CC1110 and the only thing I am doing differently is using timer 1 to trigger the ADC. ( I have tested using her settings for the ADC with still no luck) Any ideas as to what is wrong?

Thanks for any help,

Katie

* LOCAL VARIABLES
*/
static uint8 pTxData[APP_PAYLOAD_LENGTH];
static unsigned char pRxData[APP_PAYLOAD_LENGTH];
static basicRfCfg_t basicRfConfig;
uint8 START_SYMBOL = 255;


#ifdef SECURITY_CCM
// Security key
static uint8 key[]= {
    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
};
#endif


//DMA Description Structure

typedef struct {
     uint8 SRCADDRH; //Byte 0
     uint8 SRCADDRL; //Byte 1
     uint8 DESTADDRH; //Byte 2
     uint8 DESTADDRL; //Byte 3
     uint8 LENH:5; //Byte 4 - Bit 4:0
     uint8 VLEN:3; //Byte 4 - Bit 7:5
     uint8 LENL; //Byte 5
     uint8 TRIG:5; //Byte 6 - Bit 4:0
     uint8 TMODE:2; //Byte 6 - Bit 6:5
     uint8 WORDSIZE:1; //Byte 6 - Bit 7
     uint8 PRIORITY:2; //Byte 7 - Bit 1:0
     uint8 M8:1; //Byte 7 - Bit 2
     uint8 IRQMASK:1; //Byte 7 - Bit 3
     uint8 DESTINC:2; //Byte 7 - Bit 5:4
     uint8 SRCINC:2; //Byte 7 - Bit 7:6
} DMA_DESC;

static __xdata DMA_DESC dma_channel;
static __xdata uint16 adc_data[18];
uint16 adcl, adch;
int16 adc;
float voltage;

uint16 dataToRead[8]=
{
 0xaaaa, 0xbbbb, 0xcccc, 0xdddd, 0xeeee, 0x9999, 0x8888, 0x7777
};
uint16 buf[8]=
{
 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};


void main(void) {
   
    
    // Initalise board peripherals
    halBoardInit();
    halJoystickInit();
 

    // Indicate that device is powered
    halLedSet(1);

    memset(adc_data, 0, sizeof(adc_data));


    //initialize the DMA
    initDMA();    
    
    // I/O-Port configuration :
    // P0_0 - P0_5 are configured as ADC input pin
    ADCCFG = 0x3F;

   ADCCON1 = 0x23;
    //convert channels 0-5
    // SDIV = 12 bits resolution
    // SCH = Ext ref on pin 7
    ADCCON2 = 0x75;
    
    initTimer();

    while(1){
      readADCwithDMA();
    }
    // Role is undefined. This code should not be reached
    HAL_ASSERT(FALSE);
}


void readADCwithDMA(){

    P1_3 = 1; //wake sensors up

      DMAARM = 0x80; //abort all channels
      DMAIRQ = 0x00; // set interrupt to 0
      DMAARM = 0x01; // arm channel 0
      restartTimer(); //(re)start timer
 
      // Wait for conversion to complete
      //read the six sensor values
      while(!DMAIRQ);
      printf("interrupt triggered");
      DMAIRQ = 0x00;
         
    P1_3 = 0;//put sensors to sleep to conserve power
 
}


//itializes settings for timer 1 ch 0 used to start the adc
void initTimer(){

  T1CCTL0 = 0x04; //TIMER 1 CHANNNEL 0 IN COMPARE MODE (NOT SURE THIS IS ALL I NEED TO DO)
  T1CC0L = 0x87; // SET PERIOD TO 5000 TICKS, WITH 32MHz CLOCK, THIS IS A PERIOD OF 5ms
  T1CC0H = 0x13;
  T1CTL = 0x08; //TIMER 1 prescaler to 32, dont set to modulo mode yet cuz that starts the timer!!
}

void restartTimer(){
 
  //from TI code (hal_timer_32k.c)
    T1CTL &=  ~0x02;    // Stop timer
    IEN1  &=  ~0x02;    // Disable interrupt

    T1CNTL =  0x00;     // Reset counter value

    T1CTL |=  0x02;     // Start timer
    IEN1  |=  0x02;     // Enable interrupt
}

void initDMA(){
// Set the DMA channel 0 configuration address registers
    DMA0CFGL = ((uint16)&dma_channel);
    DMA0CFGH = ((uint16)&dma_channel) >> 8;
   
    dma_channel.SRCADDRH  = (uint8)((uint16)(&X_ADCL) >> 8); //X_ADCH
    dma_channel.SRCADDRL  = (uint8)((uint16)(&X_ADCL));// & 0xFF); //X_ADCL
    dma_channel.DESTADDRH = (uint8)(((uint16)&adc_data) >> 8);
    dma_channel.DESTADDRL = (uint8)(((uint16)&adc_data) & 0xFF);
    dma_channel.VLEN      = 0x00;//DMA_VLEN_FIXED;
    dma_channel.LENH      = 0x00;
    dma_channel.LENL      = 0x06;                
    dma_channel.WORDSIZE  = 1;//DMA_WORDSIZE_WORD;
    dma_channel.TMODE     = 10;//DMA_TMODE_SINGLE REPEATED;
    dma_channel.TRIG      = 20;//DMA_TRIG_ADC_CH5 //using no trigger, just set dmareq.dmareq0
    dma_channel.SRCINC    = 1;//DMA_SRCINC_0; //not sure if i need to increment this...
    dma_channel.DESTINC   = 1;//DMA_DESTINC_1;
    dma_channel.IRQMASK   = 1;//DMA_IRQMASK_ENABLE;
   // dma_channel.M8        = 1;//DMA_M8_USE_7_BITS;
    dma_channel.PRIORITY  = 2;//DMA_PRI_HIGH;
   }

  • Figured it out. Just needed to change the dma settings so it doesn't increment the source address (dma_channel.SRCCINC = 0). Apparently, you don't increment even though you are reading multiple ADC channels.

  • Hi,Katie. I am trying to read 2 sensors values from the ADC directely ,which means not  using timer compare mode ,but with the DMA on a CC2530. I configure the ADC registers and DMA tree according your code ,however , the ADC values always appear to 00. What I am suer is that the ADC conversion completed and trigger the DMA because the DMAIRQ = 1. I wonder,could you send the project files to me for reffering ??  Email:  

    spishyshfut@sina.cn

    Thanks for any help.

  • Unfortunately, I don't have those project files anymore. The only thing I had different from the above code was changing dma_channel.SRCINC = 0 instead of 1. If I am understanding correctly, you will use almost the same settings for the dma, with changes for 2 sensors instead of the 6 I was using. The main difference will be your trigger for the ADC. So I set ADCCON1 = 0x23, to use a Timer 0 compare event, you will want to use either a external trigger or no triggers with the ADC at full speed.

    Hope that helps, sorry I don't have those files anymore. Good luck.