| /* |
| * Copyright (c) 2015, Freescale Semiconductor, Inc. |
| * Copyright (c) 2016, NXP |
| * All rights reserved. |
| * |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| */ |
| |
| #include "fsl_spm.h" |
| #include "math.h" /* Using floor() function to convert float variable to int. */ |
| |
| void SPM_GetRegulatorStatus(SPM_Type *base, spm_regulator_status_t *info) |
| { |
| assert(info); |
| |
| volatile uint32_t tmp32 = base->RSR; /* volatile here is to make sure this value is actually from the hardware. */ |
| |
| info->isRadioRunForcePowerModeOn = (SPM_RSR_RFRUNFORCE_MASK == (tmp32 & SPM_RSR_RFRUNFORCE_MASK)); |
| info->radioLowPowerModeStatus = |
| (spm_radio_low_power_mode_status_t)((tmp32 & SPM_RSR_RFPMSTAT_MASK) >> SPM_RSR_RFPMSTAT_SHIFT); |
| info->mcuLowPowerModeStatus = |
| (spm_mcu_low_power_mode_status_t)((tmp32 & SPM_RSR_MCUPMSTAT_MASK) >> SPM_RSR_MCUPMSTAT_SHIFT); |
| info->isDcdcLdoOn = |
| (0x4 == (0x4 & ((tmp32 & SPM_RSR_REGSEL_MASK) >> SPM_RSR_REGSEL_SHIFT))); /* 1<<2 responses DCDC LDO. */ |
| info->isRfLdoOn = |
| (0x2 == (0x2 & ((tmp32 & SPM_RSR_REGSEL_MASK) >> SPM_RSR_REGSEL_SHIFT))); /* 1<<1 responses RF LDO. */ |
| info->isCoreLdoOn = |
| (0x1 == (0x1 & ((tmp32 & SPM_RSR_REGSEL_MASK) >> SPM_RSR_REGSEL_SHIFT))); /* 1<<0 responses CORE LDO. */ |
| } |
| |
| void SPM_SetLowVoltDetectConfig(SPM_Type *base, const spm_low_volt_detect_config_t *config) |
| { |
| uint32_t tmp32 = base->LVDSC1 & |
| ~(SPM_LVDSC1_VDD_LVDIE_MASK | SPM_LVDSC1_VDD_LVDRE_MASK | SPM_LVDSC1_VDD_LVDV_MASK | |
| SPM_LVDSC1_COREVDD_LVDIE_MASK | SPM_LVDSC1_COREVDD_LVDRE_MASK); |
| |
| /* VDD voltage detection. */ |
| tmp32 |= SPM_LVDSC1_VDD_LVDV(config->vddLowVoltDetectSelect); |
| if (config->enableIntOnVddLowVolt) |
| { |
| tmp32 |= SPM_LVDSC1_VDD_LVDIE_MASK; |
| } |
| if (config->enableResetOnVddLowVolt) |
| { |
| tmp32 |= SPM_LVDSC1_VDD_LVDRE_MASK; |
| } |
| /* Clear the Low Voltage Detect Flag with previouse power detect setting. */ |
| tmp32 |= SPM_LVDSC1_VDD_LVDACK_MASK; |
| |
| /* COREVDD voltage detection. */ |
| if (config->enableIntOnCoreLowVolt) |
| { |
| tmp32 |= SPM_LVDSC1_COREVDD_LVDIE_MASK; |
| } |
| if (config->enableResetOnCoreLowVolt) |
| { |
| tmp32 |= SPM_LVDSC1_COREVDD_LVDRE_MASK; |
| } |
| tmp32 |= SPM_LVDSC1_COREVDD_LVDACK_MASK; /* Clear previous error flag. */ |
| |
| base->LVDSC1 = tmp32; |
| } |
| |
| void SPM_SetLowVoltWarningConfig(SPM_Type *base, const spm_low_volt_warning_config_t *config) |
| { |
| uint32_t tmp32 = base->LVDSC2 & ~(SPM_LVDSC2_VDD_LVWV_MASK | SPM_LVDSC2_VDD_LVWIE_MASK); |
| |
| tmp32 |= SPM_LVDSC2_VDD_LVWV(config->vddLowVoltDetectSelect); |
| if (config->enableIntOnVddLowVolt) |
| { |
| tmp32 |= SPM_LVDSC2_VDD_LVWIE_MASK; |
| } |
| tmp32 |= SPM_LVDSC2_VDD_LVWACK_MASK; /* Clear previous error flag. */ |
| |
| base->LVDSC2 = tmp32; |
| } |
| |
| void SPM_SetHighVoltDetectConfig(SPM_Type *base, const spm_high_volt_detect_config_t *config) |
| { |
| uint32_t tmp32; |
| |
| tmp32 = base->HVDSC1 & ~(SPM_HVDSC1_VDD_HVDIE_MASK | SPM_HVDSC1_VDD_HVDRE_MASK |\ |
| SPM_HVDSC1_VDD_HVDV_MASK); |
| tmp32 |= SPM_HVDSC1_VDD_HVDV(config->vddHighVoltDetectSelect); |
| if(config->enableIntOnVddHighVolt) |
| { |
| tmp32 |= SPM_HVDSC1_VDD_HVDIE_MASK; |
| } |
| if(config->enableResetOnVddHighVolt) |
| { |
| tmp32 |= SPM_HVDSC1_VDD_HVDRE_MASK; |
| } |
| tmp32 |= SPM_HVDSC1_VDD_HVDACK_MASK; /* Clear previous error flag. */ |
| |
| base->HVDSC1 = tmp32; |
| } |
| |
| void SPM_SetRfLdoConfig(SPM_Type *base, const spm_rf_ldo_config_t *config) |
| { |
| uint32_t tmp32 = 0U; |
| |
| switch (config->lowPowerMode) |
| { |
| case kSPM_RfLdoRemainInHighPowerInLowPowerModes: |
| tmp32 |= SPM_RFLDOLPCNFG_LPSEL_MASK; |
| break; |
| default: /* kSPM_RfLdoEnterLowPowerInLowPowerModes. */ |
| break; |
| } |
| base->RFLDOLPCNFG = tmp32; |
| |
| tmp32 = SPM_RFLDOSC_IOSSSEL(config->softStartDuration) | SPM_RFLDOSC_IOREGVSEL(config->rfIoRegulatorVolt); |
| if (config->enableCurSink) |
| { |
| tmp32 |= SPM_RFLDOSC_ISINKEN_MASK; |
| } |
| base->RFLDOSC = tmp32; |
| } |
| |
| void SPM_SetDcdcBattMonitor(SPM_Type *base, uint32_t batAdcVal) |
| { |
| /* Clear the value and disable it at first. */ |
| base->DCDCC2 &= ~(SPM_DCDCC2_DCDC_BATTMONITOR_BATT_VAL_MASK | SPM_DCDCC2_DCDC_BATTMONITOR_EN_BATADJ_MASK); |
| if (0U != batAdcVal) |
| { |
| /* When setting the value to BATT_VAL field, it should be zero before. */ |
| base->DCDCC2 |= SPM_DCDCC2_DCDC_BATTMONITOR_BATT_VAL(batAdcVal); |
| base->DCDCC2 |= SPM_DCDCC2_DCDC_BATTMONITOR_EN_BATADJ_MASK; |
| } |
| } |
| |
| void SPM_EnableVddxStepLock(SPM_Type *base, bool enable) |
| { |
| if (enable) |
| { |
| base->DCDCC3 |= (SPM_DCDCC3_DCDC_VDD1P8CTRL_DISABLE_STEP_MASK | SPM_DCDCC3_DCDC_VDD1P2CTRL_DISABLE_STEP_MASK); |
| } |
| else |
| { |
| base->DCDCC3 &= ~(SPM_DCDCC3_DCDC_VDD1P8CTRL_DISABLE_STEP_MASK | SPM_DCDCC3_DCDC_VDD1P2CTRL_DISABLE_STEP_MASK); |
| } |
| } |
| |
| void SPM_BypassDcdcBattMonitor(SPM_Type *base, bool enable, uint32_t value) |
| { |
| if (enable) |
| { |
| /* Set the user-defined value before enable the bypass. */ |
| base->DCDCC3 = (base->DCDCC3 & ~SPM_DCDCC3_DCDC_VBAT_VALUE_MASK) | SPM_DCDCC3_DCDC_VBAT_VALUE(value); |
| /* Enable the bypass and load the user-defined value. */ |
| base->DCDCC3 |= SPM_DCDCC3_DCDC_BYPASS_ADC_MEAS_MASK; |
| } |
| else |
| { |
| base->DCDCC3 &= ~SPM_DCDCC3_DCDC_BYPASS_ADC_MEAS_MASK; |
| } |
| } |
| |
| void SPM_SetDcdcIntegratorConfig(SPM_Type *base, const spm_dcdc_integrator_config_t *config) |
| { |
| int32_t tmp32u; |
| double dutyCycle; |
| |
| if (NULL == config) |
| { |
| base->DCDCC4 = 0U; |
| } |
| else |
| { |
| dutyCycle = ((config->vdd1p2Value / config->vBatValue)*32 - 16)*8192; |
| tmp32u = (int32_t)(dutyCycle); |
| base->DCDCC4 = SPM_DCDCC4_PULSE_RUN_SPEEDUP_MASK | SPM_DCDCC4_INTEGRATOR_VALUE_SELECT_MASK | |
| SPM_DCDCC4_INTEGRATOR_VALUE(tmp32u); |
| } |
| } |
| |
| |
| |
| void SPM_SetLowPowerReqOutPinConfig(SPM_Type *base, const spm_low_power_req_out_pin_config_t *config) |
| { |
| if ((NULL == config) || (config->pinOutEnable)) |
| { |
| base->LPREQPINCNTRL = 0U; |
| } |
| else |
| { |
| base->LPREQPINCNTRL = |
| SPM_LPREQPINCNTRL_POLARITY(config->pinOutPol) | SPM_LPREQPINCNTRL_LPREQOE_MASK; /* Enable the output. */ |
| } |
| } |