gd32f3x0_pmu.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /*!
  2. \file gd32f3x0_pmu.c
  3. \brief PMU driver
  4. */
  5. /*
  6. Copyright (C) 2017 GigaDevice
  7. 2017-06-06, V1.0.0, firmware for GD32F3x0
  8. */
  9. #include "gd32f3x0_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] lvdt_n:
  26. only one among these parameters can be selected
  27. \arg PMU_LVDT_0: voltage threshold is 2.1V
  28. \arg PMU_LVDT_1: voltage threshold is 2.3V
  29. \arg PMU_LVDT_2: voltage threshold is 2.4V
  30. \arg PMU_LVDT_3: voltage threshold is 2.6V
  31. \arg PMU_LVDT_4: voltage threshold is 2.7V
  32. \arg PMU_LVDT_5: voltage threshold is 2.9V
  33. \arg PMU_LVDT_6: voltage threshold is 3.0V
  34. \arg PMU_LVDT_7: voltage threshold is 3.1V
  35. \param[out] none
  36. \retval none
  37. */
  38. void pmu_lvd_select(uint32_t lvdt_n)
  39. {
  40. /* disable LVD */
  41. PMU_CTL &= ~PMU_CTL_LVDEN;
  42. /* clear LVDT bits */
  43. PMU_CTL &= ~PMU_CTL_LVDT;
  44. /* set LVDT bits according to lvdt_n */
  45. PMU_CTL |= lvdt_n;
  46. /* enable LVD */
  47. PMU_CTL |= PMU_CTL_LVDEN;
  48. }
  49. /*!
  50. \brief select LDO output voltage
  51. these bits set by software when the main PLL closed
  52. \param[in] ldo_output:
  53. only one among these parameters can be selected
  54. \arg PMU_LDOVS_LOW: LDO output voltage low mode
  55. \arg PMU_LDOVS_MID: LDO output voltage mid mode
  56. \arg PMU_LDOVS_HIGH: LDO output voltage high mode
  57. \param[out] none
  58. \retval none
  59. */
  60. void pmu_ldo_output_select(uint32_t ldo_output)
  61. {
  62. PMU_CTL &= ~PMU_CTL_LDOVS;
  63. PMU_CTL |= ldo_output;
  64. }
  65. /*!
  66. \brief disable PMU lvd
  67. \param[in] none
  68. \param[out] none
  69. \retval none
  70. */
  71. void pmu_lvd_disable(void)
  72. {
  73. /* disable LVD */
  74. PMU_CTL &= ~PMU_CTL_LVDEN;
  75. }
  76. /*!
  77. \brief enable low-driver mode in deep-sleep mode
  78. \param[in] none
  79. \param[out] none
  80. \retval none
  81. */
  82. void pmu_lowdriver_mode_enable(void)
  83. {
  84. PMU_CTL &= ~PMU_CTL_LDEN;
  85. PMU_CTL |= PMU_LOWDRIVER_ENABLE;
  86. }
  87. /*!
  88. \brief enable low-driver mode in deep-sleep mode
  89. \param[in] none
  90. \param[out] none
  91. \retval none
  92. */
  93. void pmu_lowdriver_mode_disable(void)
  94. {
  95. PMU_CTL &= ~PMU_CTL_LDEN;
  96. PMU_CTL |= PMU_LOWDRIVER_DISABLE;
  97. }
  98. /*!
  99. \brief enable high-driver mode
  100. this bit set by software only when IRC8M or HXTAL used as system clock
  101. \param[in] none
  102. \param[out] none
  103. \retval none
  104. */
  105. void pmu_highdriver_mode_enable(void)
  106. {
  107. PMU_CTL |= PMU_CTL_HDEN;
  108. }
  109. /*!
  110. \brief disable high-driver mode
  111. \param[in] none
  112. \param[out] none
  113. \retval none
  114. */
  115. void pmu_highdriver_mode_disable(void)
  116. {
  117. PMU_CTL &= ~PMU_CTL_HDEN;
  118. }
  119. /*!
  120. \brief switch high-driver mode
  121. this bit set by software only when IRC8M or HXTAL used as system clock
  122. \param[in] highdr_switch:
  123. only one among these parameters can be selected
  124. \arg PMU_HIGHDR_SWITCH_NONE: disable high-driver mode switch
  125. \arg PMU_HIGHDR_SWITCH_EN: enable high-driver mode switch
  126. \param[out] none
  127. \retval none
  128. */
  129. void pmu_highdriver_switch_select(uint32_t highdr_switch)
  130. {
  131. /* wait for HDRF flag to be set */
  132. while(SET != pmu_flag_get(PMU_FLAG_HDR)){
  133. }
  134. PMU_CTL &= ~PMU_CTL_HDS;
  135. PMU_CTL |= highdr_switch;
  136. }
  137. /*!
  138. \brief low-driver mode when use low power LDO
  139. \param[in] mode:
  140. only one among these parameters can be selected
  141. \arg PMU_NORMALDR_LOWPWR: normal-driver when use low power LDO
  142. \arg PMU_LOWDR_LOWPWR: low-driver mode enabled when LDEN is 11 and use low power LDO
  143. \param[out] none
  144. \retval none
  145. */
  146. void pmu_lowpower_driver_config(uint32_t mode)
  147. {
  148. PMU_CTL &= ~PMU_CTL_LDLP;
  149. PMU_CTL |= mode;
  150. }
  151. /*!
  152. \brief low-driver mode when use normal power LDO
  153. \param[in] mode:
  154. only one among these parameters can be selected
  155. \arg PMU_NORMALDR_NORMALPWR: normal-driver when use low power LDO
  156. \arg PMU_LOWDR_NORMALPWR: low-driver mode enabled when LDEN is 11 and use low power LDO
  157. \param[out] none
  158. \retval none
  159. */
  160. void pmu_normalpower_driver_config(uint32_t mode)
  161. {
  162. PMU_CTL &= ~PMU_CTL_LDNP;
  163. PMU_CTL |= mode;
  164. }
  165. /*!
  166. \brief PMU work at sleep mode
  167. \param[in] sleepmodecmd:
  168. only one among these parameters can be selected
  169. \arg WFI_CMD: use WFI command
  170. \arg WFE_CMD: use WFE command
  171. \param[out] none
  172. \retval none
  173. */
  174. void pmu_to_sleepmode(uint8_t sleepmodecmd)
  175. {
  176. /* clear sleepdeep bit of Cortex-M4 system control register */
  177. SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
  178. /* select WFI or WFE command to enter sleep mode */
  179. if(WFI_CMD == sleepmodecmd){
  180. __WFI();
  181. }else{
  182. __WFE();
  183. }
  184. }
  185. /*!
  186. \brief PMU work at deepsleep mode
  187. \param[in] ldo:
  188. only one among these parameters can be selected
  189. \arg PMU_LDO_NORMAL: LDO operates normally when pmu enter deepsleep mode
  190. \arg PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deepsleep mode
  191. \param[in] deepsleepmodecmd:
  192. only one among these parameters can be selected
  193. \arg WFI_CMD: use WFI command
  194. \arg WFE_CMD: use WFE command
  195. \param[out] none
  196. \retval none
  197. */
  198. void pmu_to_deepsleepmode(uint32_t ldo,uint8_t deepsleepmodecmd)
  199. {
  200. /* clear stbmod and ldolp bits */
  201. PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP));
  202. /* set ldolp bit according to pmu_ldo */
  203. PMU_CTL |= ldo;
  204. /* set sleepdeep bit of Cortex-M4 system control register */
  205. SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
  206. /* select WFI or WFE command to enter deepsleep mode */
  207. if(WFI_CMD == deepsleepmodecmd){
  208. __WFI();
  209. }else{
  210. __SEV();
  211. __WFE();
  212. __WFE();
  213. }
  214. /* reset sleepdeep bit of Cortex-M4 system control register */
  215. SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
  216. }
  217. /*!
  218. \brief pmu work at standby mode
  219. \param[in] standbymodecmd:
  220. only one among these parameters can be selected
  221. \arg WFI_CMD: use WFI command
  222. \arg WFE_CMD: use WFE command
  223. \param[out] none
  224. \retval none
  225. */
  226. void pmu_to_standbymode(uint8_t standbymodecmd)
  227. {
  228. /* set sleepdeep bit of Cortex-M4 system control register */
  229. SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
  230. /* set stbmod bit */
  231. PMU_CTL |= PMU_CTL_STBMOD;
  232. /* reset wakeup flag */
  233. PMU_CTL |= PMU_CTL_WURST;
  234. /* select WFI or WFE command to enter standby mode */
  235. if(WFI_CMD == standbymodecmd){
  236. __WFI();
  237. }else{
  238. __WFE();
  239. }
  240. }
  241. /*!
  242. \brief enable wakeup pin
  243. \param[in] wakeup_pin:
  244. one or more parameters can be selected below
  245. \arg PMU_WAKEUP_PIN0: WKUP Pin 0 (PA0)
  246. \arg PMU_WAKEUP_PIN1: WKUP Pin 1 (PC13)
  247. \arg PMU_WAKEUP_PIN4: WKUP Pin 4 (PC5)
  248. \arg PMU_WAKEUP_PIN5: WKUP Pin 5 (PB5)
  249. \arg PMU_WAKEUP_PIN6: WKUP Pin 6 (PB15)
  250. \param[out] none
  251. \retval none
  252. */
  253. void pmu_wakeup_pin_enable(uint32_t wakeup_pin)
  254. {
  255. PMU_CS |= wakeup_pin;
  256. }
  257. /*!
  258. \brief disable wakeup pin
  259. \param[in] wakeup_pin:
  260. one or more parameters can be selected below
  261. \arg PMU_WAKEUP_PIN0: WKUP Pin 0 (PA0)
  262. \arg PMU_WAKEUP_PIN1: WKUP Pin 1 (PC13)
  263. \arg PMU_WAKEUP_PIN4: WKUP Pin 4 (PC5)
  264. \arg PMU_WAKEUP_PIN5: WKUP Pin 5 (PB5)
  265. \arg PMU_WAKEUP_PIN6: WKUP Pin 6 (PB15)
  266. \param[out] none
  267. \retval none
  268. */
  269. void pmu_wakeup_pin_disable(uint32_t wakeup_pin)
  270. {
  271. PMU_CS &= ~(wakeup_pin);
  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 clear flag bit
  295. \param[in] flag_clear:
  296. one or more parameters can be selected below
  297. \arg PMU_FLAG_RESET_WAKEUP: reset wakeup flag
  298. \arg PMU_FLAG_RESET_STANDBY: reset standby flag
  299. \param[out] none
  300. \retval none
  301. */
  302. void pmu_flag_clear(uint32_t flag_clear)
  303. {
  304. if(RESET != (flag_clear & PMU_FLAG_RESET_WAKEUP)){
  305. /* reset wakeup flag */
  306. PMU_CTL |= PMU_CTL_WURST;
  307. }
  308. if(RESET != (flag_clear & PMU_FLAG_RESET_STANDBY)){
  309. /* reset standby flag */
  310. PMU_CTL |= PMU_CTL_STBRST;
  311. }
  312. }
  313. /*!
  314. \brief get flag state
  315. \param[in] flag:
  316. only one among these parameters can be selected
  317. \arg PMU_FLAG_WAKEUP: wakeup flag
  318. \arg PMU_FLAG_STANDBY: standby flag
  319. \arg PMU_FLAG_LVD: lvd flag
  320. \arg PMU_FLAG_LDOVSR: LDO voltage select ready flag
  321. \arg PMU_FLAG_HDR: high-driver ready flag
  322. \arg PMU_FLAG_HDSR: high-driver switch ready flag
  323. \arg PMU_FLAG_LDR: low-driver mode ready flag
  324. \param[out] none
  325. \retval FlagStatus SET or RESET
  326. */
  327. FlagStatus pmu_flag_get(uint32_t flag)
  328. {
  329. FlagStatus ret_status = RESET;
  330. if(PMU_CS & flag){
  331. ret_status = SET;
  332. }
  333. return ret_status;
  334. }