gd32f4xx_pmu.c 8.6 KB

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