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.

CC1110/CC1111 ADC Data contains the ADC number?

I am developing code to read 6 ADC inputs and put them in MDA memory, in time of occurrence order. That appears to be working fine. But, in post processing the memory data, I need to know which ADC each value was read from. I thought I had read somewhere that the least significant data bits were the number of the ADC source. Can anyone confirm that or is there an option to make that ADC number appear in those otherwise unused bits?

Thanks,

LDT

 

  • Hi

    This is not correct.

    BR

    Siri

  • I discovered where I had seen the LSb as the ADC number. It was in an example that OR'ed in the ADC number to the LSb, in a "extra conversion". So still do not have an answer to the original question of knowing which ADC produced the data in the DMA. The only way appears to use a different DMA channel for each ADC. But, I need 6 ADC and there are only 5 DMA channels. ????

    LDT

  • Hi

    I have written some code that I hope will help you. The example code uses one DMA channel to read 6 ADC channels. I used the ADC code example found in here: http://www.ti.com/lit/zip/swrc117

    and modified it with the following code:

    static __xdata DMA_DESC dma_channel;

    // ADC result table

    static __xdata uint16 adc_data[6];

    void main(void) {

      // Set system clock source to HS XOSC, with no pre-scaling

      SLEEP &= ~SLEEP_OSC_PD;

      while( !(SLEEP & SLEEP_XOSC_S) );

      CLKCON = (CLKCON & ~(CLKCON_CLKSPD | CLKCON_OSC)) | CLKSPD_DIV_1;

      while (CLKCON & CLKCON_OSC);

      SLEEP |= SLEEP_OSC_PD;

      // I/O-Port configuration:

      // P0_0 - P0_5 are configured as ADC input pin

      ADCCFG = 0x3F;

      // STSEL = 11 => Start a conversion when ST = 1

      ADCCON1 = 0x33;

      // SREF = VDD

      // SDIV = 12 bits resolution

      // SCH = AIN5

      ADCCON2 = 0xB5;

      // Set the DMA channel 0 configuration address registers

      DMA0CFGL = ((uint16)&dma_channel);

      DMA0CFGH = ((uint16)&dma_channel) >> 8;

      dma_channel.SRCADDRH = (uint16)(&X_ADCL) >> 8;

      dma_channel.SRCADDRL = (uint16)(&X_ADCL);

      dma_channel.DESTADDRH = ((uint16)adc_data) >> 8;

      dma_channel.DESTADDRL = ((uint16)adc_data);

      dma_channel.VLEN = DMA_VLEN_FIXED;

      dma_channel.LENH = 0;

      dma_channel.LENL = 6;               

      dma_channel.WORDSIZE = DMA_WORDSIZE_WORD;

      dma_channel.TMODE = DMA_TMODE_SINGLE;

      dma_channel.TRIG = DMA_TRIG_ADC_CHALL;                 

      dma_channel.SRCINC = DMA_SRCINC_0;

      dma_channel.DESTINC = DMA_DESTINC_1;

      dma_channel.IRQMASK = DMA_IRQMASK_DISABLE;

      dma_channel.M8 = DMA_M8_USE_7_BITS;

      dma_channel.PRIORITY = DMA_PRI_HIGH;

      while (TRUE) {

        // Arm DMA channel 0

        DMAARM = 0x01;

        // Start a conversion (ST = 1)

        ADCCON1 |= 0x40;

        // Wait for convertion to complete

        while(DMAIRQ != 0x01);

        DMAIRQ = 0x00;

      }

    }

     

    BR

    Siri

  • Thanks Siri. I have your code working and I do get all 6 ADC values thru the 1 DMA and see each ADC in a different element of the destination.

    One problem (or maybe two), I think it has to do with how the ADC bits are loaded into the destination, but I can not get / understand the correct format from the data sheet. It appears that the least significant 4 bits are invalid and I tried shifting them out. But, I still get random results from the VDD reference. If I change the reference to 1.25-volts I get a consistent value from the pull-up ADC inputs but random data from lower voltages. I also need to use 7-bits resolution to speed up the process.

    Can you educate me on how to get the correct bits from the destination with a 7-bit resolution and different references? That may also help with the random results from the VDD reference at any resolution. It appears I need to shift by 5 to get to the full ref reading of 2047.??? But then I still get the random values with lower than Ref voltage.

    Is it possible I need to stop ADC and or DMA activity when I look at the destination in debug? 

    Thanks again, this is the most progress I have made on this topic.

    LDT

  • Hi

     

    Please see the 4 different code examples shown below: They show how the conversion should be done for different resolutions and different reference voltages. In the examples I only read AIN0.

     

    uint8 adcl, adch;

    int16 adc;

    float voltage;

     

    // Example 1:

     

    // STSEL = 11 => Start a conversion when ST = 1
    ADCCON1 = 0x33;
       
    // SREF = VDD (3.3 V)
    // SDIV = 12 bits resolution
    // SCH = AIN0

    ADCCON2 = 0xB0;
      
    // Start a conversion (ST = 1)
    ADCCON1 |= 0x40;
    while (!(ADCCON1 & 0x80));
    adcl = ADCL;
    adch = ADCH;
    adc = ((int16)(adch << 8) | ((int16)adcl)); // adc[15:0] = adc[11]:adc[10]:adc[9]...adc[0]:x:x:x:x
    adc = (int16)adc/16; // The adc value needs to be shifted 4 bits to the left (divide on 2^4)
    voltage = (float)(adc*(3.3/2047)); // The adc value must be multiplied with

                                       // Vref/(2^(resolution-1)-1) = 3.3/(2^(12-1)-1) = 3.3/2047
     

    // Example 2:


    // STSEL = 11 => Start a conversion when ST = 1

    ADCCON1 = 0x33;
       
    // SREF = 1.25 V
    // SDIV = 12 bits resolution

    // SCH = AIN0
    ADCCON2 = 0x30;
      
    // Start a conversion (ST = 1)
    ADCCON1 |= 0x40;
    while (!(ADCCON1 & 0x80));
    adcl = ADCL;
    adch = ADCH;
    adc = ((int16)(adch << 8) | ((int16)adcl)); // adc[11]:adc[10]:adc[9]...adc[0]:x:x:x:x
    adc = (int16)adc/16; // The adc value needs to be shifted 4 bits to the left (divide on 2^4)
    voltage = (float)(adc*(1.25/2047)); // The adc value must be multiplied with

                                        // Vref/(2^(resolution-1)-1) = 1.25/(2^(12-1)-1) = 1.25/2047

     

    // Example 3:

     

    // STSEL = 11 => Start a conversion when ST = 1
    ADCCON1 = 0x33;
       
    // SREF = VDD (3.3 V)
    // SDIV = 7 bits resolution
    // SCH = AIN0

    ADCCON2 = 0x80;
      
    // Start a conversion (ST = 1)
    ADCCON1 |= 0x40;
    while (!(ADCCON1 & 0x80));
    adcl = ADCL;
    adch = ADCH;
    adc = ((int16)(adch << 8) | ((int16)adcl)); // adc[11]:adc[10]:adc[9]...adc[5]:x:x:x:x:x:x:x:x:x

                                                // (The conversion result always resides in MSB

                                                // section of ADCH:ADCL)
    adc = (int16)adc/512; // The adc value needs to be shifted 9 bits to the left (divide on 2^9)
    voltage = (float)(adc*(3.3/63)); // The adc value must be multiplied with

                                     // Vref/(2^(resolution-1)-1) = 3.3/(2^(7-1)-1) = 3.3/63

     

    // Example 4:
       

    // STSEL = 11 => Start a conversion when ST = 1
    ADCCON1 = 0x33;
       
    // SREF = VDD (1.25 V)
    // SDIV = 7 bits resolution
    // SCH = AIN0

    ADCCON2 = 0x00;
      
    // Start a conversion (ST = 1)
    ADCCON1 |= 0x40;
    while (!(ADCCON1 & 0x80));
    adcl = ADCL;
    adch = ADCH;
    adc = ((int16)(adch << 8) | ((int16)adcl)); // adc[11]:adc[10]:adc[9]...adc[5]:x:x:x:x:x:x:x:x:x                     

                                                // (The conversion result always resides in MSB

                                                // section of ADCH:ADCL)
    adc = (int16)adc/512; // The adc value needs to be shifted 9 bits to the left (divide on 2^9)
    voltage = (float)(adc*(1.25/63)); // The adc value must be multiplied with

                                      // Vref/(2^(resolution-1)-1) = 1.25/(2^(7-1)-1) = 1.25/63

     

    BR

    Siri

  • Siri, I see that you posted an empty reply to my questions above. Did something get deleted?

    Also, I had to abanden this for a while and go back to only 5 ADC's with 5 DMA's, in order to get something shipped. I am now back to this.

    My new question - Since I am using the CC1111 there are only 6 ADC's. Given that limitation does the multiple method of reading the ADC not complete for the 6th ADC? Do I need to go to the CC1110 with 8 ADC's?

  • Siri, I see an empty posting from you after the question above. Did something get deleted?

    I had to go back to the 5 ADC read into 5 DMA to get something shipped, But I am now back to this method, since I need all 6 ADC read.

    I am not getting consistent ADC readings for all 6 ADC's. I think it may because I am using the CC1111 that has only 6 ADC's and the read of 0 thru 5 is not including the sixth sequential ADC read due to the missing 7th ADC #6. If this is the problem with the CC1111 can the CC1110 do all six ADC is sequence? Or is there a work-around?

    (This is the second try at this posting. My apologies if it shows up twice.)

  • Hi
    Something went wrong so I posted a reply before I have started to write it, so nothing is missing :-)
    There should not be any difference between the CC1110 and the CC1111 as long as you are only using 6 channels (A0 - A5).
    Can you explain some more what you mean by not getting consistent readings? Also make sure that nothing else is connected to the pins you are using as inputs. When I did the testing on our SmartRF04EB + CC1110EM I was reading the pot meter on one of the inputs.
    I am working from home today and do not have any HW to test on, but please explain some more how you are testing (what HW etc.) and what your results are and I can see if I can reproduce it.
    Are you doing tests with both the CC1110 and the CC1111? In that case, how does the result differs?
    BR
    Siri


  • I'm not sure why but I do not see the posting I sent or the reply I just received.  I did get them by email but not on the board. Is there a number of postings limit or days of delay????

    How do I reply now? Do I just reply to the old message like this????

  • Hmm, that is strange. I can see all the posts OK :-)

    Siri

  • I am still not able to see the follow up posting on this topic but still need to get more insight.

    I can get the basic function of reading all 6 ADC's with one DMA as long as I use 12-bits. Problem is I need much faster read of all 6 ADC's that I can get with 12-bit reads. With 7-bit reads I can get the timing I need but get random values with 7-bit reads. I suspect I am not reading the DMA data correctly. Please let me know how the data is formatted in the DMA words. Or is there some issue with 7-bit ADC in the CC111x devices, particularly when read through DMA.

    LDT

  • Hi
    Have you tested the code I posted the 13th of December where I show how to do the conversion for all different resolutions? Are you getting different results for the 12 bit resolution compared to 7 bit? I think it is important to first verify that you can read and convert all of your inputs correctly before involving the DMA.
    When it comes to having problems viewing the post I just experienced the same thing when using IE: When using Firefox, I was able to see them all :-)
    BR
    Siri


  • Yes, I have the 12-bit resolution working in my code. I get expected results with 12-bit. The problem comes with 7-bit (which I need for speed). At first I thought it was just the data was going into the DMA in different sequence or starting at a different ADC each time but with the ADC all pulled-up, I still get random low readings. I have not tried modifying your code (outside my code) to see if 7-bits works the same there as well. From time to time, I have had to abandon this effort due to other priorities but still need this function to meet a time limit goal for this application.

    Also, thanks for the Firefox suggestion. I now can see all the postings.

    LDT

  • Forgot to say - I suspect the formatting of the data in the DMA using the 7-bit resolution. I am not sure where the good data bits are withing the DMA words. With other resolutions some of the second byte is needed for the bits (more than 8) and it appears they are in the most-significant bits. But I can not tell if this is true for 7-bit resolution. Any clarification?

    LDT

  • Hi

    I have now combined the two code snippets I have given you before, and I am now reading ADC channels 0 - 5 using DMA, I use 7 bits resolution and I convert the results. The code only convert the channel 0 result as this is the only one I can adjust easily on my HW (pot meter) for testing.

    The DMA puts ADCH in the 8 LSB of adc_data and ADCL in the MSB of adc_data

    Here is the code:

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

    void main(void) {
     
      // Set system clock source to HS XOSC, with no pre-scaling. Ref. [clk]=>[clk_xosc.c]
      SLEEP &= ~SLEEP_OSC_PD;
      while( !(SLEEP & SLEEP_XOSC_S) );
      CLKCON = (CLKCON & ~(CLKCON_CLKSPD | CLKCON_OSC)) | CLKSPD_DIV_1;
      while (CLKCON & CLKCON_OSC);
      SLEEP |= SLEEP_OSC_PD;
     
      // I/O-Port configuration :
      // P0_0 - P0_5 are configured as ADC input pin
      ADCCFG = 0x3F;
     
      // STSEL = 11 => Start a conversion when ST = 1
      ADCCON1 = 0x33;
     
      // SREF = VDD
      // SDIV = 7 bits resolution
      // SCH = AIN5
      ADCCON2 = 0x85;
     
      // Set the DMA channel 0 configuration address registers
      DMA0CFGL = ((uint16)&dma_channel);
      DMA0CFGH = ((uint16)&dma_channel) >> 8;
     
      dma_channel.SRCADDRH  = (uint16)(&X_ADCL) >> 8;
      dma_channel.SRCADDRL  = (uint16)(&X_ADCL);
      dma_channel.DESTADDRH = ((uint16)adc_data) >> 8;
      dma_channel.DESTADDRL = ((uint16)adc_data);
      dma_channel.VLEN      = DMA_VLEN_FIXED;
      dma_channel.LENH      = 0;
      dma_channel.LENL      = 6;                
      dma_channel.WORDSIZE  = DMA_WORDSIZE_WORD;
      dma_channel.TMODE     = DMA_TMODE_SINGLE;
      dma_channel.TRIG      = DMA_TRIG_ADC_CHALL;
      dma_channel.SRCINC    = DMA_SRCINC_0;
      dma_channel.DESTINC   = DMA_DESTINC_1;
      dma_channel.IRQMASK   = DMA_IRQMASK_DISABLE;
      dma_channel.M8        = DMA_M8_USE_7_BITS;
      dma_channel.PRIORITY  = DMA_PRI_HIGH;
     
      while (TRUE) {
        
        // Arm DMA channel 0
        DMAARM = 0x01;

        // Start a conversion (ST = 1)
        ADCCON1 |= 0x40;

        // Wait for convertion to complete
        while(DMAIRQ != 0x01);

        DMAIRQ = 0x00;
        
        adch = (uint8) (adc_data[0] & 0x00FF);
        adcl = (uint8) ((adc_data[0] & 0xFF00) >> 8);
        adc = ((int16)(adch << 8) | ((int16)adcl));
        adc = (int16)adc/512;
        voltage = (float)(adc*(3.3/63));
      }
    }

    BR

    Siri

  • Hello guys,

    Is there a possibility that we use 8 analog inputs to be held  in 4 DMA channels, If so can you give an example?

    Thank you in advance

  • Or if you use the 8 inputs in 2 channels for example can it be done like this:

        // Configure DMA channel 0.
        dma_channel_init(&dma_channel[0], &adc_data[0], 8, DMA_TRIG_ADC_CH0);

        dma_channel_init(&dma_channel[0], &adc_data[1], 8, DMA_TRIG_ADC_CH1);

        dma_channel_init(&dma_channel[0], &adc_data[2], 8, DMA_TRIG_ADC_CH2);

        dma_channel_init(&dma_channel[0], &adc_data[3], 8, DMA_TRIG_ADC_CH3);


        // Configure DMA channel 1.
        dma_channel_init(&dma_channel[1], &adc_data[4], 8, DMA_TRIG_ADC_CH4);

        dma_channel_init(&dma_channel[1], &adc_data[5], 8, DMA_TRIG_ADC_CH5);

        dma_channel_init(&dma_channel[1], &adc_data[6], 8, DMA_TRIG_ADC_CH6);

        dma_channel_init(&dma_channel[1], &adc_data[7], 8, DMA_TRIG_ADC_CH7);