1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020, NXP
4  * All rights reserved.
5  *
6  *
7  * SPDX-License-Identifier: BSD-3-Clause
8  */
9 
10 #ifndef _FSL_SPM_H_
11 #define _FSL_SPM_H_
12 
13 #include "fsl_common.h"
14 
15 /*! @addtogroup spm */
16 /*! @{ */
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 
22 /*! @name Driver version */
23 /*@{*/
24 /*! @brief SPM driver version */
25 #define FSL_SPM_DRIVER_VERSION (MAKE_VERSION(2, 3, 0)) /*!< Version 2.3.0. */
26 
27 /*@}*/
28 
29 /*!
30  * @brief IP version ID definition.
31  */
32 typedef struct _spm_version_id
33 {
34     uint16_t feature; /*!< Feature set number.           */
35     uint8_t minor;    /*!< Minor version number.         */
36     uint8_t major;    /*!< Major version number.         */
37 } spm_version_id_t;
38 
39 /*!
40  * @brief Status of last MCU STOP Mode Power Configuration.
41  */
42 typedef enum _spm_mcu_low_power_mode_status
43 {
44     kSPM_McuLowPowerModeReserved = 0U,        /*!< Reserved. */
45     kSPM_McuLowPowerModeSTOP     = 1U,        /*!< Last Low Power mode is STOP. */
46     kSPM_McuLowPowerModeVLPS     = (1U << 1), /*!< Last Low Power mode is VLPS. */
47     kSPM_McuLowPowerModeLLS      = (1U << 2), /*!< Last Low Power mode is LLS. */
48     kSPM_McuLowPowerModeVLLS23   = (1U << 3), /*!< Last Low Power mode is VLLS23. */
49     kSPM_McuLowPowerModeVLLS01   = (1U << 4), /*!< Last Low Power mode is VLLS01. */
50 } spm_mcu_low_power_mode_status_t;
51 
52 /*!
53  * @brief define the mask code for LDO regulators.
54  *
55  * These mask can be combined with 'or' as a parameter to any function.
56  */
57 enum _spm_ldo_regulator
58 {
59     kSPM_CoreLdo = 1U,        /*!< Mask code for CORE LDO. */
60     kSPM_AuxLdo  = (1U << 1), /*!< Mask code for AUX LDO.  */
61     kSPM_DcdcLdo = (1U << 2), /*!< Mask code for DCDC LDO. */
62 };
63 
64 /*!
65  * @brief Keep the regulator status information.
66  */
67 typedef struct _spm_regulator_status
68 {
69     spm_mcu_low_power_mode_status_t mcuLowPowerModeStatus; /*!< Status of last MCU STOP Mode Power Configuration. */
70     bool isDcdcLdoOn;                                      /*!< DCDC LDO regulator enabled. */
71     bool isAuxLdoOn;                                       /*!< Aux LDO regulator enabled. */
72     bool isCoreLdoOn;                                      /*!< Core LDO regulator enabled. */
73 } spm_regulator_status_t;
74 
75 /*!
76  * @brief Configure the CORE LDO in run modes.
77  */
78 enum _spm_core_ldo_run_mode_config
79 {
80     kSPM_CoreLdoRunModeEnableRtcPowerMonitor =
81         SPM_CORERCNFG_RTCVDDMEN_MASK, /*!< RTC power monitor enabled in run modes. */
82     kSPM_CoreLdoRunModeEnableUsbPowerMonitor =
83         SPM_CORERCNFG_USBVDDMEN_MASK, /*!< USB power monitor enabled in run modes. */
84     kSPM_CoreLdoRunModeEnableVddioPowerMonitor =
85         SPM_CORERCNFG_VDDIOVDDMEN_MASK, /*!< VDDIO power monitor enabled in run modes. */
86 };
87 
88 /*!
89  * @brief Configure the CORE LDO in low power modes.
90  */
91 enum _spm_core_ldo_low_power_mode_config
92 {
93     kSPM_CoreLdoLowPowerModeEnableRtcPowerMonitor =
94         SPM_CORELPCNFG_RTCVDDMEN_MASK, /*!< RTC power monitor enabled in LP modes. */
95     kSPM_CoreLdoLowPowerModeEnableUsbPowerMonitor =
96         SPM_CORELPCNFG_USBVDDMEN_MASK, /*!< USB power monitor enabled in LP modes. */
97     kSPM_CoreLdoLowPowerModeEnableVddioPowerMonitor =
98         SPM_CORELPCNFG_VDDIOVDDMEN_MASK, /*!< VDDIO power monitor enabled in LP modes. */
99     kSPM_CoreLdoLowPowerModeEnableAllReference =
100         SPM_CORELPCNFG_ALLREFEN_MASK,                                        /*!< Enable all reference (bandgap, WELL
101                                                                                   BIAS, 1k clk and LP 25na) in VLLS0/1. */
102     kSPM_CoreLdoLowPowerModeEnableHighDrive = SPM_CORELPCNFG_LPHIDRIVE_MASK, /*!< Enable high driver in low power. */
103     kSPM_CoreLdoLowPowerModeEnableLVD =
104         SPM_CORELPCNFG_LVDEN_MASK, /*!< Enable level voltage detect in low power modes. */
105     kSPM_CoreLdoLowPowerModeEnablePOR = SPM_CORELPCNFG_POREN_MASK, /*!< POR brownout remains enabled in VLLS0/1 mode. */
106     kSPM_CoreLdoLowPowerModeEnableLPO = SPM_CORELPCNFG_LPOEN_MASK, /*!< LPO remains enabled in VLLS0/1 modes. */
107     kSPM_CoreLdoLowPowerModeEnableBandgapBufferHightDrive =
108         SPM_CORELPCNFG_BGBDS_MASK, /*!< Enable the high drive for Bandgap Buffer. */
109     kSPM_CoreLdoLowPowerModeEnableBandgapBuffer = SPM_CORELPCNFG_BGBEN_MASK, /*!< Enable Bandgap Buffer. */
110     kSPM_CoreLdoLowPowerModeEnableBandgapInVLPx =
111         SPM_CORELPCNFG_BGEN_MASK, /*!< Enable Bandgap in STOP/VLPx/LLS and VLLSx mode. */
112     kSPM_CoreLdoLowPowerModeRemainInHighPower =
113         SPM_CORELPCNFG_LPSEL_MASK, /*!< Core LDO remains in high power state in VLP/Stop modes. */
114 };
115 
116 /*!
117  * @brief Low-voltage Detect Voltage Select
118  */
119 typedef enum _spm_low_volt_detect_volt_select
120 {
121     kSPM_LowVoltDetectLowTrip  = 0U, /*!< Low-trip point selected (VLVD = VLVDL )*/
122     kSPM_LowVoltDetectHighTrip = 1U  /*!< High-trip point selected (VLVD = VLVDH )*/
123 } spm_low_volt_detect_volt_select_t;
124 
125 /*!
126  * @brief Low-voltage Detect Configuration Structure.
127  *
128  * This structure reuses the configuration structure from legacy PMC module.
129  */
130 typedef struct _spm_low_volt_detect_config
131 {
132     /* VDD voltage detection. */
133     bool enableIntOnVddLowVolt;   /*!< Enable interrupt when VDD Low-voltage detect. */
134     bool enableResetOnVddLowVolt; /*!< Enable forcing an MCU reset when VDD Low-voltage detect. */
135     spm_low_volt_detect_volt_select_t vddLowVoltDetectSelect; /*!< Low-voltage detect trip point voltage selection. */
136 
137     /* CORE voltage detection. */
138     bool enableIntOnCoreLowVolt;   /*!< Enable interrupt when Core Low-voltage detect. */
139     bool enableResetOnCoreLowVolt; /*!< Enable forcing an MCU reset when Core Low-voltage detect. */
140 } spm_low_volt_detect_config_t;
141 
142 /*!
143  * @brief Low-voltage Warning Voltage Select.
144  */
145 typedef enum _spm_low_volt_warning_volt_select
146 {
147     kSPM_LowVoltWarningLowTrip  = 0U, /*!< Low-trip point selected (VLVW = VLVW1)*/
148     kSPM_LowVoltWarningMID1Trip = 1U, /*!< Mid1-trip point selected (VLVW = VLVW2)*/
149     kSPM_LowVoltWarningMID2Trip = 2U, /*!< Mid2-trip point selected (VLVW = VLVW3)*/
150     kSPM_LowVoltWarningHighTrip = 3U  /*!< High-trip point selected (VLVW = VLVW4)*/
151 } spm_low_volt_warning_volt_select_t;
152 
153 /*!
154  * @brief Low-voltage Warning Configuration Structure
155  */
156 typedef struct _spm_low_volt_warning_config
157 {
158     bool enableIntOnVddLowVolt;                                /*!< Enable interrupt when low-voltage warning*/
159     spm_low_volt_warning_volt_select_t vddLowVoltDetectSelect; /*!< Low-voltage warning trip point voltage selection*/
160 } spm_low_volt_warning_config_t;
161 
162 /*!
163  * @brief High-voltage Detect Voltage Select.
164  */
165 typedef enum _spm_high_volt_detect_volt_select
166 {
167     kSPM_HighVoltDetectLowTrip  = 0U, /*!< Low-trip point selected (VHVD = VHVDL )*/
168     kSPM_HighVoltDetectHighTrip = 1U  /*!< High-trip point selected (VHVD = VHVDH )*/
169 } spm_high_volt_detect_volt_select_t;
170 
171 /*!
172  * @brief High-voltage Detect Configuration Structure.
173  *
174  * This structure reuses the configuration structure from legacy PMC module.
175  */
176 typedef struct _spm_high_volt_detect_config
177 {
178     bool enableIntOnVddHighVolt;                                /*!< Enable interrupt when high-voltage detect*/
179     bool enableResetOnVddHighVolt;                              /*!< Enable system reset when high-voltage detect*/
180     spm_high_volt_detect_volt_select_t vddHighVoltDetectSelect; /*!< High-voltage detect trip point voltage selection*/
181 } spm_high_volt_detect_config_t;
182 
183 /*!
184  * @brief Defines the AUX LDO low power behiavior when in low power modes.
185  */
186 typedef enum _spm_aux_ldo_low_power_mode
187 {
188     kSPM_AuxLdoEnterLowPowerInLowPowerModes = 0U, /*!< AUX LDO regulator enters low power state in VLP/Stop modes. */
189     kSPM_AuxLdoRemainInHighPowerInLowPowerModes =
190         1U, /*!< AUX LDO regulator remains in high power state in VLP/Stop modes. */
191 } spm_aux_ldo_low_power_mode_t;
192 
193 /*!
194  * @brief Selects the soft start duration delay for the IO 1.8 full power regulator.
195  */
196 typedef enum _spm_aux_ldo_io_soft_start_duration
197 {
198     kSPM_AuxLdoSoftStartDuration110us = 0U, /*!< 110 us. */
199     kSPM_AuxLdoSoftStartDuration95us  = 1U, /*!< 95 us. */
200     kSPM_AuxLdoSoftStartDuration60us  = 2U, /*!< 60 us. */
201     kSPM_AuxLdoSoftStartDuration48us  = 3U, /*!< 48 us. */
202     kSPM_AuxLdoSoftStartDuration38us  = 4U, /*!< 38 us. */
203     kSPM_AuxLdoSoftStartDuration30us  = 5U, /*!< 30 us. */
204     kSPM_AuxLdoSoftStartDuration24us  = 6U, /*!< 24 us. */
205     kSPM_AuxLdoSoftStartDuration17us  = 7U, /*!< 17 us. */
206 } spm_aux_ldo_io_soft_start_duration_t;
207 
208 /*!
209  * @brief IO Regulator Voltage Select.
210  */
211 typedef enum _spm_aux_io_regulator_volt_select
212 {
213     kSPM_AuxIoRegulatorVoltLevel1p8 = 0U, /*!< Regulate to 1.8V. */
214     kSPM_AuxIoRegulatorVoltLevel1p5 = 1U, /*!< Regulate to 1.5V. */
215 } spm_aux_io_regulator_volt_select_t;
216 
217 /*!
218  * @brief Aux LDO configuration structure.
219  */
220 typedef struct _spm_aux_ldo_config
221 {
222     spm_aux_ldo_low_power_mode_t lowPowerMode; /*!< AUX LDO low power behaviour when in low power modes. */
223     spm_aux_ldo_io_soft_start_duration_t
224         ioSoftStartDuration; /*!< Selects the soft start duration delay for the IO 1.8 full power regulator. */
225     spm_aux_io_regulator_volt_select_t ioRegulatorVolt; /*!< IO Regulator Voltage Select. */
226 } spm_aux_ldo_config_t;
227 
228 /*!
229  * @brief Configuration for setting DCDC integrator value.
230  */
231 typedef struct _spm_dcdc_integrator_value_config
232 {
233     double vddCoreValue; /*!< VDD_CORE output voltage value. */
234     double vBatValue;    /*!< Battery input voltage value, or the Vdd_dcdcin voltage value. */
235 } spm_dcdc_integrator_config_t;
236 
237 /*!
238  * @brief Defines the selection of DCDC vbat voltage divider for ADC measure.
239  */
240 typedef enum _spm_dcdc_vbat_adc_divider
241 {
242     kSPM_DcdcVbatAdcOff      = 0U, /*!< OFF. */
243     kSPM_DcdcVbatAdcDivider1 = 1U, /*!< VBAT. */
244     kSPM_DcdcVbatAdcDivider2 = 2U, /*!< VBAT /2. */
245     kSPM_DcdcVbatAdcDivider4 = 3U, /*!< VBAT /4. */
246 } spm_dcdc_vbat_adc_divider_t;
247 
248 /*!
249  * @brief Defines the selection of low power request pin out pin polarity.
250  */
251 typedef enum _spm_low_power_req_out_pin_pol
252 {
253     kSPM_LowPowerReqOutPinHighTruePol = 0U, /*!< High true polarity. */
254     kSPM_LowPowerReqOutPinLowTruePol  = 1U, /*!< Low true polarity. */
255 } spm_low_power_req_out_pin_pol_t;
256 
257 /*!
258  * @brief Configuration structure of low power request out pin.
259  */
260 typedef struct _spm_low_power_req_out_pin_config
261 {
262     spm_low_power_req_out_pin_pol_t pinOutPol; /*!< ow power request pin out pin polarity. */
263     bool pinOutEnable;                         /*!< Low Power request output pin is enabled or not. */
264 } spm_low_power_req_out_pin_config_t;
265 
266 /*!
267  * @brief Defines the selection of DCDC driver strength.
268  *
269  * The more FETs are enabled, the more drive strength DCDC would provide.
270  */
271 typedef enum _spm_dcdc_drive_strength
272 {
273     kSPM_DcdcDriveStrengthWithNormal                   = 0U,  /*!< No additional FET setting. */
274     kSPM_DcdcDriveStrengthWithHalfFETs                 = 0x4, /*!< Half FETs. */
275     kSPM_DcdcDriveStrengthWithDoubleFETs               = 0x2, /*!< Double FETs. */
276     kSPM_DcdcDriveStrengthWithExtraDoubleFETs          = 0x1, /*!< Extra Double FETs. */
277     kSPM_DcdcDriveStrengthWithHalfAndDoubleFETs        = 0x6, /*!< Half + Double FETs. */
278     kSPM_DcdcDriveStrengthWithHalfAndExtraDoubleFETs   = 0x5, /*!< Half + Extra Double FETs. */
279     kSPM_DcdcDriveStrengthWithDoubleAndExtraDoubleFETs = 0x3, /*!< Double + Extra Double FETs. */
280     kSPM_DcdcDriveStrengthWithAllFETs                  = 7U,  /*!< Half + Double + Extra Double FETs. */
281 } spm_dcdc_drive_strength_t;
282 
283 /*!
284  * @brief DCDC flags.
285  */
286 enum _spm_dcdc_flags
287 {
288     kSPM_DcdcStableOKFlag = (int)SPM_DCDCSC_DCDC_STS_DC_OK_MASK, /*!< Status flag to indicate DCDC lock. */
289     kSPM_DcdcClockFaultFlag =
290         SPM_DCDCSC_CLKFLT_FAULT_MASK, /*!< Asserts if DCDC detect a clk fault. Will cause a system lvd reset to assert.
291                                        */
292 };
293 
294 /*!
295  * @brief Loop control configuration.
296  */
297 typedef struct _spm_dcdc_loop_control_config
298 {
299     bool enableCommonHysteresis; /*!< Enable hysteresis in switching converter differential mode analog comparators.
300                                       This feature improves transient supply ripple and efficiency. */
301     bool enableDifferentialHysteresis; /*!< Enable hysteresis in switching converter common mode analog comparators.
302                                             This feature improves transient supply ripple and efficiency. */
303     bool invertHysteresisSign;         /*!< Invert the sign of the hysteresis in DC-DC analog comparators.
304                                             Should be enabled when in Pulsed mode. */
305 } spm_dcdc_loop_control_config_t;
306 
307 /*******************************************************************************
308  * API
309  ******************************************************************************/
310 
311 #if defined(__cplusplus)
312 extern "C" {
313 #endif /* __cplusplus*/
314 
315 /*! @name System Power Manager. */
316 /*@{*/
317 
318 /*!
319  * @brief Gets the SPM version ID.
320  *
321  * This function gets the SPM version ID, including major version number,
322  * minor version number, and a feature specification number.
323  *
324  * @param base SPM peripheral base address.
325  * @param versionId     Pointer to version ID structure.
326  */
SPM_GetVersionId(SPM_Type * base,spm_version_id_t * versionId)327 static inline void SPM_GetVersionId(SPM_Type *base, spm_version_id_t *versionId)
328 {
329     *((uint32_t *)(uint32_t)versionId) = base->VERID;
330 }
331 
332 /*!
333  * @brief Gets the regulators Status.
334  *
335  * @param base SPM peripheral base address.
336  * @param info Pointer to status structure, see to #spm_regulator_status_t.
337  */
338 void SPM_GetRegulatorStatus(SPM_Type *base, spm_regulator_status_t *info);
339 
340 /*!
341  * @brief Controls which regulators are enabled in RUN and HSRUN modes.
342  *
343  * This function controls which regulator (CORE LDO, AUX LDO, and DCDC) are enabled in RUN and HSRUN
344  * modes. It sets the SPM_RCTRL register.
345  * Note that the RCTRL bits are reset solely on a POR/LVD only event.
346  *
347  * @param base SPM peripheral base address.
348  * @param enable Enable or disable the LDOs list in ldoMask.
349  * @param ldoMask Mask value of LDO list. See to #_spm_ldo_regulator.
350  */
SPM_EnableRegulatorInRunMode(SPM_Type * base,bool enable,uint32_t ldoMask)351 static inline void SPM_EnableRegulatorInRunMode(SPM_Type *base, bool enable, uint32_t ldoMask)
352 {
353     if (true == enable)
354     {
355         base->RCTRL |= SPM_RCTRL_REGSEL(ldoMask);
356     }
357     else
358     {
359         base->RCTRL &= ~SPM_RCTRL_REGSEL(ldoMask);
360     }
361 }
362 
363 /*!
364  * @brief Controls which regulators are enabled in low power modes.
365  *
366  * This function controls which regulator (CORE LDO, AUX LDO, and DCDC) are enabled in low power
367  * modes. It sets the SPM_LPCTRL register.
368  * Note that the SPM_LPCTRL bits are reset solely on a POR/LVD only event.
369  *
370  * @param base SPM peripheral base address.
371  * @param enable Enable or disable the LDOs list in ldoMask.
372  * @param ldoMask Mask value of LDO list.
373  */
SPM_EnableRegulatorInLowPowerMode(SPM_Type * base,bool enable,uint32_t ldoMask)374 static inline void SPM_EnableRegulatorInLowPowerMode(SPM_Type *base, bool enable, uint32_t ldoMask)
375 {
376     if (true == enable)
377     {
378         base->LPCTRL |= SPM_LPCTRL_REGSEL(ldoMask);
379     }
380     else
381     {
382         base->LPCTRL &= ~SPM_LPCTRL_REGSEL(ldoMask);
383     }
384 }
385 
386 /*!
387  * @brief Configures the CORE LDO working in run modes.
388  *
389  * @param base SPM peripheral base address.
390  * @param configMask Mask value of configuration items. See to #_spm_core_ldo_run_mode_config.
391  */
SPM_SetCoreLdoRunModeConfig(SPM_Type * base,uint32_t configMask)392 static inline void SPM_SetCoreLdoRunModeConfig(SPM_Type *base, uint32_t configMask)
393 {
394     base->CORERCNFG = configMask;
395 }
396 
397 /*!
398  * @brief Configures the CORE LDO working in low power modes.
399  *
400  * @param base SPM peripheral base address.
401  * @param configMask Mask value of configuration items. See to #_spm_core_ldo_low_power_mode_config.
402  */
SPM_SetCoreLdoLowPowerModeConfig(SPM_Type * base,uint32_t configMask)403 static inline void SPM_SetCoreLdoLowPowerModeConfig(SPM_Type *base, uint32_t configMask)
404 {
405     base->CORELPCNFG = configMask;
406 }
407 
408 /*!
409  * @brief Check if the CORE LDO is in run regulation.
410  *
411  * @param base SPM peripheral base address.
412  * @retval true  Regulator is in run regulation.
413  * @retval false Regulator is in stop regulation or in transition to/from it.
414  */
SPM_GetCoreLdoInRunRegulationFlag(SPM_Type * base)415 static inline bool SPM_GetCoreLdoInRunRegulationFlag(SPM_Type *base)
416 {
417     return (SPM_CORESC_REGONS_MASK == (SPM_CORESC_REGONS_MASK & base->CORESC));
418 }
419 
420 /*!
421  * @brief Force the Core LDO to an offset voltage level.
422  *
423  * @note Please make sure Core LDO Aux LDO and DCDC regulator both have been enabled before invoking
424  *       this function.
425  *
426  * @param base SPM peripheral base address.
427  * @param enable Enable/Disable Core Ldo voltage offset.
428  *                  true    -   Apply Core LDO offset.
429  *                  false   -   Don't apply Core LDO offset.
430  */
SPM_ForceCoreLdoOffset(SPM_Type * base,bool enable)431 static inline void SPM_ForceCoreLdoOffset(SPM_Type *base, bool enable)
432 {
433     if (enable)
434     {
435         base->CORESC |= SPM_CORESC_VSEL_OFFSET_MASK;
436     }
437     else
438     {
439         base->CORESC &= ~SPM_CORESC_VSEL_OFFSET_MASK;
440     }
441 }
442 
443 /*!
444  * @brief Gets the acknowledge Peripherals and I/O pads isolation flag.
445  *
446  * This function  reads the Acknowledge Isolation setting that indicates
447  * whether certain peripherals and the I/O pads are in a latched state as
448  * a result of having been in the VLLS mode.
449  *
450  * @param base SPM peripheral base address.
451  * @return ACK isolation
452  *               0 - Peripherals and I/O pads are in a normal run state.
453  *               1 - Certain peripherals and I/O pads are in an isolated and
454  *                   latched state.
455  */
SPM_GetPeriphIOIsolationFlag(SPM_Type * base)456 static inline bool SPM_GetPeriphIOIsolationFlag(SPM_Type *base)
457 {
458     return (SPM_CORESC_ACKISO_MASK == (base->CORESC & SPM_CORESC_ACKISO_MASK));
459 }
460 
461 /*!
462  * @brief Acknowledges the isolation flag to Peripherals and I/O pads.
463  *
464  * This function  clears the ACK Isolation flag. Writing one to this setting
465  * when it is set releases the I/O pads and certain peripherals to their normal
466  * run mode state.
467  *
468  * @param base SPM peripheral base address.
469  */
SPM_ClearPeriphIOIsolationFlag(SPM_Type * base)470 static inline void SPM_ClearPeriphIOIsolationFlag(SPM_Type *base)
471 {
472     base->CORESC |= SPM_CORESC_ACKISO_MASK;
473 }
474 
475 /*@}*/
476 
477 /*! @name VDD Low voltage detection APIs*/
478 /*@{*/
479 
480 /*!
481  * @brief Configures the low-voltage detect setting.
482  *
483  * This function configures the low-voltage detect setting, including the trip
484  * point voltage setting, enables or disables the interrupt, enables or disables the system reset.
485  *
486  * @param base SPM peripheral base address.
487  * @param config Pointer to low-voltage detect configuration structure, see to #spm_low_volt_detect_config_t.
488  */
489 void SPM_SetLowVoltDetectConfig(SPM_Type *base, const spm_low_volt_detect_config_t *config);
490 
491 /*!
492  * @brief Gets VDD Low-voltage Detect Flag status.
493  *
494  * @param base SPM peripheral base address.
495  * @return Current low-voltage detect flag
496  *                - true: Low-voltage detected
497  *                - false: Low-voltage not detected
498  */
SPM_GetVddLowVoltDetectFlag(SPM_Type * base)499 static inline bool SPM_GetVddLowVoltDetectFlag(SPM_Type *base)
500 {
501     return (SPM_LVDSC1_VDD_LVDF_MASK == (base->LVDSC1 & SPM_LVDSC1_VDD_LVDF_MASK));
502 }
503 
504 /*!
505  * @brief Acknowledges clearing the Low-voltage Detect flag.
506  *
507  * This function acknowledges the low-voltage detection errors.
508  *
509  * @param base SPM peripheral base address.
510  */
SPM_ClearVddLowVoltDetectFlag(SPM_Type * base)511 static inline void SPM_ClearVddLowVoltDetectFlag(SPM_Type *base)
512 {
513     base->LVDSC1 |= SPM_LVDSC1_VDD_LVDACK_MASK; /* W1C. */
514 }
515 
516 /*@}*/
517 
518 /*! @name CORE LDO Low voltage detection APIs */
519 /*@{*/
520 
521 /*!
522  * @brief Gets the COREVdds Low-voltage Detect Flag status.
523  *
524  * This function  reads the current LVDF status. If it returns 1, a low-voltage event is detected.
525  *
526  * @param base SPM peripheral base address.
527  * @return Current low-voltage detect flag
528  *                - true: Low-voltage detected
529  *                - false: Low-voltage not detected
530  */
SPM_GetCoreLowVoltDetectFlag(SPM_Type * base)531 static inline bool SPM_GetCoreLowVoltDetectFlag(SPM_Type *base)
532 {
533     return (SPM_LVDSC1_COREVDD_LVDF_MASK == (base->LVDSC1 & SPM_LVDSC1_COREVDD_LVDF_MASK));
534 }
535 
536 /*!
537  * @brief Acknowledges clearing the CORE VDD Low-voltage Detect flag.
538  *
539  * This function acknowledges the CORE VDD low-voltage detection errors.
540  *
541  * @param base SPM peripheral base address.
542  */
SPM_ClearCoreLowVoltDetectFlag(SPM_Type * base)543 static inline void SPM_ClearCoreLowVoltDetectFlag(SPM_Type *base)
544 {
545     base->LVDSC1 |= SPM_LVDSC1_COREVDD_LVDACK_MASK; /* W1C. */
546 }
547 
548 /*!
549  * @brief Configures the low-voltage warning setting.
550  *
551  * This function configures the low-voltage warning setting, including the trip
552  * point voltage setting and enabling or disabling the interrupt.
553  *
554  * @param base SPM peripheral base address.
555  * @param config Pointer to Low-voltage warning configuration structure, see to #spm_low_volt_warning_config_t.
556  */
557 void SPM_SetLowVoltWarningConfig(SPM_Type *base, const spm_low_volt_warning_config_t *config);
558 
559 /*!
560  * @brief Gets Vdd Low-voltage Warning Flag status.
561  *
562  * This function polls the current LVWF status. When 1 is returned, it
563  * indicates a low-voltage warning event. LVWF is set when V Supply transitions
564  * below the trip point or after reset and V Supply is already below the V LVW.
565  *
566  * @param base SPM peripheral base address.
567  * @return Current LVWF status
568  *                  - true: Low-voltage Warning Flag is set.
569  *                  - false: the  Low-voltage Warning does not happen.
570  */
SPM_GetVddLowVoltWarningFlag(SPM_Type * base)571 static inline bool SPM_GetVddLowVoltWarningFlag(SPM_Type *base)
572 {
573     return (SPM_LVDSC2_VDD_LVWF_MASK == (base->LVDSC2 & SPM_LVDSC2_VDD_LVWF_MASK));
574 }
575 
576 /*!
577  * @brief Acknowledges the Low-voltage Warning flag.
578  *
579  * This function acknowledges the low voltage warning errors (write 1 to
580  * clear LVWF).
581  *
582  * @param base SPM peripheral base address.
583  */
SPM_ClearLowVoltWarningFlag(SPM_Type * base)584 static inline void SPM_ClearLowVoltWarningFlag(SPM_Type *base)
585 {
586     base->LVDSC2 |= SPM_LVDSC2_VDD_LVWACK_MASK; /* W1C. */
587 }
588 
589 /*@}*/
590 
591 /*! @name VDD high voltage detection APIs. */
592 /*@{*/
593 
594 /*!
595  * @brief Configures the high-voltage detect setting.
596  *
597  * This function configures the high-voltage detect setting, including the trip
598  * point voltage setting, enabling or disabling the interrupt, enabling or disabling the system reset.
599  *
600  * @param base SPM peripheral base address.
601  * @param config  High-voltage detect configuration structure, see to #spm_high_volt_detect_config_t.
602  */
603 void SPM_SetHighVoltDetectConfig(SPM_Type *base, const spm_high_volt_detect_config_t *config);
604 
605 /*!
606  * @brief Gets the High-voltage Detect Flag status.
607  *
608  * This function  reads the current HVDF status. If it returns 1, a low
609  * voltage event is detected.
610  *
611  * @param base SPM peripheral base address.
612  * @return Current high-voltage detect flag
613  *                - true: High-voltage detected
614  *                - false: High-voltage not detected
615  */
SPM_GetHighVoltDetectFlag(SPM_Type * base)616 static inline bool SPM_GetHighVoltDetectFlag(SPM_Type *base)
617 {
618     return (SPM_HVDSC1_VDD_HVDF_MASK == (base->HVDSC1 & SPM_HVDSC1_VDD_HVDF_MASK));
619 }
620 
621 /*!
622  * @brief Acknowledges clearing the High-voltage Detect flag.
623  *
624  * This function acknowledges the high-voltage detection errors (write 1 to
625  * clear HVDF).
626  *
627  * @param base SPM peripheral base address.
628  */
SPM_ClearHighVoltDetectFlag(SPM_Type * base)629 static inline void SPM_ClearHighVoltDetectFlag(SPM_Type *base)
630 {
631     base->HVDSC1 |= SPM_HVDSC1_VDD_HVDACK_MASK; /* W1C. */
632 }
633 
634 /*@}*/
635 
636 /*! @name AUX LDO Low voltage detection APIs */
637 /*@{*/
638 
639 /*!
640  * @brief Configures the AUX LDO.
641  *
642  * @param base SPM peripheral base address.
643  * @param config Pointer to configuration structure, see to spm_rf_ldo_config_t.
644  */
645 void SPM_SetAuxLdoConfig(SPM_Type *base, const spm_aux_ldo_config_t *config);
646 
647 /*!
648  * @brief Force auxiliary regulator voltage to an offset level.
649  *
650  * @note Please make sure DCDC has been enabled before involing this function.
651  *
652  * @param base SPM peripheral base address.
653  * @param enable Enable/Disable AUX Ldo voltage offset.
654  *                  true    -   Force auxiliary regulator voltage to an offset level.
655  *                  false   -   Do not force auxiliary regulator voltage to an offset level.
656  */
SPM_ForceAuxLdoOffset(SPM_Type * base,bool enable)657 static inline void SPM_ForceAuxLdoOffset(SPM_Type *base, bool enable)
658 {
659     if (enable)
660     {
661         base->AUXLDOSC |= SPM_AUXLDOSC_AUXREGVSEL_OFFSET_MASK;
662     }
663     else
664     {
665         base->AUXLDOSC &= ~SPM_AUXLDOSC_AUXREGVSEL_OFFSET_MASK;
666     }
667 }
668 
669 /*! @name DCDC Control APIs*/
670 /*@{*/
671 
672 /*!
673  * @brief Sets DCDC battery monitor with its ADC value.
674  *
675  * For better accuracy, software would call this function to set the battery voltage value into DCDC
676  * measured by ADC.
677  *
678  * @param base SPM peripheral base address.
679  * @param batAdcVal ADC measured battery value with an 8mV LSB resolution.
680  *              Value 0 would disable the battery monitor.
681  */
682 void SPM_SetDcdcBattMonitor(SPM_Type *base, uint32_t batAdcVal);
683 
684 /*!
685  * @brief Sets DCDC VBAT voltage divider.
686  *
687  * The divided VBAT output is input to an ADC channel which allows the battery voltage to be measured.
688  *
689  * @param base SPM peripheral base address.
690  * @param divider Setting divider, see to #spm_dcdc_vbat_adc_divider_t.
691  */
SPM_SetDcdcVbatAdcMeasure(SPM_Type * base,spm_dcdc_vbat_adc_divider_t divider)692 static inline void SPM_SetDcdcVbatAdcMeasure(SPM_Type *base, spm_dcdc_vbat_adc_divider_t divider)
693 {
694     base->DCDCSC = (base->DCDCSC & ~SPM_DCDCSC_DCDC_VBAT_DIV_CTRL_MASK) | SPM_DCDCSC_DCDC_VBAT_DIV_CTRL(divider);
695 }
696 
697 /*!
698  * @brief Power down output range comparator.
699  *
700  * @param base SPM peripheral base address.
701  * @param enable Power down the CMP or not.
702  */
SPM_EnablePowerDownCmpOffset(SPM_Type * base,bool enable)703 static inline void SPM_EnablePowerDownCmpOffset(SPM_Type *base, bool enable)
704 {
705     if (true == enable)
706     {
707         base->DCDCSC |= SPM_DCDCSC_PWD_CMP_OFFSET_MASK;
708     }
709     else
710     {
711         base->DCDCSC &= ~SPM_DCDCSC_PWD_CMP_OFFSET_MASK;
712     }
713 }
714 
715 /*!
716  * @brief Get the status flags of DCDC module.
717  *
718  * @param base SPM peripheral base address.
719  * @return Mask value of flags. See to #_spm_dcdc_flags.
720  */
SPM_GetDcdcStatusFlags(SPM_Type * base)721 static inline uint32_t SPM_GetDcdcStatusFlags(SPM_Type *base)
722 {
723     return (base->DCDCSC & (SPM_DCDCSC_DCDC_STS_DC_OK_MASK | SPM_DCDCSC_CLKFLT_FAULT_MASK));
724 }
725 
726 /*!
727  * @brief Set DCDC loop control config.
728  *
729  * @param base SPM peripheral base address.
730  * @param config The Pointer to the structure @ref spm_dcdc_loop_control_config_t.
731  */
732 void SPM_SetDcdcLoopControlConfig(SPM_Type *base, const spm_dcdc_loop_control_config_t *config);
733 
734 /*!
735  * @brief Disable stepping for VDD1P8 and VDD1P2.
736  *
737  * Must lock the step for VDD1P8 and VDD1P2 before enteing low power modes.
738  *
739  * @param base SPM peripheral base address.
740  * @param enable Enable the lock or not to VDDx stepping.
741  */
SPM_EnableVddxStepLock(SPM_Type * base,bool enable)742 static inline void SPM_EnableVddxStepLock(SPM_Type *base, bool enable)
743 {
744     if (true == enable)
745     {
746         base->DCDCC3 |= (SPM_DCDCC3_DCDC_VDD1P8CTRL_DISABLE_STEP_MASK | SPM_DCDCC3_DCDC_VDD1P2CTRL_DISABLE_STEP_MASK);
747     }
748     else
749     {
750         base->DCDCC3 &= ~(SPM_DCDCC3_DCDC_VDD1P8CTRL_DISABLE_STEP_MASK | SPM_DCDCC3_DCDC_VDD1P2CTRL_DISABLE_STEP_MASK);
751     }
752 }
753 
754 /*!
755  * @brief Set the DCDC drive strength.
756  *
757  * Do set the DCDC drive strength according to actuall loading.
758  * The related register bits are:
759  * - DCDCC3[DCDC_MINPWR_HALF_FETS]
760  * - DCDCC3[DCDC_MINPWR_DOUBLE_FETS]
761  * - DCDCC3[DCDC_MINPWR_EXTRA_DOUBLE_FETS]
762  * The more FETs are enabled, the more drive strength DCDC would provide.
763  *
764  * @param base SPM peripheral base address.
765  * @param strength Selection of setting, see to #spm_dcdc_drive_strength_t
766  */
SPM_SetDcdcDriveStrength(SPM_Type * base,spm_dcdc_drive_strength_t strength)767 static inline void SPM_SetDcdcDriveStrength(SPM_Type *base, spm_dcdc_drive_strength_t strength)
768 {
769     base->DCDCC3 = (base->DCDCC3 & ~0xE000000U) | ((uint32_t)(strength) << 25);
770 }
771 
772 /*!
773  * @brief Split the frequency of DCDC's clock to min the power of DCDC.
774  *
775  * @note The function can only be invoked in continous mode.
776  *
777  * @param base SPM peripheral base address.
778  * @param enable Split the DCDC clock frequency.
779  *                  true    -   Set DCDC clock to half frequency for the continous mode.
780  *                  false   -   Do not set DCDC clock to half frequency for the continous mode.
781  */
SPM_SplitDcdcClockFreq(SPM_Type * base,bool enable)782 static inline void SPM_SplitDcdcClockFreq(SPM_Type *base, bool enable)
783 {
784     if (enable)
785     {
786         base->DCDCC3 |= SPM_DCDCC3_DCDC_MINPWR_DC_HALFCLK_MASK;
787     }
788     else
789     {
790         base->DCDCC3 &= ~SPM_DCDCC3_DCDC_MINPWR_DC_HALFCLK_MASK;
791     }
792 }
793 
794 /*!
795  * @brief Bypasses the ADC measure value
796  *
797  * Forces DCDC to bypass the adc measuring state and loads the user-defined value in this function.
798  *
799  * @param base SPM peripheral base address.
800  * @param enable Enable the bypass or not.
801  * @param value User-setting value to be available instead of ADC measured value.
802  */
803 void SPM_BypassDcdcBattMonitor(SPM_Type *base, bool enable, uint32_t value);
804 
805 /*!
806  * @brief Configure the DCDC integrator value.
807  *
808  * Integrator value can be loaded in pulsed mode. Software can program this value according to
809  * battery voltage and VDDCORE output target value before goes to the pulsed mode.
810  *
811  * @code
812     spm_dcdc_integrator_config_t SpmDcdcIntegratorConfigStruct =
813     {
814         .vddCoreValue = 1.25f,
815         .vBatValue    = 3.34f
816     };
817  * @endcode
818  *
819  * @param base SPM peripheral base address.
820  * @param config Pointer to configuration structure, see to #spm_dcdc_integrator_config_t.
821  *               Passing NULL would clear all user-defined setting and use hardware default setting.
822  */
823 void SPM_SetDcdcIntegratorConfig(SPM_Type *base, const spm_dcdc_integrator_config_t *config);
824 
825 /*!
826  * @brief Bypass the ADC measure or not.
827  *
828  * @note If forced to bypass the ADC measure, please invoke SPM_SetDcdcIntegratorConfig()
829  *       function to select the integrator value.
830  *
831  * @param base SPM peripheral base address.
832  * @param bypass Bypass or not bypass the ADC measure
833  *          true    -   Force DCDC to bypass the ADC measuring state.
834  *          false   -   Don't force DCDC to bypass the ADC measuring state.
835  */
SPC_BypassDcdcAdcMeasure(SPM_Type * base,bool bypass)836 static inline void SPC_BypassDcdcAdcMeasure(SPM_Type *base, bool bypass)
837 {
838     if (bypass)
839     {
840         base->DCDCC3 |= SPM_DCDCC3_DCDC_BYPASS_ADC_MEAS_MASK;
841     }
842     else
843     {
844         base->DCDCC3 &= ~SPM_DCDCC3_DCDC_BYPASS_ADC_MEAS_MASK;
845     }
846 }
847 
848 /*!
849  * @brief Sets the target value of VDD1P2 in buck HSRUN mode.
850  *
851  * Sets target value of VDD1P2 in buck HSRUN mode. 25 mV each step from 0x00 to 0x0F. This value is
852  * automatically selected on entry into HSRUN. On exit from HSRUN, DCDC VDD1P2 trim values will
853  * default back to values set by DCDC_VDD1P2CTRL_TRG_BUCK register, which is operated with the API of
854  * SPM_SetDcdcVdd1p2ValueBuck().
855  *
856  * @param base SPM peripheral base address.
857  * @param trimCode Setting value of VDD1P2 in buck HSRUN mode. Please refer to the reference mannual for details.
858  */
SPM_SetDcdcVdd1p2ValueHsrun(SPM_Type * base,uint32_t trimCode)859 static inline void SPM_SetDcdcVdd1p2ValueHsrun(SPM_Type *base, uint32_t trimCode)
860 {
861     base->DCDCC6 = (base->DCDCC6 & ~SPM_DCDCC6_DCDC_HSVDD_TRIM_MASK) | SPM_DCDCC6_DCDC_HSVDD_TRIM(trimCode);
862 }
863 
864 /*!
865  * @brief Sets the target value of VDD1P2 in buck mode.
866  *
867  * Sets the target value of VDD1P2 in buck mode, 25 mV each step from 0x00 to 0x0F.
868  *
869  * @param base SPM peripheral base address.
870  * @param trimCode Setting value of VDD1P2 in buck mode. Please refer to the reference mannual for details.
871  */
SPM_SetDcdcVdd1p2ValueBuck(SPM_Type * base,uint32_t trimCode)872 static inline void SPM_SetDcdcVdd1p2ValueBuck(SPM_Type *base, uint32_t trimCode)
873 {
874     base->DCDCC6 =
875         (base->DCDCC6 & ~SPM_DCDCC6_DCDC_VDD1P2CTRL_TRG_BUCK_MASK) | SPM_DCDCC6_DCDC_VDD1P2CTRL_TRG_BUCK(trimCode);
876 }
877 
878 /*!
879  * @brief Sets the target value of VDD1P8.
880  *
881  * Sets the target value of VDD1P8 in buck mode, 25 mV each step from 0x00 to 0x3F.
882  *
883  * @param base SPM peripheral base address.
884  * @param trimCode Setting the trimCode of VDD1P8 output. Please refer to the reference mannual for details.
885  */
SPM_SetDcdcVdd1p8Value(SPM_Type * base,uint32_t trimCode)886 static inline void SPM_SetDcdcVdd1p8Value(SPM_Type *base, uint32_t trimCode)
887 {
888     base->DCDCC6 = (base->DCDCC6 & ~SPM_DCDCC6_DCDC_VDD1P8CTRL_TRG_MASK) | SPM_DCDCC6_DCDC_VDD1P8CTRL_TRG(trimCode);
889 }
890 
891 /*@}*/
892 
893 /*! @name Misc */
894 /*@{*/
895 
896 /*!
897  * brief Configures the low power requeset output pin.
898  *
899  * param base SPM peripheral base address.
900  * param config Pointer to the configuration structure, see to #spm_low_power_req_out_pin_config_t.
901  */
SPM_SetLowPowerReqOutPinConfig(SPM_Type * base,const spm_low_power_req_out_pin_config_t * config)902 static inline void SPM_SetLowPowerReqOutPinConfig(SPM_Type *base, const spm_low_power_req_out_pin_config_t *config)
903 {
904     assert(NULL != config);
905 
906     if (true == config->pinOutEnable)
907     {
908         base->LPREQPINCNTRL =
909             SPM_LPREQPINCNTRL_POLARITY(config->pinOutPol) | SPM_LPREQPINCNTRL_LPREQOE_MASK; /* Enable the output. */
910     }
911     else
912     {
913         base->LPREQPINCNTRL = 0U;
914     }
915 }
916 
917 /*@}*/
918 
919 /*@}*/
920 
921 #if defined(__cplusplus)
922 }
923 #endif /* __cplusplus*/
924 
925 /*! @}*/
926 
927 #endif /* _FSL_SPM_H_*/
928