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))
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 /* Disable LDO current limit after LDO is stable to minimize ARM PLL jitter in cold temperature. */
207 ANATOP_AI_WriteWithMaskShift(kAI_Itf_Ldo, kAI_PHY_LDO_CTRL0, 0UL,
208 AI_PHY_LDO_CTRL0_LIMIT_EN_MASK, AI_PHY_LDO_CTRL0_LIMIT_EN_SHIFT);
209
210 /* Enable Voltage Reference for PLLs before those PLLs were enabled. */
211 base->PMU_REF_CTRL |= ANADIG_PMU_PMU_REF_CTRL_EN_PLL_VOL_REF_BUFFER_MASK;
212 }
213 }
214
215 /*!
216 * brief Disables PLL LDO via AI interface in Static/Software mode.
217 */
PMU_StaticDisablePllLdo(void)218 void PMU_StaticDisablePllLdo(void)
219 {
220 ANATOP_AI_Write(kAI_Itf_Ldo, kAI_PHY_LDO_CTRL0, 0UL);
221 }
222
223 /*!
224 * brief Selects the control mode of the LPSR ANA LDO.
225 *
226 * param base PMU peripheral base address.
227 * param mode The control mode of the LPSR ANA LDO. Please refer to pmu_control_mode_t.
228 */
PMU_SetLpsrAnaLdoControlMode(ANADIG_LDO_SNVS_Type * base,pmu_control_mode_t mode)229 void PMU_SetLpsrAnaLdoControlMode(ANADIG_LDO_SNVS_Type *base, pmu_control_mode_t mode)
230 {
231 if (mode == kPMU_StaticMode)
232 {
233 base->PMU_LDO_LPSR_ANA &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_LPSR_ANA_CONTROL_MODE_MASK;
234 }
235 else
236 {
237 base->PMU_LDO_LPSR_ANA |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_LPSR_ANA_CONTROL_MODE_MASK;
238 }
239 }
240
241 /*!
242 * brief Sets the Bypass mode of the LPSR ANA LDO.
243 *
244 * param base ANADIG_LDO_SNVS peripheral base address.
245 * param enable Enable/Disable bypass mode.
246 * - \b true Enable LPSR ANA Bypass mode.
247 * - \b false Disable LPSR ANA Bypass mode.
248 */
PMU_StaticEnableLpsrAnaLdoBypassMode(ANADIG_LDO_SNVS_Type * base,bool enable)249 void PMU_StaticEnableLpsrAnaLdoBypassMode(ANADIG_LDO_SNVS_Type *base, bool enable)
250 {
251 if (enable == false)
252 {
253 /* Enable LPSR ANA LDO and HP mode. */
254 base->PMU_LDO_LPSR_ANA &=
255 ~(ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_LP_EN_MASK | ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_DISABLE_MASK);
256 SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
257
258 /* Clear Bypass. */
259 base->PMU_LDO_LPSR_ANA &= ~(ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_BYPASS_MODE_EN_MASK);
260 SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
261
262 /* Disable Tracking mode. */
263 base->PMU_LDO_LPSR_ANA &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_TRACK_MODE_EN_MASK;
264 }
265 else
266 {
267 /* Enable HP mode. */
268 base->PMU_LDO_LPSR_ANA &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_LP_EN_MASK;
269 SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
270
271 /* Enable Tracking mode. */
272 base->PMU_LDO_LPSR_ANA |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_TRACK_MODE_EN_MASK;
273 SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
274
275 /* Enabled Bypass. */
276 base->PMU_LDO_LPSR_ANA |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_BYPASS_MODE_EN_MASK;
277 SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
278
279 /* Disable LPSR ANA LDO. */
280 base->PMU_LDO_LPSR_ANA |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_DISABLE_MASK;
281 }
282 }
283
284 /*!
285 * brief Fill the LPSR ANA LDO configuration structure with default settings.
286 *
287 * The default values are:
288 * code
289 * config->mode = kPMU_HighPowerMode;
290 config->enable2mALoad = true;
291 config->enable20uALoad = false;
292 config->enable4mALoad = true;
293 config->enableStandbyMode = false;
294 config->driverStrength = kPMU_LpsrAnaLdoDriverStrength0;
295 config->brownOutDetectorConfig = kPMU_LpsrAnaLdoBrownOutDetectorDisable;
296 config->chargePumpCurrent = kPMU_LpsrAnaChargePump300nA;
297 config->outputRange = kPMU_LpsrAnaLdoOutputFrom1P77To1P83;
298 * endcode
299 *
300 * param config Pointer to the structure pmu_static_lpsr_ana_ldo_config_t. Please refer to @ref
301 * pmu_static_lpsr_ana_ldo_config_t.
302 */
PMU_StaticGetLpsrAnaLdoDefaultConfig(pmu_static_lpsr_ana_ldo_config_t * config)303 void PMU_StaticGetLpsrAnaLdoDefaultConfig(pmu_static_lpsr_ana_ldo_config_t *config)
304 {
305 assert(config != NULL);
306
307 (void)memset(config, 0, sizeof(*config));
308
309 config->mode = kPMU_HighPowerMode;
310 config->enable2mALoad = true;
311 config->enable20uALoad = false;
312 config->enable4mALoad = true;
313 config->enableStandbyMode = false;
314 }
315
316 /*!
317 * brief Initialize the LPSR ANA LDO in Static/Sofware Mode.
318 *
319 * param base ANADIG_LDO_SNVS peripheral base address.
320 * param config Pointer to the structure pmu_static_lpsr_ana_ldo_config_t. Please refer to @ref
321 * pmu_static_lpsr_ana_ldo_config_t.
322 */
PMU_StaticLpsrAnaLdoInit(ANADIG_LDO_SNVS_Type * base,const pmu_static_lpsr_ana_ldo_config_t * config)323 void PMU_StaticLpsrAnaLdoInit(ANADIG_LDO_SNVS_Type *base, const pmu_static_lpsr_ana_ldo_config_t *config)
324 {
325 assert(config != NULL);
326
327 uint32_t regValue = base->PMU_LDO_LPSR_ANA;
328
329 regValue &=
330 ~(ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_LP_EN_MASK | ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_PULL_DOWN_2MA_EN_MASK |
331 ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_ALWAYS_4MA_PULLDOWN_EN_MASK |
332 ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_PULL_DOWN_20UA_EN_MASK | ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_STANDBY_EN_MASK);
333
334 if ((config->mode) == kPMU_LowPowerMode)
335 {
336 regValue |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_LP_EN_MASK;
337 }
338 regValue |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_PULL_DOWN_2MA_EN(config->enable2mALoad);
339 regValue |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_ALWAYS_4MA_PULLDOWN_EN(config->enable4mALoad);
340 regValue |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_PULL_DOWN_20UA_EN(config->enable20uALoad);
341 regValue |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_STANDBY_EN(config->enableStandbyMode);
342
343 base->PMU_LDO_LPSR_ANA = regValue;
344
345 /* Enable LPSR ANA DIG. */
346 base->PMU_LDO_LPSR_ANA &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_DISABLE_MASK;
347 }
348
349 /*!
350 * brief Disable the output of LPSR ANA LDO.
351 *
352 * param base ANADIG_LDO_SNVS peripheral base address.
353 */
PMU_StaticLpsrAnaLdoDeinit(ANADIG_LDO_SNVS_Type * base)354 void PMU_StaticLpsrAnaLdoDeinit(ANADIG_LDO_SNVS_Type *base)
355 {
356 /* Disable LPSR ANA LDO. */
357 base->PMU_LDO_LPSR_ANA |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_REG_DISABLE_MASK;
358 }
359
360 /*!
361 * brief Selects the control mode of the LPSR DIG LDO.
362 *
363 * param base ANADIG_LDO_SNVS peripheral base address.
364 * param mode The control mode of the LPSR DIG LDO. Please refer to pmu_control_mode_t.
365 */
PMU_SetLpsrDigLdoControlMode(ANADIG_LDO_SNVS_Type * base,pmu_control_mode_t mode)366 void PMU_SetLpsrDigLdoControlMode(ANADIG_LDO_SNVS_Type *base, pmu_control_mode_t mode)
367 {
368 if (mode == kPMU_StaticMode)
369 {
370 base->PMU_LDO_LPSR_DIG &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_LPSR_DIG_CONTROL_MODE_MASK;
371 }
372 else
373 {
374 base->PMU_LDO_LPSR_DIG |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_LPSR_DIG_CONTROL_MODE_MASK;
375 }
376 }
377
378 /*!
379 * brief Turn on/off Bypass mode of the LPSR DIG LDO in Static/Software mode.
380 *
381 * param base ANADIG_LDO_SNVS peripheral base address.
382 * param enable
383 * true - Turn on Bypass mode of the LPSR DIG LDO.
384 * false - Turn off Bypass mode of the LPSR DIG LDO.
385 */
PMU_StaticEnableLpsrDigLdoBypassMode(ANADIG_LDO_SNVS_Type * base,bool enable)386 void PMU_StaticEnableLpsrDigLdoBypassMode(ANADIG_LDO_SNVS_Type *base, bool enable)
387 {
388 if (enable)
389 {
390 /* tracking */
391 base->PMU_LDO_LPSR_DIG |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_TRACKING_MODE_MASK;
392 SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
393
394 /* set BYPASS */
395 base->PMU_LDO_LPSR_DIG |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_BYPASS_MODE_MASK;
396 SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
397
398 /* Disable LPSR DIG LDO */
399 base->PMU_LDO_LPSR_DIG &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_REG_EN_MASK;
400 }
401 else
402 {
403 /* Enable LPSR DIG LDO and HP mode */
404 base->PMU_LDO_LPSR_DIG |= (ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_REG_EN_MASK);
405 SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
406
407 /* Clear BYPASS */
408 base->PMU_LDO_LPSR_DIG &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_BYPASS_MODE_MASK;
409 SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
410
411 /* Disable tracking */
412 base->PMU_LDO_LPSR_DIG &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_TRACKING_MODE_MASK;
413 }
414 }
415
416 /*!
417 * @brief Gets the default configuration of LPSR DIG LDO.
418 *
419 * @param config Pointer to the structure pmu_static_lpsr_dig_config_t. Please refer to @ref
420 * pmu_static_lpsr_dig_config_t.
421 */
PMU_StaticGetLpsrDigLdoDefaultConfig(pmu_static_lpsr_dig_config_t * config)422 void PMU_StaticGetLpsrDigLdoDefaultConfig(pmu_static_lpsr_dig_config_t *config)
423 {
424 assert(config != NULL);
425
426 (void)memset(config, 0, sizeof(*config));
427
428 config->voltageStepTime = kPMU_LpsrDigVoltageStepInc50us;
429 config->targetVoltage = kPMU_LpsrDigTargetStableVoltage1P0V;
430 }
431
432 /*!
433 * @brief Initialize the LPSR DIG LDO in static mode.
434 *
435 * @param base ANADIG_LDO_SNVS peripheral base address.
436 * @param config Pointer to the structure pmu_static_lpsr_dig_config_t. Please refer to @ref
437 * pmu_static_lpsr_dig_config_t.
438 */
PMU_StaticLpsrDigLdoInit(ANADIG_LDO_SNVS_Type * base,const pmu_static_lpsr_dig_config_t * config)439 void PMU_StaticLpsrDigLdoInit(ANADIG_LDO_SNVS_Type *base, const pmu_static_lpsr_dig_config_t *config)
440 {
441 assert(config != NULL);
442
443 uint32_t temp32 = base->PMU_LDO_LPSR_DIG;
444
445 temp32 &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_VOLTAGE_SELECT_MASK;
446 temp32 |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_VOLTAGE_SELECT(config->targetVoltage);
447 base->PMU_LDO_LPSR_DIG = temp32;
448
449 temp32 = base->PMU_LDO_LPSR_DIG_2;
450 temp32 &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_2_VOLTAGE_STEP_INC_MASK;
451 temp32 |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_2_VOLTAGE_STEP_INC(config->voltageStepTime);
452 base->PMU_LDO_LPSR_DIG_2 = temp32;
453
454 /* Enable LPSR DIG LDO. */
455 base->PMU_LDO_LPSR_DIG |= ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_REG_EN_MASK;
456 SDK_DelayAtLeastUs(125U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
457 PMU_POWER_DETECT_CTRL_REGISTER |= ANADIG_PMU_PMU_POWER_DETECT_CTRL_CKGB_LPSR1P0_MASK;
458 }
459
460 /*!
461 * @brief Disable the LPSR DIG LDO.
462 *
463 * @param base ANADIG_LDO_SNVS peripheral base address.
464 */
PMU_StaticLpsrDigLdoDeinit(ANADIG_LDO_SNVS_Type * base)465 void PMU_StaticLpsrDigLdoDeinit(ANADIG_LDO_SNVS_Type *base)
466 {
467 PMU_POWER_DETECT_CTRL_REGISTER &= ~ANADIG_PMU_PMU_POWER_DETECT_CTRL_CKGB_LPSR1P0_MASK;
468 base->PMU_LDO_LPSR_DIG &= ~ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_REG_EN_MASK;
469 }
470
471 /*!
472 * brief Sets the voltage step of LPSR DIG LDO in the certain setpoint during GPC mode.
473 *
474 * note The function provides the feature to set the voltage step to the different setpoints.
475 *
476 * param setpointMap The map of setpoints should be the OR'ed Value of _pmu_setpoint_map.
477 * param voltageStep The voltage step to be set.
478 */
PMU_GPCSetLpsrDigLdoTargetVoltage(uint32_t setpointMap,pmu_lpsr_dig_target_output_voltage_t voltageValue)479 void PMU_GPCSetLpsrDigLdoTargetVoltage(uint32_t setpointMap, pmu_lpsr_dig_target_output_voltage_t voltageValue)
480 {
481 uint32_t regValue = 0UL;
482 const uint32_t lpsrDigTrgRegArray[] = PMU_LPSR_DIG_TRG_REGISTERS;
483 uint8_t regIndex;
484 uint8_t temp8;
485 uint32_t i;
486
487 for (regIndex = 0U; regIndex < ARRAY_SIZE(lpsrDigTrgRegArray); regIndex++)
488 {
489 temp8 = (((uint8_t)(setpointMap >> (PMU_LDO_LPSR_DIG_TRG_SPX_REG_SETPOINT_COUNTS * regIndex))) & 0xFU);
490 if (temp8 != 0UL)
491 {
492 regValue = (*(volatile uint32_t *)lpsrDigTrgRegArray[regIndex]);
493 for (i = 0U; i < PMU_LDO_LPSR_DIG_TRG_SPX_REG_SETPOINT_COUNTS; i++)
494 {
495 if (((temp8 >> (1U * i)) & 0x1U) != 0U)
496 {
497 regValue &= ~(0xFFUL << (PMU_LDO_LPSR_DIG_TRG_SPX_VOLTAGE_SETPOINTX_BIT_WIDTH * i));
498 regValue |= (uint32_t)voltageValue << (PMU_LDO_LPSR_DIG_TRG_SPX_VOLTAGE_SETPOINTX_BIT_WIDTH * i);
499 }
500 }
501 (*(volatile uint32_t *)lpsrDigTrgRegArray[regIndex]) = regValue;
502 }
503 }
504 }
505
506 /*!
507 * brief Gets the default config of the SNVS DIG LDO.
508 *
509 * The default values are:
510 * code
511 * config->mode = kPMU_LowPowerMode;
512 * config->chargePumpCurrent = kPMU_SnvsDigChargePump12P5nA;
513 * config->dischargeResistorValue = kPMU_SnvsDigDischargeResistor15K;
514 * config->trimValue = 0U;
515 * config->enablePullDown = true;
516 * config->enableLdoStable = false;
517 * endcode
518 *
519 * param config Pointer to the structure pmu_snvs_dig_config_t. Please refer to pmu_snvs_dig_config_t.
520 */
PMU_GetSnvsDigLdoDefaultConfig(pmu_snvs_dig_config_t * config)521 void PMU_GetSnvsDigLdoDefaultConfig(pmu_snvs_dig_config_t *config)
522 {
523 assert(config != NULL);
524
525 (void)memset(config, 0, sizeof(*config));
526
527 config->mode = kPMU_LowPowerMode;
528 config->chargePumpCurrent = kPMU_SnvsDigChargePump12P5nA;
529 config->dischargeResistorValue = kPMU_SnvsDigDischargeResistor15K;
530 config->trimValue = 0U;
531 config->enablePullDown = true;
532 config->enableLdoStable = false;
533 }
534
535 /*!
536 * brief Initialize the SNVS DIG LDO.
537 *
538 * param base LDO SNVS DIG peripheral base address.
539 * param mode Used to control LDO power mode, please refer to pmu_ldo_operate_mode_t.
540 */
PMU_SnvsDigLdoInit(ANADIG_LDO_SNVS_DIG_Type * base,pmu_ldo_operate_mode_t mode)541 void PMU_SnvsDigLdoInit(ANADIG_LDO_SNVS_DIG_Type *base, pmu_ldo_operate_mode_t mode)
542 {
543 uint32_t temp32 = base->PMU_LDO_SNVS_DIG;
544
545 temp32 &= ~(ANADIG_LDO_SNVS_DIG_PMU_LDO_SNVS_DIG_REG_LP_EN_MASK);
546
547 temp32 |= (ANADIG_LDO_SNVS_DIG_PMU_LDO_SNVS_DIG_REG_LP_EN(mode) | ANADIG_LDO_SNVS_DIG_PMU_LDO_SNVS_DIG_REG_EN_MASK);
548
549 base->PMU_LDO_SNVS_DIG = temp32;
550 }
551
552 /*!
553 * brief Controls the ON/OFF of the selected LDO in the certain setpoints with GPC mode.
554 *
555 * param name The name of the selected ldo. Please see the enumeration pmu_ldo_name_t for details.
556 * param setpointMap The map of setpoints should be the OR'ed Value of @ref _pmu_setpoint_map, 1b'1
557 * means enable specific ldo in that setpoint.
558 * For example, the code PMU_GPCEnableLdo(kPMU_PllLdo, 0x1U) means enable PLL LDO in setpoint 0, disable
559 * PLL LDO in other setpoint.
560 */
PMU_GPCEnableLdo(pmu_ldo_name_t name,uint32_t setpointMap)561 void PMU_GPCEnableLdo(pmu_ldo_name_t name, uint32_t setpointMap)
562 {
563 assert(name != kPMU_SnvsDigLdo);
564
565 uint32_t ldoEnableRegArray[] = PMU_LDO_ENABLE_SETPOINT_REGISTERS;
566
567 (*(volatile uint32_t *)ldoEnableRegArray[(uint8_t)name]) = ~setpointMap;
568 }
569
570 /*!
571 * brief Sets the operating mode of the selected LDO in the certain setpoints with GPC mode.
572 *
573 * param name The name of the selected ldo. Please see the enumeration pmu_ldo_name_t for details.
574 * param setpointMap The map of setpoints should be the OR'ed Value of _pmu_setpoint_map.
575 * param mode The operating mode of the selected ldo. Please refer to the enumeration pmu_ldo_operate_mode_t for
576 * details.
577 */
PMU_GPCSetLdoOperateMode(pmu_ldo_name_t name,uint32_t setpointMap,pmu_ldo_operate_mode_t mode)578 void PMU_GPCSetLdoOperateMode(pmu_ldo_name_t name, uint32_t setpointMap, pmu_ldo_operate_mode_t mode)
579 {
580 assert(name > kPMU_PllLdo);
581 assert(name < kPMU_SnvsDigLdo);
582
583 uint32_t ldoLpModeRegArray[] = PMU_LDO_LP_MODE_EN_SETPOINT_REGISTERS;
584
585 if (mode == kPMU_LowPowerMode)
586 {
587 (*(volatile uint32_t *)ldoLpModeRegArray[(uint8_t)name]) &= ~setpointMap;
588 }
589 else
590 {
591 (*(volatile uint32_t *)ldoLpModeRegArray[(uint8_t)name]) |= setpointMap;
592 }
593 }
594
595 /*!
596 * brief Controls the ON/OFF of the selected LDOs' Tracking mode in the certain setpoints with GPC mode.
597 *
598 * param name The name of the selected ldo. Please see the enumeration pmu_ldo_name_t for details.
599 * param setpointMap The map of setpoints that the LDO tracking mode will be enabled in those setpoints, this value
600 * should be the OR'ed Value of @ref _pmu_setpoint_map.
601 */
PMU_GPCEnableLdoTrackingMode(pmu_ldo_name_t name,uint32_t setpointMap)602 void PMU_GPCEnableLdoTrackingMode(pmu_ldo_name_t name, uint32_t setpointMap)
603 {
604 assert(name > kPMU_PllLdo);
605 assert(name < kPMU_SnvsDigLdo);
606
607 uint32_t ldoTrackingEnableRegArray[] = PMU_LDO_TRACKING_EN_SETPOINT_REGISTERS;
608
609 (*(volatile uint32_t *)ldoTrackingEnableRegArray[(uint8_t)name]) = setpointMap;
610 }
611
612 /*!
613 * brief Controls the ON/OFF of the selected LDOs' Bypass mode in the certain setpoints with GPC mode.
614 *
615 * param name The name of the selected ldo. Please see the enumeration pmu_ldo_name_t for details.
616 * param setpointMap The map of setpoints that the LDO bypass mode will be enabled in those setpoints, this value
617 * should be the OR'ed Value of @ref _pmu_setpoint_map.
618 */
PMU_GPCEnableLdoBypassMode(pmu_ldo_name_t name,uint32_t setpointMap)619 void PMU_GPCEnableLdoBypassMode(pmu_ldo_name_t name, uint32_t setpointMap)
620 {
621 assert(name > kPMU_PllLdo);
622 assert(name < kPMU_SnvsDigLdo);
623
624 uint32_t ldoBypassEnableRegArray[] = PMU_LDO_BYPASS_EN_SETPOINT_REGISTERS;
625
626 (*(volatile uint32_t *)ldoBypassEnableRegArray[(uint8_t)name]) = setpointMap;
627 }
628
629 /*!
630 * brief When STBY assert, enable/disable the selected LDO enter it's Low power mode.
631 *
632 * param name The name of the selected ldo. Please see the enumeration pmu_ldo_name_t for details.
633 * param setpointMap The map of setpoints that the LDO low power mode will be enabled in those setpoints if STBY
634 * assert, this value should be the OR'ed Value of @ref _pmu_setpoint_map.
635 */
PMU_GPCEnableLdoStandbyMode(pmu_ldo_name_t name,uint32_t setpointMap)636 void PMU_GPCEnableLdoStandbyMode(pmu_ldo_name_t name, uint32_t setpointMap)
637 {
638 assert(name != kPMU_SnvsDigLdo);
639
640 uint32_t ldoStandbyEnableRegArray[] = PMU_LDO_STBY_EN_REGISTERS;
641
642 (*(volatile uint32_t *)ldoStandbyEnableRegArray[(uint8_t)name]) = setpointMap;
643 }
644
645 /*!
646 * brief Selects the control mode of the Bandgap Reference.
647 *
648 * param base PMU peripheral base address.
649 * param mode The control mode of the Bandgap Reference. Please refer to pmu_control_mode_t.
650 */
PMU_SetBandgapControlMode(ANADIG_PMU_Type * base,pmu_control_mode_t mode)651 void PMU_SetBandgapControlMode(ANADIG_PMU_Type *base, pmu_control_mode_t mode)
652 {
653 if (mode == kPMU_StaticMode)
654 {
655 base->PMU_REF_CTRL &= ~ANADIG_PMU_PMU_REF_CTRL_REF_CONTROL_MODE_MASK;
656 }
657 else
658 {
659 base->PMU_REF_CTRL |= ANADIG_PMU_PMU_REF_CTRL_REF_CONTROL_MODE_MASK;
660 }
661 }
662
663 /*!
664 * brief Switches the Bandgap from Static/Software Mode to GPC/Hardware Mode.
665 *
666 * param base PMU peripheral base address.
667 */
PMU_SwitchBandgapToGPCMode(ANADIG_PMU_Type * base)668 void PMU_SwitchBandgapToGPCMode(ANADIG_PMU_Type *base)
669 {
670 if ((base->BANDGAP_ENABLE_SP & ANADIG_PMU_BANDGAP_ENABLE_SP_ON_OFF_SETPOINT0_MASK) == 0UL)
671 {
672 base->PMU_REF_CTRL &= ~ANADIG_PMU_PMU_REF_CTRL_REF_ENABLE_MASK;
673 }
674 else
675 {
676 base->PMU_REF_CTRL |= ANADIG_PMU_PMU_REF_CTRL_REF_ENABLE_MASK;
677 }
678 }
679
680 /*!
681 * brief Disables Bandgap self bias for best noise performance.
682 *
683 * This function waits for the bandgap to be stable and disables the bandgap self bias.
684 * After being powered up, it needs to wait for the bandgap stable to be stable and then disable Bandgap
685 * Self bias for best noise performance.
686 */
PMU_DisableBandgapSelfBiasAfterPowerUp(void)687 void PMU_DisableBandgapSelfBiasAfterPowerUp(void)
688 {
689 uint32_t temp32;
690 uint32_t regValue;
691
692 /* Wait Bandgap stable. */
693 do
694 {
695 regValue = ANATOP_AI_Read(kAI_Itf_Bandgap, kAI_BANDGAP_STAT0);
696 } while ((regValue & AI_BANDGAP_STAT0_REFTOP_VBGUP_MASK) == 0UL);
697
698 /* Disable Bandgap self bias for best noise performance. */
699 temp32 = ANATOP_AI_Read(kAI_Itf_Bandgap, kAI_BANDGAP_CTRL0);
700 temp32 |= AI_BANDGAP_CTRL0_REFTOP_SELFBIASOFF_MASK;
701 ANATOP_AI_Write(kAI_Itf_Bandgap, kAI_BANDGAP_CTRL0, temp32);
702 }
703
704 /*!
705 * brief Enables Bandgap self bias before power down.
706 *
707 * This function will enable Bandgap self bias feature before powering down or there
708 * will be risk of Bandgap not starting properly.
709 */
PMU_EnableBandgapSelfBiasBeforePowerDown(void)710 void PMU_EnableBandgapSelfBiasBeforePowerDown(void)
711 {
712 uint32_t temp32;
713
714 temp32 = ANATOP_AI_Read(kAI_Itf_Bandgap, kAI_BANDGAP_CTRL0);
715 temp32 &= ~AI_BANDGAP_CTRL0_REFTOP_SELFBIASOFF_MASK;
716 ANATOP_AI_Write(kAI_Itf_Bandgap, kAI_BANDGAP_CTRL0, temp32);
717 }
718
719 /*!
720 * brief Init Bandgap.
721 *
722 * param config. Pointer to the structure pmu_static_bandgap_config_t. Please refer to pmu_static_bandgap_config_t.
723 */
PMU_StaticBandgapInit(const pmu_static_bandgap_config_t * config)724 void PMU_StaticBandgapInit(const pmu_static_bandgap_config_t *config)
725 {
726 assert(config != NULL);
727
728 uint32_t temp32;
729
730 temp32 = ANATOP_AI_Read(kAI_Itf_Bandgap, kAI_BANDGAP_CTRL0);
731 temp32 &= ~(AI_BANDGAP_CTRL0_REFTOP_PWD_MASK | AI_BANDGAP_CTRL0_REFTOP_LINREGREF_PWD_MASK |
732 AI_BANDGAP_CTRL0_REFTOP_PWDVBGUP_MASK | AI_BANDGAP_CTRL0_REFTOP_LOWPOWER_MASK |
733 AI_BANDGAP_CTRL0_REFTOP_VBGADJ_MASK | AI_BANDGAP_CTRL0_REFTOP_IBZTCADJ_MASK);
734 temp32 |= ((uint32_t)(config->powerDownOption) &
735 (AI_BANDGAP_CTRL0_REFTOP_PWD_MASK | AI_BANDGAP_CTRL0_REFTOP_LINREGREF_PWD_MASK |
736 AI_BANDGAP_CTRL0_REFTOP_PWDVBGUP_MASK));
737 temp32 |= AI_BANDGAP_CTRL0_REFTOP_LOWPOWER(config->enableLowPowerMode);
738 temp32 |= AI_BANDGAP_CTRL0_REFTOP_VBGADJ(config->outputVoltage);
739 temp32 |= AI_BANDGAP_CTRL0_REFTOP_IBZTCADJ(config->outputCurrent);
740
741 ANATOP_AI_Write(kAI_Itf_Bandgap, kAI_BANDGAP_CTRL0, temp32);
742 }
743
744 /*!
745 * brief Configures Well bias, such as power source, clock source and so on.
746 *
747 * param base PMU peripheral base address.
748 * param config Pointer to the pmu_well_bias_config_t structure.
749 */
PMU_WellBiasInit(ANADIG_PMU_Type * base,const pmu_well_bias_config_t * config)750 void PMU_WellBiasInit(ANADIG_PMU_Type *base, const pmu_well_bias_config_t *config)
751 {
752 assert(config != NULL);
753
754 uint32_t tmp32;
755
756 tmp32 = base->PMU_BIAS_CTRL;
757 tmp32 &= ~(ANADIG_PMU_PMU_BIAS_CTRL_WB_CFG_1P8_MASK | ANADIG_PMU_PMU_BIAS_CTRL_WB_VDD_SEL_1P8_MASK);
758 tmp32 |= ((uint32_t)config->wellBiasOption.wellBiasData &
759 (ANADIG_PMU_PMU_BIAS_CTRL_WB_CFG_1P8_MASK | ANADIG_PMU_PMU_BIAS_CTRL_WB_VDD_SEL_1P8_MASK));
760 base->PMU_BIAS_CTRL = tmp32;
761
762 tmp32 = base->PMU_BIAS_CTRL2;
763 tmp32 &= ~ANADIG_PMU_PMU_BIAS_CTRL2_WB_ADJ_1P8_MASK;
764 tmp32 |= ANADIG_PMU_PMU_BIAS_CTRL2_WB_ADJ_1P8(config->adjustment);
765 base->PMU_BIAS_CTRL2 = tmp32;
766 }
767
768 /*!
769 * brief Enables/disables the selected body bias.
770 *
771 * param base PMU peripheral base address.
772 * param name The name of the body bias to be turned on/off, please refer to pmu_body_bias_name_t.
773 * param enable Used to turn on/off the specific body bias.
774 * - \b true Enable the selected body bias.
775 * - \b false Disable the selected body bias.
776 */
PMU_GetWellBiasDefaultConfig(pmu_well_bias_config_t * config)777 void PMU_GetWellBiasDefaultConfig(pmu_well_bias_config_t *config)
778 {
779 assert(config != NULL);
780
781 (void)memset(config, 0, sizeof(*config));
782
783 config->wellBiasOption.wellBiasData = 0U;
784 config->adjustment = kPMU_Cref0fFCspl0fFDeltaC0fF;
785 }
786
787 /*!
788 * brief Selects the control mode of the Body Bias.
789 *
790 * param base PMU peripheral base address.
791 * param name The name of the body bias. Please refer to pmu_body_bias_name_t.
792 * param mode The control mode of the Body Bias. Please refer to pmu_control_mode_t.
793 */
PMU_SetBodyBiasControlMode(ANADIG_PMU_Type * base,pmu_body_bias_name_t name,pmu_control_mode_t mode)794 void PMU_SetBodyBiasControlMode(ANADIG_PMU_Type *base, pmu_body_bias_name_t name, pmu_control_mode_t mode)
795 {
796 uint32_t temp32;
797
798 switch (name)
799 {
800 #if (defined(PMU_HAS_FBB) && PMU_HAS_FBB)
801 case kPMU_FBB_CM7:
802 {
803 temp32 = base->PMU_BIAS_CTRL2;
804 temp32 &= ~ANADIG_PMU_PMU_BIAS_CTRL2_FBB_M7_CONTROL_MODE_MASK;
805 temp32 |= ANADIG_PMU_PMU_BIAS_CTRL2_FBB_M7_CONTROL_MODE(mode);
806 base->PMU_BIAS_CTRL2 = temp32;
807 break;
808 }
809 #endif /* PMU_HAS_FBB */
810 case kPMU_RBB_SOC:
811 {
812 temp32 = base->PMU_BIAS_CTRL2;
813 temp32 &= ~ANADIG_PMU_PMU_BIAS_CTRL2_RBB_SOC_CONTROL_MODE_MASK;
814 temp32 |= ANADIG_PMU_PMU_BIAS_CTRL2_RBB_SOC_CONTROL_MODE(mode);
815 base->PMU_BIAS_CTRL2 = temp32;
816 break;
817 }
818 case kPMU_RBB_LPSR:
819 {
820 temp32 = base->PMU_BIAS_CTRL2;
821 temp32 &= ~ANADIG_PMU_PMU_BIAS_CTRL2_RBB_LPSR_CONTROL_MODE_MASK;
822 temp32 |= ANADIG_PMU_PMU_BIAS_CTRL2_RBB_LPSR_CONTROL_MODE(mode);
823 base->PMU_BIAS_CTRL2 = temp32;
824 break;
825 }
826 default:
827 /* This branch should never be hit. */
828 break;
829 }
830 }
831
832 /*!
833 * brief Enables/disables the selected body bias.
834 *
835 * param base PMU peripheral base address.
836 * param name The name of the body bias to be turned on/off, please refer to pmu_body_bias_name_t.
837 * param enable Used to turn on/off the specific body bias.
838 * - \b true Enable the selected body bias.
839 * - \b false Disable the selected body bias.
840 */
PMU_EnableBodyBias(ANADIG_PMU_Type * base,pmu_body_bias_name_t name,bool enable)841 void PMU_EnableBodyBias(ANADIG_PMU_Type *base, pmu_body_bias_name_t name, bool enable)
842 {
843 uint32_t tmp32;
844
845 if (enable)
846 {
847 switch (name)
848 {
849 #if (defined(PMU_HAS_FBB) && PMU_HAS_FBB)
850 case kPMU_FBB_CM7:
851 {
852 tmp32 = base->PMU_BIAS_CTRL;
853 tmp32 &= ~(PMU_BIAS_CTRL_WB_NW_LVL_1P8_MASK | PMU_BIAS_CTRL_WB_PW_LVL_1P8_MASK |
854 ANADIG_PMU_PMU_BIAS_CTRL_WB_CFG_1P8_MASK);
855 tmp32 |= PMU_BIAS_CTRL_WB_NW_LVL_1P8(1U) | PMU_BIAS_CTRL_WB_PW_LVL_1P8(1U) |
856 PMU_BIAS_CTRL_WB_CFG_1P8_PULL_DOWN_OPTION_MASK |
857 PMU_BIAS_CTRL_WB_CFG_1P8_VOLTAGE_THRESHOLD_MASK;
858 base->PMU_BIAS_CTRL = tmp32;
859
860 tmp32 = base->PMU_BIAS_CTRL2;
861 tmp32 &= ~(ANADIG_PMU_PMU_BIAS_CTRL2_WB_PWR_SW_EN_1P8_MASK);
862 tmp32 |= ANADIG_PMU_PMU_BIAS_CTRL2_WB_PWR_SW_EN_1P8(1U) | ANADIG_PMU_PMU_BIAS_CTRL2_WB_EN_MASK;
863 base->PMU_BIAS_CTRL2 = tmp32;
864
865 while ((base->PMU_BIAS_CTRL2 & ANADIG_PMU_PMU_BIAS_CTRL2_WB_OK_MASK) !=
866 ANADIG_PMU_PMU_BIAS_CTRL2_WB_OK_MASK)
867 {
868 }
869 break;
870 }
871 #endif /* PMU_HAS_FBB */
872 case kPMU_RBB_SOC:
873 {
874 tmp32 = base->PMU_BIAS_CTRL;
875 tmp32 &= ~(PMU_BIAS_CTRL_WB_CFG_1P8_WELL_SELECT_MASK | PMU_BIAS_CTRL_WB_CFG_1P8_VOLTAGE_THRESHOLD_MASK);
876 base->PMU_BIAS_CTRL = tmp32;
877
878 tmp32 = base->PMU_BIAS_CTRL2;
879 tmp32 &= ~(ANADIG_PMU_PMU_BIAS_CTRL2_WB_PWR_SW_EN_1P8_MASK);
880 tmp32 |= ANADIG_PMU_PMU_BIAS_CTRL2_WB_PWR_SW_EN_1P8(2U) | ANADIG_PMU_PMU_BIAS_CTRL2_WB_EN_MASK;
881 base->PMU_BIAS_CTRL2 = tmp32;
882 while ((base->PMU_BIAS_CTRL2 & ANADIG_PMU_PMU_BIAS_CTRL2_WB_OK_MASK) !=
883 ANADIG_PMU_PMU_BIAS_CTRL2_WB_OK_MASK)
884 {
885 }
886 break;
887 }
888 case kPMU_RBB_LPSR:
889 {
890 tmp32 = base->PMU_BIAS_CTRL;
891 tmp32 &= ~(PMU_BIAS_CTRL_WB_CFG_1P8_WELL_SELECT_MASK | PMU_BIAS_CTRL_WB_CFG_1P8_VOLTAGE_THRESHOLD_MASK);
892 base->PMU_BIAS_CTRL = tmp32;
893
894 tmp32 = base->PMU_BIAS_CTRL2;
895 tmp32 &= ~(ANADIG_PMU_PMU_BIAS_CTRL2_WB_PWR_SW_EN_1P8_MASK);
896 tmp32 |= ANADIG_PMU_PMU_BIAS_CTRL2_WB_PWR_SW_EN_1P8(4U) | ANADIG_PMU_PMU_BIAS_CTRL2_WB_EN_MASK;
897 base->PMU_BIAS_CTRL2 = tmp32;
898 while ((base->PMU_BIAS_CTRL2 & ANADIG_PMU_PMU_BIAS_CTRL2_WB_OK_MASK) !=
899 ANADIG_PMU_PMU_BIAS_CTRL2_WB_OK_MASK)
900 {
901 }
902 break;
903 }
904 default:
905 /* This branch should never be hit. */
906 break;
907 }
908 }
909 else
910 {
911 base->PMU_BIAS_CTRL2 &=
912 ~(ANADIG_PMU_PMU_BIAS_CTRL2_WB_PWR_SW_EN_1P8_MASK | ANADIG_PMU_PMU_BIAS_CTRL2_WB_EN_MASK);
913 }
914 }
915
916 /*!
917 * brief Controls the ON/OFF of the selected body bias in the certain setpoints with GPC mode.
918 *
919 * param name The name of the selected body bias. Please see the enumeration pmu_body_bias_name_t for details.
920 * param setpointMap The map of setpoints that the specific body bias will be enabled in those setpoints, this value
921 * should be the OR'ed Value of _pmu_setpoint_map.
922 */
PMU_GPCEnableBodyBias(pmu_body_bias_name_t name,uint32_t setpointMap)923 void PMU_GPCEnableBodyBias(pmu_body_bias_name_t name, uint32_t setpointMap)
924 {
925 uint32_t bodyBiasEnableRegArray[] = PMU_BODY_BIAS_ENABLE_REGISTERS;
926
927 (*(volatile uint32_t *)bodyBiasEnableRegArray[(uint8_t)name]) = ~setpointMap;
928 }
929
930 /*!
931 * brief Controls the ON/OFF of the selected Body Bias' Wbias power switch in certain setpoints with GPC mode.
932 *
933 * param name The name of the selected body bias. Please see the enumeration pmu_body_bias_name_t for details.
934 * param setpointMap The map of setpoints that the specific body bias's wbias power switch will be turn on in those
935 * setpoints, this value should be the OR'ed Value of _pmu_setpoint_map.
936 */
PMU_GPCEnableBodyBiasStandbyMode(pmu_body_bias_name_t name,uint32_t setpointMap)937 void PMU_GPCEnableBodyBiasStandbyMode(pmu_body_bias_name_t name, uint32_t setpointMap)
938 {
939 uint32_t BBStandbyEnableRegArray[] = PMU_BODY_BIAS_STBY_EN_REGISTERS;
940
941 (*(volatile uint32_t *)BBStandbyEnableRegArray[(uint8_t)name]) = setpointMap;
942 }
943
944 /*!
945 * brief Gets the default config of body bias in GPC mode.
946 *
947 * param config Pointer to the structure pmu_gpc_body_bias_config_t.
948 */
PMU_GPCGetBodyBiasDefaultConfig(pmu_gpc_body_bias_config_t * config)949 void PMU_GPCGetBodyBiasDefaultConfig(pmu_gpc_body_bias_config_t *config)
950 {
951 assert(config != NULL);
952
953 config->PWELLRegulatorSize = 1U;
954 config->NWELLRegulatorSize = 1U;
955 config->oscillatorSize = 7U;
956 config->regulatorStrength = 5U;
957 }
958
959 /*!
960 * brief Sets the config of the selected Body Bias in GPC mode.
961 *
962 * param name The name of the selected body bias. Please see the enumeration pmu_body_bias_name_t for details.
963 * param config Pointer to the structure pmu_gpc_body_bias_config_t.
964 */
PMU_GPCSetBodyBiasConfig(pmu_body_bias_name_t name,const pmu_gpc_body_bias_config_t * config)965 void PMU_GPCSetBodyBiasConfig(pmu_body_bias_name_t name, const pmu_gpc_body_bias_config_t *config)
966 {
967 assert(config != NULL);
968
969 uint32_t bodyBiasConfigRegArray[] = PMU_BODY_BIAS_CONFIGURE_REGISTERS;
970 uint32_t temp32;
971
972 temp32 = (*(volatile uint32_t *)bodyBiasConfigRegArray[(uint8_t)name]);
973 temp32 &=
974 (ANADIG_PMU_RBB_SOC_CONFIGURE_WB_CFG_PW_MASK | ANADIG_PMU_RBB_SOC_CONFIGURE_WB_CFG_NW_MASK |
975 ANADIG_PMU_RBB_SOC_CONFIGURE_OSCILLATOR_BITS_MASK | ANADIG_PMU_RBB_SOC_CONFIGURE_REGULATOR_STRENGTH_MASK);
976 temp32 |= ANADIG_PMU_RBB_SOC_CONFIGURE_WB_CFG_PW(config->PWELLRegulatorSize) |
977 ANADIG_PMU_RBB_SOC_CONFIGURE_WB_CFG_NW(config->NWELLRegulatorSize) |
978 ANADIG_PMU_RBB_SOC_CONFIGURE_OSCILLATOR_BITS(config->oscillatorSize) |
979 ANADIG_PMU_RBB_SOC_CONFIGURE_REGULATOR_STRENGTH(config->regulatorStrength);
980 (*(volatile uint32_t *)bodyBiasConfigRegArray[(uint8_t)name]) = temp32;
981 }
982