fsl_pmu.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959
  1. /*
  2. * Copyright 2020-2021 NXP
  3. * All rights reserved.
  4. *
  5. * SPDX-License-Identifier: BSD-3-Clause
  6. */
  7. #include "fsl_pmu.h"
  8. #include "fsl_anatop_ai.h"
  9. /* Component ID definition, used by tools. */
  10. #ifndef FSL_COMPONENT_ID
  11. #define FSL_COMPONENT_ID "platform.drivers.pmu_1"
  12. #endif
  13. /*******************************************************************************
  14. * Definitions
  15. ******************************************************************************/
  16. #define PMU_LDO_LPSR_DIG_TRG_SPX_REG_SETPOINT_COUNTS 4U
  17. #define PMU_LDO_LPSR_DIG_TRG_SPX_VOLTAGE_SETPOINTX_BIT_WIDTH 8UL
  18. #define PMU_POWER_DETECT_CTRL_REGISTER (ANADIG_PMU->PMU_POWER_DETECT_CTRL)
  19. #define PMU_BIAS_CTRL_WB_CFG_1P8_WELL_SELECT_MASK (0x1U)
  20. #define PMU_BIAS_CTRL_WB_CFG_1P8_VOLTAGE_THRESHOLD_MASK (0x2U)
  21. #define PMU_BIAS_CTRL_WB_CFG_1P8_VOLTAGE_THRESHOLD_SHIFT 1U
  22. #define PMU_BIAS_CTRL_WB_CFG_1P8_VOLTAGE_THRESHOLD(x) \
  23. (((uint32_t)(((uint32_t)(x)) << PMU_BIAS_CTRL_WB_CFG_1P8_VOLTAGE_THRESHOLD_SHIFT)) & \
  24. PMU_BIAS_CTRL_WB_CFG_1P8_VOLTAGE_THRESHOLD_MASK)
  25. #define PMU_BIAS_CTRL_WB_CFG_1P8_DRIVE_STRENGTH_MASK (0x1CU)
  26. #define PMU_BIAS_CTRL_WB_CFG_1P8_DRIVE_STRENGTH_SHIFT 2U
  27. #define PMU_BIAS_CTRL_WB_CFG_1P8_DRIVE_STRENGTH(x) \
  28. (((uint32_t)(((uint32_t)(x)) << PMU_BIAS_CTRL_WB_CFG_1P8_DRIVE_STRENGTH_SHIFT)) & \
  29. PMU_BIAS_CTRL_WB_CFG_1P8_DRIVE_STRENGTH_MASK)
  30. #define PMU_BIAS_CTRL_WB_CFG_1P8_OSCILLATOR_FREQ_MASK (0x1E0U)
  31. #define PMU_BIAS_CTRL_WB_CFG_1P8_OSCILLATOR_FREQ_SHIFT 5U
  32. #define PMU_BIAS_CTRL_WB_CFG_1P8_OSCILLATOR_FREQ(x) \
  33. (((uint32_t)(((uint32_t)(x)) << PMU_BIAS_CTRL_WB_CFG_1P8_OSCILLATOR_FREQ_SHIFT)) & \
  34. PMU_BIAS_CTRL_WB_CFG_1P8_OSCILLATOR_FREQ_MASK)
  35. #define PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(member) \
  36. ((uint32_t)((ANADIG_PMU_BASE) + (uint32_t)offsetof(ANADIG_PMU_Type, member)))
  37. #define PMU_LDO_ENABLE_SETPOINT_REGISTERS \
  38. { \
  39. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(LDO_PLL_ENABLE_SP), \
  40. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(LDO_LPSR_ANA_ENABLE_SP), \
  41. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(LDO_LPSR_DIG_ENABLE_SP), 0UL \
  42. }
  43. #define PMU_LDO_LP_MODE_EN_SETPOINT_REGISTERS \
  44. { \
  45. 0UL, PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(LDO_LPSR_ANA_LP_MODE_SP), \
  46. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(LDO_LPSR_DIG_LP_MODE_SP), 0UL \
  47. }
  48. #define PMU_LDO_TRACKING_EN_SETPOINT_REGISTERS \
  49. { \
  50. 0UL, PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(LDO_LPSR_ANA_TRACKING_EN_SP), \
  51. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(LDO_LPSR_DIG_TRACKING_EN_SP), 0UL \
  52. }
  53. #define PMU_LDO_BYPASS_EN_SETPOINT_REGISTERS \
  54. { \
  55. 0UL, PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(LDO_LPSR_ANA_BYPASS_EN_SP), \
  56. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(LDO_LPSR_DIG_BYPASS_EN_SP), 0UL \
  57. }
  58. #define PMU_LDO_STBY_EN_REGISTERS \
  59. { \
  60. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(PLL_LDO_STBY_EN_SP), \
  61. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(LDO_LPSR_ANA_STBY_EN_SP), \
  62. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(LDO_LPSR_DIG_STBY_EN_SP), 0UL \
  63. }
  64. #define PMU_LPSR_DIG_TRG_REGISTERS \
  65. { \
  66. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(LDO_LPSR_DIG_TRG_SP0), \
  67. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(LDO_LPSR_DIG_TRG_SP1), \
  68. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(LDO_LPSR_DIG_TRG_SP2), \
  69. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(LDO_LPSR_DIG_TRG_SP3) \
  70. }
  71. #if (defined(PMU_HAS_FBB) && PMU_HAS_FBB)
  72. #define PMU_BODY_BIAS_ENABLE_REGISTERS \
  73. { \
  74. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(FBB_M7_ENABLE_SP), PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(RBB_SOC_ENABLE_SP), \
  75. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(RBB_LPSR_ENABLE_SP) \
  76. }
  77. #else
  78. #define PMU_BODY_BIAS_ENABLE_REGISTERS \
  79. { \
  80. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(RBB_SOC_ENABLE_SP), PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(RBB_LPSR_ENABLE_SP) \
  81. }
  82. #endif /* PMU_HAS_FBB */
  83. #if (defined(PMU_HAS_FBB) && PMU_HAS_FBB)
  84. #define PMU_BODY_BIAS_STBY_EN_REGISTERS \
  85. { \
  86. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(FBB_M7_STBY_EN_SP), PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(RBB_SOC_STBY_EN_SP), \
  87. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(RBB_LPSR_STBY_EN_SP) \
  88. }
  89. #else
  90. #define PMU_BODY_BIAS_STBY_EN_REGISTERS \
  91. { \
  92. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(RBB_SOC_STBY_EN_SP), PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(RBB_LPSR_STBY_EN_SP) \
  93. }
  94. #endif /* PMU_HAS_FBB */
  95. #if (defined(PMU_HAS_FBB) && PMU_HAS_FBB)
  96. #define PMU_BODY_BIAS_CONFIGURE_REGISTERS \
  97. { \
  98. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(FBB_M7_CONFIGURE), PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(RBB_SOC_CONFIGURE), \
  99. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(RBB_LPSR_CONFIGURE) \
  100. }
  101. #else
  102. #define PMU_BODY_BIAS_CONFIGURE_REGISTERS \
  103. { \
  104. PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(RBB_SOC_CONFIGURE), PMU_GET_ANADIG_PMU_MEMBER_ADDRESS(RBB_LPSR_CONFIGURE) \
  105. }
  106. #endif /* PMU_HAS_FBB */
  107. /*******************************************************************************
  108. * Prototypes
  109. ******************************************************************************/
  110. /*******************************************************************************
  111. * Variables
  112. ******************************************************************************/
  113. /*******************************************************************************
  114. * Code
  115. ******************************************************************************/
  116. /*!
  117. * brief Selects the control mode of the PLL LDO.
  118. *
  119. * param base PMU peripheral base address.
  120. * param mode The control mode of the PLL LDO. Please refer to pmu_control_mode_t.
  121. */
  122. void PMU_SetPllLdoControlMode(ANADIG_PMU_Type *base, pmu_control_mode_t mode)
  123. {
  124. if (mode == kPMU_StaticMode)
  125. {
  126. base->PMU_LDO_PLL &= ~ANADIG_PMU_PMU_LDO_PLL_LDO_PLL_CONTROL_MODE_MASK;
  127. }
  128. else
  129. {
  130. base->PMU_LDO_PLL |= ANADIG_PMU_PMU_LDO_PLL_LDO_PLL_CONTROL_MODE_MASK;
  131. }
  132. }
  133. /*!
  134. * brief Switches the PLL LDO from Static/Software Mode to GPC/Hardware Mode.
  135. *
  136. * param base PMU peripheral base address.
  137. */
  138. void PMU_SwitchPllLdoToGPCMode(ANADIG_PMU_Type *base)
  139. {
  140. if ((base->LDO_PLL_ENABLE_SP & ANADIG_PMU_LDO_PLL_ENABLE_SP_ON_OFF_SETPOINT0_MASK) != 0UL)
  141. {
  142. base->PMU_LDO_PLL |= ANADIG_PMU_PMU_LDO_PLL_LDO_PLL_ENABLE_MASK;
  143. }
  144. else
  145. {
  146. base->PMU_LDO_PLL &= ~ANADIG_PMU_PMU_LDO_PLL_LDO_PLL_ENABLE_MASK;
  147. }
  148. }
  149. /*!
  150. * brief Enables PLL LDO via AI interface in Static/Software mode.
  151. *
  152. * param base PMU peripheral base address.
  153. */
  154. void PMU_StaticEnablePllLdo(ANADIG_PMU_Type *base)
  155. {
  156. uint32_t temp32;
  157. temp32 = ANATOP_AI_Read(kAI_Itf_Ldo, kAI_PHY_LDO_CTRL0);
  158. if (temp32 !=
  159. (AI_PHY_LDO_CTRL0_OUTPUT_TRG(0x10) | AI_PHY_LDO_CTRL0_LINREG_EN_MASK | AI_PHY_LDO_CTRL0_LIMIT_EN_MASK))
  160. {
  161. ANATOP_AI_Write(
  162. kAI_Itf_Ldo, kAI_PHY_LDO_CTRL0,
  163. (AI_PHY_LDO_CTRL0_OUTPUT_TRG(0x10) | AI_PHY_LDO_CTRL0_LINREG_EN_MASK | AI_PHY_LDO_CTRL0_LIMIT_EN_MASK));
  164. SDK_DelayAtLeastUs(1, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
  165. /* Enable Voltage Reference for PLLs before those PLLs were enabled. */
  166. base->PMU_REF_CTRL |= ANADIG_PMU_PMU_REF_CTRL_EN_PLL_VOL_REF_BUFFER_MASK;
  167. }
  168. }
  169. /*!
  170. * brief Disables PLL LDO via AI interface in Static/Software mode.
  171. */
  172. void PMU_StaticDisablePllLdo(void)
  173. {
  174. ANATOP_AI_Write(kAI_Itf_Ldo, kAI_PHY_LDO_CTRL0, 0UL);
  175. }
  176. /*!
  177. * brief Selects the control mode of the LPSR ANA LDO.
  178. *
  179. * param base PMU peripheral base address.
  180. * param mode The control mode of the LPSR ANA LDO. Please refer to pmu_control_mode_t.
  181. */
  182. void PMU_SetLpsrAnaLdoControlMode(ANADIG_LDO_SNVS_Type *base, pmu_control_mode_t mode)
  183. {
  184. if (mode == kPMU_StaticMode)
  185. {
  186. base->PMU_LDO_LPSR_ANA &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_LPSR_ANA_CONTROL_MODE_MASK;
  187. }
  188. else
  189. {
  190. base->PMU_LDO_LPSR_ANA |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_LPSR_ANA_CONTROL_MODE_MASK;
  191. }
  192. }
  193. /*!
  194. * brief Sets the Bypass mode of the LPSR ANA LDO.
  195. *
  196. * param base ANADIG_LDO_SNVS peripheral base address.
  197. * param enable Enable/Disable bypass mode.
  198. * - \b true Enable LPSR ANA Bypass mode.
  199. * - \b false Disable LPSR ANA Bypass mode.
  200. */
  201. void PMU_StaticEnableLpsrAnaLdoBypassMode(ANADIG_LDO_SNVS_Type *base, bool enable)
  202. {
  203. if (enable == false)
  204. {
  205. /* Enable LPSR ANA LDO and HP mode. */
  206. base->PMU_LDO_LPSR_ANA &=
  207. ~(ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_LP_EN_MASK | ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_DISABLE_MASK);
  208. SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
  209. /* Clear Bypass. */
  210. base->PMU_LDO_LPSR_ANA &= ~(ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_BYPASS_MODE_EN_MASK);
  211. SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
  212. /* Disable Tracking mode. */
  213. base->PMU_LDO_LPSR_ANA &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_TRACK_MODE_EN_MASK;
  214. }
  215. else
  216. {
  217. /* Enable HP mode. */
  218. base->PMU_LDO_LPSR_ANA &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_LP_EN_MASK;
  219. SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
  220. /* Enable Tracking mode. */
  221. base->PMU_LDO_LPSR_ANA |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_TRACK_MODE_EN_MASK;
  222. SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
  223. /* Enabled Bypass. */
  224. base->PMU_LDO_LPSR_ANA |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_BYPASS_MODE_EN_MASK;
  225. SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
  226. /* Disable LPSR ANA LDO. */
  227. base->PMU_LDO_LPSR_ANA |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_DISABLE_MASK;
  228. }
  229. }
  230. /*!
  231. * brief Fill the LPSR ANA LDO configuration structure with default settings.
  232. *
  233. * The default values are:
  234. * code
  235. * config->mode = kPMU_HighPowerMode;
  236. config->enable2mALoad = true;
  237. config->enable20uALoad = false;
  238. config->enable4mALoad = true;
  239. config->enableStandbyMode = false;
  240. config->driverStrength = kPMU_LpsrAnaLdoDriverStrength0;
  241. config->brownOutDetectorConfig = kPMU_LpsrAnaLdoBrownOutDetectorDisable;
  242. config->chargePumpCurrent = kPMU_LpsrAnaChargePump300nA;
  243. config->outputRange = kPMU_LpsrAnaLdoOutputFrom1P77To1P83;
  244. * endcode
  245. *
  246. * param config Pointer to the structure pmu_static_lpsr_ana_ldo_config_t. Please refer to @ref
  247. * pmu_static_lpsr_ana_ldo_config_t.
  248. */
  249. void PMU_StaticGetLpsrAnaLdoDefaultConfig(pmu_static_lpsr_ana_ldo_config_t *config)
  250. {
  251. assert(config != NULL);
  252. (void)memset(config, 0, sizeof(*config));
  253. config->mode = kPMU_HighPowerMode;
  254. config->enable2mALoad = true;
  255. config->enable20uALoad = false;
  256. config->enable4mALoad = true;
  257. config->enableStandbyMode = false;
  258. }
  259. /*!
  260. * brief Initialize the LPSR ANA LDO in Static/Sofware Mode.
  261. *
  262. * param base ANADIG_LDO_SNVS peripheral base address.
  263. * param config Pointer to the structure pmu_static_lpsr_ana_ldo_config_t. Please refer to @ref
  264. * pmu_static_lpsr_ana_ldo_config_t.
  265. */
  266. void PMU_StaticLpsrAnaLdoInit(ANADIG_LDO_SNVS_Type *base, const pmu_static_lpsr_ana_ldo_config_t *config)
  267. {
  268. assert(config != NULL);
  269. uint32_t regValue = base->PMU_LDO_LPSR_ANA;
  270. regValue &=
  271. ~(ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_LP_EN_MASK | ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_PULL_DOWN_2MA_EN_MASK |
  272. ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_ALWAYS_4MA_PULLDOWN_EN_MASK |
  273. ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_PULL_DOWN_20UA_EN_MASK | ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_STANDBY_EN_MASK);
  274. if ((config->mode) == kPMU_LowPowerMode)
  275. {
  276. regValue |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_LP_EN_MASK;
  277. }
  278. regValue |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_PULL_DOWN_2MA_EN(config->enable2mALoad);
  279. regValue |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_ALWAYS_4MA_PULLDOWN_EN(config->enable4mALoad);
  280. regValue |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_PULL_DOWN_20UA_EN(config->enable20uALoad);
  281. regValue |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_STANDBY_EN(config->enableStandbyMode);
  282. base->PMU_LDO_LPSR_ANA = regValue;
  283. /* Enable LPSR ANA DIG. */
  284. base->PMU_LDO_LPSR_ANA &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_DISABLE_MASK;
  285. }
  286. /*!
  287. * brief Disable the output of LPSR ANA LDO.
  288. *
  289. * param base ANADIG_LDO_SNVS peripheral base address.
  290. */
  291. void PMU_StaticLpsrAnaLdoDeinit(ANADIG_LDO_SNVS_Type *base)
  292. {
  293. /* Disable LPSR ANA LDO. */
  294. base->PMU_LDO_LPSR_ANA |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_DISABLE_MASK;
  295. }
  296. /*!
  297. * brief Selects the control mode of the LPSR DIG LDO.
  298. *
  299. * param base ANADIG_LDO_SNVS peripheral base address.
  300. * param mode The control mode of the LPSR DIG LDO. Please refer to pmu_control_mode_t.
  301. */
  302. void PMU_SetLpsrDigLdoControlMode(ANADIG_LDO_SNVS_Type *base, pmu_control_mode_t mode)
  303. {
  304. if (mode == kPMU_StaticMode)
  305. {
  306. base->PMU_LDO_LPSR_DIG &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_LPSR_DIG_CONTROL_MODE_MASK;
  307. }
  308. else
  309. {
  310. base->PMU_LDO_LPSR_DIG |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_LPSR_DIG_CONTROL_MODE_MASK;
  311. }
  312. }
  313. /*!
  314. * brief Turn on/off Bypass mode of the LPSR DIG LDO in Static/Software mode.
  315. *
  316. * param base ANADIG_LDO_SNVS peripheral base address.
  317. * param enable
  318. * true - Turn on Bypass mode of the LPSR DIG LDO.
  319. * false - Turn off Bypass mode of the LPSR DIG LDO.
  320. */
  321. void PMU_StaticEnableLpsrDigLdoBypassMode(ANADIG_LDO_SNVS_Type *base, bool enable)
  322. {
  323. if (enable)
  324. {
  325. /* tracking */
  326. base->PMU_LDO_LPSR_DIG |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_TRACKING_MODE_MASK;
  327. SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
  328. /* set BYPASS */
  329. base->PMU_LDO_LPSR_DIG |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_BYPASS_MODE_MASK;
  330. SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
  331. /* Disable LPSR DIG LDO */
  332. base->PMU_LDO_LPSR_DIG &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_REG_EN_MASK;
  333. }
  334. else
  335. {
  336. /* Enable LPSR DIG LDO and HP mode */
  337. base->PMU_LDO_LPSR_DIG |= (ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_REG_EN_MASK);
  338. SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
  339. /* Clear BYPASS */
  340. base->PMU_LDO_LPSR_DIG &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_BYPASS_MODE_MASK;
  341. SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
  342. /* Disable tracking */
  343. base->PMU_LDO_LPSR_DIG &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_TRACKING_MODE_MASK;
  344. }
  345. }
  346. /*!
  347. * @brief Gets the default configuration of LPSR DIG LDO.
  348. *
  349. * @param config Pointer to the structure pmu_static_lpsr_dig_config_t. Please refer to @ref
  350. * pmu_static_lpsr_dig_config_t.
  351. */
  352. void PMU_StaticGetLpsrDigLdoDefaultConfig(pmu_static_lpsr_dig_config_t *config)
  353. {
  354. assert(config != NULL);
  355. (void)memset(config, 0, sizeof(*config));
  356. config->voltageStepTime = kPMU_LpsrDigVoltageStepInc50us;
  357. config->targetVoltage = kPMU_LpsrDigTargetStableVoltage1P0V;
  358. }
  359. /*!
  360. * @brief Initialize the LPSR DIG LDO in static mode.
  361. *
  362. * @param base ANADIG_LDO_SNVS peripheral base address.
  363. * @param config Pointer to the structure pmu_static_lpsr_dig_config_t. Please refer to @ref
  364. * pmu_static_lpsr_dig_config_t.
  365. */
  366. void PMU_StaticLpsrDigLdoInit(ANADIG_LDO_SNVS_Type *base, const pmu_static_lpsr_dig_config_t *config)
  367. {
  368. assert(config != NULL);
  369. uint32_t temp32 = base->PMU_LDO_LPSR_DIG;
  370. temp32 &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_VOLTAGE_SELECT_MASK;
  371. temp32 |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_VOLTAGE_SELECT(config->targetVoltage);
  372. base->PMU_LDO_LPSR_DIG = temp32;
  373. temp32 = base->PMU_LDO_LPSR_DIG_2;
  374. temp32 &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_2_VOLTAGE_STEP_INC_MASK;
  375. temp32 |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_2_VOLTAGE_STEP_INC(config->voltageStepTime);
  376. base->PMU_LDO_LPSR_DIG_2 = temp32;
  377. /* Enable LPSR DIG LDO. */
  378. base->PMU_LDO_LPSR_DIG |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_REG_EN_MASK;
  379. SDK_DelayAtLeastUs(125U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
  380. PMU_POWER_DETECT_CTRL_REGISTER |= ANADIG_PMU_PMU_POWER_DETECT_CTRL_CKGB_LPSR1P0_MASK;
  381. }
  382. /*!
  383. * @brief Disable the LPSR DIG LDO.
  384. *
  385. * @param base ANADIG_LDO_SNVS peripheral base address.
  386. */
  387. void PMU_StaticLpsrDigLdoDeinit(ANADIG_LDO_SNVS_Type *base)
  388. {
  389. PMU_POWER_DETECT_CTRL_REGISTER &= ~ANADIG_PMU_PMU_POWER_DETECT_CTRL_CKGB_LPSR1P0_MASK;
  390. base->PMU_LDO_LPSR_DIG &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_REG_EN_MASK;
  391. }
  392. /*!
  393. * brief Sets the voltage step of LPSR DIG LDO in the certain setpoint during GPC mode.
  394. *
  395. * note The function provides the feature to set the voltage step to the different setpoints.
  396. *
  397. * param setpointMap The map of setpoints should be the OR'ed Value of _pmu_setpoint_map.
  398. * param voltageStep The voltage step to be set.
  399. */
  400. void PMU_GPCSetLpsrDigLdoTargetVoltage(uint32_t setpointMap, pmu_lpsr_dig_target_output_voltage_t voltageValue)
  401. {
  402. uint32_t regValue = 0UL;
  403. const uint32_t lpsrDigTrgRegArray[] = PMU_LPSR_DIG_TRG_REGISTERS;
  404. uint8_t regIndex;
  405. uint8_t temp8;
  406. uint32_t i;
  407. for (regIndex = 0U; regIndex < ARRAY_SIZE(lpsrDigTrgRegArray); regIndex++)
  408. {
  409. temp8 = (((uint8_t)(setpointMap >> (PMU_LDO_LPSR_DIG_TRG_SPX_REG_SETPOINT_COUNTS * regIndex))) & 0xFU);
  410. if (temp8 != 0UL)
  411. {
  412. regValue = (*(volatile uint32_t *)lpsrDigTrgRegArray[regIndex]);
  413. for (i = 0U; i < PMU_LDO_LPSR_DIG_TRG_SPX_REG_SETPOINT_COUNTS; i++)
  414. {
  415. if (((temp8 >> (1U * i)) & 0x1U) != 0U)
  416. {
  417. regValue &= ~(0xFFUL << (PMU_LDO_LPSR_DIG_TRG_SPX_VOLTAGE_SETPOINTX_BIT_WIDTH * i));
  418. regValue |= (uint32_t)voltageValue << (PMU_LDO_LPSR_DIG_TRG_SPX_VOLTAGE_SETPOINTX_BIT_WIDTH * i);
  419. }
  420. }
  421. (*(volatile uint32_t *)lpsrDigTrgRegArray[regIndex]) = regValue;
  422. }
  423. }
  424. }
  425. /*!
  426. * brief Gets the default config of the SNVS DIG LDO.
  427. *
  428. * The default values are:
  429. * code
  430. * config->mode = kPMU_LowPowerMode;
  431. * config->chargePumpCurrent = kPMU_SnvsDigChargePump12P5nA;
  432. * config->dischargeResistorValue = kPMU_SnvsDigDischargeResistor15K;
  433. * config->trimValue = 0U;
  434. * config->enablePullDown = true;
  435. * config->enableLdoStable = false;
  436. * endcode
  437. *
  438. * param config Pointer to the structure pmu_snvs_dig_config_t. Please refer to pmu_snvs_dig_config_t.
  439. */
  440. void PMU_GetSnvsDigLdoDefaultConfig(pmu_snvs_dig_config_t *config)
  441. {
  442. assert(config != NULL);
  443. (void)memset(config, 0, sizeof(*config));
  444. config->mode = kPMU_LowPowerMode;
  445. config->chargePumpCurrent = kPMU_SnvsDigChargePump12P5nA;
  446. config->dischargeResistorValue = kPMU_SnvsDigDischargeResistor15K;
  447. config->trimValue = 0U;
  448. config->enablePullDown = true;
  449. config->enableLdoStable = false;
  450. }
  451. /*!
  452. * brief Initialize the SNVS DIG LDO.
  453. *
  454. * param base LDO SNVS DIG peripheral base address.
  455. * param mode Used to control LDO power mode, please refer to pmu_ldo_operate_mode_t.
  456. */
  457. void PMU_SnvsDigLdoInit(ANADIG_LDO_SNVS_DIG_Type *base, pmu_ldo_operate_mode_t mode)
  458. {
  459. uint32_t temp32 = base->PMU_LDO_SNVS_DIG;
  460. temp32 &= ~(ANADIG_LDO_SNVS_DIG_PMU_LDO_SNVS_DIG_REG_LP_EN_MASK);
  461. temp32 |= (ANADIG_LDO_SNVS_DIG_PMU_LDO_SNVS_DIG_REG_LP_EN(mode) | ANADIG_LDO_SNVS_DIG_PMU_LDO_SNVS_DIG_REG_EN_MASK);
  462. base->PMU_LDO_SNVS_DIG = temp32;
  463. }
  464. /*!
  465. * brief Controls the ON/OFF of the selected LDO in the certain setpoints with GPC mode.
  466. *
  467. * param name The name of the selected ldo. Please see the enumeration pmu_ldo_name_t for details.
  468. * param setpointMap The map of setpoints should be the OR'ed Value of @ref _pmu_setpoint_map, 1b'1
  469. * means enable specific ldo in that setpoint.
  470. * For example, the code PMU_GPCEnableLdo(kPMU_PllLdo, 0x1U) means enable PLL LDO in setpoint 0, disable
  471. * PLL LDO in other setpoint.
  472. */
  473. void PMU_GPCEnableLdo(pmu_ldo_name_t name, uint32_t setpointMap)
  474. {
  475. assert(name != kPMU_SnvsDigLdo);
  476. uint32_t ldoEnableRegArray[] = PMU_LDO_ENABLE_SETPOINT_REGISTERS;
  477. (*(volatile uint32_t *)ldoEnableRegArray[(uint8_t)name]) = ~setpointMap;
  478. }
  479. /*!
  480. * brief Sets the operating mode of the selected LDO in the certain setpoints with GPC mode.
  481. *
  482. * param name The name of the selected ldo. Please see the enumeration pmu_ldo_name_t for details.
  483. * param setpointMap The map of setpoints should be the OR'ed Value of _pmu_setpoint_map.
  484. * param mode The operating mode of the selected ldo. Please refer to the enumeration pmu_ldo_operate_mode_t for
  485. * details.
  486. */
  487. void PMU_GPCSetLdoOperateMode(pmu_ldo_name_t name, uint32_t setpointMap, pmu_ldo_operate_mode_t mode)
  488. {
  489. assert(name > kPMU_PllLdo);
  490. assert(name < kPMU_SnvsDigLdo);
  491. uint32_t ldoLpModeRegArray[] = PMU_LDO_LP_MODE_EN_SETPOINT_REGISTERS;
  492. if (mode == kPMU_LowPowerMode)
  493. {
  494. (*(volatile uint32_t *)ldoLpModeRegArray[(uint8_t)name]) &= ~setpointMap;
  495. }
  496. else
  497. {
  498. (*(volatile uint32_t *)ldoLpModeRegArray[(uint8_t)name]) |= setpointMap;
  499. }
  500. }
  501. /*!
  502. * brief Controls the ON/OFF of the selected LDOs' Tracking mode in the certain setpoints with GPC mode.
  503. *
  504. * param name The name of the selected ldo. Please see the enumeration pmu_ldo_name_t for details.
  505. * param setpointMap The map of setpoints that the LDO tracking mode will be enabled in those setpoints, this value
  506. * should be the OR'ed Value of @ref _pmu_setpoint_map.
  507. */
  508. void PMU_GPCEnableLdoTrackingMode(pmu_ldo_name_t name, uint32_t setpointMap)
  509. {
  510. assert(name > kPMU_PllLdo);
  511. assert(name < kPMU_SnvsDigLdo);
  512. uint32_t ldoTrackingEnableRegArray[] = PMU_LDO_TRACKING_EN_SETPOINT_REGISTERS;
  513. (*(volatile uint32_t *)ldoTrackingEnableRegArray[(uint8_t)name]) = setpointMap;
  514. }
  515. /*!
  516. * brief Controls the ON/OFF of the selected LDOs' Bypass mode in the certain setpoints with GPC mode.
  517. *
  518. * param name The name of the selected ldo. Please see the enumeration pmu_ldo_name_t for details.
  519. * param setpointMap The map of setpoints that the LDO bypass mode will be enabled in those setpoints, this value
  520. * should be the OR'ed Value of @ref _pmu_setpoint_map.
  521. */
  522. void PMU_GPCEnableLdoBypassMode(pmu_ldo_name_t name, uint32_t setpointMap)
  523. {
  524. assert(name > kPMU_PllLdo);
  525. assert(name < kPMU_SnvsDigLdo);
  526. uint32_t ldoBypassEnableRegArray[] = PMU_LDO_BYPASS_EN_SETPOINT_REGISTERS;
  527. (*(volatile uint32_t *)ldoBypassEnableRegArray[(uint8_t)name]) = setpointMap;
  528. }
  529. /*!
  530. * brief When STBY assert, enable/disable the selected LDO enter it's Low power mode.
  531. *
  532. * param name The name of the selected ldo. Please see the enumeration pmu_ldo_name_t for details.
  533. * param setpointMap The map of setpoints that the LDO low power mode will be enabled in those setpoints if STBY
  534. * assert, this value should be the OR'ed Value of @ref _pmu_setpoint_map.
  535. */
  536. void PMU_GPCEnableLdoStandbyMode(pmu_ldo_name_t name, uint32_t setpointMap)
  537. {
  538. assert(name != kPMU_SnvsDigLdo);
  539. uint32_t ldoStandbyEnableRegArray[] = PMU_LDO_STBY_EN_REGISTERS;
  540. (*(volatile uint32_t *)ldoStandbyEnableRegArray[(uint8_t)name]) = setpointMap;
  541. }
  542. /*!
  543. * brief Selects the control mode of the Bandgap Reference.
  544. *
  545. * param base PMU peripheral base address.
  546. * param mode The control mode of the Bandgap Reference. Please refer to pmu_control_mode_t.
  547. */
  548. void PMU_SetBandgapControlMode(ANADIG_PMU_Type *base, pmu_control_mode_t mode)
  549. {
  550. if (mode == kPMU_StaticMode)
  551. {
  552. base->PMU_REF_CTRL &= ~ANADIG_PMU_PMU_REF_CTRL_REF_CONTROL_MODE_MASK;
  553. }
  554. else
  555. {
  556. base->PMU_REF_CTRL |= ANADIG_PMU_PMU_REF_CTRL_REF_CONTROL_MODE_MASK;
  557. }
  558. }
  559. /*!
  560. * brief Switches the Bandgap from Static/Software Mode to GPC/Hardware Mode.
  561. *
  562. * param base PMU peripheral base address.
  563. */
  564. void PMU_SwitchBandgapToGPCMode(ANADIG_PMU_Type *base)
  565. {
  566. if ((base->BANDGAP_ENABLE_SP & ANADIG_PMU_BANDGAP_ENABLE_SP_ON_OFF_SETPOINT0_MASK) == 0UL)
  567. {
  568. base->PMU_REF_CTRL &= ~ANADIG_PMU_PMU_REF_CTRL_REF_ENABLE_MASK;
  569. }
  570. else
  571. {
  572. base->PMU_REF_CTRL |= ANADIG_PMU_PMU_REF_CTRL_REF_ENABLE_MASK;
  573. }
  574. }
  575. /*!
  576. * brief Disables Bandgap self bias for best noise performance.
  577. *
  578. * This function waits for the bandgap to be stable and disables the bandgap self bias.
  579. * After being powered up, it needs to wait for the bandgap stable to be stable and then disable Bandgap
  580. * Self bias for best noise performance.
  581. */
  582. void PMU_DisableBandgapSelfBiasAfterPowerUp(void)
  583. {
  584. uint32_t temp32;
  585. uint32_t regValue;
  586. /* Wait Bandgap stable. */
  587. do
  588. {
  589. regValue = ANATOP_AI_Read(kAI_Itf_Bandgap, kAI_BANDGAP_STAT0);
  590. } while ((regValue & AI_BANDGAP_STAT0_REFTOP_VBGUP_MASK) == 0UL);
  591. /* Disable Bandgap self bias for best noise performance. */
  592. temp32 = ANATOP_AI_Read(kAI_Itf_Bandgap, kAI_BANDGAP_CTRL0);
  593. temp32 |= AI_BANDGAP_CTRL0_REFTOP_SELFBIASOFF_MASK;
  594. ANATOP_AI_Write(kAI_Itf_Bandgap, kAI_BANDGAP_CTRL0, temp32);
  595. }
  596. /*!
  597. * brief Enables Bandgap self bias before power down.
  598. *
  599. * This function will enable Bandgap self bias feature before powering down or there
  600. * will be risk of Bandgap not starting properly.
  601. */
  602. void PMU_EnableBandgapSelfBiasBeforePowerDown(void)
  603. {
  604. uint32_t temp32;
  605. temp32 = ANATOP_AI_Read(kAI_Itf_Bandgap, kAI_BANDGAP_CTRL0);
  606. temp32 &= ~AI_BANDGAP_CTRL0_REFTOP_SELFBIASOFF_MASK;
  607. ANATOP_AI_Write(kAI_Itf_Bandgap, kAI_BANDGAP_CTRL0, temp32);
  608. }
  609. /*!
  610. * brief Init Bandgap.
  611. *
  612. * param config. Pointer to the structure pmu_static_bandgap_config_t. Please refer to pmu_static_bandgap_config_t.
  613. */
  614. void PMU_StaticBandgapInit(const pmu_static_bandgap_config_t *config)
  615. {
  616. assert(config != NULL);
  617. uint32_t temp32;
  618. temp32 = ANATOP_AI_Read(kAI_Itf_Bandgap, kAI_BANDGAP_CTRL0);
  619. temp32 &= ~(AI_BANDGAP_CTRL0_REFTOP_PWD_MASK | AI_BANDGAP_CTRL0_REFTOP_LINREGREF_PWD_MASK |
  620. AI_BANDGAP_CTRL0_REFTOP_PWDVBGUP_MASK | AI_BANDGAP_CTRL0_REFTOP_LOWPOWER_MASK |
  621. AI_BANDGAP_CTRL0_REFTOP_VBGADJ_MASK | AI_BANDGAP_CTRL0_REFTOP_IBZTCADJ_MASK);
  622. temp32 |= ((uint32_t)(config->powerDownOption) &
  623. (AI_BANDGAP_CTRL0_REFTOP_PWD_MASK | AI_BANDGAP_CTRL0_REFTOP_LINREGREF_PWD_MASK |
  624. AI_BANDGAP_CTRL0_REFTOP_PWDVBGUP_MASK));
  625. temp32 |= AI_BANDGAP_CTRL0_REFTOP_LOWPOWER(config->enableLowPowerMode);
  626. temp32 |= AI_BANDGAP_CTRL0_REFTOP_VBGADJ(config->outputVoltage);
  627. temp32 |= AI_BANDGAP_CTRL0_REFTOP_IBZTCADJ(config->outputCurrent);
  628. ANATOP_AI_Write(kAI_Itf_Bandgap, kAI_BANDGAP_CTRL0, temp32);
  629. }
  630. /*!
  631. * brief Configures Well bias, such as power source, clock source and so on.
  632. *
  633. * param base PMU peripheral base address.
  634. * param config Pointer to the pmu_well_bias_config_t structure.
  635. */
  636. void PMU_WellBiasInit(ANADIG_PMU_Type *base, const pmu_well_bias_config_t *config)
  637. {
  638. assert(config != NULL);
  639. uint32_t tmp32;
  640. tmp32 = base->PMU_BIAS_CTRL;
  641. tmp32 &= ~(ANADIG_PMU_PMU_BIAS_CTRL_WB_CFG_1P8_MASK | ANADIG_PMU_PMU_BIAS_CTRL_WB_VDD_SEL_1P8_MASK);
  642. tmp32 |= ((uint32_t)config->wellBiasOption.wellBiasData &
  643. (ANADIG_PMU_PMU_BIAS_CTRL_WB_CFG_1P8_MASK | ANADIG_PMU_PMU_BIAS_CTRL_WB_VDD_SEL_1P8_MASK));
  644. base->PMU_BIAS_CTRL = tmp32;
  645. tmp32 = base->PMU_BIAS_CTRL2;
  646. tmp32 &= ~ANADIG_PMU_PMU_BIAS_CTRL2_WB_ADJ_1P8_MASK;
  647. tmp32 |= ANADIG_PMU_PMU_BIAS_CTRL2_WB_ADJ_1P8(config->adjustment);
  648. base->PMU_BIAS_CTRL2 = tmp32;
  649. }
  650. /*!
  651. * brief Enables/disables the selected body bias.
  652. *
  653. * param base PMU peripheral base address.
  654. * param name The name of the body bias to be turned on/off, please refer to pmu_body_bias_name_t.
  655. * param enable Used to turn on/off the specific body bias.
  656. * - \b true Enable the selected body bias.
  657. * - \b false Disable the selected body bias.
  658. */
  659. void PMU_GetWellBiasDefaultConfig(pmu_well_bias_config_t *config)
  660. {
  661. assert(config != NULL);
  662. (void)memset(config, 0, sizeof(*config));
  663. config->wellBiasOption.wellBiasData = 0U;
  664. config->adjustment = kPMU_Cref0fFCspl0fFDeltaC0fF;
  665. }
  666. /*!
  667. * brief Selects the control mode of the Body Bias.
  668. *
  669. * param base PMU peripheral base address.
  670. * param name The name of the body bias. Please refer to pmu_body_bias_name_t.
  671. * param mode The control mode of the Body Bias. Please refer to pmu_control_mode_t.
  672. */
  673. void PMU_SetBodyBiasControlMode(ANADIG_PMU_Type *base, pmu_body_bias_name_t name, pmu_control_mode_t mode)
  674. {
  675. uint32_t temp32;
  676. switch (name)
  677. {
  678. #if (defined(PMU_HAS_FBB) && PMU_HAS_FBB)
  679. case kPMU_FBB_CM7:
  680. {
  681. temp32 = base->PMU_BIAS_CTRL2;
  682. temp32 &= ~ANADIG_PMU_PMU_BIAS_CTRL2_FBB_M7_CONTROL_MODE_MASK;
  683. temp32 |= ANADIG_PMU_PMU_BIAS_CTRL2_FBB_M7_CONTROL_MODE(mode);
  684. base->PMU_BIAS_CTRL2 = temp32;
  685. break;
  686. }
  687. #endif /* PMU_HAS_FBB */
  688. case kPMU_RBB_SOC:
  689. {
  690. temp32 = base->PMU_BIAS_CTRL2;
  691. temp32 &= ~ANADIG_PMU_PMU_BIAS_CTRL2_RBB_SOC_CONTROL_MODE_MASK;
  692. temp32 |= ANADIG_PMU_PMU_BIAS_CTRL2_RBB_SOC_CONTROL_MODE(mode);
  693. base->PMU_BIAS_CTRL2 = temp32;
  694. break;
  695. }
  696. case kPMU_RBB_LPSR:
  697. {
  698. temp32 = base->PMU_BIAS_CTRL2;
  699. temp32 &= ~ANADIG_PMU_PMU_BIAS_CTRL2_RBB_LPSR_CONTROL_MODE_MASK;
  700. temp32 |= ANADIG_PMU_PMU_BIAS_CTRL2_RBB_LPSR_CONTROL_MODE(mode);
  701. base->PMU_BIAS_CTRL2 = temp32;
  702. break;
  703. }
  704. default:
  705. /* This branch should never be hit. */
  706. break;
  707. }
  708. }
  709. /*!
  710. * brief Enables/disables the selected body bias.
  711. *
  712. * param base PMU peripheral base address.
  713. * param name The name of the body bias to be turned on/off, please refer to pmu_body_bias_name_t.
  714. * param enable Used to turn on/off the specific body bias.
  715. * - \b true Enable the selected body bias.
  716. * - \b false Disable the selected body bias.
  717. */
  718. void PMU_EnableBodyBias(ANADIG_PMU_Type *base, pmu_body_bias_name_t name, bool enable)
  719. {
  720. uint32_t tmp32;
  721. if (enable)
  722. {
  723. switch (name)
  724. {
  725. #if (defined(PMU_HAS_FBB) && PMU_HAS_FBB)
  726. case kPMU_FBB_CM7:
  727. {
  728. tmp32 = base->PMU_BIAS_CTRL;
  729. tmp32 &= ~PMU_BIAS_CTRL_WB_CFG_1P8_WELL_SELECT_MASK;
  730. tmp32 |= PMU_BIAS_CTRL_WB_CFG_1P8_VOLTAGE_THRESHOLD_MASK;
  731. base->PMU_BIAS_CTRL = tmp32;
  732. tmp32 = base->PMU_BIAS_CTRL2;
  733. tmp32 &= ~(ANADIG_PMU_PMU_BIAS_CTRL2_WB_PWR_SW_EN_1P8_MASK);
  734. tmp32 |= ANADIG_PMU_PMU_BIAS_CTRL2_WB_PWR_SW_EN_1P8(1U) | ANADIG_PMU_PMU_BIAS_CTRL2_WB_EN_MASK;
  735. base->PMU_BIAS_CTRL2 = tmp32;
  736. while ((base->PMU_BIAS_CTRL2 & ANADIG_PMU_PMU_BIAS_CTRL2_WB_OK_MASK) !=
  737. ANADIG_PMU_PMU_BIAS_CTRL2_WB_OK_MASK)
  738. {
  739. }
  740. break;
  741. }
  742. #endif /* PMU_HAS_FBB */
  743. case kPMU_RBB_SOC:
  744. {
  745. tmp32 = base->PMU_BIAS_CTRL;
  746. tmp32 &= ~(PMU_BIAS_CTRL_WB_CFG_1P8_WELL_SELECT_MASK | PMU_BIAS_CTRL_WB_CFG_1P8_VOLTAGE_THRESHOLD_MASK);
  747. base->PMU_BIAS_CTRL = tmp32;
  748. tmp32 = base->PMU_BIAS_CTRL2;
  749. tmp32 &= ~(ANADIG_PMU_PMU_BIAS_CTRL2_WB_PWR_SW_EN_1P8_MASK);
  750. tmp32 |= ANADIG_PMU_PMU_BIAS_CTRL2_WB_PWR_SW_EN_1P8(2U) | ANADIG_PMU_PMU_BIAS_CTRL2_WB_EN_MASK;
  751. base->PMU_BIAS_CTRL2 = tmp32;
  752. while ((base->PMU_BIAS_CTRL2 & ANADIG_PMU_PMU_BIAS_CTRL2_WB_OK_MASK) !=
  753. ANADIG_PMU_PMU_BIAS_CTRL2_WB_OK_MASK)
  754. {
  755. }
  756. break;
  757. }
  758. case kPMU_RBB_LPSR:
  759. {
  760. tmp32 = base->PMU_BIAS_CTRL;
  761. tmp32 &= ~(PMU_BIAS_CTRL_WB_CFG_1P8_WELL_SELECT_MASK | PMU_BIAS_CTRL_WB_CFG_1P8_VOLTAGE_THRESHOLD_MASK);
  762. base->PMU_BIAS_CTRL = tmp32;
  763. tmp32 = base->PMU_BIAS_CTRL2;
  764. tmp32 &= ~(ANADIG_PMU_PMU_BIAS_CTRL2_WB_PWR_SW_EN_1P8_MASK);
  765. tmp32 |= ANADIG_PMU_PMU_BIAS_CTRL2_WB_PWR_SW_EN_1P8(4U) | ANADIG_PMU_PMU_BIAS_CTRL2_WB_EN_MASK;
  766. base->PMU_BIAS_CTRL2 = tmp32;
  767. while ((base->PMU_BIAS_CTRL2 & ANADIG_PMU_PMU_BIAS_CTRL2_WB_OK_MASK) !=
  768. ANADIG_PMU_PMU_BIAS_CTRL2_WB_OK_MASK)
  769. {
  770. }
  771. break;
  772. }
  773. default:
  774. /* This branch should never be hit. */
  775. break;
  776. }
  777. }
  778. else
  779. {
  780. base->PMU_BIAS_CTRL2 &=
  781. ~(ANADIG_PMU_PMU_BIAS_CTRL2_WB_PWR_SW_EN_1P8_MASK | ANADIG_PMU_PMU_BIAS_CTRL2_WB_EN_MASK);
  782. }
  783. }
  784. /*!
  785. * brief Controls the ON/OFF of the selected body bias in the certain setpoints with GPC mode.
  786. *
  787. * param name The name of the selected body bias. Please see the enumeration pmu_body_bias_name_t for details.
  788. * param setpointMap The map of setpoints that the specific body bias will be enabled in those setpoints, this value
  789. * should be the OR'ed Value of _pmu_setpoint_map.
  790. */
  791. void PMU_GPCEnableBodyBias(pmu_body_bias_name_t name, uint32_t setpointMap)
  792. {
  793. uint32_t bodyBiasEnableRegArray[] = PMU_BODY_BIAS_ENABLE_REGISTERS;
  794. (*(volatile uint32_t *)bodyBiasEnableRegArray[(uint8_t)name]) = ~setpointMap;
  795. }
  796. /*!
  797. * brief Controls the ON/OFF of the selected Body Bias' Wbias power switch in certain setpoints with GPC mode.
  798. *
  799. * param name The name of the selected body bias. Please see the enumeration pmu_body_bias_name_t for details.
  800. * param setpointMap The map of setpoints that the specific body bias's wbias power switch will be turn on in those
  801. * setpoints, this value should be the OR'ed Value of _pmu_setpoint_map.
  802. */
  803. void PMU_GPCEnableBodyBiasStandbyMode(pmu_body_bias_name_t name, uint32_t setpointMap)
  804. {
  805. uint32_t BBStandbyEnableRegArray[] = PMU_BODY_BIAS_STBY_EN_REGISTERS;
  806. (*(volatile uint32_t *)BBStandbyEnableRegArray[(uint8_t)name]) = setpointMap;
  807. }
  808. /*!
  809. * brief Gets the default config of body bias in GPC mode.
  810. *
  811. * param config Pointer to the structure pmu_gpc_body_bias_config_t.
  812. */
  813. void PMU_GPCGetBodyBiasDefaultConfig(pmu_gpc_body_bias_config_t *config)
  814. {
  815. assert(config != NULL);
  816. config->PWELLRegulatorSize = 1U;
  817. config->NWELLRegulatorSize = 1U;
  818. config->oscillatorSize = 7U;
  819. config->regulatorStrength = 5U;
  820. }
  821. /*!
  822. * brief Sets the config of the selected Body Bias in GPC mode.
  823. *
  824. * param name The name of the selected body bias. Please see the enumeration pmu_body_bias_name_t for details.
  825. * param config Pointer to the structure pmu_gpc_body_bias_config_t.
  826. */
  827. void PMU_GPCSetBodyBiasConfig(pmu_body_bias_name_t name, const pmu_gpc_body_bias_config_t *config)
  828. {
  829. assert(config != NULL);
  830. uint32_t bodyBiasConfigRegArray[] = PMU_BODY_BIAS_CONFIGURE_REGISTERS;
  831. uint32_t temp32;
  832. temp32 = (*(volatile uint32_t *)bodyBiasConfigRegArray[(uint8_t)name]);
  833. temp32 &=
  834. (ANADIG_PMU_RBB_SOC_CONFIGURE_WB_CFG_PW_MASK | ANADIG_PMU_RBB_SOC_CONFIGURE_WB_CFG_NW_MASK |
  835. ANADIG_PMU_RBB_SOC_CONFIGURE_OSCILLATOR_BITS_MASK | ANADIG_PMU_RBB_SOC_CONFIGURE_REGULATOR_STRENGTH_MASK);
  836. temp32 |= ANADIG_PMU_RBB_SOC_CONFIGURE_WB_CFG_PW(config->PWELLRegulatorSize) |
  837. ANADIG_PMU_RBB_SOC_CONFIGURE_WB_CFG_NW(config->NWELLRegulatorSize) |
  838. ANADIG_PMU_RBB_SOC_CONFIGURE_OSCILLATOR_BITS(config->oscillatorSize) |
  839. ANADIG_PMU_RBB_SOC_CONFIGURE_REGULATOR_STRENGTH(config->regulatorStrength);
  840. (*(volatile uint32_t *)bodyBiasConfigRegArray[(uint8_t)name]) = temp32;
  841. }