usbd_pwr.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*!
  2. \file usbd_pwr.c
  3. \brief USB device power management driver
  4. */
  5. /*
  6. Copyright (C) 2017 GigaDevice
  7. 2017-02-10, V1.0.0, firmware for GD32F30x
  8. */
  9. #include "usbd_pwr.h"
  10. #ifdef USBD_LOWPWR_MODE_ENABLE
  11. static void lowpower_mode_exit (void);
  12. #endif /* USBD_LOWPWR_MODE_ENABLE */
  13. __IO uint8_t g_ESOF_count = 0U;
  14. __IO uint8_t g_suspend_enabled = 1U;
  15. __IO uint8_t g_remote_wakeup_on = 0U;
  16. #ifdef LPM_ENABLED
  17. extern __IO uint32_t L1_resume;
  18. #endif /* LPM_ENABLED */
  19. /*!
  20. \brief USB wakeup first operation is to wakeup mcu
  21. \param[in] none
  22. \param[out] none
  23. \retval none
  24. */
  25. void resume_mcu (void)
  26. {
  27. /* clear low_power mode bit in USBD_CTL */
  28. USBD_REG_SET(USBD_CTL, USBD_REG_GET(USBD_CTL) & (~CTL_LOWM));
  29. #ifdef USBD_LOWPWR_MODE_ENABLE
  30. /* restore normal operations */
  31. lowpower_mode_exit();
  32. #endif /* USBD_LOWPWR_MODE_ENABLE */
  33. /* clear SETSPS bit */
  34. USBD_REG_SET(USBD_CTL, USBD_REG_GET(USBD_CTL) & (~CTL_SETSPS));
  35. }
  36. #ifdef USBD_LOWPWR_MODE_ENABLE
  37. /*!
  38. \brief restore system clocks and power while exiting suspend mode
  39. \param[in] none
  40. \param[out] none
  41. \retval none
  42. */
  43. static void lowpower_mode_exit (void)
  44. {
  45. /* restore system clock */
  46. /* enable HSE */
  47. rcu_osci_on(RCU_HXTAL);
  48. /* wait till HSE is ready */
  49. while(RESET == rcu_flag_get(RCU_FLAG_HXTALSTB));
  50. /* enable PLL */
  51. rcu_osci_on(RCU_PLL_CK);
  52. /* wait till PLL is ready */
  53. while(RESET == rcu_flag_get(RCU_FLAG_PLLSTB));
  54. /* select PLL as system clock source */
  55. rcu_system_clock_source_config(RCU_CKSYSSRC_PLL);
  56. /* wait till PLL is used as system clock source */
  57. while(0x08 != rcu_system_clock_source_get());
  58. /* low power sleep on exit disabled */
  59. system_lowpower_reset(SCB_LPM_DEEPSLEEP);
  60. }
  61. #endif /* USBD_LOWPWR_MODE_ENABLE */
  62. /*!
  63. \brief set USB device to suspend mode
  64. \param[in] none
  65. \param[out] none
  66. \retval none
  67. */
  68. void usbd_suspend (void)
  69. {
  70. /* set usb module to suspend and low-power mode */
  71. USBD_REG_SET(USBD_CTL, USBD_REG_GET(USBD_CTL) | CTL_SETSPS | CTL_LOWM);
  72. #ifdef USBD_LOWPWR_MODE_ENABLE
  73. /* check wakeup flag is set */
  74. if (0 == (USBD_REG_GET(USBD_INTF) & INTF_WKUPIF)) {
  75. /* enter DEEP_SLEEP mode with LDO in low power mode */
  76. pmu_to_deepsleepmode(PMU_LDO_LOWPOWER, WFI_CMD);
  77. } else {
  78. /* clear wakeup interrupt flag */
  79. USBD_REG_SET(USBD_INTF, CLR_WKUPIF);
  80. /* clear set_suspend flag */
  81. USBD_REG_SET(USBD_CTL, USBD_REG_GET(USBD_CTL) & ~CTL_SETSPS);
  82. }
  83. #endif /* USBD_LOWPWR_MODE_ENABLE */
  84. }
  85. /*!
  86. \brief start to remote wakeup
  87. \param[in] none
  88. \param[out] none
  89. \retval none
  90. */
  91. void usbd_remote_wakeup_active(void)
  92. {
  93. resume_mcu();
  94. #ifdef LPM_ENABLED
  95. USBD_REG_SET(USBD_CTL, USBD_REG_GET(USBD_CTL) | CTL_L1RSREQ);
  96. L1_resume = 1U;
  97. #else
  98. g_remote_wakeup_on = 1U;
  99. g_ESOF_count = 15U;
  100. USBD_REG_SET(USBD_CTL, USBD_REG_GET(USBD_CTL) | CTL_RSREQ);
  101. #endif /* LPM_ENABLED */
  102. }