cancel
Showing results for 
Search instead for 
Did you mean: 

tickless idle on my STM32H7 HOW IT WORKS???

Patryk_Kucia
Associate III

Hi,

I'm trying to implement a simple tickless idle on my STM32H7 running on the CM7 core i use TIM1 for TimeBase.

I followed the example from this video:
https://www.youtube.com/watch?v=hVlpf1Rm4Qo

My question is how it works, because the default implementation in FreeRTOSConfig.h is:

Why is time to sleep set to __x__ = 0;  ???

#if configUSE_TICKLESS_IDLE == 1
#define configPRE_SLEEP_PROCESSING(__x__)                           \
                                       do {                         \
                                         __x__ = 0;                 \
                                         PreSleepProcessing(__x__); \
                                      }while(0)
#define configPOST_SLEEP_PROCESSING                       PostSleepProcessing

With this implementation and my PreSleepProcessing and PostSleepProcessing functions I use an LPTIM to wake up (similar to the video):

__weak void PreSleepProcessing(uint32_t ulExpectedIdleTime) {
    /* place for user code */
    HAL_GPIO_WritePin(LED_1_GPIO_Port, LED_1_Pin, GPIO_PIN_SET);
    //HAL_TIM_Base_Stop_IT(&htim1);
    HAL_SuspendTick(); // suspend SysTick timer
    HAL_LPTIM_TimeOut_Start_IT(&hlptim1, 0xFFFF, ulExpectedIdleTime); // enable interrupt from low-power timer
}

__weak void PostSleepProcessing(uint32_t ulExpectedIdleTime)
{
    /* place for user code */
    for (uint8_t i = 0; i < 8; i++) { // Check all NVIC pending registers (STM32 usually 0-2, loop to 8 is safer)
        if (NVIC->ISPR[i] != 0) {
            printf("WAKE SOURCE: Pending IRQ in NVIC->ISPR[%d]: 0x%08lX\r\n", i, NVIC->ISPR[i]);

            // Optionally: more detailed decoding of bits
            for (int bit = 0; bit < 32; bit++) {
                if ((NVIC->ISPR[i] >> bit) & 1) {
                    int irq_number = (i * 32) + bit;
                    printf(" -> Active interrupt #: %d\r\n", irq_number);
                }
            }
        }
    }
    actual_sleep_ticks = HAL_LPTIM_ReadCounter(&hlptim1);
    HAL_LPTIM_TimeOut_Stop_IT(&hlptim1);
    //HAL_TIM_Base_Start_IT(&htim1);
    HAL_ResumeTick();
    HAL_GPIO_WritePin(LED_1_GPIO_Port, LED_1_Pin, GPIO_PIN_RESET);
    printf("[CM7] PT: %lu t, ST: %lu t \r\n", ulExpectedIdleTime, actual_sleep_ticks);
}

 

With the configPRE_SLEEP_PROCESSING macro shown above I get waking every 10 ticks, why ? i tryed turing off everything and still get woken up

[CM7] PT: 500 t,ST: 0 t
[CM7] PT: 490 t,ST: 0 t
[CM7] PT: 480 t,ST: 0 t
[CM7] PT: 470 t,ST: 0 t
[CM7] PT: 460 t,ST: 0 t
[CM7] PT: 450 t,ST: 0 t
[CM7] PT: 440 t,ST: 0 t
[CM7] PT: 430 t,ST: 0 t
[CM7] PT: 420 t,ST: 0 t
[CM7] PT: 410 t,ST: 0 t
[CM7] PT: 400 t,ST: 0 t
[CM7] PT: 390 t,ST: 0 t
[CM7] PT: 380 t,ST: 0 t
[CM7] PT: 370 t,ST: 0 t
[CM7] PT: 360 t,ST: 0 t
[CM7] PT: 350 t,ST: 0 t
[CM7] PT: 340 t,ST: 0 t
[CM7] PT: 330 t,ST: 0 t
[CM7] PT: 320 t,ST: 0 t
[CM7] PT: 310 t,ST: 0 t

In the video FreeRTOSConfig.h they use:

#if configUSE_TICKLESS_IDLE == 1
#define configPRE_SLEEP_PROCESSING                        PreSleepProcessing
#define configPOST_SLEEP_PROCESSING                       PostSleepProcessing

After changing to that, my LPTIM starts to count but it counts multiple times — I thought it would count from 500 (500 from SysTick Overflow - i know) to zero and wake only once, but instead I see:

[CM7] PT: 500 t,ST: 510 t
[CM7] PT: 490 t,ST: 489 t
[CM7] PT: 486 t,ST: 485 t
...

What am I missing? Why does it wake repeatedly instead of sleeping once for the full requested interval?

Thanks.

0 REPLIES 0