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