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.

CC2530: Using an ADC conversion sequence with Zstack

Part Number: CC2530
Other Parts Discussed in Thread: Z-STACK

I have a question regarding the adc functionality of the CC2530.

I have a firmware with zstack 3.0.1 and I need to trigger an adc conversion sequence using Timer 1 and transfer the result via dma (so i am not using the interface defined in hal_adc.h). I noticed that zstack also uses the adc to check the power supply voltage everytime it needs to write an item to non volatile memory. Does anybody know if I can have both an extra conversion (the zstack one) and a sequence triggered by Timer 1?

I noticed some strange behaviour where my conversion sequence at times gets wrong values that seem exactly the VCC value. Do I need to add some form of synchronization to access the adc registers in a safe manner?

  • You will need to change the ADC channel to start. Please refer to HalAdcCheckVddRaw along with the CC2530 Software Examples: www.ti.com/.../swrc135

    Regards,
    Ryan
  • Hi Ryan,

    yes i am using adc channels 0 and 1 for a conversion sequence triggered periodically by Timer1 using dma to transfer the data to memory. The point that i am trying to understand is if the extra sequence made by zstack (function HalAdcCheckVddRaw as you wrote) can be safely executed while my periodic conversion is running. I ask you this because I randomly noticed incorrect values when i get the result values of the adc sequence; they seem exactly equal to the value that the conversion made by HalAdcCheckVddRaw should return (3.3v). I think that there may be a data race when accessing the adc registers ADCH and ADCL that causes this behavior. Does anyone know if these two kind of adc uses can coexist at the same time (both extra conversion and conversion sequence)?

  • Hey Daniele,

    HalAdcCheckVddRaw is only called by OnBoard_CheckVoltage which is used in the ZDO_VOLTAGE_CHECK event of ZDApp.c and for osal_nv_item_init/osal_nv_write, so there is a possible race condition involved with initializing/writing NV items. You can stop the ADC, perform the voltage check, and re-initialize the ADC during each NV action or disable OSAL_NV_CHECK_BUS_VOLTAGE.

    Regards,
    Ryan
  • Hi Ryan,

    how would you proceed about stopping the adc? I already tried modifying the function like this:

    bool HalAdcCheckVdd(uint8 vdd)
    {
    bool res = FALSE;

    halIntState_t his;
    HAL_ENTER_CRITICAL_SECTION(his);

    // Disable trigger on timer
    ADCCON1 = 0x33;

    // Wait until no conv is in progress
    while (ADCCON1 & HAL_ADC_START);
    ADCH; // Make sure eoc returned low
    while (ADCCON1 & HAL_ADC_EOC);

    ADCCON3 = 0x0F;
    while (!(ADCCON1 & 0x80));
    res = (ADCH > vdd);

    HAL_EXIT_CRITICAL_SECTION(his);

    // Enable trigger on timer
    ADCCON1 = 0x23;

    return res;
    }

    but i still randomly receive incorrect values, does it seem correct to you?

    I am not sure about disabling OSAL_NV_CHECK_BUS_VOLTAGE, isn't it a bit risky?

    Regards,

    Daniele

  • First, I would recommend using Z-Stack 3.0.2 which includes improved OSAL_NV_CHECK_BUS_VOLTAGE logic. Second, I advise bit clear (&=)
    and bit set (|=) instead of strait setting (=) register values (ADCCON1) if you do not know the previous status of the register. You can review the User's Guide for more information on ADC operation and expected register values.

    Disabling OSAL_NV_CHECK_BUS_VOLTAGE is risky if you plan on operating at VCC_MIN (2 V) or power-cycling frequently with slow ramps.

    Regards,
    Ryan