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.

battery voltage check with TPS62730

Other Parts Discussed in Thread: CC2540

hello everyone...

i am making cc2540 based device, for that i read swru 191 guide and also see example from keyfob demo,battservice.

but that did't me a help lot.

in my device battery Nominal Voltage is 3.7V  and The voltage present at the ADC port will be no more than one third (1/3) of the actual Li-ion cell voltage. Actual voltage measurement should be compared to digital reading to know the actual equivalence of analog reading and digital reading. ADC will be set to have reference voltage as internal which is set to a fixed value of 1.27V.A fully charged Li-ion will be higher than 3.7 V. We will set full charge as equivalent to 4.2 V.

i use P0_7 as my ADC port.

i don't know where and what to do changes in battservice.c and hal_adc.c file

thanks

  • Hello hirenkumar sakhiya,
    I guess you know, but the CC2540 does not support higher supply voltage than a maximum of 3.9 V (See CC2540 Data Sheet). If your battery will be higher than this at any moment you will need to use an external DCDC or LDO.

    You can look at the CC2541/43/44/45 Peripherals Software Examples as this can be easily ported to CC2540. Open the CC2540 user guide and look at "Table 7-1. Peripheral I/O Pin Mapping". There you can see which ADC inputs is mapped to which IOs. In the battservice.c the following call is made to do a ADC measruement od VDD:
    adc = HalAdcRead( battServiceAdcCh, HAL_ADC_RESOLUTION_10 );
    battServiceAdcCh is set to HAL_ADC_CHANNEL_VDD. Change this to HAL_ADC_CHN_AIN7. Look at the example code mentioned above to understand the rest.

  • thanks Eirik V for reply
    i use 3.7V li-ion battery.i also configured HAL_ADC_CHN_AIN7 for battServiceAdcCh.
    for 14-bit resolution and 512 decimation rate, i use 8192 as maximum value of ADC.

    // ADC voltage levels
    #define BATT_ADC_LEVEL_3V 8083 // for 3.7V 
    #define BATT_ADC_LEVEL_2V 6117 //for 2.8V


    i configured APCFG=0x80 for peripheral ADC input but it shows me wrong value.
    thanks

  • The internal reference voltage on CC2540 is 1.15 Volt (See CC2540 Data Sheet).
    Can you tell me which values you get vs. the actual input voltage on the P0.7 pin. I am interested in the following results from within the HalAdcRead function:
    /* Read the result */
    reading = (int16) (ADCL);
    reading |= (int16) (ADCH << 8);
  • i am getting 64 value in battery level from battrey service.
    i do not change anything into hal_adc.
    here is my change in battservice.c

    static uint8 battMeasure( void )
    {
    uint16 adc;
    uint8 percent;

    /**
    * Battery level conversion from ADC to a percentage:
    *
    * The maximum ADC value for the battery voltage level is 8192 for a
    * 14-bit conversion. The ADC value is references vs. 1.25v and
    * this maximum value corresponds to a voltage of 3.75v.
    *
    * For a coin cell battery 3.7v = 100%. The minimum operating
    * voltage of the CC2540 is 2.8v so 2.8v = 0%.
    *
    * To convert a voltage to an ADC value use:
    *
    * (v/3)/1.25 * 8192 = adc
    *
    * 3.7v = 8083 ADC
    * 2.8v = 6117 ADC
    *
    * We need to map ADC values from 8083-6117 to 100%-0%.
    *
    * Normalize the ADC values to zero:

    // Call measurement setup callback
    if (battServiceSetupCB != NULL)
    {
    battServiceSetupCB();
    }

    // Configure ADC and perform a read

    HalAdcSetReference( HAL_ADC_REF_125V );
    adc = HalAdcRead( battServiceAdcCh, HAL_ADC_RESOLUTION_14 ); //
    TURN_ON_BATTERY_SENSE(); //

    // Call measurement teardown callback
    if (battServiceTeardownCB != NULL)
    {
    battServiceTeardownCB();
    }

    if (adc >= battMaxLevel)
    {
    percent = 100;
    }
    else if (adc <= battMinLevel)
    {
    percent = 0;
    }
    else
    {
    if (battServiceCalcCB != NULL)
    {
    percent = battServiceCalcCB(adc);
    }
    else
    {
    uint16 range = battMaxLevel - battMinLevel + 1;

    // optional if you want to keep it even, otherwise just take floor of divide
    // range += (range & 1);
    range >>= 2; // divide by 4

    percent = (uint8) ((((adc - battMinLevel) * 25) + (range - 1)) / range);
    }
    }
    TURN_OFF_BATTERY_SENSE(); //
    return percent;

    }
    thanks..

  • hirenkumar sakhiya,

    The internal reference is 1.15 VOLT! Which means 3.7v/3 = 1.2333333 (over the reference).

    What do you mean by "i am getting 64 value in battery level from battery service."?

    If you input 3V/3, 2V/3 and 1V/3 to P0.7, which values to you read from the ADC in your code (I.E. return value from HalAdcRead)?

  • hello..eirik
    i use voltage divider network .
    "i am getting 64 value in battery level from battery service." mean i am seeing 64 hex value in ble device monitor.
    i did not understand "which values to you read from the ADC in your code (I.E. return value from HalAdcRead)?" or i don't have idea how to check uint16 reading value .
    can you please tell me how check this...?

    thanks..

  • Hello,
    0x64 in hex is 100 in decimal. That would be expected for any input level over 1.15 Volt. What is your input voltage level at this reading? Currently the range (3.45 - 3.7) V will give full scale results (8192 or close to it). To get a more suitable range you can change your voltage divider network to divide by 4 instead and then set up the following:

    (v/4)/1.15 * (2^13 - 1) = adc value
    3.7/4 V = 0.925 V = 6588.413
    2.8/4 V = 0.7 V -> 4985.8261

    static uint16 battMinLevel = 4986;

    static uint16 battMaxLevel = 6588;

    If you cannot change the voltage divider you must then either change the reference voltage or accept the limited range in your current setup. To read values directly from your firmware code go into debug mode, set a breakpoint of the HalAdcRead line and single step beyond this line while adding the return value variable to watch. Read more about debugging here:
    supp.iar.com/.../tutor_debugging.ENU.html

  • hello eirik.
    i use voltage divder network ...
    i am getting 1.4 V for 100% battery charge and 0.93 for 0% battery charge.

    so 1.4/3 = 0.46.

    i tried also for this but still facing same problem.

    thanks..

  • Hello,

    I tested this and it works here. I suspect you have not set up the IO configuration correctly. You need to set up the following after your IO configuration to make sure that P0.7 is high impedance (no pull up or down) and is set as input:

    P0DIR |= ~0x80;// Set P0.7 as input.
    
    P0INP |= 0x80;   // Set P0.7 to tri-state (high impedance).
    
    APCFG |= 0x80; // Enable analog function for P0.7.

    Also remember to chose resistors of appropriate values in your voltage divider to get good accuracy:

    e2e.ti.com/.../1185031

  • hello eirik.
    thanks for the reply..
    i already tried this pin configuration.
    i took battery service from keyfobdemo code. it uses VDD channel for measurement .i change it to channel 7 as mine.i use 14 bit resolution instead of 10 bit. i did not change anything in hal_adc file.
    i am going to check if any hardware problem.
    i do not want to share my diagram publically. so can we contact you privatley?
    thanks...
  • Did you check that P0DIR, P0INP and APCFG is set correctly during debugging?
    Do you measure the actual voltage supplied to the ADC input pin?