1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright (c) 2016, NXP
4 * All rights reserved.
5 *
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 */
9
10 #include "fsl_spm.h"
11 #include "math.h" /* Using floor() function to convert float variable to int. */
12
SPM_GetRegulatorStatus(SPM_Type * base,spm_regulator_status_t * info)13 void SPM_GetRegulatorStatus(SPM_Type *base, spm_regulator_status_t *info)
14 {
15 assert(info);
16
17 volatile uint32_t tmp32 = base->RSR; /* volatile here is to make sure this value is actually from the hardware. */
18
19 info->isRadioRunForcePowerModeOn = (SPM_RSR_RFRUNFORCE_MASK == (tmp32 & SPM_RSR_RFRUNFORCE_MASK));
20 info->radioLowPowerModeStatus =
21 (spm_radio_low_power_mode_status_t)((tmp32 & SPM_RSR_RFPMSTAT_MASK) >> SPM_RSR_RFPMSTAT_SHIFT);
22 info->mcuLowPowerModeStatus =
23 (spm_mcu_low_power_mode_status_t)((tmp32 & SPM_RSR_MCUPMSTAT_MASK) >> SPM_RSR_MCUPMSTAT_SHIFT);
24 info->isDcdcLdoOn =
25 (0x4 == (0x4 & ((tmp32 & SPM_RSR_REGSEL_MASK) >> SPM_RSR_REGSEL_SHIFT))); /* 1<<2 responses DCDC LDO. */
26 info->isRfLdoOn =
27 (0x2 == (0x2 & ((tmp32 & SPM_RSR_REGSEL_MASK) >> SPM_RSR_REGSEL_SHIFT))); /* 1<<1 responses RF LDO. */
28 info->isCoreLdoOn =
29 (0x1 == (0x1 & ((tmp32 & SPM_RSR_REGSEL_MASK) >> SPM_RSR_REGSEL_SHIFT))); /* 1<<0 responses CORE LDO. */
30 }
31
SPM_SetLowVoltDetectConfig(SPM_Type * base,const spm_low_volt_detect_config_t * config)32 void SPM_SetLowVoltDetectConfig(SPM_Type *base, const spm_low_volt_detect_config_t *config)
33 {
34 uint32_t tmp32 = base->LVDSC1 &
35 ~(SPM_LVDSC1_VDD_LVDIE_MASK | SPM_LVDSC1_VDD_LVDRE_MASK | SPM_LVDSC1_VDD_LVDV_MASK |
36 SPM_LVDSC1_COREVDD_LVDIE_MASK | SPM_LVDSC1_COREVDD_LVDRE_MASK);
37
38 /* VDD voltage detection. */
39 tmp32 |= SPM_LVDSC1_VDD_LVDV(config->vddLowVoltDetectSelect);
40 if (config->enableIntOnVddLowVolt)
41 {
42 tmp32 |= SPM_LVDSC1_VDD_LVDIE_MASK;
43 }
44 if (config->enableResetOnVddLowVolt)
45 {
46 tmp32 |= SPM_LVDSC1_VDD_LVDRE_MASK;
47 }
48 /* Clear the Low Voltage Detect Flag with previouse power detect setting. */
49 tmp32 |= SPM_LVDSC1_VDD_LVDACK_MASK;
50
51 /* COREVDD voltage detection. */
52 if (config->enableIntOnCoreLowVolt)
53 {
54 tmp32 |= SPM_LVDSC1_COREVDD_LVDIE_MASK;
55 }
56 if (config->enableResetOnCoreLowVolt)
57 {
58 tmp32 |= SPM_LVDSC1_COREVDD_LVDRE_MASK;
59 }
60 tmp32 |= SPM_LVDSC1_COREVDD_LVDACK_MASK; /* Clear previous error flag. */
61
62 base->LVDSC1 = tmp32;
63 }
64
SPM_SetLowVoltWarningConfig(SPM_Type * base,const spm_low_volt_warning_config_t * config)65 void SPM_SetLowVoltWarningConfig(SPM_Type *base, const spm_low_volt_warning_config_t *config)
66 {
67 uint32_t tmp32 = base->LVDSC2 & ~(SPM_LVDSC2_VDD_LVWV_MASK | SPM_LVDSC2_VDD_LVWIE_MASK);
68
69 tmp32 |= SPM_LVDSC2_VDD_LVWV(config->vddLowVoltDetectSelect);
70 if (config->enableIntOnVddLowVolt)
71 {
72 tmp32 |= SPM_LVDSC2_VDD_LVWIE_MASK;
73 }
74 tmp32 |= SPM_LVDSC2_VDD_LVWACK_MASK; /* Clear previous error flag. */
75
76 base->LVDSC2 = tmp32;
77 }
78
SPM_SetHighVoltDetectConfig(SPM_Type * base,const spm_high_volt_detect_config_t * config)79 void SPM_SetHighVoltDetectConfig(SPM_Type *base, const spm_high_volt_detect_config_t *config)
80 {
81 uint32_t tmp32;
82
83 tmp32 = base->HVDSC1 & ~(SPM_HVDSC1_VDD_HVDIE_MASK | SPM_HVDSC1_VDD_HVDRE_MASK |\
84 SPM_HVDSC1_VDD_HVDV_MASK);
85 tmp32 |= SPM_HVDSC1_VDD_HVDV(config->vddHighVoltDetectSelect);
86 if(config->enableIntOnVddHighVolt)
87 {
88 tmp32 |= SPM_HVDSC1_VDD_HVDIE_MASK;
89 }
90 if(config->enableResetOnVddHighVolt)
91 {
92 tmp32 |= SPM_HVDSC1_VDD_HVDRE_MASK;
93 }
94 tmp32 |= SPM_HVDSC1_VDD_HVDACK_MASK; /* Clear previous error flag. */
95
96 base->HVDSC1 = tmp32;
97 }
98
SPM_SetRfLdoConfig(SPM_Type * base,const spm_rf_ldo_config_t * config)99 void SPM_SetRfLdoConfig(SPM_Type *base, const spm_rf_ldo_config_t *config)
100 {
101 uint32_t tmp32 = 0U;
102
103 switch (config->lowPowerMode)
104 {
105 case kSPM_RfLdoRemainInHighPowerInLowPowerModes:
106 tmp32 |= SPM_RFLDOLPCNFG_LPSEL_MASK;
107 break;
108 default: /* kSPM_RfLdoEnterLowPowerInLowPowerModes. */
109 break;
110 }
111 base->RFLDOLPCNFG = tmp32;
112
113 tmp32 = SPM_RFLDOSC_IOSSSEL(config->softStartDuration) | SPM_RFLDOSC_IOREGVSEL(config->rfIoRegulatorVolt);
114 if (config->enableCurSink)
115 {
116 tmp32 |= SPM_RFLDOSC_ISINKEN_MASK;
117 }
118 base->RFLDOSC = tmp32;
119 }
120
SPM_SetDcdcBattMonitor(SPM_Type * base,uint32_t batAdcVal)121 void SPM_SetDcdcBattMonitor(SPM_Type *base, uint32_t batAdcVal)
122 {
123 /* Clear the value and disable it at first. */
124 base->DCDCC2 &= ~(SPM_DCDCC2_DCDC_BATTMONITOR_BATT_VAL_MASK | SPM_DCDCC2_DCDC_BATTMONITOR_EN_BATADJ_MASK);
125 if (0U != batAdcVal)
126 {
127 /* When setting the value to BATT_VAL field, it should be zero before. */
128 base->DCDCC2 |= SPM_DCDCC2_DCDC_BATTMONITOR_BATT_VAL(batAdcVal);
129 base->DCDCC2 |= SPM_DCDCC2_DCDC_BATTMONITOR_EN_BATADJ_MASK;
130 }
131 }
132
SPM_EnableVddxStepLock(SPM_Type * base,bool enable)133 void SPM_EnableVddxStepLock(SPM_Type *base, bool enable)
134 {
135 if (enable)
136 {
137 base->DCDCC3 |= (SPM_DCDCC3_DCDC_VDD1P8CTRL_DISABLE_STEP_MASK | SPM_DCDCC3_DCDC_VDD1P2CTRL_DISABLE_STEP_MASK);
138 }
139 else
140 {
141 base->DCDCC3 &= ~(SPM_DCDCC3_DCDC_VDD1P8CTRL_DISABLE_STEP_MASK | SPM_DCDCC3_DCDC_VDD1P2CTRL_DISABLE_STEP_MASK);
142 }
143 }
144
SPM_BypassDcdcBattMonitor(SPM_Type * base,bool enable,uint32_t value)145 void SPM_BypassDcdcBattMonitor(SPM_Type *base, bool enable, uint32_t value)
146 {
147 if (enable)
148 {
149 /* Set the user-defined value before enable the bypass. */
150 base->DCDCC3 = (base->DCDCC3 & ~SPM_DCDCC3_DCDC_VBAT_VALUE_MASK) | SPM_DCDCC3_DCDC_VBAT_VALUE(value);
151 /* Enable the bypass and load the user-defined value. */
152 base->DCDCC3 |= SPM_DCDCC3_DCDC_BYPASS_ADC_MEAS_MASK;
153 }
154 else
155 {
156 base->DCDCC3 &= ~SPM_DCDCC3_DCDC_BYPASS_ADC_MEAS_MASK;
157 }
158 }
159
SPM_SetDcdcIntegratorConfig(SPM_Type * base,const spm_dcdc_integrator_config_t * config)160 void SPM_SetDcdcIntegratorConfig(SPM_Type *base, const spm_dcdc_integrator_config_t *config)
161 {
162 int32_t tmp32u;
163 double dutyCycle;
164
165 if (NULL == config)
166 {
167 base->DCDCC4 = 0U;
168 }
169 else
170 {
171 dutyCycle = ((config->vdd1p2Value / config->vBatValue)*32 - 16)*8192;
172 tmp32u = (int32_t)(dutyCycle);
173 base->DCDCC4 = SPM_DCDCC4_PULSE_RUN_SPEEDUP_MASK | SPM_DCDCC4_INTEGRATOR_VALUE_SELECT_MASK |
174 SPM_DCDCC4_INTEGRATOR_VALUE(tmp32u);
175 }
176 }
177
178
179
SPM_SetLowPowerReqOutPinConfig(SPM_Type * base,const spm_low_power_req_out_pin_config_t * config)180 void SPM_SetLowPowerReqOutPinConfig(SPM_Type *base, const spm_low_power_req_out_pin_config_t *config)
181 {
182 if ((NULL == config) || (config->pinOutEnable))
183 {
184 base->LPREQPINCNTRL = 0U;
185 }
186 else
187 {
188 base->LPREQPINCNTRL =
189 SPM_LPREQPINCNTRL_POLARITY(config->pinOutPol) | SPM_LPREQPINCNTRL_LPREQOE_MASK; /* Enable the output. */
190 }
191 }
192