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