Correct procedure for entering WAITFOREVENT __WFE()

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
Tabulous
Posts: 518
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 18 times

Correct procedure for entering WAITFOREVENT __WFE()

Post by Tabulous »

Hi
i'm trying to enter WFE, and want to wake backup when EXTI pin is asserted.

all the EXTI are working when running normally so i know its nothing to do with them.

using F101 device.
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Correct procedure for entering WAITFOREVENT __WFE()

Post by Giovanni »

Hi,

The EXT driver should be able to handle this but I never tested the scenario, you need to enable an EXTI channel but the callback must be NULL, an event will be generated instead.

Giovanni
Tabulous
Posts: 518
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 18 times

Re: Correct procedure for entering WAITFOREVENT __WFE()

Post by Tabulous »

so this is what im doing, this is my test to enter WFE, which it does ok.

I have a break point after the last __WFE() on chSysUnlock(); When PA0/WAKEUP is stimulated, it wakes up, but it just jumps straight to hard fault!!!

Code: Select all

int main( void )
{
static int timeout = 10;

    /*
     * System initializations.
     * - HAL initialization, this also initializes the configured device drivers
     *   and performs the board-specific initializations.
     * - Kernel initialization, the main() function becomes a thread and the
     *   RTOS is active.
     */
    halInit();
    chSysInit();
    debugInit();

    bootMessage();

    extStart( &EXTD1, &extio1 );

    DBGMCU->CR |= DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP;

    while (true)
    {
        timeout--;

        TGL_DEBUG( DBG_MASK_APP,
                   "$ APP - Testing!\r\n" );

        if(timeout == 0)
        {
            timeout = 10;

            palClearPad( GPIOA, GPIOA_GSM_PWR );

            TGL_DEBUG( DBG_MASK_APP,
                       "$ APP - Entering Low Power State!\r\n" );

            chThdSleepMilliseconds( 5000 );

            /* clear PDDS and LPDS bits */
             PWR->CR &= ~(PWR_CR_PDDS | PWR_CR_LPDS);

             /* set LPDS and clear  */
             PWR->CR |= (PWR_CR_LPDS | PWR_CR_CSBF | PWR_CR_CWUF);

             /* Setup the deepsleep mask */
             SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

             chSysLock();
             __ISB();
             __SEV();
             __WFE();
             __WFE();
             chSysUnlock();

            /* clear the deep sleep mask */
            SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;

            /* reset the sytem to restart */
            __ASM volatile ("dsb");

            /* Keep priority group unchanged */
            SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |        \
                           (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |        \
                            SCB_AIRCR_SYSRESETREQ_Msk);

            __ASM volatile ("dsb");
        }

        chThdSleepMilliseconds( 1000 );

    }
}
Tabulous
Posts: 518
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 18 times

Re: Correct procedure for entering WAITFOREVENT __WFE()

Post by Tabulous »

Revised working code, needed to use port_disable not chsyslock.


Code: Select all

int main( void )
{
static int timeout = 10;

    /*
     * System initializations.
     * - HAL initialization, this also initializes the configured device drivers
     *   and performs the board-specific initializations.
     * - Kernel initialization, the main() function becomes a thread and the
     *   RTOS is active.
     */
    halInit();
    chSysInit();
    debugInit();

    bootMessage();

    extStart( &EXTD1, &extio1 );

    DBGMCU->CR |= DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP;

    while (true)
    {
        timeout--;

        TGL_DEBUG( DBG_MASK_APP,
                   "$ APP - Testing!\r\n" );

        if(timeout == 0)
        {
            timeout = 10;

            palClearPad( GPIOA, GPIOA_GSM_PWR );

            TGL_DEBUG( DBG_MASK_APP,
                       "$ APP - Entering Low Power State!\r\n" );

            chThdSleepMilliseconds( 5000 );

            /* clear PDDS and LPDS bits */
             PWR->CR &= ~(PWR_CR_PDDS | \
                          PWR_CR_LPDS);

             /* set LPDS and clear  */
             PWR->CR |= (PWR_CR_LPDS | \
                         PWR_CR_CSBF | \
                         PWR_CR_CWUF);

             /* Setup the deepsleep mask */
             SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

             port_disable();

             __WFE();

             port_enable();

            /* clear the deep sleep mask */
            SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;

            /* Keep priority group unchanged */
            SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |        \
                           (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |        \
                            SCB_AIRCR_SYSRESETREQ_Msk);
        }

        chThdSleepMilliseconds( 1000 );

    }
}
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Correct procedure for entering WAITFOREVENT __WFE()

Post by Giovanni »

Hi,

The equivalents would be chSysDisable() and chSysEnable().

Giovanni
Post Reply