none
Wake up Windows CE from suspend

    Question

  • I'm developing Windows CE 6.0 on an embedded system (Friendly ARM 6410).  I want to go to the suspend mode and after pressing a push button it wakes up. I write a driver for EINT0 and define this IRQ as IOCTL_HAL_ENABLE_WAKE. The driver works fine. When I press a button an event triggered. But when I suspend, the driver and pressing push button doesn't work. I couldn't wake up windows CE from suspend. Why? What must I do more?
    Saturday, November 10, 2012 1:57 PM

All replies

  • So, your wakeup from suspend mode is not working but system suspend works fine.

    1. You should configure the register for wake up source, for the interrupt that you are using first . That is : Set wake-up enable capabilities for the (interrupt used for wakeup). Check your processor data sheet and then configure it in your BSP. I guess in the OEM this is not implemented for the interrupt that you are using hence "IOCTL_HAL_ENABLE_WAKE" is not effecting.

    2. when the processor receives this interrupt (wake up source) it shall perform wake up from suspend.

    --- Misbah



    Senior Design Engineer T.E.S Electroni Solutions (Bangalore-India) www.tes-dst.com email-misbah.khan@tes-dst.com


    • Edited by Misbah Khan Sunday, November 11, 2012 8:11 PM
    Sunday, November 11, 2012 6:18 PM
  • Hi Namnabat,

    I don't know when the follwoing IOCTL is caleld IOCTL_HAL_ENABLE_WAKE.

    But, while entering into suspend state only a small piece code will be executing the driver is not active.

    So, before entering into suspend configure the GPIO Pin for wakeup capability.

    Also configure the processor to receive this GPIO press as wakeup.

    Once the system comes out of suspend process the interrupt in your driver.

    Regards,

    GSR

    Monday, November 12, 2012 3:09 AM
  • I called this function in Init function of driver:

    similar code:

     if( !InterruptInitialize(gIntrEINT0, KEWEvent, NULL, 0) )
    {
    }

      if(!KernelIoControl( IOCTL_HAL_ENABLE_WAKE,
            &gIntrEINT0,
            sizeof( gIntrEINT0 ),
            NULL,
            0,
            NULL ))
        {
    }

    Monday, November 12, 2012 10:04 AM
  • So, your wakeup from suspend mode is not working but system suspend works fine.

    1. You should configure the register for wake up source, for the interrupt that you are using first . That is : Set wake-up enable capabilities for the (interrupt used for wakeup). Check your processor data sheet and then configure it in your BSP. I guess in the OEM this is not implemented for the interrupt that you are using hence "IOCTL_HAL_ENABLE_WAKE" is not effecting.

    2. when the processor receives this interrupt (wake up source) it shall perform wake up from suspend.

    --- Misbah



    Senior Design Engineer T.E.S Electroni Solutions (Bangalore-India) www.tes-dst.com email-misbah.khan@tes-dst.com


    Exactly,during suspend, KITL outputs are:

    [MFC IOCTL_POWER_SET] newdx = 4
    [TSP] ++DdsiTouchPanelPowerHandler(1)
    [TSP] ++TSP_PowerOff()
    [TSP] --TSP_PowerOff()
    [TSP] --DdsiTouchPanelPowerHandler()
    USERLED: LED_PowerDown
    KEW: KEW_PowerDown g_pSysConReg ->EINT_MASK:0
    [USBH] HcdPdd_PowerDown()

    [OEM] ++OEMPowerOff(

    1-There was an EINT_MASK register of the processor that mask external interrupts and disable them as wake-up source. But I clear this register. Maybe you're correct, In power control driver, I didn't see anything about sleep mode of the processor. If so what should I do to sleep and wake up the processor?

    Monday, November 12, 2012 10:38 AM
  • Here is code snippet i am sharing with you from"OEMPowerOff()" function implemented in the OAL layer.

    //----------------------------------------------
        // Enable wake sources interrupts
        for (sysIntr = SYSINTR_FIRMWARE; sysIntr < SYSINTR_MAXIMUM; sysIntr++)
            {
            // Skip if sysIntr isn't allowed as wake source
            if (!OALPowerWakeSource(sysIntr)) continue;

            // Enable it as interrupt
            OEMInterruptEnable(sysIntr, NULL, 0);
            OALMSG(1, (L"OALPowerWakeSource--> %d\r\n",sysIntr));

            }

        OALMSG(1, (L" %d Wakeup Source found %d\r\n",SYSINTR_MAXIMUM,sysIntr));

        // enter full retention
        PrcmSuspend();

        OALMSG(1, (L"+PrcmSuspend \r\n"));

        //----------------------------------------------
        // Find wakeup source
        for (sysIntr = SYSINTR_FIRMWARE; sysIntr < SYSINTR_MAXIMUM; sysIntr++)
            {
            // Skip if sysIntr isn't allowed as wake source
            if (!OALPowerWakeSource(sysIntr)) continue;

            // When this sysIntr is pending we find wake source
            if (OEMInterruptPending(sysIntr))
                {
                g_oalWakeSource = sysIntr;
                break;
                }
            }

            OALMSG(1, (L"+%d Wakeup done --> %d\r\n",SYSINTR_FIRMWARE, sysIntr));

    System suspends after calling " PrcmSuspend()" and resumes on receiving interrupt.

    Hence, sysintr of the interrupt that you are using should be configured for the wakeup, this is something you have to check and do.

    At the same time check your "OEMPowerOff()" function implementation see where it blocks when suspended.

    --- Misbah


    Senior Design Engineer T.E.S Electroni Solutions (Bangalore-India) www.tes-dst.com email-misbah.khan@tes-dst.com

    Monday, November 12, 2012 11:18 AM
  • Here is code snippet i am sharing with you from"OEMPowerOff()" function implemented in the OAL layer.

    //----------------------------------------------
        // Enable wake sources interrupts
        for (sysIntr = SYSINTR_FIRMWARE; sysIntr < SYSINTR_MAXIMUM; sysIntr++)
            {
            // Skip if sysIntr isn't allowed as wake source
            if (!OALPowerWakeSource(sysIntr)) continue;

            // Enable it as interrupt
            OEMInterruptEnable(sysIntr, NULL, 0);
            OALMSG(1, (L"OALPowerWakeSource--> %d\r\n",sysIntr));

            }

        OALMSG(1, (L" %d Wakeup Source found %d\r\n",SYSINTR_MAXIMUM,sysIntr));

        // enter full retention
        PrcmSuspend();

        OALMSG(1, (L"+PrcmSuspend \r\n"));

        //----------------------------------------------
        // Find wakeup source
        for (sysIntr = SYSINTR_FIRMWARE; sysIntr < SYSINTR_MAXIMUM; sysIntr++)
            {
            // Skip if sysIntr isn't allowed as wake source
            if (!OALPowerWakeSource(sysIntr)) continue;

            // When this sysIntr is pending we find wake source
            if (OEMInterruptPending(sysIntr))
                {
                g_oalWakeSource = sysIntr;
                break;
                }
            }

            OALMSG(1, (L"+%d Wakeup done --> %d\r\n",SYSINTR_FIRMWARE, sysIntr));

    System suspends after calling " PrcmSuspend()" and resumes on receiving interrupt.

    Hence, sysintr of the interrupt that you are using should be configured for the wakeup, this is something you have to check and do.

    At the same time check your "OEMPowerOff()" function implementation see where it blocks when suspended.

    --- Misbah


    Senior Design Engineer T.E.S Electroni Solutions (Bangalore-India) www.tes-dst.com email-misbah.khan@tes-dst.com

    You're right. The OEMPowerOff doesn't have above code. It simply mask all interrupts and only enable EINT11 (name it as power button) as wake up source. So IOCTL_HAL_ENABLE_WAKE not worked. But I'm really confused . Because  I change the OEMPowerOff to enable EINT0 ( my external interrupt) instead of EINT 11 as wake up source. But it doesn't still work and the processor not still wake up from suspend mode. The routines executed during suspend is written in assembly and I can not check it easily. That's strange. What must I do?

    Wednesday, November 14, 2012 5:38 AM
  • Extend your OEMPowerOff() function for Wakeup enable/disable as per the code i posted for you.

    This is the thing much needed.

    Let the EINT11 be there as wakeup source. You need to extend for your externel interrupt and others which your processor supports in "OALPowerWakeSource()"

    --- Misbah


    Senior Design Engineer T.E.S Electroni Solutions (Bangalore-India) www.tes-dst.com email-misbah.khan@tes-dst.com

    Wednesday, November 14, 2012 6:21 AM
  • Extend your OEMPowerOff() function for Wakeup enable/disable as per the code i posted for you.

    This is the thing much needed.

    Let the EINT11 be there as wakeup source. You need to extend for your externel interrupt and others which your processor supports in "OALPowerWakeSource()"

    --- Misbah


    Senior Design Engineer T.E.S Electroni Solutions (Bangalore-India) www.tes-dst.com email-misbah.khan@tes-dst.com

    I can not insert your code to my BSP. Because the OEMInterruptPending function wasn't implemented in my BSP.

    I connect a push button to EINT11. I'm sure I find correct OEMPowerOff function. I'm sure the interrupt EINT11 using inserted push button is generated when the system is not suspended.  I test the voltage of EINT11 during suspend, It's high and OK in suspend mode.

    Wednesday, November 14, 2012 11:00 AM
  • I disable below codes:

            ;bl        System_WaitForInterrupt
            ;b        .

    ;------------------------------------------------------------------------------
    ;    Now CPU is in Sleep Mode
    ;------------------------------------------------------------------------------

        ;---------------------------
        ;    Set WaitForInterrupt
        ;---------------------------
        LEAF_ENTRY System_WaitForInterrupt

            mov        r0, #0

            mcr        p15,0,r0,c7,c10,4        ; Data Synchronization Barrier (TRM said...)
            mcr        p15,0,r0,c7,c0,4        ; Wait For Interrupt

            mov        pc, lr

            ENTRY_END

    System went to suspend and the waked up from suspend mode Immediately.I know above codes wait for interrupts. Are these codes correct?

    What means above codes exactly?

    Sunday, November 18, 2012 7:15 AM
  • The System_WaitForInterrupt is called in OALCPUIdle() meaning when there is nothing to do he will enter a low power mode. And will wake up whenever an interrupt occurs.

    The 'MCR p15,0,<Rd>,c7,c0,4    ; Wait For Interrupt.' Is directly taken from the ARM manual so I 'assume' this is correct.

    (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0301h/Babhejba.html section: 3.2.22. c7, Cache operations “Wait For Interrupt operation”)

    My guess would be that you'll have to configure the wake-up source somewhere; otherwise it will never wake up…

    Check paragraph 10.2.2. Standby mode to investigate how this standby mode works...



    -- Good luck, Erwin Zwart, Check out my blog: http://GuruCE.com/blog GuruCE Microsoft Embedded Partner http://GuruCE.com Consultancy, training and development services.

    Sunday, November 18, 2012 12:15 PM
  • You need to configure the wakeup source. As explained in my earlier post.

    That's the solution to your problem.

    ---Misbah


    Senior Design Engineer T.E.S Electroni Solutions (Bangalore-India) www.tes-dst.com email-misbah.khan@tes-dst.com

    Sunday, November 18, 2012 4:36 PM