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