drv_pm.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * Change Logs:
  19. * Date Author Notes
  20. * 2020-12-15 liuhy the first version
  21. */
  22. #include "drv_pm.h"
  23. #ifdef RT_USING_PM
  24. /* 注意:进入睡眠前,如果有中断挂起(SYSTICK、PENDSV、UART、EXTI等),睡眠将被瞬间唤醒。*/
  25. static void sleep(struct rt_pm *pm, uint8_t mode)
  26. {
  27. rt_base_t level;
  28. level = rt_hw_interrupt_disable();
  29. rt_hw_interrupt_enable(0x88);
  30. switch (mode)
  31. {
  32. case PM_SLEEP_MODE_NONE:
  33. break;
  34. case PM_SLEEP_MODE_IDLE:
  35. break;
  36. case PM_SLEEP_MODE_LIGHT:
  37. ald_pmu_stop_enter();
  38. break;
  39. case PM_SLEEP_MODE_DEEP:
  40. ald_pmu_stop_enter();
  41. break;
  42. case PM_SLEEP_MODE_STANDBY:
  43. ald_pmu_stop_enter();
  44. break;
  45. case PM_SLEEP_MODE_SHUTDOWN:
  46. ald_pmu_stop_enter();
  47. break;
  48. default:
  49. RT_ASSERT(0);
  50. break;
  51. }
  52. rt_hw_interrupt_enable(level);
  53. }
  54. static void run(struct rt_pm *pm, uint8_t mode)
  55. {
  56. static uint8_t last_mode;
  57. if (mode == last_mode)
  58. return;
  59. last_mode = mode;
  60. switch (mode)
  61. {
  62. case PM_RUN_MODE_HIGH_SPEED:
  63. case PM_RUN_MODE_NORMAL_SPEED:
  64. case PM_RUN_MODE_MEDIUM_SPEED:
  65. case PM_RUN_MODE_LOW_SPEED:
  66. default:
  67. break;
  68. }
  69. }
  70. /**
  71. * This function caculate the PM tick from OS tick
  72. *
  73. * @param tick OS tick
  74. *
  75. * @return the PM tick
  76. */
  77. static rt_tick_t es32f3_pm_tick_from_os_tick(rt_tick_t tick)
  78. {
  79. rt_uint32_t freq = 1;
  80. return (freq * tick / RT_TICK_PER_SECOND);
  81. }
  82. /**
  83. * This function caculate the OS tick from PM tick
  84. *
  85. * @param tick PM tick
  86. *
  87. * @return the OS tick
  88. */
  89. static rt_tick_t es32f3_os_tick_from_pm_tick(rt_uint32_t tick)
  90. {
  91. static rt_uint32_t os_tick_remain = 0;
  92. rt_uint32_t ret, freq;
  93. freq = 1;
  94. ret = (tick * RT_TICK_PER_SECOND + os_tick_remain) / freq;
  95. os_tick_remain += (tick * RT_TICK_PER_SECOND);
  96. os_tick_remain %= freq;
  97. return ret;
  98. }
  99. /**
  100. * This function start the timer of pm
  101. *
  102. * @param pm Pointer to power manage structure
  103. * @param timeout How many OS Ticks that MCU can sleep
  104. */
  105. static void pm_timer_start(struct rt_pm *pm, rt_uint32_t timeout)
  106. {
  107. RT_ASSERT(pm != RT_NULL);
  108. RT_ASSERT(timeout > 0);
  109. if (timeout != RT_TICK_MAX)
  110. {
  111. /* Convert OS Tick to pmtimer timeout value */
  112. timeout = es32f3_pm_tick_from_os_tick(timeout);
  113. /* MAX 0xFFFF */
  114. if (timeout > 0xFFFF)
  115. {
  116. timeout = 0xFFFF;
  117. }
  118. }
  119. }
  120. /**
  121. * This function stop the timer of pm
  122. *
  123. * @param pm Pointer to power manage structure
  124. */
  125. static void pm_timer_stop(struct rt_pm *pm)
  126. {
  127. RT_ASSERT(pm != RT_NULL);
  128. }
  129. /**
  130. * This function calculate how many OS Ticks that MCU have suspended
  131. *
  132. * @param pm Pointer to power manage structure
  133. *
  134. * @return OS Ticks
  135. */
  136. static rt_tick_t pm_timer_get_tick(struct rt_pm *pm)
  137. {
  138. rt_uint32_t timer_tick;
  139. RT_ASSERT(pm != RT_NULL);
  140. timer_tick = 1;
  141. return es32f3_os_tick_from_pm_tick(timer_tick);
  142. }
  143. /**
  144. * This function initialize the power manager
  145. */
  146. int drv_pm_hw_init(void)
  147. {
  148. static const struct rt_pm_ops _ops =
  149. {
  150. sleep,
  151. run,
  152. pm_timer_start,
  153. pm_timer_stop,
  154. pm_timer_get_tick
  155. };
  156. rt_uint8_t timer_mask = 0;
  157. /* initialize timer mask */
  158. timer_mask = 1UL << PM_SLEEP_MODE_DEEP;
  159. /* initialize system pm module */
  160. rt_system_pm_init(&_ops, timer_mask, RT_NULL);
  161. return 0;
  162. }
  163. INIT_BOARD_EXPORT(drv_pm_hw_init);
  164. #endif