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 - reading the ADC

Other Parts Discussed in Thread: CC2540

Hello,

I have trouble with reading an input on pin P0_6 and am wondering if someone sees something obvious that I am doing wrong.

I will paste the code snippets below. The reference voltage is on P0_7.

P0SEL = 0

P0DIR = 0;

APCFG = BIT7|BIT6|BIT2|BIT1|BIT0;

The above initialization is done once after reset.

Then, whenever in need to read the input, using channel number 6:

#define REF_VOLTAGE 1 // External on AIN7 pin
#define DECIMATION_RATE 3
ADCCON3 = (REF_VOLTAGE << 6) | (DECIMATION_RATE << 4) | 6;

// Wait for completion
while( !(ADCCON1 & BIT7) );

int16 adc_result;
adc_result = (ADCH << 8);
adc_result |= ADCL;

Is there anything wrong with the above sequence?

Thanks,
Marius Matioc 

  • Hello Marius,
    I would highly recommend that you simply follow the format that is used in all the BLE v1.3 examples and use the HAL/OSAL APIs.  The main reason is there are more people are doing it that way and that results in more people being able to assist you.
    Once you initialize the ADC
    // Initialize ADC
      HalAdcInit();
    Then all you do is call the function to set your reference voltage and read the appropriate ADC Port pin:

          uint16 adc6;

          HalAdcSetReference( HAL_ADC_REF_125V );
          adc6 =  HalAdcRead( HAL_ADC_CHN_AIN6, HAL_ADC_RESOLUTION_12 );
    You can find all the details about the HAL_ADC in the documents folder of the BLE v1.3.  If you want to dissect the HalAdcRead function, then by all means do so.  That way you will get a more clear understanding of how it works.  Otherwise, read the CC253x/CC254x User's Guide swru191c chapter 12, it details the correct way to configure the ADC.
    Thanks,
  • Thank you very much for the answer.

    I have now changed our code as per your recommendation.
    The value returned still does not seem right (it is always 1FFF). It could be a problem with our hardware, but I just want to make sure that I did everything right in the firmware.

    I did not call HalAdcInit() since it is called in HalDriverInit()

    In addition to what you mention, I did also set APCFG. I assume that is needed to program the ports correctly?
    Then I read the A/D like this:

    uint16 adcResult;
    HalAdcSetReference( HAL_ADC_REF_AIN7 );
    adcResult = HalAdcRead( channelNumber, HAL_ADC_RESOLUTION_14 );

    Anything else that needs to be done?

    Thanks,

    Marius

     

     

  • Glad to see you are getting with the program.  You do not need to set APCFG.  The port gets configured each time you call the routine.

    Try setting your reference to AVDD or _125 and make sure you are calling a single ended conversion.  You can also measure the VDD by using that as the channel number. The defines are in hal_adc.h

  • Thanks again.

    I tried HAL_ADC_REF_125V, but got the same result 1FFF.

    How does that work, is it a voltage that is always present?
    We are trying to measure P0_6 (channel 6) which is supposed to be the baterry voltage of our board.

    And, what is AVDD? Sorry to ask you such basic things...

    Thanks,

    Marius

     

  • Marius,

    STEP1: Use the Keyfob first.  Look at the batteryService.c profile to see how they are measuring the voltage.  The Keyfob has P_06 and P_07 available.  Test out your code on that before you attempt to do anything with a custom board.

    STEP 2: Read the sections of the HAL that deal with the ADC and the CC254x users guide that I mentioned in the first post that covers the ADC. AVDD is the analog voltage.  The person who designed the board would have to know that, unless of coarse it was left blank...

    It will save you a lot of waisted time.  You are playing with too many variables here.  If you can at least be sure your code works on a proven and working device like the Keyfob, then you will be able to determine if your new hardware is working correctly.

  • Hi greenja,

    I am having problem reading the ADC on my module. First of all my module is the Bluradios single mode module.I have tried with their stack but i go no result. I then tried the TI stack and used the same code that u have provided above. which is still not working. I first set a timer for 10sec and then read the ADC  input. What might be wrong with what am doing??

    HalAdcInit();
    uint16 value;

    HalAdcSetReference( HAL_ADC_REF_AVDD);
    value = HalAdcRead( HAL_ADC_CHANNEL_0, HAL_ADC_RESOLUTION_12 );
    AT_DBG("value = %d", value);

    thank you.

    Joseph

  • Hello Joseph,

    Unfortunately, I am not familiar with the BlueRadio modules.  I do not know which ADC port pins are used or are available on their board.

    If you haven't already tried running some of their sample code on the module, then I suggest you do so.  They should have an example that covers the ADC input for measuring the battery voltage.  They should also have either an iOS or PC GUI that allows you to see this reading.  If these are available, then you would be able to confirm that your module is working correctly.  From there you would then look in their example code for the battery service code.

    Look up the schematics for the module on their site to make sure and also see what ADC (Port 0) are available.

    Thanks,

  • Hi greenja,
    1. With respect to the ADC port pins they have a mapping in the documentation with that of cc2540. I have set everything right but i am getting nothing. Till now i have only been able to use the register to get the raw ADC data. So now i know that the module is working but the code is not. I have a lot of sample code form bluradios and TI.
    They don't really have any examples for reading the battery voltage and what not!! the IOS and PC GUI too don't know of anything like that. I used the code from the Hal_adc to read the ADCL and ADCH just to see the values and know if the module is working. If there are any more suggestion u can give it will be much appreciated.

    2. The next thing i want to do it is send the bogus ADC data to the dongle. Bluradios has data streaming profile called BRSP. My problem is i don't know how the data am seeing on the hyperterminal(ADC) can be sent to to the dongle when they are connected. I don't know if i shd just write it to the to comm the dongle is connected or not. Also if i want to use the TI way of sending the data from the hyperterminal am little bit confused on how the output can be fed in att and how it becomes a characteristic value to be sent.???

    3. The bluetooth Dongle from bluradios uses AT commands to communicate with the module. I planning on using PC utility on control the dongle programmatically using C#. Do u know any source codes for this or any examples that are available??

    Any input will much appreciate.

    thank you.
    Joseph.

  • Hi greenja,

    What is the difference if the ADC is initialized using the HalAdcInit() function and followed by the coresponding ( ,HalAdcSetReference,HalAdcRead)

    or it is done like:

    void main(void)
    {
       CLKCONCMD = (CLKCONCMD & ~(CLKCON_OSC | CLKCON_CLKSPD)) | CLKCON_CLKSPD_32M;
        while (CLKCONSTA & CLKCON_OSC);   //Wait until clock source has changed
     
        
        APCFG = APCFG_APCFG1 | APCFG_APCFG0;


        ADCCON2 = ADCCON2_SREF_AVDD | ADCCON2_SDIV_128 | ADCCON2_SCH_AIN1;

      
        ADCCON1 = (ADCCON1 & ~ADCCON1_STSEL) | ADCCON1_STSEL_FULL_SPEED;

        while( !(DMAIRQ & (DMAIRQ_DMAIF1 | DMAIRQ_DMAIF0)) );


        ADCCON1 |= ADCCON1_ST;
     

        adc_data[0] = (adc_data[0] >> 7) & 0x01FF;
        adc_data[1] = (adc_data[1] >> 7) & 0x01FF;

        while (1);
    }