Problems waking up from sleep with SysTick

Hello,

I had some problems choosing the right forum (I am not using the Arduino libraries but the Ambiq SDK alone).

Anyway, here is my problem:

I am trying to port my own RTOS (which already runs on some other M4F-based MCUs) to Apollo3.

As many other RTOSs, I am using the SysTick for Tick generation, and a idle-task, which is basically a

__WFE() loop.

Problem: The Apollo3 does not wake up from sleeping if SysTick interrupts are generated.

I boiled down the problem to the following source code:

#include "am_mcu_apollo.h"

void SysTick_Handler(void) {
    am_hal_gpio_state_write(13, AM_HAL_GPIO_OUTPUT_TOGGLE);
}

int main(void)
{
    const am_hal_gpio_pincfg_t config13 = {
        .uFuncSel       =       AM_HAL_PIN_13_GPIO,
        .eDriveStrength =       AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA,        
        .eGPOutcfg      =       AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL,
        .eGPInput       =       AM_HAL_GPIO_PIN_INPUT_NONE
    };

    const am_hal_gpio_pincfg_t config19 = {
        .uFuncSel       =       AM_HAL_PIN_19_GPIO,
        .eDriveStrength =       AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA,        
        .eGPOutcfg      =       AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL,
        .eGPInput       =       AM_HAL_GPIO_PIN_INPUT_NONE
    };

    am_hal_gpio_pinconfig(13, config13);
    am_hal_gpio_pinconfig(19, config19);

    SysTick_Config(SystemCoreClock / 5);

    while(1) {
        __WFE();
//        am_hal_gpio_state_write(19, AM_HAL_GPIO_OUTPUT_TOGGLE);
//        for (int i=0; i < 100000; ++i) ;
    }
}

When I have a active waiting loop (comment out WFE and commenting in the other two lines),

everything is working as expected. Two LEDs blinking…

When I use only __WFE in the waiting loop, the LED controlled by SysTick is not blinking any more.

The processor stays in sleep (or some other strange state I am not aware of) , although interrupts

(events) should be generated by SysTick. At least this is working without any problems on other M4F-based MCUs.

Yes, I know that there are various methods in the Ambiq SDK to control the memory power in sleep

states, cache control etc. etc., but up to now I had no success in making this simple setup work.

Another strange thing is, that if I attach a debugger (Ozone) to the not-working program via a Segger JLink,

the LED starts blinking. I suspect that the debug events make a change somehow. When I disconnect the

debugger, the LED stops blinking again.

I am using a Artemis Nano Board, btw.

So what is going wrong here? What do I have to do to wake up Apollo3 from sleep via SysTick interrupts?

Any help is welcome!

Andreas

Hello,

I made some further investigations and found this interesting article (already some years old…):

https://community.arm.com/developer/ip- … -processor

It seems that the M4F MCUs I have been using so far were all enabling the SysTick during (deep) sleep phases. I was not aware of the fact that this feature is something that the silicon vendor might design/modify.

I have made a request to the Ambiq team to verify my assumption (no SysTick counting during (deep) sleep, STCLK and HCLK both disabled). I will post the answer here as soon as I get one.

BR, Andreas

I can confirm that the Apollo3 systick timer does not run in deepsleep. If you read the SDK source file “am_hal_systick.c”, you will find this:

//*****************************************************************************
//
//! @brief Start the SYSTICK.
//!
//! This function starts the systick timer.
//!
//! @note This timer does not run in deep-sleep mode as it runs from the core
//! clock, which is gated in deep-sleep. If a timer is needed in deep-sleep use
//! one of the ctimers instead. Also to note is this timer will consume higher
//! power than the ctimers.
//!
//! @return None.
//

This is why the Ambiq port of FreeRTOS is configured to use a CTIMER instead of SYSTICK.