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