gd32f30x_pmu.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /*!
  2. \file gd32f30x_pmu.c
  3. \brief PMU driver
  4. */
  5. /*
  6. Copyright (C) 2017 GigaDevice
  7. 2017-02-10, V1.0.0, firmware for GD32F30x
  8. */
  9. #include "gd32f30x_pmu.h"
  10. /*!
  11. \brief reset PMU register
  12. \param[in] none
  13. \param[out] none
  14. \retval none
  15. */
  16. void pmu_deinit(void)
  17. {
  18. /* reset PMU */
  19. rcu_periph_reset_enable(RCU_PMURST);
  20. rcu_periph_reset_disable(RCU_PMURST);
  21. }
  22. /*!
  23. \brief select low voltage detector threshold
  24. \param[in] lvdt_n:
  25. \arg PMU_LVDT_0: voltage threshold is 2.1V
  26. \arg PMU_LVDT_1: voltage threshold is 2.3V
  27. \arg PMU_LVDT_2: voltage threshold is 2.4V
  28. \arg PMU_LVDT_3: voltage threshold is 2.6V
  29. \arg PMU_LVDT_4: voltage threshold is 2.7V
  30. \arg PMU_LVDT_5: voltage threshold is 2.9V
  31. \arg PMU_LVDT_6: voltage threshold is 3.0V
  32. \arg PMU_LVDT_7: voltage threshold is 3.1V
  33. \param[out] none
  34. \retval none
  35. */
  36. void pmu_lvd_select(uint32_t lvdt_n)
  37. {
  38. /* disable LVD */
  39. PMU_CTL &= ~PMU_CTL_LVDEN;
  40. /* clear LVDT bits */
  41. PMU_CTL &= ~PMU_CTL_LVDT;
  42. /* set LVDT bits according to lvdt_n */
  43. PMU_CTL |= lvdt_n;
  44. /* enable LVD */
  45. PMU_CTL |= PMU_CTL_LVDEN;
  46. }
  47. /*!
  48. \brief select LDO output voltage
  49. this bit set by software when the main PLL closed, before closing PLL, change the system clock to IRC16M or HXTAL
  50. \param[in] ldo_output:
  51. \arg PMU_LDOVS_LOW: low-driver mode enable in deep-sleep mode
  52. \arg PMU_LDOVS_MID: low-driver mode disable in deep-sleep mode
  53. \arg PMU_LDOVS_HIGH: low-driver mode disable in deep-sleep mode
  54. \param[out] none
  55. \retval none
  56. */
  57. void pmu_ldo_output_select(uint32_t ldo_output)
  58. {
  59. PMU_CTL &= ~PMU_CTL_LDOVS;
  60. PMU_CTL |= ldo_output;
  61. }
  62. /*!
  63. \brief switch high-driver mode
  64. this bit set by software only when IRC16M or HXTAL used as system clock
  65. \param[in] highdr_switch:
  66. \arg PMU_HIGHDR_SWITCH_NONE: disable high-driver mode switch
  67. \arg PMU_HIGHDR_SWITCH_EN: enable high-driver mode switch
  68. \param[out] none
  69. \retval none
  70. */
  71. void pmu_highdriver_switch_select(uint32_t highdr_switch)
  72. {
  73. /* wait for HDRF flag set */
  74. while(SET != pmu_flag_get(PMU_FLAG_HDRF)){
  75. }
  76. PMU_CTL &= ~PMU_CTL_HDS;
  77. PMU_CTL |= highdr_switch;
  78. }
  79. /*!
  80. \brief enable low-driver mode in deep-sleep mode
  81. \param[in] none
  82. \param[out] none
  83. \retval none
  84. */
  85. void pmu_lowdriver_mode_enable(void)
  86. {
  87. PMU_CTL |= PMU_CTL_LDEN;
  88. }
  89. /*!
  90. \brief disable low-driver mode in deep-sleep mode
  91. \param[in] none
  92. \param[out] none
  93. \retval none
  94. */
  95. void pmu_lowdriver_mode_disable(void)
  96. {
  97. PMU_CTL &= ~PMU_CTL_LDEN;
  98. }
  99. /*!
  100. \brief enable high-driver mode
  101. this bit set by software only when IRC16M or HXTAL used as system clock
  102. \param[in] none
  103. \param[out] none
  104. \retval none
  105. */
  106. void pmu_highdriver_mode_enable(void)
  107. {
  108. PMU_CTL |= PMU_CTL_HDEN;
  109. }
  110. /*!
  111. \brief disable high-driver mode
  112. \param[in] none
  113. \param[out] none
  114. \retval none
  115. */
  116. void pmu_highdriver_mode_disable(void)
  117. {
  118. PMU_CTL &= ~PMU_CTL_HDEN;
  119. }
  120. /*!
  121. \brief disable PMU lvd
  122. \param[in] none
  123. \param[out] none
  124. \retval none
  125. */
  126. void pmu_lvd_disable(void)
  127. {
  128. /* disable LVD */
  129. PMU_CTL &= ~PMU_CTL_LVDEN;
  130. }
  131. /*!
  132. \brief driver mode when use low power LDO
  133. \param[in] mode:
  134. \arg PMU_NORMALDR_LOWPWR: normal driver when use low power LDO
  135. \arg PMU_LOWDR_LOWPWR: low-driver mode enabled when LDEN is 11 and use low power LDO
  136. \param[out] none
  137. \retval none
  138. */
  139. void pmu_lowpower_driver_config(uint32_t mode)
  140. {
  141. PMU_CTL &= ~PMU_CTL_LDLP;
  142. PMU_CTL |= mode;
  143. }
  144. /*!
  145. \brief driver mode when use normal power LDO
  146. \param[in] mode:
  147. \arg PMU_NORMALDR_NORMALPWR: normal driver when use low power LDO
  148. \arg PMU_LOWDR_NORMALPWR: low-driver mode enabled when LDEN is 11 and use low power LDO
  149. \param[out] none
  150. \retval none
  151. */
  152. void pmu_normalpower_driver_config(uint32_t mode)
  153. {
  154. PMU_CTL &= ~PMU_CTL_LDNP;
  155. PMU_CTL |= mode;
  156. }
  157. /*!
  158. \brief PMU work at sleep mode
  159. \param[in] sleepmodecmd:
  160. \arg WFI_CMD: use WFI command
  161. \arg WFE_CMD: use WFE command
  162. \param[out] none
  163. \retval none
  164. */
  165. void pmu_to_sleepmode(uint8_t sleepmodecmd)
  166. {
  167. /* clear sleepdeep bit of Cortex-M4 system control register */
  168. SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
  169. /* select WFI or WFE command to enter sleep mode */
  170. if(WFI_CMD == sleepmodecmd){
  171. __WFI();
  172. }else{
  173. __WFE();
  174. }
  175. }
  176. /*!
  177. \brief PMU work at deepsleep mode
  178. \param[in] ldo
  179. \arg PMU_LDO_NORMAL: LDO normal work when pmu enter deepsleep mode
  180. \arg PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deepsleep mode
  181. \param[in] deepsleepmodecmd:
  182. \arg WFI_CMD: use WFI command
  183. \arg WFE_CMD: use WFE command
  184. \param[out] none
  185. \retval none
  186. */
  187. void pmu_to_deepsleepmode(uint32_t ldo,uint8_t deepsleepmodecmd)
  188. {
  189. /* clear stbmod and ldolp bits */
  190. PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP));
  191. /* set ldolp bit according to pmu_ldo */
  192. PMU_CTL |= ldo;
  193. /* set sleepdeep bit of Cortex-M4 system control register */
  194. SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
  195. /* select WFI or WFE command to enter deepsleep mode */
  196. if(WFI_CMD == deepsleepmodecmd){
  197. __WFI();
  198. }else{
  199. __SEV();
  200. __WFE();
  201. __WFE();
  202. }
  203. /* reset sleepdeep bit of Cortex-M4 system control register */
  204. SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
  205. }
  206. /*!
  207. \brief pmu work at standby mode
  208. \param[in] standbymodecmd:
  209. \arg WFI_CMD: use WFI command
  210. \arg WFE_CMD: use WFE command
  211. \param[out] none
  212. \retval none
  213. */
  214. void pmu_to_standbymode(uint8_t standbymodecmd)
  215. {
  216. /* set sleepdeep bit of Cortex-M4 system control register */
  217. SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
  218. /* set stbmod bit */
  219. PMU_CTL |= PMU_CTL_STBMOD;
  220. /* reset wakeup flag */
  221. PMU_CTL |= PMU_CTL_WURST;
  222. /* select WFI or WFE command to enter standby mode */
  223. if(WFI_CMD == standbymodecmd){
  224. __WFI();
  225. }else{
  226. __WFE();
  227. }
  228. }
  229. /*!
  230. \brief clear flag bit
  231. \param[in] flag_reset:
  232. \arg PMU_FLAG_RESET_WAKEUP: reset wakeup flag
  233. \arg PMU_FLAG_RESET_STANDBY: reset standby flag
  234. \param[out] none
  235. \retval none
  236. */
  237. void pmu_flag_clear(uint32_t flag_reset)
  238. {
  239. switch(flag_reset){
  240. case PMU_FLAG_RESET_WAKEUP:
  241. /* reset wakeup flag */
  242. PMU_CTL |= PMU_CTL_WURST;
  243. break;
  244. case PMU_FLAG_RESET_STANDBY:
  245. /* reset standby flag */
  246. PMU_CTL |= PMU_CTL_STBRST;
  247. break;
  248. default :
  249. break;
  250. }
  251. }
  252. /*!
  253. \brief get flag state
  254. \param[in] flag:
  255. \arg PMU_FLAG_WAKEUP: wakeup flag
  256. \arg PMU_FLAG_STANDBY: standby flag
  257. \arg PMU_FLAG_LVD: lvd flag
  258. \arg PMU_FLAG_LDOVSRF: LDO voltage select ready flag
  259. \arg PMU_FLAG_HDRF: high-driver ready flag
  260. \arg PMU_FLAG_HDSRF: high-driver switch ready flag
  261. \arg PMU_FLAG_LDRF: low-driver mode ready flag
  262. \param[out] none
  263. \retval FlagStatus SET or RESET
  264. */
  265. FlagStatus pmu_flag_get(uint32_t flag)
  266. {
  267. if(PMU_CS & flag){
  268. return SET;
  269. }else{
  270. return RESET;
  271. }
  272. }
  273. /*!
  274. \brief enable backup domain write
  275. \param[in] none
  276. \param[out] none
  277. \retval none
  278. */
  279. void pmu_backup_write_enable(void)
  280. {
  281. PMU_CTL |= PMU_CTL_BKPWEN;
  282. }
  283. /*!
  284. \brief disable backup domain write
  285. \param[in] none
  286. \param[out] none
  287. \retval none
  288. */
  289. void pmu_backup_write_disable(void)
  290. {
  291. PMU_CTL &= ~PMU_CTL_BKPWEN;
  292. }
  293. /*!
  294. \brief enable wakeup pin
  295. \param[in] none
  296. \param[out] none
  297. \retval none
  298. */
  299. void pmu_wakeup_pin_enable(void)
  300. {
  301. PMU_CS |= PMU_CS_WUPEN;
  302. }
  303. /*!
  304. \brief disable wakeup pin
  305. \param[in] none
  306. \param[out] none
  307. \retval none
  308. */
  309. void pmu_wakeup_pin_disable(void)
  310. {
  311. PMU_CS &= ~PMU_CS_WUPEN;
  312. }