| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- #include "stm32l1xx_hal.h"
- #include "stm32l1xx_hal_pwr.h"
- #include "stm32l1xx_hal_pwr_ex.h"
- #include "stm32l1xx_hal_pcd.h"
- #include "core/gpio.h"
- #include "core/main.h"
- #include "core/sleep_and_exti.h"
- #include "core/csect.h"
- #include <intrinsics.h>
- #include "core/config.h"
- #include "core/config_pins.h"
- // USB_VBUS_WKPIN
- // Specifies the special wake up pin (WKUP1..WKUP3) for waking up from USB_VBUS signal
- // Possible values: PWR_WAKEUP_PIN1, PWR_WAKEUP_PIN2, PWR_WAKEUP_PIN3, or undefined
- #define USB_VBUS_WKPIN (CONFIG_PIN__USB__VBUSWKUP)
- // USB_VBUS_LINE
- // Specifies the GPIO line number for USB_VBUS detecting using EXTI GPIO
- // Possible values: GPIO_PIN_0 .. GPIO_PIN_15
- #define USB_VBUS_LINE (CONFIG_PIN__USB__VBUSDETECT)
- // USB_VBUS_PORT
- // Specifies the GPIO port for USB_VBUS detecting using EXTI GPIO
- // Possible values: GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOH
- #define USB_VBUS_PORT (CONFIG_PORT__USB__VBUSDETECT)
- // USB_VBUS_PORT_CLKEN
- // Enables the corresponding port clocking (see USB_VBUS_PORT)
- #define USB_VBUS_PORT_CLKEN() __HAL_RCC_GPIOC_CLK_ENABLE()
- #define USB_VBUS_PORT_CLKDS() __HAL_RCC_GPIOC_CLK_DISABLE()
- // USB_VBUS_EXTI_IRQ
- // Specifies the IRQ-number for USB_VBUS detecting using EXTI GPIO
- // Possible values: EXTI15_10_IRQn, EXTI9_5_IRQn, EXTI4_IRQn, EXTI3_IRQn, EXTI2_IRQn, EXTI1_IRQn, EXTI0_IRQn
- #define USB_VBUS_EXTI_IRQ (EXTI15_10_IRQn)
- // USB_INTERNAL_WKUP_SUPPORT
- // Enables internal USB wakeup-event support
- #define USB_INTERNAL_WKUP_SUPPORT CONFIG_USB_INTERNAL_WKUP_SUPPORT
- // USB_DEBUG_SUPRESS_VBUS_WKUP
- // Debug: do not wakeup on VBUS line changing
- #define USB_DEBUG_SUPRESS_VBUS_WKUP CONFIG_DEBUG_USB_SUPRESS_VBUS_WKUP
- #if CONFIG_SLEEPMANAGER
- // This module uses WakeUp Pin #2 as a wakeup source
- // This WakeUp Pin (PC13, Pin #2) is connected to USB_VBUS
- // Rising edge means the USB cable plugging in
- // Falling edge means the USB cable unplugging
- static bool bInitialized = false;
- static bool bUSBActive = false; // shows if USB in suspend mode or not
- static bool bUSBPlugged = false; // shows if USB cable connected (USB VBUS Pin monitoring)
- static eSleepManager_WakeupReason_t xWakeupReason = eSleepManager_GenericWakeup;
- static bool SleepManager_Init();
- static void SleepManager_DeInit();
- static bool SleepManager_SetUSBWakeUp( bool );
- static bool SleepManager_EnterSleepTimeout( uint32_t );
- static bool SleepManager_EnterSleep();
- static bool SleepManager_GetUSBPlugged();
- static bool SleepManager_GetUSBActive();
- static eSleepManager_WakeupReason_t SleepManager_Sleep();
- static eSleepManager_WakeupReason_t SleepManager_SleepTimeout( uint32_t );
- static bool SleepManager_USBPlugStatusUpdate();
- const sSleepManager_Handle_t SleepManagerHandle = {
- .Init = SleepManager_Init,
- .SetUSBWakeup = SleepManager_SetUSBWakeUp,
- .Sleep = SleepManager_Sleep,
- .SleepTimeout = SleepManager_SleepTimeout,
- .GetUSBPlugged = SleepManager_GetUSBPlugged,
- .GetUSBActive = SleepManager_GetUSBActive,
- .DeInit = SleepManager_DeInit,
- };
- static void SleepManager_USBSuspendEvent();
- static void SleepManager_USBResumeEvent();
- const sSleepManager_Notify_t SleepManagerNotify = {
- .USBSuspendEvent = SleepManager_USBSuspendEvent,
- .USBResumeEvent = SleepManager_USBResumeEvent,
- };
- static bool SleepManager_Init()
- {
- __DI__
-
- HAL_PWR_DisableSleepOnExit();
- HAL_PWREx_EnableFastWakeUp();
- HAL_PWREx_DisableLowPowerRunMode();
-
- bInitialized = true;
- SleepManager_SetUSBWakeUp( false );
- SleepManager_USBPlugStatusUpdate();
- __EI__
- return true;
- }
- static void SleepManager_DeInit()
- {
- __DI__
- HAL_PWREx_DisableFastWakeUp();
- HAL_PWR_DisableSleepOnExit();
- HAL_PWREx_DisableLowPowerRunMode();
-
- SleepManager_SetUSBWakeUp( false );
- bInitialized = false;
-
- __EI__
- }
- static bool SleepManager_USBPlugStatusUpdate()
- {
- bool bValue = (GPIO_PIN_SET == HAL_GPIO_ReadPin( USB_VBUS_PORT, USB_VBUS_LINE ));
- __DI__
- bUSBPlugged = bValue;
- __EI__
- return bValue;
- }
- static bool SleepManager_SetUSBWakeUp( bool state )
- {
- bool ret = false;
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- __DI__
- if( bInitialized )
- {
- if( state )
- {
- // Configure GPIO pins for VBUS
- #if USB_DEBUG_SUPRESS_VBUS_WKUP == 0
- // Enable port clocking
- USB_VBUS_PORT_CLKEN();
- // Configure EXTI line
- GPIO_InitStruct.Pin = USB_VBUS_LINE;
- GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; // use rising and falling edges
- GPIO_InitStruct.Pull = GPIO_PULLDOWN;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- HAL_GPIO_Init( USB_VBUS_PORT, &GPIO_InitStruct );
- // Enable EXTI Interrupt
- HAL_NVIC_EnableIRQ( USB_VBUS_EXTI_IRQ );
- #ifdef USB_VBUS_WKPIN
- HAL_PWR_EnableWakeUpPin( USB_VBUS_WKPIN );
- #endif
- #endif
- #if USB_INTERNAL_WKUP_SUPPORT
- __HAL_USB_WAKEUP_EXTI_ENABLE_IT(); // Enable corresponding internal EXTI line (USB Wakeup)
- HAL_NVIC_EnableIRQ( USB_FS_WKUP_IRQn );
- #endif
- }
- else
- {
- #if USB_INTERNAL_WKUP_SUPPORT
- HAL_NVIC_DisableIRQ( USB_FS_WKUP_IRQn );
- __HAL_USB_WAKEUP_EXTI_DISABLE_IT(); // Disable corresponding internal EXTI line (USB Wakeup)
- #endif
- #if USB_DEBUG_SUPRESS_VBUS_WKUP == 0
- #ifdef USB_VBUS_WKPIN
- HAL_PWR_DisableWakeUpPin( PWR_WAKEUP_PIN2 );
- #endif
- // DeConfigure EXTI line, configure as Input
- GPIO_InitStruct.Pin = USB_VBUS_LINE;
- GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // use port as input to poll signal
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
- HAL_GPIO_Init( USB_VBUS_PORT, &GPIO_InitStruct );
- // Disable EXTI Interrupt
- HAL_NVIC_DisableIRQ( USB_VBUS_EXTI_IRQ );
- // DO NOT DISABLE PORT CLOCKING DUE TO IT CAN BE IN USE!!!
- /* __ USB_VBUS_PORT_CLKDS(); __ */
- #else
- // DeConfigure EXTI line, configure as Input
- GPIO_InitStruct.Pin = USB_VBUS_LINE;
- GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // use port as input to poll signal
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
- HAL_GPIO_Init( USB_VBUS_PORT, &GPIO_InitStruct );
- #endif
- }
- ret = true;
- }
- __EI__
-
- return ret;
- }
- // SleepManager_USBSuspendEvent callback
- // Is called by Low-Level PCD Module (USB HAL) to inform the high level
- // about the fact that USB enters in SUSPEND mode
- static void SleepManager_USBSuspendEvent()
- {
- __DI__
- if( bInitialized )
- {
- bUSBActive = false;
- }
- __EI__
- }
- // SleepManager_USBResumeEvent callback
- // Is called by Low-Level PCD Module (USB HAL) to inform the high level
- // about the fact that USB enters in RUN mode
- static void SleepManager_USBResumeEvent()
- {
- __DI__
- if( bInitialized )
- {
- bUSBActive = true;
- }
- __EI__
- }
-
- static bool SleepManager_GetUSBPlugged()
- {
- // Check if initialized:
- DI();
- if( !bInitialized )
- {
- EI();
- return false;
- }
- EI();
- return SleepManager_USBPlugStatusUpdate();
- }
- static bool SleepManager_GetUSBActive()
- {
- bool ret = false;
- __DI__ ret = bInitialized && bUSBActive; __EI__
-
- return ret;
- }
- static eSleepManager_WakeupReason_t SleepManager_GetWakeupReason()
- {
- eSleepManager_WakeupReason_t xValue;
- __DI__ xValue = xWakeupReason; __EI__
- return xValue;
- }
- static bool SleepManager_EnterSleepTimeout( uint32_t timeout )
- {
- xWakeupReason = eSleepManager_Error;
- // HAL_PWR_EnterSLEEPMode( PWR_LOWPOWERREGULATOR_ON,
- // PWR_SLEEPENTRY_WFE );
- //
- return false;
- }
- static bool SleepManager_EnterSleep( )
- {
- xWakeupReason = eSleepManager_GenericWakeup;
- // disable some clocks for the power consumption reducing?
- //RCC_AHBENR
- //RCC_AHB1ENR
- //RCC_AHB2ENR
- // HAL_PWR_EnableSleepOnExit();
- #if CONFIG_SLEEPMANAGER_KEEPDEBUGCLK
- HAL_DBGMCU_EnableDBGSleepMode();
- HAL_DBGMCU_EnableDBGStopMode();
- #endif
- #if CONFIG_SLEEPMANAGER_DEBUGPIN
- CONFIG_SLEEPMANAGER_DEBUGPIN_SETPIN
- #endif
- #if CONFIG_SLEEPMANAGER_DEBUG_NOSLEEP
- __NOP();
- #else
- HAL_PWR_EnterSLEEPMode( PWR_MAINREGULATOR_ON, // OK
- PWR_SLEEPENTRY_WFI ); // OK
- // HAL_PWR_EnterSLEEPMode( PWR_LOWPOWERREGULATOR_ON, //??
- // PWR_SLEEPENTRY_WFI ); //??
- //HAL_PWR_EnterSLEEPMode( PWR_MAINREGULATOR_ON,
- // PWR_SLEEPENTRY_WFE );
- //HAL_PWR_EnterSTOPMode( PWR_LOWPOWERREGULATOR_ON, //PWR_MAINREGULATOR_ON,
- // PWR_STOPENTRY_WFI );
- //HAL_PWR_EnterSTOPMode( PWR_LOWPOWERREGULATOR_ON, //PWR_MAINREGULATOR_ON,
- // PWR_STOPENTRY_WFE );
- #endif
- #if CONFIG_SLEEPMANAGER_DEBUGPIN
- CONFIG_SLEEPMANAGER_DEBUGPIN_CLRPIN
- #endif
- return true;
- }
- static eSleepManager_WakeupReason_t SleepManager_Sleep()
- {
- if( SleepManager_EnterSleep() )
- return SleepManager_GetWakeupReason();
- return eSleepManager_Error;
- }
- static eSleepManager_WakeupReason_t SleepManager_SleepTimeout( uint32_t timeout )
- {
- if( SleepManager_EnterSleepTimeout( timeout ) )
- return SleepManager_GetWakeupReason();
- return eSleepManager_Error;
- }
- #endif
- #if USB_INTERNAL_WKUP_SUPPORT
- //
- // USB-Wakeup Interrupt Event Routing
- //
- void USB_FS_WKUP_IRQHandler() // startup_stm32l151xb.s
- {
- xWakeupReason = eSleepManager_USBPlugWakeup;
- HAL_PWR_DisableSleepOnExit();
- }
- #endif
- // EXTI line detection callbacks.
- // Note: It is required to route the interrupt routine to the
- // HAL-function HAL_GPIO_EXTI_IRQHandler()
- // e.g. void EXTI4_IRQHandler { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4); }
- //
- void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) // stm32l1xx_hal_gpio.c
- {
- // USB VBUS is connected to PC13.
- // This callback is called if any GPIO pin is triggered and
- // the corresponding EXTI-line is configured.
- // Check if the pin number is corresponds to PC13:
- if( USB_VBUS_LINE == GPIO_Pin )
- {
- #if CONFIG_SLEEPMANAGER
- SleepManager_USBPlugStatusUpdate();
- xWakeupReason = eSleepManager_USBPlugWakeup;
- #endif
- HAL_PWR_DisableSleepOnExit();
- }
- }
|