Hello Daniel,
"...And based on my testing, SysTick is stopped in STOP2 and can't wake up...." , I have slightly different observation. Please find below code,
static void prvReadADC0DataTask( void *pvParameters )
{
uint16_t adcMax; // ADC resolution, used in user value calculation for now.
status_t retV = STATUS_SUCCESS; /* Variable used for status of changing mode */
/* Casting pvParameters to void because it is unused */
(void)pvParameters;
/* Infinite loop
* Wait for ADC conversion complete interrupt,
* then process and send the result to user.
*/
while(1)
{
char msg[255] = { 0 }; // Buffer to hold printable string
/*
* ADC0 is software triggered, hence configuring new channel to
* ADC0 will automatically trigger next conversion.
* As soon as next conversion is complete, it will get in to
* ADC0 ADC_IRQHandler funtion.
* Go to ADC0 ADC_IRQHandler function for more details.*/
/* And convert it to string */
print(headerStrPOT1);
floatToStr(&adcValuePOT1, msg, 5);
print(msg);
print(" V\r\n");
print(headerStrPOT2);
floatToStr(&adcValuePOT2, msg, 5);
print(msg);
print(" V\r\n");
print(headerStrOBPOT);
floatToStr(&adcValueOBPOT, msg, 5);
print(msg);
print(" V\r\n");
if((OBDThreshold >= adcValueOBPOT) && (true == isDataUpdatedFirst))
{
print((const char*)"**Critically low OBPOT value, it's below threshold level...\r\n");
xTimerStop(xADC0StartReadTimer,mainADC0_READ_TIMER_PERIOD_MS); // Stop Timer
vPortSuppressTicksAndSleep(1);
myStopSysTick();
adConv1_ConvConfig0.continuousConvEnable = true;
ADC_DRV_ConfigConverter(INST_ADC0, &adConv1_ConvConfig0);
ADC_DRV_ConfigHwCompare(INST_ADC0, &adConv1_HwCompConfig0); // Apply hardware compare limits
curADCChannel = adConv1_OB_POT_ChnConfig6.channel;
ADC_DRV_ConfigChan(INST_ADC0, 0UL, &adConv1_OB_POT_ChnConfig6);
print((const char*)"**Switching to STOP2 Power Mode\r\n");
/* Set power mode to STOP2 */
retV = POWER_SYS_SetMode(STOP2, POWER_MANAGER_POLICY_FORCIBLE);//POWER_MANAGER_POLICY_AGREEMENT);
if (retV == STATUS_SUCCESS)
{
//vPortSetupTimerInterrupt();
myStartSysTick();
adConv1_ConvConfig0.continuousConvEnable = false;
ADC_DRV_ConfigConverter(INST_ADC0, &adConv1_ConvConfig0);
adConv1_HwCompConfig0.compareEnable = false; // disable comparator
ADC_DRV_ConfigHwCompare(INST_ADC0, &adConv1_HwCompConfig0);
xTimerStart(xADC0StartReadTimer,mainADC0_READ_TIMER_PERIOD_MS); // reset timer to start from beginning
print((const char*)"Switched out of STOP2 mode successfully\r\n");
}
else
{
print((const char*)"Switched out of STOP2 mode unsuccessfully\r\n");
}
}
delayCycles(0x7FFFFF);
}
}
void myStopSysTick()
{
__asm volatile( "cpsid i" );
portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
__asm volatile( "cpsie i" );
}
void myStartSysTick()
{
/* Restart SysTick. */
__asm volatile( "cpsid i" );
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
__asm volatile( "cpsie i" );
}
Sequence is as below ,
1. prvReadADC0DataTask task prints values of 3 ADC0 channels having POT connected to them.
2. If value of OB POT goes below defined threshold, then systick will be stopped with
vPortSuppressTicksAndSleep(1);
myStopSysTick();
3. Configure OB POT ADC channel to trigger an interrupt when it's value goes above threshold. (HW compare enabled)
4. Move to STOP2 by calling POWER_SYS_SetMode. ---> Successful here
5. As OB POT adjusted to be above threshold, MCU comes in RUN mode.
6. Do mentioned stuff on successful exit of STOP2. ex. start ADC channel read timer, start myStartSysTick
7. Go to step 2.
Observation :
MCU does not move to stay in STOP2 second time onwards. I am wondering, why does it work with stopping SysTick in first attempt and does not work second time onwards.
This is little bit confusing for me.
Regards,
Akshay K.