CC3230SF: Interrupt mode for GPIO3 when the battery goes down to wake up the hibernate mode

Part Number: CC3230SF

Tool/software:

Dear,  and other experts

I have a question about making GPIO3 an interrupt or wake-up source. The product is tested in Hibernate using code from the platform.c file. This program tested working to successfully bring the MCU to hibernate mode. I have confirmed it because the current drop of about 25mA can be seen when the MCU changes mode from Active to hibernate.

I want to make the MCU wake up on an interrupt from hibernate mode to active mode when the battery level drops to below 20%. The battery level is measured via GPIO3 as the charger output is connected to GPIO3 after a voltage divider.


Thus, if referring to the datasheet and prcm.h file the GPIO3 is not available for an interrupt. So my question is, how do I make GPIO3 an interrupt? I made code for it and tested. Please see the images attached. The last image shows that GPIO3 is set as an interrupt, but it gets stuck there before going to the next loop.My code is below, and there's a mistake there.

My code is below and there's some mistake there. I'm humbly looking forward from the experts to help me identify this issues.

----------------------------------------------------------------------------------------------------------------------------------------------

(Main.c file)

float BatteryLevel(){

ADC_Handle adc;
ADC_Params params;
int_fast16_t res;
float Vin_battery, percentage;

uint32_t sum = 0;
int count = 0;
int i;

ADC_init();

ADC_Params_init(&params);

adc = ADC_open(CONFIG_ADC_0, &params);

if (adc == NULL)
{
return 0.0f;
}

for (i = 0; i < 100; i++) {
uint16_t adcValue0;
res = ADC_convert(adc, &adcValue0);
if (res == ADC_STATUS_SUCCESS) {
uint32_t adcValue0MicroVolt = ADC_convertRawToMicroVolts(adc, adcValue0);
sum += adcValue0MicroVolt;
count++;
}
}

if (count > 0) {
uint32_t average_adcValue0MicroVolt = sum / count;
Vin_battery = average_adcValue0MicroVolt / 1000000.0f;

Vin_battery_calibrated = Vin_battery - 0.047f;

percentage = ((Vin_battery_calibrated - 0.435f) / ( 0.609f - 0.435f)) * 100.0f;
if (percentage < 0.0f) percentage = 0.0f;
else if (percentage > 100.0f) percentage = 100.0f;

}

ADC_close(adc);

return percentage;

}

void interruptOn(){

#define GPIO_BASE 0x40024000
#define PRCM_HIB_GPIO3 (1 << 3)

// Set pin with internal pull-up
PinTypeGPIO(PIN_58, PIN_MODE_0, true); // true = pull-up enabled

// Set as input and falling edge trigger
GPIODirModeSet(GPIO_BASE, 1 << 3, GPIO_DIR_MODE_IN);
GPIOIntTypeSet(GPIO_BASE, 1 << 3, GPIO_FALLING_EDGE);
GPIOIntClear(GPIO_BASE, 1 << 3);
GPIOIntEnable(GPIO_BASE, 1 << 3);

// Allow GPIO3 to wake from hibernate
PRCMHibernateWakeupSourceEnable(PRCM_HIB_GPIO3);

}

void interruptOff() {
#define GPIO_BASE 0x40024000
GPIOIntDisable(GPIO_BASE, 1 << 3); // Disable interrupt on GPIO3
}

mainThread(){

if (battery_percentage < 20.0f) {
UART_PRINT("This is battery less than 20 percent...\n");
interruptOn();
setHibRetentionReg();
getHibRetentionReg();
}

UART_PRINT("This is battery more than 20 percent...\n");

scheduleShutdown(NULL);
powerShutdown(shutdownMs);

}

----------------------------------------------------------------------------------------------------------------------------------------------

(platform.c file)

#define SLOW_CLK_FREQ 32768

void powerShutdown(uint32_t shutdownTime)
{

Power_NotifyObj hibSignal;
uint32_t ticks = (shutdownTime * SLOW_CLK_FREQ)/1000;
UART_PRINT("Shutdown ticks = %lu\n", ticks);
PRCMHibernateIntervalSet(ticks);
PRCMHibernateWakeupSourceEnable(PRCM_HIB_SLOW_CLK_CTR);

UART_PRINT("Entering Hibernate for %lu ms...", shutdownTime);
Power_registerNotify(&hibSignal, PowerCC32XX_ENTERING_SHUTDOWN,
preHibConfig,
(uintptr_t)NULL);
int status = Power_shutdown(0, ticks);

if (status != Power_SOK) {
UART_PRINT("Hibernate FAILED! Power_shutdown returned: %d\n", status);
} else {
UART_PRINT("Hibernate requested (you should never see this line)\n");
}
}

----------------------------------------------------------------------------------------------------------------------------------------------

Best,

Aiman

  • Hi Aiman,

    According to TRM for CC323x are wake-up sources for hibernation following pins: GPIO2, GPIO4, GPIO13, GPIO17, GPIO11, GPIO24. Pin GPIO3 is not listed there. This likely mean you cannot use GPIO3 for this purpose.

    Jan

  • Hi ,

    I want to know if let say i changed to GPIO2, is the code above is correct to perform interrupt.

    Aiman

  • Hi Aiman,

    I am sorry, but I am not able debug your code. Please wait for answer from TI. But I can provide you few comments:

    • your code is weird. You are mixing power power management layer of TI drviers (PowerCC32XX.h) together with driverlib layer. Even though this approach may to work, it can introduce some side effect because this is not intended use of power management  layer.
    • do not define and use your own macros like yours macro PRCM_HIB_GPIO3. Use only defined PRCM_HIB_ macros in driver.
    • you missed to call function PRCMHibernateWakeUpGPIOSelect()
    • if I can recommend one thing. Do not mix multiple abstraction layer together. Use TI drviers or drvierlib but not both at same code, unless you exactly know what you are doing.

    Jan