Other Parts Discussed in Thread: SYSCONFIG, CC2640
My customer found that CC2340 current consumption is unexpectedly high after ADC_close. The issue can be reproduced with CC2340R5 LaunchPad and latest SDK8.10, using following steps:
1. Modify adcsinglechannel example from simplelink_lowpower_f3_sdk_8_10_00_55 to call ADC_open, ADC_convert and ADC_close every 4 seconds.
2. Disable the Display driver to make sure the device goes to sleep between every ADC sampling.
3. Connect the ADC pin to an AAA battery(input voltage 1.5V - 1.7V).
4. The average current consumption would be >100uA when input voltage is around 1.5V, but if input voltage is 0 or 3.3V, the average current is <10uA.
Looks the input voltage level has an impact of the current consumption, does the ADC driver not set the GPIO properly?
Please find the modified adcsinglechannel.c and syscfg file as below to reproduce this issue:
/* * Copyright (c) 2016-2022, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * ======== adcsinglechannel.c ======== */ #include <unistd.h> #include <stdint.h> #include <stddef.h> /* POSIX Header files */ #include <pthread.h> /* Driver Header files */ #include <ti/drivers/ADC.h> #include <ti/drivers/GPIO.h> // #include <ti/display/Display.h> /* Driver configuration */ #include "ti_drivers_config.h" /* ADC sample count */ #define ADC_SAMPLE_COUNT (10) #define THREADSTACKSIZE (768) /* Inputs to the ADC on the CC32XX launchpads are downscaled by a factor of 0.42 * Multiplying the conversion output with 2.365 will provide compensated output. */ #if DeviceFamily_PARENT == DeviceFamily_PARENT_CC32XX #define COMPENSATION_FACTOR 2365 #else #define COMPENSATION_FACTOR 1000 #endif /* ADC conversion result variables */ //uint16_t adcValue0; //uint32_t adcValue0MicroVolt; uint16_t adcValue1[ADC_SAMPLE_COUNT]; uint32_t adcValue1MicroVolt[ADC_SAMPLE_COUNT]; // static Display_Handle display; /* * ======== threadFxn0 ======== * Open an ADC instance and get a sampling result from a one-shot conversion. */ //void *threadFxn0(void *arg0) //{ // ADC_Handle adc; // ADC_Params params; // int_fast16_t res; // // ADC_Params_init(¶ms); // adc = ADC_open(CONFIG_ADC_0, ¶ms); // // if (adc == NULL) // { // // Display_printf(display, 0, 0, "Error initializing CONFIG_ADC_0\n"); // while (1) {} // } // // /* Blocking mode conversion */ // res = ADC_convert(adc, &adcValue0); // // if (res == ADC_STATUS_SUCCESS) // { // // adcValue0MicroVolt = (COMPENSATION_FACTOR * ADC_convertRawToMicroVolts(adc, adcValue0)) / 1000; // // // Display_printf(display, 0, 0, "CONFIG_ADC_0 raw result: %d\n", adcValue0); // // Display_printf(display, 0, 0, "CONFIG_ADC_0 convert result: %d uV\n", adcValue0MicroVolt); // } // else // { // // Display_printf(display, 0, 0, "CONFIG_ADC_0 convert failed\n"); // } // // ADC_close(adc); // // return (NULL); //} void doAdc() { uint16_t i; ADC_Handle adc; ADC_Params params; int_fast16_t res; ADC_Params_init(¶ms); adc = ADC_open(CONFIG_ADC_1, ¶ms); if (adc == NULL) { // Display_printf(display, 0, 0, "Error initializing CONFIG_ADC_1\n"); while (1) {} } for (i = 0; i < ADC_SAMPLE_COUNT; i++) { res = ADC_convert(adc, &adcValue1[i]); if (res == ADC_STATUS_SUCCESS) { adcValue1MicroVolt[i] = (COMPENSATION_FACTOR * (ADC_convertToMicroVolts(adc, adcValue1[i]))) / 1000; // Display_printf(display, 0, 0, "CONFIG_ADC_1 raw result (%d): %d\n", i, adcValue1[i]); // Display_printf(display, 0, 0, "CONFIG_ADC_1 convert result (%d): %d uV\n", i, adcValue1MicroVolt[i]); } else { // Display_printf(display, 0, 0, "CONFIG_ADC_1 convert failed (%d)\n", i); } } //GPIO_setConfig(CONFIG_GPIO_ADC_1_AIN, GPIO_CFG_INPUT); GPIO_setConfigAndMux(CONFIG_GPIO_ADC_1_AIN, GPIO_CFG_INPUT, GPIO_MUX_GPIO); ADC_close(adc); } /* * ======== threadFxn1 ======== * Open a ADC handle and get an array of sampling results after * calling several conversions. */ void *threadFxn1(void *arg0) { while(1) { doAdc(); sleep(4); } return (NULL); } /* * ======== mainThread ======== */ void *mainThread(void *arg0) { pthread_t thread0, thread1; pthread_attr_t attrs; struct sched_param priParam; int retc; int detachState; /* Call driver init functions */ ADC_init(); // Display_init(); /* Open the display for output */ // display = Display_open(Display_Type_UART, NULL); // if (display == NULL) // { // /* Failed to open display driver */ // while (1) {} // } // Display_printf(display, 0, 0, "Starting the acdsinglechannel example\n"); /* Create application threads */ pthread_attr_init(&attrs); detachState = PTHREAD_CREATE_DETACHED; /* Set priority and stack size attributes */ retc = pthread_attr_setdetachstate(&attrs, detachState); if (retc != 0) { /* pthread_attr_setdetachstate() failed */ while (1) {} } retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE); if (retc != 0) { /* pthread_attr_setstacksize() failed */ while (1) {} } /* Create threadFxn0 thread */ priParam.sched_priority = 1; pthread_attr_setschedparam(&attrs, &priParam); // retc = pthread_create(&thread0, &attrs, threadFxn0, NULL); // if (retc != 0) // { // /* pthread_create() failed */ // while (1) {} // } /* Create threadFxn1 thread */ retc = pthread_create(&thread1, &attrs, threadFxn1, (void *)0); if (retc != 0) { /* pthread_create() failed */ while (1) {} } return (NULL); }
Best regards,
Shuyang