1 /*
2  * Copyright 2022-2024 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_spc.h"
9 
10 /* Component ID definition, used by tools. */
11 #ifndef FSL_COMPONENT_ID
12 #define FSL_COMPONENT_ID "platform.drivers.mcx_spc"
13 #endif
14 
15 /*
16  * $Coverage Justification Reference$
17  *
18  * $Justification spc_c_ref_1$
19  * The SPC busy status flag is too short to get coverage data.
20  */
21 
22 /*******************************************************************************
23  * Definitions
24  ******************************************************************************/
25 
26 /*******************************************************************************
27  * Prototypes
28  ******************************************************************************/
29 
30 /*******************************************************************************
31  * Variables
32  ******************************************************************************/
33 
34 /*******************************************************************************
35  * Code
36  ******************************************************************************/
37 
38 /*!
39  * brief Gets selected power domain's requested low power mode.
40  *
41  * param base SPC peripheral base address.
42  * param powerDomainId Power Domain Id, please refer to spc_power_domain_id_t.
43  *
44  * return The selected power domain's requested low power mode, please refer to spc_power_domain_low_power_mode_t.
45  */
SPC_GetPowerDomainLowPowerMode(SPC_Type * base,spc_power_domain_id_t powerDomainId)46 spc_power_domain_low_power_mode_t SPC_GetPowerDomainLowPowerMode(SPC_Type *base, spc_power_domain_id_t powerDomainId)
47 {
48     assert((uint8_t)powerDomainId < SPC_PD_STATUS_COUNT);
49 
50     uint32_t val;
51 
52     val = ((base->PD_STATUS[(uint8_t)powerDomainId] & SPC_PD_STATUS_LP_MODE_MASK) >> SPC_PD_STATUS_LP_MODE_SHIFT);
53     return (spc_power_domain_low_power_mode_t)val;
54 }
55 
56 /*!
57  * brief Gets Isolation status for each power domains.
58  *
59  * This function gets the status which indicates whether certain
60  * peripheral and the IO pads are in a latched state as a result
61  * of having been in POWERDOWN mode.
62  *
63  * param base SPC peripheral base address.
64  * return Current isolation status for each power domains.
65  */
SPC_GetPeriphIOIsolationStatus(SPC_Type * base)66 uint8_t SPC_GetPeriphIOIsolationStatus(SPC_Type *base)
67 {
68     uint32_t reg;
69 
70     reg = base->SC;
71     return (uint8_t)((reg & SPC_SC_ISO_CLR_MASK) >> SPC_SC_ISO_CLR_SHIFT);
72 }
73 
74 /*!
75  * brief Configs Low power request output pin.
76  *
77  * This function configs the low power request output pin
78  *
79  * param base SPC peripheral base address.
80  * param config Pointer the spc_LowPower_Request_config_t structure.
81  */
SPC_SetLowPowerRequestConfig(SPC_Type * base,const spc_lowpower_request_config_t * config)82 void SPC_SetLowPowerRequestConfig(SPC_Type *base, const spc_lowpower_request_config_t *config)
83 {
84     assert(config != NULL);
85 
86     uint32_t reg;
87 
88     reg = base->LPREQ_CFG;
89     reg &= ~(SPC_LPREQ_CFG_LPREQOE_MASK | SPC_LPREQ_CFG_LPREQPOL_MASK | SPC_LPREQ_CFG_LPREQOV_MASK);
90 
91     if (config->enable)
92     {
93         reg |= SPC_LPREQ_CFG_LPREQOE_MASK | SPC_LPREQ_CFG_LPREQPOL((uint8_t)(config->polarity)) |
94                SPC_LPREQ_CFG_LPREQOV((uint8_t)(config->override));
95     }
96     else
97     {
98         reg &= ~SPC_LPREQ_CFG_LPREQOE_MASK;
99     }
100 
101     base->LPREQ_CFG = reg;
102 }
103 
104 #if !(defined(FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) && FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT)
105 /*!
106  * brief Configures VDD Core Glitch detector, including ripple counter selection, timeout value and so on.
107  *
108  * param base SPC peripheral base address.
109  * param config Pointer to the structure in type of spc_vdd_core_glitch_detector_config_t.
110  */
SPC_ConfigVddCoreGlitchDetector(SPC_Type * base,const spc_vdd_core_glitch_detector_config_t * config)111 void SPC_ConfigVddCoreGlitchDetector(SPC_Type *base, const spc_vdd_core_glitch_detector_config_t *config)
112 {
113     assert(config != NULL);
114 
115     uint32_t reg;
116 
117     reg = (base->VDD_CORE_GLITCH_DETECT_SC) &
118           ~(SPC_VDD_CORE_GLITCH_DETECT_SC_CNT_SELECT_MASK | SPC_VDD_CORE_GLITCH_DETECT_SC_TIMEOUT_MASK |
119             SPC_VDD_CORE_GLITCH_DETECT_SC_RE_MASK | SPC_VDD_CORE_GLITCH_DETECT_SC_IE_MASK);
120 
121     reg |= SPC_VDD_CORE_GLITCH_DETECT_SC_CNT_SELECT(config->rippleCounterSelect) |
122            SPC_VDD_CORE_GLITCH_DETECT_SC_TIMEOUT(config->resetTimeoutValue) |
123            SPC_VDD_CORE_GLITCH_DETECT_SC_RE(config->enableReset) |
124            SPC_VDD_CORE_GLITCH_DETECT_SC_IE(config->enableInterrupt);
125 
126     base->VDD_CORE_GLITCH_DETECT_SC = reg;
127 }
128 #endif
129 
130 /*!
131  * brief Set SRAM operate voltage.
132  *
133  * param base SPC peripheral base address.
134  * param config The pointer to spc_sram_voltage_config_t, specifies the configuration of sram voltage.
135  */
SPC_SetSRAMOperateVoltage(SPC_Type * base,const spc_sram_voltage_config_t * config)136 void SPC_SetSRAMOperateVoltage(SPC_Type *base, const spc_sram_voltage_config_t *config)
137 {
138     assert(config != NULL);
139 
140     uint32_t reg = 0UL;
141 
142     reg |= SPC_SRAMCTL_VSM(config->operateVoltage);
143 
144     base->SRAMCTL = reg;
145 
146     if (config->requestVoltageUpdate)
147     {
148         base->SRAMCTL |= SPC_SRAMCTL_REQ_MASK;
149         while ((base->SRAMCTL & SPC_SRAMCTL_ACK_MASK) == 0UL)
150         {
151             /* Wait until acknowledged */
152             ;
153         }
154         base->SRAMCTL &= ~SPC_SRAMCTL_REQ_MASK;
155     }
156 }
157 
158 /*!
159  * brief Configs Bandgap mode in Active mode.
160  *
161  * @note To disable bandgap in Active mode:
162  *          1. Disable all LVD's and HVD's in active mode;
163  *          2. Disable Glitch detect;
164  *          3. Configrue LDO's and DCDC to low drive strength in active mode;
165  *          4. Invoke this function to disable bandgap in active mode;
166  *      otherwise the error status will be reported.
167  *
168  * @note Some other system resources(such as PLL, CMP) require bandgap to be enabled, to disable bandgap please
169  * take care of other system resources.
170  *
171  * param base SPC peripheral base address.
172  * param mode The Bandgap mode be selected.
173  *
174  * retval kStatus_SPC_BandgapModeWrong The Bandgap can not be disabled in active mode.
175  * retval kStatus_Success Config Bandgap mode in Active power mode successful.
176  */
SPC_SetActiveModeBandgapModeConfig(SPC_Type * base,spc_bandgap_mode_t mode)177 status_t SPC_SetActiveModeBandgapModeConfig(SPC_Type *base, spc_bandgap_mode_t mode)
178 {
179     uint32_t reg;
180     uint32_t state;
181 
182     reg = base->ACTIVE_CFG;
183 
184     if (mode == kSPC_BandgapDisabled)
185     {
186         state = SPC_GetActiveModeVoltageDetectStatus(base);
187 
188         /* If any of the LVD/HVDs are kept enabled, bandgap mode must be enabled with buffer disabled. */
189         if (state != 0UL)
190         {
191             return kStatus_SPC_BandgapModeWrong;
192         }
193 
194         /* The bandgap mode must be enabled if any regulators' drive strength set as Normal. */
195 #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO)
196         if ((base->ACTIVE_CFG & SPC_ACTIVE_CFG_SYSLDO_VDD_DS_MASK) ==
197             SPC_ACTIVE_CFG_SYSLDO_VDD_DS(kSPC_SysLDO_NormalDriveStrength))
198         {
199             return kStatus_SPC_BandgapModeWrong;
200         }
201 #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */
202 
203 #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC)
204         if ((base->ACTIVE_CFG & SPC_ACTIVE_CFG_DCDC_VDD_DS_MASK) == SPC_ACTIVE_CFG_DCDC_VDD_DS(kSPC_DCDC_NormalVoltage))
205         {
206             return kStatus_SPC_BandgapModeWrong;
207         }
208 #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */
209 
210 #if !(defined(FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) && FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT)
211         /* state of GLITCH_DETECT_DISABLE will be ignored if bandgap is disabled. */
212         if ((base->ACTIVE_CFG & SPC_ACTIVE_CFG_GLITCH_DETECT_DISABLE_MASK) == 0UL)
213         {
214             return kStatus_SPC_BandgapModeWrong;
215         }
216 #endif
217 #if defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS
218         if ((base->ACTIVE_CFG & SPC_ACTIVE_CFG_CORELDO_VDD_DS_MASK) ==
219             SPC_ACTIVE_CFG_CORELDO_VDD_DS(kSPC_CoreLDO_NormalDriveStrength))
220         {
221             return kStatus_SPC_BandgapModeWrong;
222         }
223 #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */
224     }
225 
226     reg &= ~SPC_ACTIVE_CFG_BGMODE_MASK;
227     reg |= SPC_ACTIVE_CFG_BGMODE(mode);
228 
229     base->ACTIVE_CFG = reg;
230 
231     return kStatus_Success;
232 }
233 
234 /*!
235  * brief Configs Bandgap mode in Low Power mode.
236  *
237  * @note To disable Bandgap in Low-power mode:
238  *          1. Disable all LVD's ad HVD's in low power mode;
239  *          2. Disable Glitch detect in low power mode;
240  *          3. Configure LDO's and DCDC to low drive strength in low power mode;
241  *          4. Disable bandgap in low power mode;
242  *      Otherwise, the error status will be reported.
243  *
244  * @note Some other system resources(such as PLL, CMP) require bandgap to be enabled, to disable bandgap please
245  * take care of other system resources.
246  *
247  * param base SPC peripheral base address.
248  * param mode The Bandgap mode be selected.
249  *
250  * retval kStatus_SPC_BandgapModeWrong The bandgap mode setting in Low Power mode is wrong.
251  * retval kStatus_Success Config Bandgap mode in Low Power power mode successful.
252  */
SPC_SetLowPowerModeBandgapmodeConfig(SPC_Type * base,spc_bandgap_mode_t mode)253 status_t SPC_SetLowPowerModeBandgapmodeConfig(SPC_Type *base, spc_bandgap_mode_t mode)
254 {
255     uint32_t reg;
256     uint32_t state;
257 
258     reg = base->LP_CFG;
259 
260     if (mode == kSPC_BandgapDisabled)
261     {
262         state = (uint32_t)SPC_GetLowPowerModeVoltageDetectStatus(base);
263 
264         /* If any of the LVD/HVDs are kept enabled, bandgap mode must be enabled with buffer disabled. */
265         if (state != 0UL)
266         {
267             return kStatus_SPC_BandgapModeWrong;
268         }
269 
270 #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC)
271         if ((base->LP_CFG & SPC_LP_CFG_DCDC_VDD_DS_MASK) == SPC_LP_CFG_DCDC_VDD_DS(kSPC_DCDC_NormalDriveStrength))
272         {
273             return kStatus_SPC_BandgapModeWrong;
274         }
275 #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */
276 
277 #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO)
278         if ((base->LP_CFG & SPC_LP_CFG_SYSLDO_VDD_DS_MASK) == SPC_LP_CFG_SYSLDO_VDD_DS(kSPC_SysLDO_NormalDriveStrength))
279         {
280             return kStatus_SPC_BandgapModeWrong;
281         }
282 #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */
283 
284         if ((base->LP_CFG & SPC_LP_CFG_CORELDO_VDD_DS_MASK) ==
285             SPC_LP_CFG_CORELDO_VDD_DS(kSPC_CoreLDO_NormalDriveStrength))
286         {
287             return kStatus_SPC_BandgapModeWrong;
288         }
289 
290 #if !(defined(FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) && FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT)
291         /* state of GLITCH_DETECT_DISABLE will be ignored if bandgap is disabled. */
292         if ((base->LP_CFG & SPC_LP_CFG_GLITCH_DETECT_DISABLE_MASK) == 0UL)
293         {
294             return kStatus_SPC_BandgapModeWrong;
295         }
296 #endif
297     }
298 
299     reg &= ~SPC_LP_CFG_BGMODE_MASK;
300     reg |= SPC_LP_CFG_BGMODE(mode);
301     base->LP_CFG = reg;
302 
303     return kStatus_Success;
304 }
305 
306 /*!
307  * brief Configs CORE voltage detect options.
308  *
309  * This function configs CORE voltage detect options.
310  * Note: Setting both the voltage detect interrupt and reset
311  *       enable will cause interrupt to be generated on exit from reset.
312  *       If those conditioned is not desired, interrupt/reset only one is enabled.
313  *
314  * param base       SPC peripheral base address.
315  * param config     Pointer to spc_core_voltage_detect_config_t structure.
316  */
SPC_SetCoreVoltageDetectConfig(SPC_Type * base,const spc_core_voltage_detect_config_t * config)317 void SPC_SetCoreVoltageDetectConfig(SPC_Type *base, const spc_core_voltage_detect_config_t *config)
318 {
319     assert(config != NULL);
320 
321     uint32_t reg = 0UL;
322 
323 #if (defined(FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD) && FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD)
324     reg |= (config->option.HVDInterruptEnable) ? SPC_VD_CORE_CFG_HVDIE(1U) : SPC_VD_CORE_CFG_HVDIE(0U);
325     reg |= (config->option.HVDResetEnable) ? SPC_VD_CORE_CFG_HVDRE(1U) : SPC_VD_CORE_CFG_HVDRE(0U);
326 #endif /* FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD */
327     reg |= (config->option.LVDInterruptEnable) ? SPC_VD_CORE_CFG_LVDIE(1U) : SPC_VD_CORE_CFG_LVDIE(0U);
328     reg |= (config->option.LVDResetEnable) ? SPC_VD_CORE_CFG_LVDRE(1U) : SPC_VD_CORE_CFG_LVDRE(0U);
329 
330     base->VD_CORE_CFG = reg;
331 }
332 
333 #if (defined(FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD) && FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD)
334 /*!
335  * brief Enables the Core High Voltage Detector in Active mode.
336  *
337  * note If the CORE_LDO high voltage detect is enabled in Active mode, please note that the bandgap must be enabled
338  * and the drive strength of each regulator must not set to low.
339  *
340  * param base SPC peripheral base address.
341  * param enable Enable/Disable Core HVD.
342  *          true    -   Enable Core High voltage detector in active mode.
343  *          false   -   Disable Core High voltage detector in active mode.
344  *
345  * retval kStatus_Success Enable Core High Voltage Detect successfully.
346  */
SPC_EnableActiveModeCoreHighVoltageDetect(SPC_Type * base,bool enable)347 status_t SPC_EnableActiveModeCoreHighVoltageDetect(SPC_Type *base, bool enable)
348 {
349     status_t status = kStatus_Success;
350 
351     if (enable)
352     {
353         base->ACTIVE_CFG |= SPC_ACTIVE_CFG_CORE_HVDE_MASK;
354     }
355     else
356     {
357         base->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_CORE_HVDE_MASK;
358     }
359 
360     return status;
361 }
362 
363 /*!
364  * brief Enables the Core High Voltage Detector in Low Power mode.
365  *
366  * note If the CORE_LDO high voltage detect is enabled in Low Power mode,
367  * please note that the bandgap must be enabled and the drive strength of each regulator
368  * must not set to low in low power mode.
369  *
370  * param base SPC peripheral base address.
371  * param enable Enable/Disable Core HVD.
372  *          true    -   Enable Core High voltage detector in low power mode.
373  *          false   -   Disable Core High voltage detector in low power mode.
374  *
375  * retval kStatus_Success Enable Core High Voltage Detect in low power mode successfully.
376  */
SPC_EnableLowPowerModeCoreHighVoltageDetect(SPC_Type * base,bool enable)377 status_t SPC_EnableLowPowerModeCoreHighVoltageDetect(SPC_Type *base, bool enable)
378 {
379     status_t status = kStatus_Success;
380 
381     if (enable)
382     {
383         base->LP_CFG |= SPC_LP_CFG_CORE_HVDE_MASK;
384     }
385     else
386     {
387         base->LP_CFG &= ~SPC_LP_CFG_CORE_HVDE_MASK;
388     }
389 
390     return status;
391 }
392 #endif /* FSL_FEATURE_MCX_SPC_HAS_COREVDD_HVD */
393 
394 /*!
395  * brief Enables the Core VDD Low Voltage Detector in Active mode.
396  *
397  * note If the Core VDD high voltage detect is enabled in Active mode, please note that the bandgap must be enabled
398  * and the drive strength of each regulator must not set to low.
399  *
400  * param base SPC peripheral base address.
401  * param enable Enable/Disable Core LVD.
402  *          true    -   Enable Core Low voltage detector in active mode.
403  *          false   -   Disable Core Low voltage detector in active mode.
404  *
405  * retval kStatus_Success Enable Core Low Voltage Detect successfully.
406  */
SPC_EnableActiveModeCoreLowVoltageDetect(SPC_Type * base,bool enable)407 status_t SPC_EnableActiveModeCoreLowVoltageDetect(SPC_Type *base, bool enable)
408 {
409     status_t status = kStatus_Success;
410 
411     if (enable)
412     {
413         base->ACTIVE_CFG |= SPC_ACTIVE_CFG_CORE_LVDE_MASK;
414     }
415     else
416     {
417         base->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_CORE_LVDE_MASK;
418     }
419 
420     return status;
421 }
422 
423 /*!
424  * brief Enables the Core Low Voltage Detector in Low Power mode.
425  *
426  * note If the Core VDD low voltage detect is enabled in Low Power mode, please note that the bandgap must be enabled
427  * and the drive strength of each regulator must not set to low in Low Power mode.
428  *
429  * param base SPC peripheral base address.
430  * param enable Enable/Disable Core HVD.
431  *          true    -   Enable Core Low voltage detector in low power mode.
432  *          false   -   Disable Core Low voltage detector in low power mode.
433  *
434  * retval kStatus_Success Enable Core Low Voltage Detect in low power mode successfully.
435  */
SPC_EnableLowPowerModeCoreLowVoltageDetect(SPC_Type * base,bool enable)436 status_t SPC_EnableLowPowerModeCoreLowVoltageDetect(SPC_Type *base, bool enable)
437 {
438     status_t status = kStatus_Success;
439 
440     if (enable)
441     {
442         base->LP_CFG |= SPC_LP_CFG_CORE_LVDE_MASK;
443     }
444     else
445     {
446         base->LP_CFG &= ~SPC_LP_CFG_CORE_LVDE_MASK;
447     }
448 
449     return status;
450 }
451 
452 /*!
453  * brief Set system VDD Low-voltage level selection.
454  *
455  * This function selects the system VDD low-voltage level. Changing system VDD low-voltage level
456  * must be done after disabling the System VDD low voltage reset and interrupt.
457  *
458  * @deprecated In latest RM, reserved for all devices, will removed in next release.
459  *
460  * param base SPC peripheral base address.
461  * param level System VDD Low-Voltage level selection. See @ref spc_low_voltage_level_select_t for details.
462  */
SPC_SetSystemVDDLowVoltageLevel(SPC_Type * base,spc_low_voltage_level_select_t level)463 void SPC_SetSystemVDDLowVoltageLevel(SPC_Type *base, spc_low_voltage_level_select_t level)
464 {
465     (void)level;
466     (void)base;
467 
468     /*
469     uint32_t reg;
470 
471     reg = base->VD_SYS_CFG;
472 
473     base->VD_SYS_CFG &= ~(SPC_VD_SYS_CFG_LVDRE_MASK | SPC_VD_SYS_CFG_LVDIE_MASK);
474     reg |= SPC_VD_SYS_CFG_LVSEL(level);
475 
476     base->VD_SYS_CFG = reg; */
477 }
478 
479 /*!
480  * brief Configs SYS VDD voltage detect options.
481  *
482  * This function config SYS voltage detect options.
483  * Note: Setting both the voltage detect interrupt and reset
484  *       enable will cause interrupt to be generated on exit from reset.
485  *       If those conditioned is not desired, interrupt/reset only one is enabled.
486  *
487  * param base       SPC peripheral base address.
488  * param config     Pointer to spc_system_voltage_detect_config_t structure.
489  */
SPC_SetSystemVoltageDetectConfig(SPC_Type * base,const spc_system_voltage_detect_config_t * config)490 void SPC_SetSystemVoltageDetectConfig(SPC_Type *base, const spc_system_voltage_detect_config_t *config)
491 {
492     assert(config != NULL);
493 
494     uint32_t reg = 0UL;
495 
496     reg |= (config->option.HVDInterruptEnable) ? SPC_VD_SYS_CFG_HVDIE(1U) : SPC_VD_SYS_CFG_HVDIE(0U);
497     reg |= (config->option.LVDInterruptEnable) ? SPC_VD_SYS_CFG_LVDIE(1U) : SPC_VD_SYS_CFG_LVDIE(0U);
498     reg |= (config->option.HVDResetEnable) ? SPC_VD_SYS_CFG_HVDRE(1U) : SPC_VD_SYS_CFG_HVDRE(0U);
499     reg |= (config->option.LVDResetEnable) ? SPC_VD_SYS_CFG_LVDRE(1U) : SPC_VD_SYS_CFG_LVDRE(0U);
500 
501     base->VD_SYS_CFG = reg;
502 
503     (void)(config->level);
504     /* SPC_SetSystemVDDLowVoltageLevel(base, config->level); */
505 }
506 
507 /*!
508  * brief Enables the System VDD High Voltage Detector in Active mode.
509  *
510  * note If the System_LDO high voltage detect is enabled in Active mode,
511  * please note that the bandgap must be enabled and the drive strength of
512  * each regulator must not set to low in Active mode.
513  *
514  * param base SPC peripheral base address.
515  * param enable Enable/Disable System HVD.
516  *          true    -   Enable System High voltage detector in active mode.
517  *          false   -   Disable System High voltage detector in active mode.
518  *
519  * retval kStatus_Success Enable System High Voltage Detect successfully.
520  */
SPC_EnableActiveModeSystemHighVoltageDetect(SPC_Type * base,bool enable)521 status_t SPC_EnableActiveModeSystemHighVoltageDetect(SPC_Type *base, bool enable)
522 {
523     status_t status = kStatus_Success;
524 
525     if (enable)
526     {
527         base->ACTIVE_CFG |= SPC_ACTIVE_CFG_SYS_HVDE_MASK;
528     }
529     else
530     {
531         base->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_SYS_HVDE_MASK;
532     }
533 
534     return status;
535 }
536 
537 /*!
538  * brief Enables the System VDD Low Voltage Detector in Active mode.
539  *
540  * note If the System_LDO low voltage detect is enabled in Active mode,
541  * please note that the bandgap must be enabled and the drive strength of each
542  * regulator must not set to low in Active mode.
543  *
544  * param base SPC peripheral base address.
545  * param enable Enable/Disable System LVD.
546  *          true    -   Enable System Low voltage detector in active mode.
547  *          false   -   Disable System Low voltage detector in active mode.
548  *
549  * retval kStatus_Success Enable the System Low Voltage Detect successfully.
550  */
SPC_EnableActiveModeSystemLowVoltageDetect(SPC_Type * base,bool enable)551 status_t SPC_EnableActiveModeSystemLowVoltageDetect(SPC_Type *base, bool enable)
552 {
553     status_t status = kStatus_Success;
554 
555     if (enable)
556     {
557         base->ACTIVE_CFG |= SPC_ACTIVE_CFG_SYS_LVDE_MASK;
558     }
559     else
560     {
561         base->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_SYS_LVDE_MASK;
562     }
563 
564     return status;
565 }
566 
567 /*!
568  * brief Enables the System VDD High Voltage Detector in Low Power mode.
569  *
570  * note If the System_LDO high voltage detect is enabled in low power mode,
571  * please note that the bandgap must be enabled and the drive strength of each
572  * regulator must not set to low in low power mode.
573  *
574  * param base SPC peripheral base address.
575  * param enable Enable/Disable System HVD.
576  *          true    -   Enable System High voltage detector in low power mode.
577  *          false   -   Disable System High voltage detector in low power mode.
578  *
579  * retval kStatus_Success Enable System High Voltage Detect in low power mode successfully.
580  */
SPC_EnableLowPowerModeSystemHighVoltageDetect(SPC_Type * base,bool enable)581 status_t SPC_EnableLowPowerModeSystemHighVoltageDetect(SPC_Type *base, bool enable)
582 {
583     status_t status = kStatus_Success;
584 
585     if (enable)
586     {
587         base->LP_CFG |= SPC_LP_CFG_SYS_HVDE_MASK;
588     }
589     else
590     {
591         base->LP_CFG &= ~SPC_LP_CFG_SYS_HVDE_MASK;
592     }
593 
594     return status;
595 }
596 
597 /*!
598  * brief Enables the System VDD Low Voltage Detector in Low Power mode.
599  *
600  * note If the System_LDO low voltage detect is enabled in Low Power mode,
601  * please note that the bandgap must be enabled and the drive strength of each
602  * regulator must not set to low in Low Power mode.
603  *
604  * param base SPC peripheral base address.
605  * param enable Enable/Disable System HVD.
606  *          true    -   Enable System Low voltage detector in low power mode.
607  *          false   -   Disable System Low voltage detector in low power mode.
608  *
609  * retval kStatus_Success Enable System Low Voltage Detect in low power mode successfully.
610  */
SPC_EnableLowPowerModeSystemLowVoltageDetect(SPC_Type * base,bool enable)611 status_t SPC_EnableLowPowerModeSystemLowVoltageDetect(SPC_Type *base, bool enable)
612 {
613     status_t status = kStatus_Success;
614 
615     if (enable)
616     {
617         base->LP_CFG |= SPC_LP_CFG_SYS_LVDE_MASK;
618     }
619     else
620     {
621         base->LP_CFG &= ~SPC_LP_CFG_SYS_LVDE_MASK;
622     }
623 
624     return status;
625 }
626 
627 #if (defined(FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD) && FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD)
628 /*!
629  * brief Set IO VDD Low-Voltage level selection.
630  *
631  * This function selects the IO VDD Low-voltage level. Changing IO VDD low-voltage level
632  * must be done after disabling the IO VDD low voltage reset and interrupt.
633  *
634  * param base SPC peripheral base address.
635  * param level IO VDD Low-voltage level selection.
636  */
SPC_SetIOVDDLowVoltageLevel(SPC_Type * base,spc_low_voltage_level_select_t level)637 void SPC_SetIOVDDLowVoltageLevel(SPC_Type *base, spc_low_voltage_level_select_t level)
638 {
639     uint32_t reg;
640 
641     reg = base->VD_IO_CFG;
642 
643     base->VD_IO_CFG &= ~(SPC_VD_IO_CFG_LVDRE_MASK | SPC_VD_IO_CFG_LVDIE_MASK | SPC_VD_IO_CFG_LVSEL_MASK);
644     reg |= SPC_VD_IO_CFG_LVSEL(level);
645 
646     base->VD_IO_CFG = reg;
647 }
648 
649 /*!
650  * brief Configs IO VDD voltage detect options.
651  *
652  * This function config IO voltage detect options.
653  * Note: Setting both the voltage detect interrupt and reset
654  *       enable will cause interrupt to be generated on exit from reset.
655  *       If those conditioned is not desired, interrupt/reset so only one is enabled.
656  *
657  * param base       SPC peripheral base address.
658  * param config     Pointer to spc_IO_voltage_detect_config_t structure.
659  */
SPC_SetIOVoltageDetectConfig(SPC_Type * base,const spc_io_voltage_detect_config_t * config)660 void SPC_SetIOVoltageDetectConfig(SPC_Type *base, const spc_io_voltage_detect_config_t *config)
661 {
662     assert(config != NULL);
663 
664     uint32_t reg = 0UL;
665 
666     /* Set trip voltage level. */
667     SPC_SetIOVDDLowVoltageLevel(base, config->level);
668 
669     reg = base->VD_IO_CFG;
670     reg &= ~(SPC_VD_IO_CFG_LVDRE_MASK | SPC_VD_IO_CFG_LVDIE_MASK | SPC_VD_IO_CFG_HVDRE_MASK | SPC_VD_IO_CFG_HVDIE_MASK);
671 
672     reg |= (config->option.HVDInterruptEnable) ? SPC_VD_IO_CFG_HVDIE(1U) : SPC_VD_IO_CFG_HVDIE(0U);
673     reg |= (config->option.LVDInterruptEnable) ? SPC_VD_IO_CFG_LVDIE(1U) : SPC_VD_IO_CFG_LVDIE(0U);
674     reg |= (config->option.HVDResetEnable) ? SPC_VD_IO_CFG_HVDRE(1U) : SPC_VD_IO_CFG_HVDRE(0U);
675     reg |= (config->option.LVDResetEnable) ? SPC_VD_IO_CFG_LVDRE(1U) : SPC_VD_IO_CFG_LVDRE(0U);
676 
677     base->VD_IO_CFG = reg;
678 }
679 
680 /*!
681  * brief Enables the IO VDD High Voltage Detector in Active mode.
682  *
683  * note If the IO high voltage detect is enabled in Active mode,
684  * please note that the bandgap must be enabled and the drive strength
685  * of each regulator must not set to low in Active mode.
686  *
687  * param base SPC peripheral base address.
688  * param enable Enable/Disable IO HVD.
689  *          true    -   Enable IO High voltage detector in active mode.
690  *          false   -   Disable IO High voltage detector in active mode.
691  *
692  * retval kStatus_Success Enable IO High Voltage Detect successfully.
693  */
SPC_EnableActiveModeIOHighVoltageDetect(SPC_Type * base,bool enable)694 status_t SPC_EnableActiveModeIOHighVoltageDetect(SPC_Type *base, bool enable)
695 {
696     status_t status = kStatus_Success;
697 
698     if (enable)
699     {
700         base->ACTIVE_CFG |= SPC_ACTIVE_CFG_IO_HVDE_MASK;
701     }
702     else
703     {
704         base->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_IO_HVDE_MASK;
705     }
706 
707     return status;
708 }
709 
710 /*!
711  * brief Enables the IO VDD Low Voltage Detector in Active mode.
712  *
713  * note If the IO low voltage detect is enabled in Active mode,
714  * please note that the bandgap must be enabled and the drive strength
715  * of each regulator must not set to low in Active mode.
716  *
717  * param base SPC peripheral base address.
718  * param enable Enable/Disable IO LVD.
719  *          true    -   Enable IO Low voltage detector in active mode.
720  *          false   -   Disable IO Low voltage detector in active mode.
721  *
722  * retval kStatus_Success Enable IO Low Voltage Detect successfully.
723  */
SPC_EnableActiveModeIOLowVoltageDetect(SPC_Type * base,bool enable)724 status_t SPC_EnableActiveModeIOLowVoltageDetect(SPC_Type *base, bool enable)
725 {
726     status_t status = kStatus_Success;
727 
728     if (enable)
729     {
730         base->ACTIVE_CFG |= SPC_ACTIVE_CFG_IO_LVDE_MASK;
731     }
732     else
733     {
734         base->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_IO_LVDE_MASK;
735     }
736 
737     return status;
738 }
739 
740 /*!
741  * brief Enables the IO VDD High Voltage Detector in Low Power mode.
742  *
743  * note If the IO high voltage detect is enabled in Low Power mode, please note that the bandgap must be enabled
744  * and the drive strength of each regulator must not set to low in Low Power mode.
745  *
746  * param base SPC peripheral base address.
747  * param enable Enable/Disable IO HVD.
748  *          true    -   Enable IO High voltage detector in low power mode.
749  *          false   -   Disable IO High voltage detector in low power mode.
750  *
751  * retval kStatus_Success Enable IO High Voltage Detect in low power mode successfully.
752  */
SPC_EnableLowPowerModeIOHighVoltageDetect(SPC_Type * base,bool enable)753 status_t SPC_EnableLowPowerModeIOHighVoltageDetect(SPC_Type *base, bool enable)
754 {
755     status_t status = kStatus_Success;
756 
757     if (enable)
758     {
759         base->LP_CFG |= SPC_LP_CFG_IO_HVDE_MASK;
760     }
761     else
762     {
763         base->LP_CFG &= ~SPC_LP_CFG_IO_HVDE_MASK;
764     }
765 
766     return status;
767 }
768 
769 /*!
770  * brief Enables the IO VDD Low Voltage Detector in Low Power mode.
771  *
772  * note If the IO low voltage detect is enabled in Low Power mode, please note that the bandgap must be enabled
773  * and the drive strength of each regulator must not set to low in Low Power mode.
774  *
775  * param base SPC peripheral base address.
776  * param enable Enable/Disable IO HVD.
777  *          true    -   Enable IO Low voltage detector in low power mode.
778  *          false   -   Disable IO Low voltage detector in low power mode.
779  *
780  * retval kStatus_Success Enable IO Low Voltage Detect in low power mode successfully.
781  */
SPC_EnableLowPowerModeIOLowVoltageDetect(SPC_Type * base,bool enable)782 status_t SPC_EnableLowPowerModeIOLowVoltageDetect(SPC_Type *base, bool enable)
783 {
784     status_t status = kStatus_Success;
785 
786     if (enable)
787     {
788         base->LP_CFG |= SPC_LP_CFG_IO_LVDE_MASK;
789     }
790     else
791     {
792         base->LP_CFG &= ~SPC_LP_CFG_IO_LVDE_MASK;
793     }
794 
795     return status;
796 }
797 #endif /* FSL_FEATURE_MCX_SPC_HAS_IOVDD_VD */
798 
799 /*!
800  * brief Configs external voltage domains
801  *
802  * This function configs external voltage domains isolation.
803  *
804  * param base SPC peripheral base address.
805  * param lowPowerIsoMask The mask of external domains isolate enable during low power mode.
806  * param IsoMask The mask of external domains isolate.
807  */
SPC_SetExternalVoltageDomainsConfig(SPC_Type * base,uint8_t lowPowerIsoMask,uint8_t IsoMask)808 void SPC_SetExternalVoltageDomainsConfig(SPC_Type *base, uint8_t lowPowerIsoMask, uint8_t IsoMask)
809 {
810     uint32_t reg = 0UL;
811 
812     reg |= SPC_EVD_CFG_REG_EVDISO(IsoMask) | SPC_EVD_CFG_REG_EVDLPISO(lowPowerIsoMask);
813     base->EVD_CFG = reg;
814 }
815 
816 /*!
817  * brief Configs Core LDO Regulator in Active mode.
818  *
819  * @note The bandgap must be enabled before invoking this function.
820  * @note To set Core LDO as low drive strength, all HVDs/LVDs must be disabled previously.
821  *
822  * param base SPC peripheral base address.
823  * param option Pointer to the spc_active_mode_Core_LDO_option_t structure.
824  *
825  * retval kStatus_Success Config Core LDO regulator in Active power mode successful.
826  * retval kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition.
827  * retval kStatus_SPC_BandgapModeWrong Bandgap should be enabled before invoking this function.
828  * retval kStatus_SPC_CORELDOLowDriveStrengthIgnore To set Core LDO as low drive strength,
829  *                                                  all LVDs/HVDs must be disabled before invoking this function.
830  */
SPC_SetActiveModeCoreLDORegulatorConfig(SPC_Type * base,const spc_active_mode_core_ldo_option_t * option)831 status_t SPC_SetActiveModeCoreLDORegulatorConfig(SPC_Type *base, const spc_active_mode_core_ldo_option_t *option)
832 {
833     assert(option != NULL);
834 
835     if ((base->SC & SPC_SC_BUSY_MASK) != 0UL)
836     {
837         return kStatus_SPC_Busy;
838     }
839 
840     /* Check input parameters. */
841     /*  1. Bandgap must not be disabled. */
842     if (SPC_GetActiveModeBandgapMode(base) == kSPC_BandgapDisabled)
843     {
844         return kStatus_SPC_BandgapModeWrong;
845     }
846 
847     /*  2. To set to low drive strength, all LVDs/HVDs must be disabled previously. */
848     if ((SPC_GetActiveModeVoltageDetectStatus(base) != 0UL) &&
849         (option->CoreLDODriveStrength == kSPC_CoreLDO_LowDriveStrength))
850     {
851         return kStatus_SPC_CORELDOLowDriveStrengthIgnore;
852     }
853 
854     if ((uint8_t)SPC_GetActiveModeCoreLDOVDDVoltageLevel(base) != (uint8_t)(option->CoreLDOVoltage))
855     {
856 #if defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS
857         (void)SPC_SetActiveModeCoreLDORegulatorDriveStrength(base, kSPC_CoreLDO_NormalDriveStrength);
858 #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */
859         (void)SPC_SetActiveModeCoreLDORegulatorVoltageLevel(base, option->CoreLDOVoltage);
860     }
861 
862 #if defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS
863     (void)SPC_SetActiveModeCoreLDORegulatorDriveStrength(base, option->CoreLDODriveStrength);
864 #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */
865 
866     return kStatus_Success;
867 }
868 
869 /*!
870  * brief Set Core LDO VDD Regulator Voltage level in Active mode.
871  *
872  * @note In active mode, the Core LDO voltage level should only be changed when the
873  *  Core LDO is in normal drive strength.
874  *
875  * @note Update Core LDO voltage level will set Busy flag,
876  *      this function return only when busy flag is cleared by hardware
877  *
878  * param base SPC peripheral base address.
879  * param voltageLevel Specify the voltage level of CORE LDO Regulator in Active mode, please
880         refer to @ref spc_core_ldo_voltage_level_t.
881  *
882  * retval kStatus_SPC_CORELDOVoltageSetFail  Core LDO voltage level should only be
883  *                                          changed when the CORE_LDO is in normal drive strength.
884  * retval kStatus_Success Set Core LDO regulator voltage level in Active power mode successful.
885  */
SPC_SetActiveModeCoreLDORegulatorVoltageLevel(SPC_Type * base,spc_core_ldo_voltage_level_t voltageLevel)886 status_t SPC_SetActiveModeCoreLDORegulatorVoltageLevel(SPC_Type *base, spc_core_ldo_voltage_level_t voltageLevel)
887 {
888     if ((uint8_t)voltageLevel != (uint8_t)SPC_GetActiveModeCoreLDOVDDVoltageLevel(base))
889     {
890 #if (defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS)
891         if (SPC_GetActiveModeCoreLDODriveStrength(base) != kSPC_CoreLDO_NormalDriveStrength)
892         {
893             return kStatus_SPC_CORELDOVoltageSetFail;
894         }
895 #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */
896 
897         base->ACTIVE_CFG =
898             ((base->ACTIVE_CFG & ~SPC_ACTIVE_CFG_CORELDO_VDD_LVL_MASK) | SPC_ACTIVE_CFG_CORELDO_VDD_LVL(voltageLevel));
899 
900         /*
901          * $Branch Coverage Justification$
902          * $ref spc_c_ref_1$.
903          */
904         while ((base->SC & SPC_SC_BUSY_MASK) != 0UL)
905         {
906         }
907     }
908     return kStatus_Success;
909 }
910 
911 #if defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS
912 /*!
913  * brief Set Core LDO VDD Regulator Drive Strength in Active mode.
914  *
915  * param base SPC peripheral base address.
916  * param driveStrength Specify the drive strength of CORE LDO Regulator in Active mode, please
917         refer to @ref spc_core_ldo_drive_strength_t.
918  *
919  * retval #kStatus_Success Set Core LDO regulator drive strength in Active power mode successful.
920  * retval #kStatus_SPC_CORELDOLowDriveStrengthIgnore If any voltage detect enabled,
921             core_ldo's drive strength can not set to low.
922  * retval #kStatus_SPC_BandgapModeWrong The selected bandgap mode is not allowed.
923  */
SPC_SetActiveModeCoreLDORegulatorDriveStrength(SPC_Type * base,spc_core_ldo_drive_strength_t driveStrength)924 status_t SPC_SetActiveModeCoreLDORegulatorDriveStrength(SPC_Type *base, spc_core_ldo_drive_strength_t driveStrength)
925 {
926     if (driveStrength == kSPC_CoreLDO_LowDriveStrength)
927     {
928         /* If any voltage detect feature is enabled in Active mode, then CORE_LDO's drive strength must not set to low.
929          */
930         if (SPC_GetActiveModeVoltageDetectStatus(base) != 0UL)
931         {
932             return kStatus_SPC_CORELDOLowDriveStrengthIgnore;
933         }
934     }
935 
936     if (driveStrength == kSPC_CoreLDO_NormalDriveStrength)
937     {
938         /* If specify normal drive strength, bandgap must not be disabled. */
939         if (SPC_GetActiveModeBandgapMode(base) == kSPC_BandgapDisabled)
940         {
941             return kStatus_SPC_BandgapModeWrong;
942         }
943     }
944 
945     base->ACTIVE_CFG =
946         ((base->ACTIVE_CFG & ~SPC_ACTIVE_CFG_CORELDO_VDD_DS_MASK) | SPC_ACTIVE_CFG_CORELDO_VDD_DS(driveStrength));
947 
948     return kStatus_Success;
949 }
950 #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */
951 
952 /*!
953  * brief Configs CORE LDO Regulator in low power mode
954  *
955  * This function configs CORE LDO Regulator in Low Power mode.
956  * If CORE LDO VDD Drive Strength is set to Normal, the CORE LDO VDD regulator voltage
957  * level in Active mode must be equal to the voltage level in Low power mode. And the Bandgap
958  * must be programmed to select bandgap enabled.
959  * Core VDD voltage levels for the Core LDO low power regulator can only be changed when the CORE
960  * LDO Drive Strength is set as Normal.
961  *
962  * param base SPC peripheral base address.
963  * param option Pointer to the spc_lowpower_mode_Core_LDO_option_t structure.
964  * retval kStatus_Success Config Core LDO regulator in power mode successfully.
965  * retval kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition.
966  * retval kStatus_SPC_CORELDOLowDriveStrengthIgnore HVDs/LVDs are not disabled before invoking this function.
967  * retval kStatus_SPC_BandgapModeWrong The bandgap is not enabled before invoking this function.
968  */
SPC_SetLowPowerModeCoreLDORegulatorConfig(SPC_Type * base,const spc_lowpower_mode_core_ldo_option_t * option)969 status_t SPC_SetLowPowerModeCoreLDORegulatorConfig(SPC_Type *base, const spc_lowpower_mode_core_ldo_option_t *option)
970 {
971     status_t status = kStatus_Success;
972 
973     if ((base->SC & SPC_SC_BUSY_MASK) != 0UL)
974     {
975         /*
976          * $Line Coverage Justification$
977          * $ref spc_c_ref_1$.
978          */
979         return kStatus_SPC_Busy;
980     }
981 
982     status = SPC_SetLowPowerModeCoreLDORegulatorDriveStrength(base, option->CoreLDODriveStrength);
983     if (status == kStatus_Success)
984     {
985         (void)SPC_SetLowPowerModeCoreLDORegulatorVoltageLevel(base, option->CoreLDOVoltage);
986     }
987 
988     return status;
989 }
990 
991 /*!
992  * brief Set Core LDO VDD Regulator Voltage level in Low power mode.
993  *
994  * @note If Core LDO's drive strengths are same in active and low power mode, the Core LDO's voltage must be set to the
995  * same value in active and low power mode. Application should take care of this limitation.
996  *
997  * @note Some devices require Core LDO and DCDC have the same voltage level even if Core LDO is off. Application should
998  * take care of this limitation.
999  *
1000  * param base SPC peripheral base address.
1001  * param voltageLevel Voltage level of CORE LDO Regulator in Low power mode, please
1002         refer to @ref spc_core_ldo_voltage_level_t.
1003  *
1004  * retval #kStatus_SPC_Busy The SPC instance is busy to execute other operation.
1005  * retval #kStatus_Success Set Core LDO regulator voltage level in Low power mode successful.
1006  */
SPC_SetLowPowerModeCoreLDORegulatorVoltageLevel(SPC_Type * base,spc_core_ldo_voltage_level_t voltageLevel)1007 status_t SPC_SetLowPowerModeCoreLDORegulatorVoltageLevel(SPC_Type *base, spc_core_ldo_voltage_level_t voltageLevel)
1008 {
1009     if ((base->SC & SPC_SC_BUSY_MASK) != 0UL)
1010     {
1011         /*
1012             * $Line Coverage Justification$
1013             * $ref spc_c_ref_1$.
1014             */
1015         return kStatus_SPC_Busy;
1016     }
1017 
1018     base->LP_CFG = ((base->LP_CFG & ~SPC_LP_CFG_CORELDO_VDD_LVL_MASK) | SPC_LP_CFG_CORELDO_VDD_LVL(voltageLevel));
1019 
1020     /*
1021         * $Branch Coverage Justification$
1022         * $ref spc_c_ref_1$.
1023         */
1024     while ((base->SC & SPC_SC_BUSY_MASK) != 0UL)
1025     {
1026     }
1027 
1028     return kStatus_Success;
1029 }
1030 
1031 /*!
1032  * brief Set Core LDO VDD Regulator Drive Strength in Low power mode.
1033  *
1034  * param base SPC peripheral base address.
1035  * param driveStrength Specify drive strength of CORE LDO in low power mode.
1036  *
1037  * retval #kStatus_SPC_CORELDOLowDriveStrengthIgnore Some voltage detect enabled, CORE LDO's drive strength can not set
1038  *           as low.
1039  * retval #kStatus_Success Set Core LDO regulator drive strength in Low power mode successful.
1040  * retval #kStatus_SPC_BandgapModeWrong Bandgap is disabled when attempt to set CORE LDO work as normal drive strength.
1041  */
SPC_SetLowPowerModeCoreLDORegulatorDriveStrength(SPC_Type * base,spc_core_ldo_drive_strength_t driveStrength)1042 status_t SPC_SetLowPowerModeCoreLDORegulatorDriveStrength(SPC_Type *base, spc_core_ldo_drive_strength_t driveStrength)
1043 {
1044     if (driveStrength == kSPC_CoreLDO_LowDriveStrength)
1045     {
1046         /* If any voltage detect feature is enabled in Low Power mode, then CORE_LDO's drive strength must not set to
1047          * low.
1048          */
1049         if (SPC_GetLowPowerModeVoltageDetectStatus(base) != 0UL)
1050         {
1051             return kStatus_SPC_CORELDOLowDriveStrengthIgnore;
1052         }
1053     }
1054     else
1055     {
1056         /* To specify normal drive strength, the bandgap must be enabled in low power mode. */
1057         if (SPC_GetLowPowerModeBandgapMode(base) == kSPC_BandgapDisabled)
1058         {
1059             return kStatus_SPC_BandgapModeWrong;
1060         }
1061     }
1062 
1063     base->LP_CFG = ((base->LP_CFG & ~SPC_LP_CFG_CORELDO_VDD_DS_MASK) | SPC_LP_CFG_CORELDO_VDD_DS(driveStrength));
1064 
1065     return kStatus_Success;
1066 }
1067 
1068 #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO)
1069 /*!
1070  * brief Configs System LDO VDD Regulator in Active mode.
1071  *
1072  * This function configs System LDO VDD Regulator in Active mode.
1073  * If System LDO VDD Drive Strength is set to Normal, the Bandgap mode in Active mode must be programmed
1074  * to a value that enable the bandgap.
1075  * If any voltage detects are kept enabled, configuration to set System LDO VDD drive strength to low will
1076  * be ignored.
1077  * If select System LDO VDD Regulator voltage level to Over Drive Voltage, the Drive Strength of System LDO VDD
1078  * Regulator must be set to Normal otherwise the regulator Drive Strength will be forced to Normal.
1079  * If select System LDO VDD Regulator voltage level to Over Drive Voltage, the High voltage detect must be disabled.
1080  * Otherwise it will be fail to regulator to Over Drive Voltage.
1081  *
1082  * param base SPC peripheral base address.
1083  * param option Pointer to the spc_active_mode_Sys_LDO_option_t structure.
1084  * retval kStatus_Success Config System LDO regulator in Active power mode successful.
1085  * retval kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition.
1086  * retval kStatus_SPC_BandgapModeWrong The bandgap is not enabled before invoking this function.
1087  * retval kStatus_SPC_SYSLDOOverDriveVoltageFail HVD of System VDD is not disable before setting to Over Drive voltage.
1088  * retval kStatus_SPC_SYSLDOLowDriveStrengthIgnore Set System LDO VDD regulator's driver strength to Low will be
1089  * ignored.
1090  */
SPC_SetActiveModeSystemLDORegulatorConfig(SPC_Type * base,const spc_active_mode_sys_ldo_option_t * option)1091 status_t SPC_SetActiveModeSystemLDORegulatorConfig(SPC_Type *base, const spc_active_mode_sys_ldo_option_t *option)
1092 {
1093     assert(option != NULL);
1094 
1095     if ((base->SC & SPC_SC_BUSY_MASK) != 0UL)
1096     {
1097         /*
1098          * $Line Coverage Justification$
1099          * $ref spc_c_ref_1$.
1100          */
1101         return kStatus_SPC_Busy;
1102     }
1103 
1104     /* Check input parameters before setting registers. */
1105     /*  1. To set to low DS, all LVDs/HVDs must be disabled previously. */
1106     if ((SPC_GetActiveModeVoltageDetectStatus(base) != 0UL) &&
1107         (option->SysLDODriveStrength == kSPC_SysLDO_LowDriveStrength))
1108     {
1109         return kStatus_SPC_SYSLDOLowDriveStrengthIgnore;
1110     }
1111     /* 2. If specify normal drive strength, bandgap must not be disabled. */
1112     if ((SPC_GetActiveModeBandgapMode(base) == kSPC_BandgapDisabled) &&
1113         (option->SysLDODriveStrength == kSPC_SysLDO_NormalDriveStrength))
1114     {
1115         return kStatus_SPC_BandgapModeWrong;
1116     }
1117 
1118     /* 3. Must disable system LDO high voltage detector before specifing overdrive voltage. */
1119     if ((option->SysLDOVoltage == kSPC_SysLDO_OverDriveVoltage) &&
1120         ((SPC_GetActiveModeVoltageDetectStatus(base) & SPC_ACTIVE_CFG_SYS_HVDE_MASK) != 0UL))
1121     {
1122         return kStatus_SPC_SYSLDOOverDriveVoltageFail;
1123     }
1124 
1125     (void)SPC_SetActiveModeSystemLDORegulatorDriveStrength(base, option->SysLDODriveStrength);
1126     (void)SPC_SetActiveModeSystemLDORegulatorVoltageLevel(base, option->SysLDOVoltage);
1127 
1128     return kStatus_Success;
1129 }
1130 
1131 /*!
1132  * brief Set System LDO Regulator voltage level in Active mode.
1133  *
1134  * @note The system LDO regulator can only operate at the overdrive voltage level for a limited amount of time for the
1135  * life of chip.
1136  *
1137  * param base SPC peripheral base address.
1138  * param voltageLevel Specify the voltage level of System LDO Regulator in Active mode.
1139  *
1140  * retval #kStatus_Success Set System LDO Regulator voltage level in Active mode successfully.
1141  * retval #kStatus_SPC_SYSLDOOverDriveVoltageFail Must disable system LDO high voltage detector before specifing
1142  * overdrive voltage.
1143  */
SPC_SetActiveModeSystemLDORegulatorVoltageLevel(SPC_Type * base,spc_sys_ldo_voltage_level_t voltageLevel)1144 status_t SPC_SetActiveModeSystemLDORegulatorVoltageLevel(SPC_Type *base, spc_sys_ldo_voltage_level_t voltageLevel)
1145 {
1146     if (voltageLevel == kSPC_SysLDO_OverDriveVoltage)
1147     {
1148         /* Must disable system LDO high voltage detector before specifing overdrive voltage. */
1149         if ((SPC_GetActiveModeVoltageDetectStatus(base) & SPC_ACTIVE_CFG_SYS_HVDE_MASK) != 0UL)
1150         {
1151             return kStatus_SPC_SYSLDOOverDriveVoltageFail;
1152         }
1153     }
1154 
1155     base->ACTIVE_CFG =
1156         (base->ACTIVE_CFG & ~SPC_ACTIVE_CFG_SYSLDO_VDD_LVL_MASK) | SPC_ACTIVE_CFG_SYSLDO_VDD_LVL(voltageLevel);
1157 
1158     return kStatus_Success;
1159 }
1160 
1161 /*!
1162  * brief Set System LDO Regulator Drive Strength in Active mode.
1163  *
1164  * param base SPC peripheral base address.
1165  * param driveStrength Specify the drive strength  of System LDO Regulator in Active mode.
1166  *
1167  * retval #kStatus_Success Set System LDO Regulator drive strength in Active mode successfully.
1168  * retval #kStatus_SPC_SYSLDOLowDriveStrengthIgnore Attempt to specify low drive strength is ignored due to any
1169             voltage detect feature is enabled in active mode.
1170  * retval #kStatus_SPC_BandgapModeWrong Bandgap mode in Active mode must be programmed to a value that enables
1171             the bandgap if attempt to specify normal drive strength.
1172  */
SPC_SetActiveModeSystemLDORegulatorDriveStrength(SPC_Type * base,spc_sys_ldo_drive_strength_t driveStrength)1173 status_t SPC_SetActiveModeSystemLDORegulatorDriveStrength(SPC_Type *base, spc_sys_ldo_drive_strength_t driveStrength)
1174 {
1175     if (driveStrength == kSPC_SysLDO_LowDriveStrength)
1176     {
1177         /* If enabled any LVDs or HVDs, SPC will ignore the attempt to specify low drive strength. */
1178         if (SPC_GetActiveModeVoltageDetectStatus(base) != 0UL)
1179         {
1180             return kStatus_SPC_SYSLDOLowDriveStrengthIgnore;
1181         }
1182     }
1183 
1184     if (driveStrength == kSPC_SysLDO_NormalDriveStrength)
1185     {
1186         /* If specify normal drive strength, bandgap must not be disabled. */
1187         if (SPC_GetActiveModeBandgapMode(base) == kSPC_BandgapDisabled)
1188         {
1189             return kStatus_SPC_BandgapModeWrong;
1190         }
1191     }
1192 
1193     base->ACTIVE_CFG =
1194         (base->ACTIVE_CFG & ~SPC_ACTIVE_CFG_SYSLDO_VDD_DS_MASK) | SPC_ACTIVE_CFG_SYSLDO_VDD_DS(driveStrength);
1195 
1196     return kStatus_Success;
1197 }
1198 
1199 /*!
1200  * brief Configs System LDO regulator in low power modes.
1201  *
1202  * This function configs System LDO regulator in low power modes.
1203  * If System LDO VDD Regulator Drive strength is set to normal, bandgap mode in low power
1204  * mode must be programmed to a value that enables the Bandgap.
1205  * If any High voltage detectors or Low Voltage detectors are kept enabled, configuration
1206  * to set System LDO Regulator drive strength as Low will be ignored.
1207  *
1208  * param base SPC peripheral base address.
1209  * param option Pointer to spc_lowpower_mode_Sys_LDO_option_t structure.
1210  *
1211  * retval kStatus_Success Config System LDO regulator in Low Power Mode successfully.
1212  * retval kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition.
1213  * retval kStatus_SPC_BandgapModeWrong The bandgap mode setting in Low Power Mode is wrong.
1214  * retval kStatus_SPC_SYSLDOLowDriveStrengthIgnore Set driver strength to low will be ignored.
1215  */
SPC_SetLowPowerModeSystemLDORegulatorConfig(SPC_Type * base,const spc_lowpower_mode_sys_ldo_option_t * option)1216 status_t SPC_SetLowPowerModeSystemLDORegulatorConfig(SPC_Type *base, const spc_lowpower_mode_sys_ldo_option_t *option)
1217 {
1218     status_t status;
1219 
1220     if ((base->SC & SPC_SC_BUSY_MASK) != 0UL)
1221     {
1222         /*
1223          * $Line Coverage Justification$
1224          * $ref spc_c_ref_1$.
1225          */
1226         return kStatus_SPC_Busy;
1227     }
1228 
1229     status = SPC_SetLowPowerModeSystemLDORegulatorDriveStrength(base, option->SysLDODriveStrength);
1230 
1231     return status;
1232 }
1233 
1234 /*!
1235  * brief Set System LDO Regulator drive strength in Low Power Mode.
1236  *
1237  * param base SPC peripheral base address.
1238  * param driveStrength Specify the drive strength of System LDO Regulator in Low Power Mode.
1239  *
1240  * retval #kStatus_Success Set System LDO Regulator drive strength in Low Power Mode successfully.
1241  * retval #kStatus_SPC_SYSLDOLowDriveStrengthIgnore Attempt to specify low drive strength is ignored due to any
1242             voltage detect feature is enabled in low power mode.
1243  * retval #kStatus_SPC_BandgapModeWrong Bandgap mode in low power mode must be programmed to a value that enables
1244             the bandgap if attempt to specify normal drive strength.
1245  */
SPC_SetLowPowerModeSystemLDORegulatorDriveStrength(SPC_Type * base,spc_sys_ldo_drive_strength_t driveStrength)1246 status_t SPC_SetLowPowerModeSystemLDORegulatorDriveStrength(SPC_Type *base, spc_sys_ldo_drive_strength_t driveStrength)
1247 {
1248     if (driveStrength == kSPC_SysLDO_LowDriveStrength)
1249     {
1250         /* If enabled any LVDs or HVDs, SPC will ignore the attempt to specify low drive strength. */
1251         if (SPC_GetLowPowerModeVoltageDetectStatus(base) != 0UL)
1252         {
1253             return kStatus_SPC_SYSLDOLowDriveStrengthIgnore;
1254         }
1255     }
1256     else
1257     {
1258         /* If specify normal drive strength, bandgap must not be disabled. */
1259         if (SPC_GetLowPowerModeBandgapMode(base) == kSPC_BandgapDisabled)
1260         {
1261             return kStatus_SPC_BandgapModeWrong;
1262         }
1263     }
1264 
1265     base->LP_CFG = (base->LP_CFG & ~SPC_LP_CFG_SYSLDO_VDD_DS_MASK) | SPC_LP_CFG_SYSLDO_VDD_DS(driveStrength);
1266 
1267     return kStatus_Success;
1268 }
1269 #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */
1270 
1271 #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC)
1272 /*!
1273  * brief Configs DCDC VDD Regulator in Active mode.
1274  *
1275  * note When changing the DCDC output voltage level, take care to change the CORE LDO voltage level.
1276  *
1277  * param base SPC peripheral base address.
1278  * param option Pointer to the spc_active_mode_DCDC_option_t structure.
1279  *
1280  * retval kStatus_Success Config DCDC regulator in Active power mode successful.
1281  * retval kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition.
1282  * retval kStatus_SPC_BandgapModeWrong The bandgap mode setting in Active mode is wrong.
1283  */
SPC_SetActiveModeDCDCRegulatorConfig(SPC_Type * base,const spc_active_mode_dcdc_option_t * option)1284 status_t SPC_SetActiveModeDCDCRegulatorConfig(SPC_Type *base, const spc_active_mode_dcdc_option_t *option)
1285 {
1286     assert(option != NULL);
1287     status_t status = kStatus_Success;
1288 
1289     if ((base->SC & SPC_SC_BUSY_MASK) != 0UL)
1290     {
1291         /*
1292          * $Line Coverage Justification$
1293          * $ref spc_c_ref_1$.
1294          */
1295         return kStatus_SPC_Busy;
1296     }
1297 
1298     status = SPC_SetActiveModeDCDCRegulatorDriveStrength(base, option->DCDCDriveStrength);
1299 
1300     if (status == kStatus_Success)
1301     {
1302         SPC_SetActiveModeDCDCRegulatorVoltageLevel(base, option->DCDCVoltage);
1303     }
1304 
1305     /*
1306      * $Branch Coverage Justification$
1307      * $ref spc_c_ref_1$.
1308      */
1309     while ((base->SC & SPC_SC_BUSY_MASK) != 0UL)
1310     {
1311     }
1312 
1313     return status;
1314 }
1315 
1316 /*!
1317  * brief Set DCDC VDD Regulator drive strength in Active mode.
1318  *
1319  * note To set DCDC drive strength as Normal, the bandgap must be enabled.
1320  *
1321  * param base SPC peripheral base address.
1322  * param driveStrength Specify the DCDC VDD regulator drive strength, please refer to @ref spc_dcdc_drive_strength_t.
1323  *
1324  * retval #kStatus_Success Set DCDC VDD Regulator drive strength in Active mode successfully.
1325  * retval #kStatus_SPC_BandgapModeWrong Set DCDC VDD Regulator drive strength to Normal, the Bandgap must be enabled.
1326  */
SPC_SetActiveModeDCDCRegulatorDriveStrength(SPC_Type * base,spc_dcdc_drive_strength_t driveStrength)1327 status_t SPC_SetActiveModeDCDCRegulatorDriveStrength(SPC_Type *base, spc_dcdc_drive_strength_t driveStrength)
1328 {
1329     if (driveStrength == kSPC_DCDC_NormalDriveStrength)
1330     {
1331         /* If specify normal drive strength, bandgap must not be disabled. */
1332         if (SPC_GetActiveModeBandgapMode(base) == kSPC_BandgapDisabled)
1333         {
1334             return kStatus_SPC_BandgapModeWrong;
1335         }
1336     }
1337 
1338     base->ACTIVE_CFG =
1339         ((base->ACTIVE_CFG) & (~SPC_ACTIVE_CFG_DCDC_VDD_DS_MASK)) | SPC_ACTIVE_CFG_DCDC_VDD_DS(driveStrength);
1340 
1341     return kStatus_Success;
1342 }
1343 
1344 /*!
1345  * brief Configs DCDC VDD Regulator in Low power modes.
1346  *
1347  * If DCDC VDD Drive Strength is set to Normal, the Bandgap mode in Low Power mode must be programmed
1348  * to a value that enables the Bandgap.
1349  * In Deep Power Down mode, DCDC regulator is always turned off.
1350  *
1351  * param base SPC peripheral base address.
1352  * param option Pointer to the spc_lowpower_mode_DCDC_option_t structure.
1353  *
1354  * retval kStatus_Success Config DCDC regulator in low power mode successfully.
1355  * retval kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition.
1356  * retval kStatus_SPC_BandgapModeWrong The bandgap should be enabled before invoking this function.
1357  */
SPC_SetLowPowerModeDCDCRegulatorConfig(SPC_Type * base,const spc_lowpower_mode_dcdc_option_t * option)1358 status_t SPC_SetLowPowerModeDCDCRegulatorConfig(SPC_Type *base, const spc_lowpower_mode_dcdc_option_t *option)
1359 {
1360     if ((base->SC & SPC_SC_BUSY_MASK) != 0UL)
1361     {
1362         /*
1363          * $Line Coverage Justification$
1364          * $ref spc_c_ref_1$.
1365          */
1366         return kStatus_SPC_Busy;
1367     }
1368 
1369     /* Check input parameter before setting registers. */
1370     if ((option->DCDCDriveStrength == kSPC_DCDC_NormalDriveStrength) &&
1371         (SPC_GetLowPowerModeBandgapMode(base) == kSPC_BandgapDisabled))
1372     {
1373         return kStatus_SPC_BandgapModeWrong;
1374     }
1375 
1376     /*
1377         1. Configure to desired voltage level.
1378         2. Change to low drive strength.
1379         3. Configure same voltage level in active mode.
1380     */
1381     SPC_SetLowPowerModeDCDCRegulatorVoltageLevel(base, option->DCDCVoltage);
1382 
1383     /* Change to desired drive strength. */
1384     if (option->DCDCDriveStrength != kSPC_DCDC_LowDriveStrength)
1385     {
1386         (void)SPC_SetLowPowerModeDCDCRegulatorDriveStrength(base, option->DCDCDriveStrength);
1387     }
1388 
1389     /*
1390      * $Branch Coverage Justification$
1391      * $ref spc_c_ref_1$.
1392      */
1393     while ((base->SC & SPC_SC_BUSY_MASK) != 0UL)
1394     {
1395     }
1396 
1397     return kStatus_Success;
1398 }
1399 
1400 /*!
1401  * brief Set DCDC VDD Regulator drive strength in Low power mode.
1402  *
1403  * param base SPC peripheral base address.
1404  * param driveStrength Specify the DCDC VDD Regulator drive strength, please refer to @ref spc_dcdc_drive_strength_t.
1405  *
1406  * retval #kStatus_Success Set DCDC VDD Regulator drive strength in Low power mode successfully.
1407  * retval #kStatus_SPC_BandgapModeWrong Set DCDC VDD Regulator drive strength to Normal, the Bandgap must be enabled.
1408  */
SPC_SetLowPowerModeDCDCRegulatorDriveStrength(SPC_Type * base,spc_dcdc_drive_strength_t driveStrength)1409 status_t SPC_SetLowPowerModeDCDCRegulatorDriveStrength(SPC_Type *base, spc_dcdc_drive_strength_t driveStrength)
1410 {
1411     if (driveStrength == kSPC_DCDC_NormalDriveStrength)
1412     {
1413         /* If specify normal drive strength, bandgap must not be disabled. */
1414         if (SPC_GetLowPowerModeBandgapMode(base) == kSPC_BandgapDisabled)
1415         {
1416             return kStatus_SPC_BandgapModeWrong;
1417         }
1418     }
1419 
1420     base->LP_CFG = ((base->LP_CFG) & (~SPC_LP_CFG_DCDC_VDD_DS_MASK)) | SPC_LP_CFG_DCDC_VDD_DS(driveStrength);
1421 
1422     return kStatus_Success;
1423 }
1424 
1425 /*!
1426  * brief Config DCDC Burst options
1427  *
1428  * param base SPC peripheral base address.
1429  * param config Pointer to spc_DCDC_burst_config_t structure.
1430  */
SPC_SetDCDCBurstConfig(SPC_Type * base,spc_dcdc_burst_config_t * config)1431 void SPC_SetDCDCBurstConfig(SPC_Type *base, spc_dcdc_burst_config_t *config)
1432 {
1433     assert(config != NULL);
1434     uint32_t reg;
1435     reg = base->DCDC_CFG;
1436     reg &= ~(SPC_DCDC_CFG_FREQ_CNTRL_MASK | SPC_DCDC_CFG_FREQ_CNTRL_ON_MASK);
1437     reg |= SPC_DCDC_CFG_FREQ_CNTRL(config->freq);
1438     reg |= config->stabilizeBurstFreq ? SPC_DCDC_CFG_FREQ_CNTRL_ON(1U) : SPC_DCDC_CFG_FREQ_CNTRL_ON(0U);
1439     base->DCDC_CFG = reg;
1440 
1441     /* Blocking until previous DCDC burst completed. */
1442     while ((base->DCDC_BURST_CFG & SPC_DCDC_BURST_CFG_BURST_ACK_MASK) == 0UL)
1443     {
1444     }
1445 
1446     if ((config->sofwareBurstRequest) || (config->externalBurstRequest))
1447     {
1448         /* Clear DCDC burst acknowledge flag. */
1449         base->DCDC_BURST_CFG |= SPC_DCDC_BURST_CFG_BURST_ACK_MASK;
1450     }
1451     base->DCDC_BURST_CFG |= SPC_DCDC_BURST_CFG_EXT_BURST_EN(config->externalBurstRequest);
1452 
1453     if (config->sofwareBurstRequest)
1454     {
1455         base->DCDC_BURST_CFG |= SPC_DCDC_BURST_CFG_BURST_REQ_MASK;
1456     }
1457 }
1458 
1459 /*!
1460  * brief Set the count value of the reference clock.
1461  *
1462  * This function set the count value of the reference clock to control the frequency
1463  * of dcdc refresh when dcdc is configured in Pulse Refresh mode.
1464  *
1465  * param base SPC peripheral base address.
1466  * param count The count value, 16 bit width.
1467  */
SPC_SetDCDCRefreshCount(SPC_Type * base,uint16_t count)1468 void SPC_SetDCDCRefreshCount(SPC_Type *base, uint16_t count)
1469 {
1470     uint32_t reg;
1471 
1472     reg = base->DCDC_BURST_CFG;
1473     reg &= ~SPC_DCDC_BURST_CFG_PULSE_REFRESH_CNT_MASK;
1474     reg |= SPC_DCDC_BURST_CFG_PULSE_REFRESH_CNT(count);
1475 
1476     base->DCDC_BURST_CFG = reg;
1477 }
1478 #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */
1479 
1480 /*!
1481  * brief Configs all settings of regulators in Active mode at a time.
1482  *
1483  * @note This function is used to overwrite all settings of regulators(including bandgap mode, regulators'
1484  * drive strength and voltage level) in active mode at a time.
1485  *
1486  * @note Enable/disable LVDs/HVDs before invoking this function.
1487  *
1488  * @note This function will check input parameters based on hardware restrictions before setting registers, if input
1489  * parameters do not satisfy hardware restrictions the specific error will be reported.
1490  *
1491  *
1492  * @note Some hardware restrictions not covered, application should be aware of this and follow this hardware
1493  * restrictions otherwise some unkown issue may occur:
1494  *        1. If Core LDO's drive strength are set to same value in both Active mode and low power mode,
1495  *          the voltage level should also set to same value.
1496  *        2. When switching Core LDO's drive strength from low to normal, ensure the LDO_CORE high voltage level is set
1497  *          to same level that was set prior to switching to the LDO_CORE drive strength. Otherwise, if the LVDs are
1498  *          enabled, an unexpected LVD can occur.
1499  *
1500  * @note If this function can not satisfy some tricky settings, please invoke other low-level functions.
1501  *
1502  * param base SPC peripheral base address.
1503  * param config Pointer to spc_active_mode_regulators_config_t structure.
1504  * retval kStatus_Success Config regulators in Active power mode successful.
1505  * retval kStatus_SPC_BandgapModeWrong The bandgap mode setting in Active mode is wrong.
1506  * retval kStatus_SPC_Busy The SPC instance is busy to execute any type of power mode transition.
1507  * retval kStatus_SPC_CORELDOVoltageWrong The selected voltage level in active mode is not allowed.
1508  * retval kStatus_SPC_SYSLDOOverDriveVoltageFail Fail to regulator to Over Drive Voltage.
1509  * retval kStatus_SPC_SYSLDOLowDriveStrengthIgnore Set driver strength to Low will be ignored.
1510  * retval kStatus_SPC_DCDCLowDriveStrengthIgnore Set driver strength to Low will be ignored.
1511  */
SPC_SetActiveModeRegulatorsConfig(SPC_Type * base,const spc_active_mode_regulators_config_t * config)1512 status_t SPC_SetActiveModeRegulatorsConfig(SPC_Type *base, const spc_active_mode_regulators_config_t *config)
1513 {
1514     assert(config != NULL);
1515 
1516     uint32_t activeModeVDValue = SPC_GetActiveModeVoltageDetectStatus(base);
1517 
1518     /* Check input parameters */
1519     /*  1. Bandgap should not be disabled if any of regulator in normal drive strength or
1520             if any of LVDs/HVDs are enabled or if VDD CORE glitch detect are enabled. */
1521     if ((config->bandgapMode == kSPC_BandgapDisabled) &&
1522         ((activeModeVDValue != 0UL)
1523 #if !(defined(FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) && FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT)
1524          || (SPC_CheckActiveModeVddCoreGlitchDetectEnabled(base) == true)
1525 #endif /* FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT */
1526 #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC)
1527          || (config->DCDCOption.DCDCDriveStrength == kSPC_DCDC_NormalDriveStrength)
1528 #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */
1529 #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO)
1530          || (config->SysLDOOption.SysLDODriveStrength == kSPC_SysLDO_NormalDriveStrength)
1531 #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */
1532 #if (defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS)
1533          || (config->CoreLDOOption.CoreLDODriveStrength == kSPC_CoreLDO_NormalDriveStrength)
1534 #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */
1535              ))
1536     {
1537         return kStatus_SPC_BandgapModeWrong;
1538     }
1539 
1540 #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO)
1541     /*  2. Must disable system LDO high voltage detector before specifing SysLDO to overdrive voltage  */
1542     if (((activeModeVDValue & SPC_ACTIVE_CFG_SYS_HVDE_MASK) != 0UL) &&
1543         (config->SysLDOOption.SysLDOVoltage == kSPC_SysLDO_OverDriveVoltage))
1544     {
1545         return kStatus_SPC_SYSLDOOverDriveVoltageFail;
1546     }
1547 #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */
1548 
1549 #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO)
1550     /* 3. To set System LDO's drive strength to low, all LVDs and HVDs must be disabled. */
1551     if ((activeModeVDValue != 0UL) && (config->SysLDOOption.SysLDODriveStrength == kSPC_SysLDO_LowDriveStrength))
1552     {
1553         return kStatus_SPC_SYSLDOLowDriveStrengthIgnore;
1554     }
1555 #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */
1556 
1557 #if (defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS)
1558     /* 4. To set Core LDO's drive strength to low, all LVDs and HVDs must be disabled. */
1559     if ((activeModeVDValue != 0UL) && (config->CoreLDOOption.CoreLDODriveStrength == kSPC_CoreLDO_LowDriveStrength))
1560     {
1561         return kStatus_SPC_CORELDOLowDriveStrengthIgnore;
1562     }
1563 #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */
1564 
1565 #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC)
1566     /* 5. Core LDO and DCDC should have same voltage level. */
1567     if ((uint8_t)config->DCDCOption.DCDCVoltage != (uint8_t)config->CoreLDOOption.CoreLDOVoltage)
1568     {
1569         return kStatus_SPC_CORELDOVoltageWrong;
1570     }
1571 #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */
1572 
1573     if ((base->SC & SPC_SC_BUSY_MASK) != 0UL)
1574     {
1575         return kStatus_SPC_Busy;
1576     }
1577 
1578     base->ACTIVE_CFG =
1579         ((base->ACTIVE_CFG) & ~(SPC_ACTIVE_CFG_BGMODE_MASK)) | SPC_ACTIVE_CFG_BGMODE(config->bandgapMode);
1580 #if (defined(FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT) && FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT)
1581     SPC_EnableActiveModeCMPBandgapBuffer(base, config->lpBuff);
1582 #endif /* FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT */
1583 
1584 #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO)
1585     (void)SPC_SetActiveModeSystemLDORegulatorConfig(base, &config->SysLDOOption);
1586 #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */
1587 
1588 #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC)
1589     (void)SPC_SetActiveModeDCDCRegulatorConfig(base, &config->DCDCOption);
1590 #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */
1591 
1592     (void)SPC_SetActiveModeCoreLDORegulatorConfig(base, &config->CoreLDOOption);
1593 
1594     return kStatus_Success;
1595 }
1596 
1597 /*!
1598  * brief Configs regulators in Low Power mode.
1599  *
1600  * This function provides the method to config all on-chip regulators in Low Power mode.
1601  *
1602  * param base SPC peripheral base address.
1603  * param config Pointer to spc_lowpower_mode_regulators_config_t structure.
1604  * retval #kStatus_Success Config regulators in Low power mode successful.
1605  * retval #kStatus_SPC_BandgapModeWrong The bandgap should not be disabled based on input settings.
1606  * retval #kStatus_SPC_CORELDOLowDriveStrengthIgnore Set driver strength to low will be ignored.
1607  * retval #kStatus_SPC_SYSLDOLowDriveStrengthIgnore Set driver strength to low will be ignored.
1608  * retval #kStatus_SPC_CORELDOVoltageWrong Core LDO and System LDO do not have same voltage level.
1609  */
SPC_SetLowPowerModeRegulatorsConfig(SPC_Type * base,const spc_lowpower_mode_regulators_config_t * config)1610 status_t SPC_SetLowPowerModeRegulatorsConfig(SPC_Type *base, const spc_lowpower_mode_regulators_config_t *config)
1611 {
1612     assert(config != NULL);
1613     uint32_t lpModeVDValue = SPC_GetLowPowerModeVoltageDetectStatus(base);
1614 
1615     /* Check input parameters */
1616     /*  1. Bandgap should not be disabled if any of regulator in normal drive strength or
1617             if any of LVDs/HVDs are enabled or if VDD CORE glitch detect are enabled. */
1618     if ((config->bandgapMode == kSPC_BandgapDisabled) &&
1619         ((lpModeVDValue != 0UL)
1620 #if !(defined(FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT) && FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT)
1621          || (SPC_CheckLowPowerModeVddCoreGlitchDetectEnabled(base) == true)
1622 #endif /* FSL_FEATURE_MCX_SPC_HAS_NO_GLITCH_DETECT */
1623 #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC)
1624          || (config->DCDCOption.DCDCDriveStrength == kSPC_DCDC_NormalDriveStrength)
1625 #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */
1626 #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO)
1627          || (config->SysLDOOption.SysLDODriveStrength == kSPC_SysLDO_NormalDriveStrength)
1628 #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */
1629 #if (defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS)
1630          || (config->CoreLDOOption.CoreLDODriveStrength == kSPC_CoreLDO_NormalDriveStrength)
1631 #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */
1632              ))
1633     {
1634         return kStatus_SPC_BandgapModeWrong;
1635     }
1636 
1637 #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO)
1638     /* 2. To set System LDO's drive strength to low, all LVDs and HVDs must be disabled. */
1639     if ((lpModeVDValue != 0UL) && (config->SysLDOOption.SysLDODriveStrength == kSPC_SysLDO_LowDriveStrength))
1640     {
1641         return kStatus_SPC_SYSLDOLowDriveStrengthIgnore;
1642     }
1643 #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */
1644 
1645 #if (defined(FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS) && FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS)
1646     /* 3. To set Core LDO's drive strength to low, all LVDs and HVDs must be disabled. */
1647     if ((lpModeVDValue != 0UL) && (config->CoreLDOOption.CoreLDODriveStrength == kSPC_CoreLDO_LowDriveStrength))
1648     {
1649         return kStatus_SPC_CORELDOLowDriveStrengthIgnore;
1650     }
1651 #endif /* FSL_FEATURE_SPC_HAS_CORELDO_VDD_DS */
1652 
1653 #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC)
1654     /* 5. Core LDO and DCDC should have same voltage level. */
1655     if ((uint8_t)config->DCDCOption.DCDCVoltage != (uint8_t)config->CoreLDOOption.CoreLDOVoltage)
1656     {
1657         return kStatus_SPC_CORELDOVoltageWrong;
1658     }
1659 #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */
1660     base->LP_CFG = ((base->LP_CFG) & ~(SPC_LP_CFG_BGMODE_MASK)) | SPC_LP_CFG_BGMODE(config->bandgapMode);
1661 #if (defined(FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT) && FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT)
1662     SPC_EnableLowPowerModeCMPBandgapBuffer(base, config->lpBuff);
1663 #endif /* FSL_FEATURE_MCX_SPC_HAS_LPBUFF_EN_BIT */
1664 #if (defined(FSL_FEATURE_MCX_SPC_HAS_COREVDD_IVS_EN_BIT) && FSL_FEATURE_MCX_SPC_HAS_COREVDD_IVS_EN_BIT)
1665     SPC_EnableLowPowerModeCoreVDDInternalVoltageScaling(base, config->CoreIVS);
1666 #endif /* FSL_FEATURE_MCX_SPC_HAS_COREVDD_IVS_EN_BIT */
1667     SPC_EnableLowPowerModeLowPowerIREF(base, config->lpIREF);
1668 
1669 #if (defined(FSL_FEATURE_MCX_SPC_HAS_SYS_LDO) && FSL_FEATURE_MCX_SPC_HAS_SYS_LDO)
1670     (void)SPC_SetLowPowerModeSystemLDORegulatorConfig(base, &config->SysLDOOption);
1671 #endif /* FSL_FEATURE_MCX_SPC_HAS_SYS_LDO */
1672 
1673 #if (defined(FSL_FEATURE_MCX_SPC_HAS_DCDC) && FSL_FEATURE_MCX_SPC_HAS_DCDC)
1674     (void)SPC_SetLowPowerModeDCDCRegulatorConfig(base, &config->DCDCOption);
1675 #endif /* FSL_FEATURE_MCX_SPC_HAS_DCDC */
1676 
1677     (void)SPC_SetLowPowerModeCoreLDORegulatorConfig(base, &config->CoreLDOOption);
1678 
1679     return kStatus_Success;
1680 }
1681