1126 lines
42 KiB
C
1126 lines
42 KiB
C
/*
|
|
* Copyright 2016 Freescale Semiconductor, Inc.
|
|
* Copyright 2016 NXP
|
|
* All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include "fsl_common.h"
|
|
#include "fsl_pf3000.h"
|
|
|
|
/*******************************************************************************
|
|
* Definitions
|
|
******************************************************************************/
|
|
/* CONCTL bit-field. */
|
|
#define PF3000_COIN_CTRL_ENABLE_MASK (0x08U)
|
|
#define PF3000_COIN_CTRL_VOLT_MASK (0x07U)
|
|
#define PF3000_COIN_CTRL_VOLT_SHIFT (0U)
|
|
#define PF3000_COIN_CTRL_VOLT(x) (((uint8_t)((uint8_t)(x) << PF3000_COIN_CTRL_VOLT_SHIFT)) & PF3000_COIN_CTRL_VOLT_MASK)
|
|
/* PWRCTL bit-field. */
|
|
#define PF3000_PWR_CTRL_REGSCCP_ENABLE_MASK (0x80U)
|
|
#define PF3000_PWR_CTRL_STANDBYINV_MASK (0x40U)
|
|
#define PF3000_PWR_CTRL_STBYDLY_MASK (0x30U)
|
|
#define PF3000_PWR_CTRL_STBYDLY_SHIFT (4U)
|
|
#define PF3000_PWR_CTRL_STBYDLY(x) \
|
|
(((uint8_t)((uint8_t)(x) << PF3000_PWR_CTRL_STBYDLY_SHIFT)) & PF3000_PWR_CTRL_STBYDLY_MASK)
|
|
#define PF3000_PWR_CTRL_PWRONDBNC_MASK (0x0CU)
|
|
#define PF3000_PWR_CTRL_PWRONDBNC_SHIFT (2U)
|
|
#define PF3000_PWR_CTRL_PWRONDBNC(x) \
|
|
(((uint8_t)((uint8_t)(x) << PF3000_PWR_CTRL_PWRONDBNC_SHIFT)) & PF3000_PWR_CTRL_PWRONDBNC_MASK)
|
|
#define PF3000_PWR_CTRL_PWRONRSTEN_MASK (0x02U)
|
|
#define PF3000_PWR_CTRL_RESTARTEN_MASK (0x01U)
|
|
/* SW1XVOLT, SW1XSTBY, SW1XOFF bit-field. */
|
|
#define PF3000_SW1X_VOLT_CTRL_MASK (0x1FU)
|
|
#define PF3000_SW1X_VOLT_CTRL_SHIFT (0U)
|
|
#define PF3000_SW1X_VOLT_CTRL(x) (((uint8_t)((uint8_t)(x) << PF3000_SW1X_VOLT_CTRL_SHIFT)) & PF3000_SW1X_VOLT_CTRL_MASK)
|
|
/* SW2VOLT, SW2STBY, SW2OFF bit-field. */
|
|
#define PF3000_SW2_VOLT_CTRL_MASK (0x07U)
|
|
#define PF3000_SW2_VOLT_CTRL_SHIFT (0U)
|
|
#define PF3000_SW2_VOLT_CTRL(x) (((uint8_t)((uint8_t)(x) << PF3000_SW2_VOLT_CTRL_SHIFT)) & PF3000_SW2_VOLT_CTRL_MASK)
|
|
/* SW3VOLT, SW3STBY, SW3OFF bit-field. */
|
|
#define PF3000_SW3_VOLT_CTRL_MASK (0x0FU)
|
|
#define PF3000_SW3_VOLT_CTRL_SHIFT (0U)
|
|
#define PF3000_SW3_VOLT_CTRL(x) (((uint8_t)((uint8_t)(x) << PF3000_SW3_VOLT_CTRL_SHIFT)) & PF3000_SW3_VOLT_CTRL_MASK)
|
|
/* SW MODE bit-field. */
|
|
#define PF3000_SW_MODE_OFF_MASK (0x20U)
|
|
#define PF3000_SW_MODE_SELECTOR_MASK (0x0FU)
|
|
#define PF3000_SW_MODE_SELECTOR_SHIFT (0U)
|
|
#define PF3000_SW_MODE_SELECTOR(x) \
|
|
(((uint8_t)((uint8_t)(x) << PF3000_SW_MODE_SELECTOR_SHIFT)) & PF3000_SW_MODE_SELECTOR_MASK)
|
|
/* SW CONFIG bit-field. */
|
|
#define PF3000_SW_CTRL_DVSSPEED_MASK (0x40U)
|
|
#define PF3000_SW_CTRL_PHASE_MASK (0x30U)
|
|
#define PF3000_SW_CTRL_PHASE_SHIFT (4U)
|
|
#define PF3000_SW_CTRL_PHASE(x) (((uint8_t)((uint8_t)(x) << PF3000_SW_CTRL_PHASE_SHIFT)) & PF3000_SW_CTRL_PHASE_MASK)
|
|
#define PF3000_SW_CTRL_FREQUENCY_MASK (0x0CU)
|
|
#define PF3000_SW_CTRL_FREQUENCY_SHIFT (2U)
|
|
#define PF3000_SW_CTRL_FREQUENCY(x) \
|
|
(((uint8_t)((uint8_t)(x) << PF3000_SW_CTRL_FREQUENCY_SHIFT)) & PF3000_SW_CTRL_FREQUENCY_MASK)
|
|
#define PF3000_SW_CTRL_CURRENT_LIMIT_MASK (0x01U)
|
|
/* SW_BOOST_CTRL bit-field. */
|
|
#define PF3000_SW_BST_CTRL_STANDBY_MODE_MASK (0x60U)
|
|
#define PF3000_SW_BST_CTRL_STANDBY_MODE_SHIFT (5U)
|
|
#define PF3000_SW_BST_CTRL_STANDBY_MODE(x) \
|
|
(((uint8_t)((uint8_t)(x) << PF3000_SW_BST_CTRL_STANDBY_MODE_SHIFT)) & PF3000_SW_BST_CTRL_STANDBY_MODE_MASK)
|
|
#define PF3000_SW_BST_CTRL_NORMAL_MODE_MASK (0x0CU)
|
|
#define PF3000_SW_BST_CTRL_NORMAL_MODE_SHIFT (2U)
|
|
#define PF3000_SW_BST_CTRL_NORMAL_MODE(x) \
|
|
(((uint8_t)((uint8_t)(x) << PF3000_SW_BST_CTRL_NORMAL_MODE_SHIFT)) & PF3000_SW_BST_CTRL_NORMAL_MODE_MASK)
|
|
#define PF3000_SW_BST_CTRL_VOLT_MASK (0x03U)
|
|
#define PF3000_SW_BST_CTRL_VOLT_SHIFT (0U)
|
|
#define PF3000_SW_BST_CTRL_VOLT(x) \
|
|
(((uint8_t)((uint8_t)(x) << PF3000_SW_BST_CTRL_VOLT_SHIFT)) & PF3000_SW_BST_CTRL_VOLT_MASK)
|
|
/* VREFDDRCTL bit-field. */
|
|
#define PF3000_VREFDDR_SUPPLY_ENABLE_MASK (0x01U)
|
|
/* VSNVSCTL bit-field. */
|
|
#define PF3000_VSNVS_VOLT_CTRL_MASK (0x07U)
|
|
#define PF3000_VSNVS_VOLT_CTRL_SHIFT (0U)
|
|
#define PF3000_VSNVS_VOLT_CTRL(x) \
|
|
(((uint8_t)((uint8_t)(x) << PF3000_VSNVS_VOLT_CTRL_SHIFT)) & PF3000_VSNVS_VOLT_CTRL_MASK)
|
|
#define PF3000_VSNVS_VOLT_CTRL_VALUE (0x06U)
|
|
/* VLDO CTL bit-field. */
|
|
#define PF3000_LDO_OFF_MODE_MASK (0x80U)
|
|
#define PF3000_LDO_LOW_POWER_MODE_MASK (0x40U)
|
|
#define PF3000_LDO_STANDBY_ON_OFF_MASK (0x20U)
|
|
#define PF3000_LDO_ENABLE_MASK (0x10U)
|
|
#define PF3000_LDO_VOLT_CTRL_MASK (0x0FU)
|
|
#define PF3000_LDO_VOLT_CTRL_SHIFT (0U)
|
|
#define PF3000_LDO_VOLT_CTRL(x) (((uint8_t)((uint8_t)(x) << PF3000_LDO_VOLT_CTRL_SHIFT)) & PF3000_LDO_VOLT_CTRL_MASK)
|
|
/* VCC_SDCTL bit-field. */
|
|
#define PF3000_VCC_SD_VOLT_CTRL_MASK (0x03U)
|
|
#define PF3000_VCC_SD_VOLT_CTRL_SHIFT (0U)
|
|
#define PF3000_VCC_SD_VOLT_CTRL(x) \
|
|
(((uint8_t)((uint8_t)(x) << PF3000_VCC_SD_VOLT_CTRL_SHIFT)) & PF3000_VCC_SD_VOLT_CTRL_MASK)
|
|
/* V33 bit-field. */
|
|
#define PF3000_V33_VOLT_CTRL_MASK (0x03U)
|
|
#define PF3000_V33_VOLT_CTRL_SHIFT (0U)
|
|
#define PF3000_V33_VOLT_CTRL(x) (((uint8_t)((uint8_t)(x) << PF3000_V33_VOLT_CTRL_SHIFT)) & PF3000_V33_VOLT_CTRL_MASK)
|
|
/* Page Selection bit-field. */
|
|
#define PF3000_PAGE_SELECTION_MASK (0x0FU)
|
|
#define PF3000_PAGE_SELECTION_SHIFT (0U)
|
|
#define PF3000_PAGE_SELECTION(x) (((uint8_t)((uint8_t)(x) << PF3000_PAGE_SELECTION_SHIFT)) & PF3000_PAGE_SELECTION_MASK)
|
|
|
|
/* Regulator Voltage Control Helper Macros. */
|
|
#define PF3000_SW1A_SET_POINT_MAX_NUM (31U)
|
|
#define PF3000_SW1A_OUTPUT_LIMIT_LOW_DVS (700000U)
|
|
#define PF3000_SW1A_OUTPUT_STEP_DVS (25000U)
|
|
#define PF3000_SW1B_SET_POINT_MAX_NUM (31U)
|
|
#define PF3000_SW1B_OUTPUT_LIMIT_LOW_DVS (700000U)
|
|
#define PF3000_SW1B_OUTPUT_STEP_DVS (25000U)
|
|
#define PF3000_SW2_SET_POINT_MAX_NUM (7U)
|
|
#define PF3000_SW2_OUTPUT_LIMIT_LOW_DVS (1500000U)
|
|
#define PF3000_SW2_OUTPUT_STEP_DVS (50000U)
|
|
#define PF3000_SW3_SET_POINT_MAX_NUM (15U)
|
|
#define PF3000_SW3_OUTPUT_LIMIT_LOW_DVS (900000U)
|
|
#define PF3000_SW3_OUTPUT_STEP_DVS (50000U)
|
|
#define PF3000_SW_BST_SET_POINT_MAX_NUM (3U)
|
|
#define PF3000_SW_BST_OUTPUT_LIMIT_LOW_DVS (5000000U)
|
|
#define PF3000_SW_BST_OUTPUT_STEP_DVS (50000U)
|
|
#define PF3000_LDOX_SET_POINT_MAX_NUM (15U)
|
|
#define PF3000_LDOX_OUTPUT_LIMIT_LOW_DVS (1800000U)
|
|
#define PF3000_LDOX_OUTPUT_STEP_DVS (100000U)
|
|
#define PF3000_LDOY_SET_POINT_MAX_NUM (15U)
|
|
#define PF3000_LDOY_OUTPUT_LIMIT_LOW_DVS (800000U)
|
|
#define PF3000_LDOY_OUTPUT_STEP_DVS (50000U)
|
|
#define PF3000_VCC_SD_SET_POINT_MAX_NUM (3U)
|
|
#define PF3000_VCC_SD_OUTPUT_LIMIT_LOW_DVS (2850000U)
|
|
#define PF3000_VCC_SD_OUTPUT_STEP_DVS (150000U)
|
|
#define PF3000_V33_SET_POINT_MAX_NUM (3U)
|
|
#define PF3000_V33_OUTPUT_LIMIT_LOW_DVS (2850000U)
|
|
#define PF3000_V33_OUTPUT_STEP_DVS (150000U)
|
|
#define PF3000_VSNVS_OUTPUT_VOLTAGE (3000000U)
|
|
|
|
/*******************************************************************************
|
|
* Prototypes
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Variables
|
|
******************************************************************************/
|
|
static const uint8_t regulatorCtrlRegTab[] = {
|
|
PF3000_SW1A_CONF, PF3000_SW1B_CONF, PF3000_SW2_CONF, PF3000_SW3_CONF, PF3000_SWBST_CTRL,
|
|
PF3000_VLDO1_CTRL, PF3000_VLDO2_CTRL, PF3000_VLDO3_CTRL, PF3000_VLDO4_CTRL, PF3000_VCC_SD_CTRL,
|
|
PF3000_V33_CTRL, PF3000_VSNVS_CTRL, PF3000_VREFDDR_CTRL};
|
|
|
|
static const uint8_t switchVoltRegTab[][3] = {
|
|
{PF3000_SW1A_VOLT, PF3000_SW1A_STBY, PF3000_SW1A_OFF},
|
|
{PF3000_SW1B_VOLT, PF3000_SW1B_STBY, PF3000_SW1B_OFF},
|
|
{PF3000_SW2_VOLT, PF3000_SW2_STBY, PF3000_SW2_OFF},
|
|
{PF3000_SW3_VOLT, PF3000_SW3_STBY, PF3000_SW3_OFF},
|
|
};
|
|
|
|
/*******************************************************************************
|
|
* Code
|
|
******************************************************************************/
|
|
static bool PF3000_ReadOtp(pf3000_handle_t *handle, uint8_t page, uint8_t reg, uint8_t *val)
|
|
{
|
|
bool result = false;
|
|
|
|
assert(handle);
|
|
assert(val);
|
|
assert((page == 0x01U) || (page == 0x02U));
|
|
|
|
result = PF3000_WriteReg(handle, PF3000_PAGE_REGISTER, PF3000_PAGE_SELECTION(page));
|
|
if (true == result)
|
|
{
|
|
result = PF3000_ReadReg(handle, reg, val);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static uint8_t PF3000_GetRegulatorSetPoint(pf3000_handle_t *handle, pf3000_module_t module, uint32_t voltage)
|
|
{
|
|
uint8_t regulatorSetPoint = 0U;
|
|
uint32_t index;
|
|
|
|
assert(handle);
|
|
assert((kPF3000_ModuleSwitch1A == module) || (kPF3000_ModuleSwitch1B == module) ||
|
|
(kPF3000_ModuleSwitch2 == module) || (kPF3000_ModuleSwitch3 == module) ||
|
|
(kPF3000_ModuleSwitchBoost == module) || (kPF3000_ModuleLdo1 == module) || (kPF3000_ModuleLdo2 == module) ||
|
|
(kPF3000_ModuleLdo3 == module) || (kPF3000_ModuleLdo4 == module) || (kPF3000_ModuleVcc_sd == module) ||
|
|
(kPF3000_ModuleV33 == module));
|
|
|
|
switch (module)
|
|
{
|
|
/* Process Switch 1A. */
|
|
case kPF3000_ModuleSwitch1A:
|
|
/* Process Switch 1B. */
|
|
case kPF3000_ModuleSwitch1B:
|
|
if ((handle->switch1Mode == kPF3000_SW1SinglePhase) ||
|
|
((handle->switch1Mode == kPF3000_SW1IndependentMode) && (module == kPF3000_ModuleSwitch1A)))
|
|
{
|
|
/* Find the first Vset_point <= voltage */
|
|
if (3300000U <= voltage)
|
|
{
|
|
index = PF3000_SW1A_SET_POINT_MAX_NUM;
|
|
}
|
|
else if (1800000U <= voltage)
|
|
{
|
|
index = PF3000_SW1A_SET_POINT_MAX_NUM - 1U;
|
|
}
|
|
else
|
|
{
|
|
for (index = PF3000_SW1A_SET_POINT_MAX_NUM - 2U; index > 0U; index--)
|
|
{
|
|
if ((PF3000_SW1A_OUTPUT_LIMIT_LOW_DVS + (PF3000_SW1A_OUTPUT_STEP_DVS * index)) <= voltage)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ((handle->switch1Mode == kPF3000_SW1IndependentMode) && (module == kPF3000_ModuleSwitch1B))
|
|
{
|
|
/* Find the first Vset_point >= voltage */
|
|
for (index = PF3000_SW1B_SET_POINT_MAX_NUM; index > 0U; index--)
|
|
{
|
|
if ((PF3000_SW1B_OUTPUT_LIMIT_LOW_DVS + (PF3000_SW1B_OUTPUT_STEP_DVS * index)) <= voltage)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
;
|
|
}
|
|
break;
|
|
|
|
/* Process Switch 2. */
|
|
case kPF3000_ModuleSwitch2:
|
|
/* OTP_SW2_HI= 0, SW2 is in low output voltage range */
|
|
if (handle->switch2Range == kPF3000_SW2LowVoltRange)
|
|
{
|
|
for (index = PF3000_SW2_SET_POINT_MAX_NUM; index > 0U; index--)
|
|
{
|
|
if ((PF3000_SW2_OUTPUT_LIMIT_LOW_DVS + (PF3000_SW2_OUTPUT_STEP_DVS * index)) <= voltage)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/* OTP_SW2_HI= 1, SW2 is in high output voltage range */
|
|
else
|
|
{
|
|
if (3300000 <= voltage)
|
|
{
|
|
index = 0x7U;
|
|
}
|
|
else if (3200000 <= voltage)
|
|
{
|
|
index = 0x6U;
|
|
}
|
|
else if (3150000 <= voltage)
|
|
{
|
|
index = 0x5U;
|
|
}
|
|
else if (3100000 <= voltage)
|
|
{
|
|
index = 0x4U;
|
|
}
|
|
else if (3000000 <= voltage)
|
|
{
|
|
index = 0x3U;
|
|
}
|
|
else if (2850000 <= voltage)
|
|
{
|
|
index = 0x2U;
|
|
}
|
|
else if (2800000 <= voltage)
|
|
{
|
|
index = 0x1U;
|
|
}
|
|
else
|
|
{
|
|
index = 0x0U;
|
|
}
|
|
}
|
|
break;
|
|
|
|
/* Process Switch 3. */
|
|
case kPF3000_ModuleSwitch3:
|
|
for (index = PF3000_SW3_SET_POINT_MAX_NUM; index > 0U; index--)
|
|
{
|
|
if ((PF3000_SW3_OUTPUT_LIMIT_LOW_DVS + (PF3000_SW3_OUTPUT_STEP_DVS * index)) <= voltage)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
/* Process Switch Boost. */
|
|
case kPF3000_ModuleSwitchBoost:
|
|
for (index = PF3000_SW_BST_SET_POINT_MAX_NUM; index > 0U; index--)
|
|
{
|
|
if ((PF3000_SW_BST_OUTPUT_LIMIT_LOW_DVS + (PF3000_SW_BST_OUTPUT_STEP_DVS * index)) <= voltage)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
/* Process LDO X, including LDO1, LDO3, LDO4. */
|
|
case kPF3000_ModuleLdo1:
|
|
case kPF3000_ModuleLdo3:
|
|
case kPF3000_ModuleLdo4:
|
|
for (index = PF3000_LDOX_SET_POINT_MAX_NUM; index > 0U; index--)
|
|
{
|
|
if ((PF3000_LDOX_OUTPUT_LIMIT_LOW_DVS + (PF3000_LDOX_OUTPUT_STEP_DVS * index)) <= voltage)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
/* Process LDO Y, including LDO2. */
|
|
case kPF3000_ModuleLdo2:
|
|
for (index = PF3000_LDOY_SET_POINT_MAX_NUM; index > 0U; index--)
|
|
{
|
|
if ((PF3000_LDOY_OUTPUT_LIMIT_LOW_DVS + (PF3000_LDOY_OUTPUT_STEP_DVS * index)) <= voltage)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
/* Process Vcc_sd. */
|
|
case kPF3000_ModuleVcc_sd:
|
|
/* VSD_VSEL= 0. */
|
|
if (handle->vccsdVsel == 0U)
|
|
{
|
|
for (index = PF3000_VCC_SD_SET_POINT_MAX_NUM; index > 0U; index--)
|
|
{
|
|
if ((PF3000_VCC_SD_OUTPUT_LIMIT_LOW_DVS + (PF3000_VCC_SD_OUTPUT_STEP_DVS * index)) <= voltage)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/* VSD_VSEL= 1. */
|
|
else
|
|
{
|
|
if (1850000U <= voltage)
|
|
{
|
|
index = 0x3U;
|
|
}
|
|
else
|
|
{
|
|
index = 0x0U;
|
|
}
|
|
}
|
|
break;
|
|
|
|
/* Process Vcc_sd. */
|
|
case kPF3000_ModuleV33:
|
|
for (index = PF3000_V33_SET_POINT_MAX_NUM; index > 0U; index--)
|
|
{
|
|
if ((PF3000_V33_OUTPUT_LIMIT_LOW_DVS + (PF3000_V33_OUTPUT_STEP_DVS * index)) <= voltage)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
index = 0U;
|
|
break;
|
|
}
|
|
|
|
/* Assin index to regulatorSetPoint*/
|
|
regulatorSetPoint = index;
|
|
|
|
return regulatorSetPoint;
|
|
}
|
|
|
|
static uint32_t PF3000_GetRegulatorOutputVolt(pf3000_handle_t *handle, pf3000_module_t module, uint8_t voltRegContent)
|
|
{
|
|
uint32_t voltage = 0U;
|
|
|
|
assert(handle);
|
|
assert((kPF3000_ModuleSwitch1A == module) || (kPF3000_ModuleSwitch1B == module) ||
|
|
(kPF3000_ModuleSwitch2 == module) || (kPF3000_ModuleSwitch3 == module) ||
|
|
(kPF3000_ModuleSwitchBoost == module) || (kPF3000_ModuleLdo1 == module) || (kPF3000_ModuleLdo2 == module) ||
|
|
(kPF3000_ModuleLdo3 == module) || (kPF3000_ModuleLdo4 == module) || (kPF3000_ModuleVcc_sd == module) ||
|
|
(kPF3000_ModuleV33 == module) || (kPF3000_ModuleVsnvs == module));
|
|
|
|
switch (module)
|
|
{
|
|
/* Process Switch 1A. */
|
|
case kPF3000_ModuleSwitch1A:
|
|
/* Process Switch 1B. */
|
|
case kPF3000_ModuleSwitch1B:
|
|
if ((handle->switch1Mode == kPF3000_SW1SinglePhase) ||
|
|
((handle->switch1Mode == kPF3000_SW1IndependentMode) && (module == kPF3000_ModuleSwitch1A)))
|
|
{
|
|
if (voltRegContent <= (PF3000_SW1A_SET_POINT_MAX_NUM - 2))
|
|
{
|
|
voltage = PF3000_SW1A_OUTPUT_LIMIT_LOW_DVS + PF3000_SW1A_OUTPUT_STEP_DVS * voltRegContent;
|
|
}
|
|
else if (voltRegContent == (PF3000_SW1A_SET_POINT_MAX_NUM - 1))
|
|
{
|
|
voltage = 1800000U;
|
|
}
|
|
else if (voltRegContent == (PF3000_SW1A_SET_POINT_MAX_NUM))
|
|
{
|
|
voltage = 3300000U;
|
|
}
|
|
else
|
|
{
|
|
;
|
|
}
|
|
}
|
|
else if ((handle->switch1Mode == kPF3000_SW1IndependentMode) && (module == kPF3000_ModuleSwitch1B))
|
|
{
|
|
voltage = PF3000_SW1B_OUTPUT_LIMIT_LOW_DVS + PF3000_SW1B_OUTPUT_STEP_DVS * voltRegContent;
|
|
}
|
|
else
|
|
{
|
|
;
|
|
}
|
|
break;
|
|
|
|
/* Process Switch 2. */
|
|
case kPF3000_ModuleSwitch2:
|
|
/* OTP_SW2_HI= 0, SW2 is in low output voltage range */
|
|
if (handle->switch2Range == kPF3000_SW2LowVoltRange)
|
|
{
|
|
voltage = PF3000_SW3_OUTPUT_LIMIT_LOW_DVS + PF3000_SW3_OUTPUT_STEP_DVS * voltRegContent;
|
|
}
|
|
/* OTP_SW2_HI= 1, SW2 is in high output voltage range */
|
|
else
|
|
{
|
|
switch (voltRegContent)
|
|
{
|
|
case 0x0U:
|
|
voltage = 2500000U;
|
|
break;
|
|
case 0x1U:
|
|
voltage = 2800000U;
|
|
break;
|
|
case 0x2U:
|
|
voltage = 2850000U;
|
|
break;
|
|
case 0x3U:
|
|
voltage = 3000000U;
|
|
break;
|
|
case 0x4U:
|
|
voltage = 3100000U;
|
|
break;
|
|
case 0x5U:
|
|
voltage = 3150000U;
|
|
break;
|
|
case 0x6U:
|
|
voltage = 3200000U;
|
|
break;
|
|
case 0x7U:
|
|
voltage = 3300000U;
|
|
break;
|
|
default:
|
|
voltage = 0U;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
/* Process Switch 3. */
|
|
case kPF3000_ModuleSwitch3:
|
|
voltage = PF3000_SW3_OUTPUT_LIMIT_LOW_DVS + PF3000_SW3_OUTPUT_STEP_DVS * voltRegContent;
|
|
break;
|
|
|
|
/* Process Switch Boost. */
|
|
case kPF3000_ModuleSwitchBoost:
|
|
voltage = PF3000_SW_BST_OUTPUT_LIMIT_LOW_DVS + PF3000_SW_BST_OUTPUT_STEP_DVS * voltRegContent;
|
|
break;
|
|
|
|
/* Process LDO X, including LDO1, LDO3, LDO4. */
|
|
case kPF3000_ModuleLdo1:
|
|
case kPF3000_ModuleLdo3:
|
|
case kPF3000_ModuleLdo4:
|
|
voltage = PF3000_LDOX_OUTPUT_LIMIT_LOW_DVS + PF3000_LDOX_OUTPUT_STEP_DVS * voltRegContent;
|
|
break;
|
|
|
|
/* Process LDO Y, including LDO2. */
|
|
case kPF3000_ModuleLdo2:
|
|
voltage = PF3000_LDOY_OUTPUT_LIMIT_LOW_DVS + PF3000_LDOY_OUTPUT_STEP_DVS * voltRegContent;
|
|
break;
|
|
|
|
/* Process Vcc_sd. */
|
|
case kPF3000_ModuleVcc_sd:
|
|
/* VSD_VSEL= 0. */
|
|
if (handle->vccsdVsel == 0U)
|
|
{
|
|
voltage = PF3000_VCC_SD_OUTPUT_LIMIT_LOW_DVS + PF3000_VCC_SD_OUTPUT_STEP_DVS * voltRegContent;
|
|
}
|
|
/* VSD_VSEL= 1. */
|
|
else
|
|
{
|
|
if (voltRegContent == 3U)
|
|
{
|
|
voltage = 1850000U;
|
|
}
|
|
else
|
|
{
|
|
voltage = 1800000U;
|
|
}
|
|
}
|
|
break;
|
|
|
|
/* Process Vcc_sd. */
|
|
case kPF3000_ModuleV33:
|
|
voltage = PF3000_V33_OUTPUT_LIMIT_LOW_DVS + PF3000_V33_OUTPUT_STEP_DVS * voltRegContent;
|
|
break;
|
|
|
|
/* Process Vsnvs. It's fixed in 3.0V, can't be changed. */
|
|
case kPF3000_ModuleVsnvs:
|
|
assert(voltRegContent == PF3000_VSNVS_VOLT_CTRL_VALUE);
|
|
voltage = PF3000_VSNVS_OUTPUT_VOLTAGE;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return voltage;
|
|
}
|
|
|
|
void PF3000_GetDefaultConfig(pf3000_config_t *config)
|
|
{
|
|
assert(config);
|
|
|
|
/* Set callback function to NULL Pointer. */
|
|
config->I2C_SendFunc = NULL;
|
|
config->I2C_ReceiveFunc = NULL;
|
|
|
|
/* Set Default Slave Address. */
|
|
config->slaveAddress = PF3000_DEFAULT_I2C_ADDR;
|
|
/* Short-circuit protection enabled. */
|
|
config->enableRegSCP = true;
|
|
/* VSD_VSEL. */
|
|
config->vccsdVsel = 0U;
|
|
}
|
|
|
|
void PF3000_Init(pf3000_handle_t *handle, const pf3000_config_t *config)
|
|
{
|
|
uint8_t temp;
|
|
uint8_t regValue;
|
|
|
|
assert(handle);
|
|
assert(config);
|
|
|
|
/* Initialize Callback functions. */
|
|
handle->I2C_SendFunc = config->I2C_SendFunc;
|
|
handle->I2C_ReceiveFunc = config->I2C_ReceiveFunc;
|
|
/* Set Slave Address. */
|
|
handle->slaveAddress = config->slaveAddress;
|
|
|
|
/* Modify Switch Mode Register Value. */
|
|
temp = (config->enableRegSCP ? PF3000_PWR_CTRL_REGSCCP_ENABLE_MASK : 0U);
|
|
|
|
PF3000_ModifyReg(handle, PF3000_PWR_CTRL, PF3000_PWR_CTRL_REGSCCP_ENABLE_MASK, temp);
|
|
|
|
/* VSD_VSEL. */
|
|
handle->vccsdVsel = config->vccsdVsel;
|
|
|
|
/* Read the register value of OTP SW1x CONFIG */
|
|
PF3000_ReadOtp(handle, 0x01U, PF3000_OTP_SW1x_CONFIG, ®Value);
|
|
/* SW1A SW1B mode selection. */
|
|
handle->switch1Mode = (pf3000_switch1_mode_t)((regValue & 0x0CU) >> 2U);
|
|
|
|
assert((handle->switch1Mode == kPF3000_SW1SinglePhase) || (handle->switch1Mode == kPF3000_SW1IndependentMode));
|
|
|
|
/* Read the register value of OTP SW2 VOLT */
|
|
PF3000_ReadOtp(handle, 0x01U, PF3000_OTP_SW2_VOLT, ®Value);
|
|
/* SW2 voltage range. */
|
|
handle->switch2Range = (regValue & 0x08U) ? (kPF3000_SW2HighVoltRange) : (kPF3000_SW2LowVoltRange);
|
|
}
|
|
|
|
bool PF3000_WriteReg(pf3000_handle_t *handle, uint8_t reg, uint8_t val)
|
|
{
|
|
assert(handle);
|
|
assert(handle->I2C_SendFunc);
|
|
|
|
return handle->I2C_SendFunc(handle->slaveAddress, reg, 1U, &val, 1U);
|
|
}
|
|
|
|
bool PF3000_ReadReg(pf3000_handle_t *handle, uint8_t reg, uint8_t *val)
|
|
{
|
|
assert(handle);
|
|
assert(handle->I2C_ReceiveFunc);
|
|
assert(val);
|
|
|
|
return handle->I2C_ReceiveFunc(handle->slaveAddress, reg, 1U, val, 1U);
|
|
}
|
|
|
|
bool PF3000_ModifyReg(pf3000_handle_t *handle, uint8_t reg, uint8_t mask, uint8_t val)
|
|
{
|
|
bool result = false;
|
|
uint8_t regValue;
|
|
|
|
assert(handle);
|
|
|
|
/* Read back the register content. */
|
|
result = PF3000_ReadReg(handle, reg, ®Value);
|
|
if (true == result)
|
|
{
|
|
/* Modify the bit-fields you want to change. */
|
|
regValue &= (uint8_t)~mask;
|
|
regValue |= val;
|
|
|
|
/* Write back the content to the registers. */
|
|
result = PF3000_WriteReg(handle, reg, regValue);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool PF3000_DumpReg(pf3000_handle_t *handle, uint8_t page, uint8_t reg, uint8_t *buffer, uint8_t size)
|
|
{
|
|
bool result = true;
|
|
uint8_t i;
|
|
|
|
assert(handle);
|
|
assert(buffer);
|
|
assert((page == 0x00U) || (page == 0x01U) || (page == 0x02U));
|
|
|
|
PF3000_WriteReg(handle, PF3000_PAGE_REGISTER, PF3000_PAGE_SELECTION(page));
|
|
|
|
/* It seems that PF3000 only supports single-byte I2C transactions
|
|
for read and write. */
|
|
for (i = 0; i < size; i++)
|
|
{
|
|
if (false == PF3000_ReadReg(handle, reg++, buffer++))
|
|
{
|
|
result = false;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void PF3000_EnableInterrupts(pf3000_handle_t *handle, uint32_t source)
|
|
{
|
|
assert(handle);
|
|
|
|
/* Enable INTSTAT0 interrupts. */
|
|
PF3000_ModifyReg(handle, PF3000_SW_INT_MASK0, (source & 0xFFU), 0x0U);
|
|
/* Enable INTSTAT1 interrupts. */
|
|
PF3000_ModifyReg(handle, PF3000_SW_INT_MASK1, ((source & 0xFF00U) >> 8U), 0x0U);
|
|
/* Enable INTSTAT3 interrupts. */
|
|
PF3000_ModifyReg(handle, PF3000_SW_INT_MASK3, ((source & 0xFF0000U) >> 16U), 0x0U);
|
|
/* Enable INTSTAT4 interrupts. */
|
|
PF3000_ModifyReg(handle, PF3000_SW_INT_MASK4, ((source & 0xFF000000U) >> 24), 0x0U);
|
|
}
|
|
|
|
void PF3000_DisableInterrupts(pf3000_handle_t *handle, uint32_t source)
|
|
{
|
|
assert(handle);
|
|
|
|
/* Enable INTSTAT0 interrupts. */
|
|
PF3000_ModifyReg(handle, PF3000_SW_INT_MASK0, 0x0U, (source & 0xFFU));
|
|
/* Enable INTSTAT1 interrupts. */
|
|
PF3000_ModifyReg(handle, PF3000_SW_INT_MASK1, 0x0U, ((source & 0xFF00U) >> 8U));
|
|
/* Enable INTSTAT3 interrupts. */
|
|
PF3000_ModifyReg(handle, PF3000_SW_INT_MASK3, 0x0U, ((source & 0xFF0000U) >> 16U));
|
|
/* Enable INTSTAT4 interrupts. */
|
|
PF3000_ModifyReg(handle, PF3000_SW_INT_MASK4, 0x0U, ((source & 0xFF000000U) >> 24));
|
|
}
|
|
|
|
uint32_t PF3000_GetInterruptStatus(pf3000_handle_t *handle)
|
|
{
|
|
uint32_t status = 0x0U;
|
|
uint8_t temp;
|
|
|
|
assert(handle);
|
|
|
|
/* Get INTSTAT0 interrupts flag. */
|
|
PF3000_ReadReg(handle, PF3000_SW_INT_STAT0, &temp);
|
|
status = temp;
|
|
|
|
/* Get INTSTAT1 interrupts flag. */
|
|
PF3000_ReadReg(handle, PF3000_SW_INT_STAT1, &temp);
|
|
status |= (uint32_t)((uint32_t)temp << 8U);
|
|
|
|
/* Get INTSTAT3 interrupts flag. */
|
|
PF3000_ReadReg(handle, PF3000_SW_INT_STAT3, &temp);
|
|
status |= (uint32_t)((uint32_t)temp << 16U);
|
|
|
|
/* Get INTSTAT4 interrupts flag. */
|
|
PF3000_ReadReg(handle, PF3000_SW_INT_STAT4, &temp);
|
|
status |= (uint32_t)((uint32_t)temp << 24U);
|
|
|
|
return status;
|
|
}
|
|
|
|
void PF3000_ClearInterruptStatus(pf3000_handle_t *handle, uint32_t source)
|
|
{
|
|
assert(handle);
|
|
|
|
/* Clear INTSTAT0 interrupts flag. */
|
|
PF3000_WriteReg(handle, PF3000_SW_INT_STAT0, (source & 0xFFU));
|
|
/* Clear INTSTAT1 interrupts flag. */
|
|
PF3000_WriteReg(handle, PF3000_SW_INT_STAT1, ((source & 0xFF00U) >> 8U));
|
|
/* Clear INTSTAT3 interrupts flag. */
|
|
PF3000_WriteReg(handle, PF3000_SW_INT_STAT3, ((source & 0xFF0000U) >> 16U));
|
|
/* Clear INTSTAT4 interrupts flag. */
|
|
PF3000_WriteReg(handle, PF3000_SW_INT_STAT4, ((source & 0xFF000000U) >> 24U));
|
|
}
|
|
|
|
void PF3000_SetRegulatorOutputVoltage(pf3000_handle_t *handle,
|
|
pf3000_module_t module,
|
|
pf3000_operating_status_t status,
|
|
uint32_t voltage)
|
|
{
|
|
uint8_t regulatorVoltRegAddr;
|
|
uint8_t regulatorVoltRegContent;
|
|
uint8_t regulatorVoltRegMask;
|
|
|
|
assert(handle);
|
|
assert((kPF3000_ModuleSwitch1A == module) || (kPF3000_ModuleSwitch1B == module) ||
|
|
(kPF3000_ModuleSwitch2 == module) || (kPF3000_ModuleSwitch3 == module) ||
|
|
(kPF3000_ModuleSwitchBoost == module) || (kPF3000_ModuleLdo1 == module) || (kPF3000_ModuleLdo2 == module) ||
|
|
(kPF3000_ModuleLdo3 == module) || (kPF3000_ModuleLdo4 == module) || (kPF3000_ModuleVcc_sd == module) ||
|
|
(kPF3000_ModuleV33 == module));
|
|
|
|
assert((kPF3000_OperatingStatusSystemOn == status) || (kPF3000_OperatingStatusStandby == status) ||
|
|
(kPF3000_OperatingStatusOff == status));
|
|
|
|
/* Get Register Value. */
|
|
regulatorVoltRegContent = PF3000_GetRegulatorSetPoint(handle, module, voltage);
|
|
|
|
switch (module)
|
|
{
|
|
/* Process SW1A, SW1B. */
|
|
case kPF3000_ModuleSwitch1A:
|
|
case kPF3000_ModuleSwitch1B:
|
|
regulatorVoltRegAddr = switchVoltRegTab[module][status];
|
|
regulatorVoltRegContent = PF3000_SW1X_VOLT_CTRL(regulatorVoltRegContent);
|
|
regulatorVoltRegMask = PF3000_SW1X_VOLT_CTRL_MASK;
|
|
break;
|
|
|
|
/* Process SW2. */
|
|
case kPF3000_ModuleSwitch2:
|
|
regulatorVoltRegAddr = switchVoltRegTab[module][status];
|
|
regulatorVoltRegContent = PF3000_SW2_VOLT_CTRL(regulatorVoltRegContent);
|
|
regulatorVoltRegMask = PF3000_SW2_VOLT_CTRL_MASK;
|
|
break;
|
|
|
|
/* Process SW3. */
|
|
case kPF3000_ModuleSwitch3:
|
|
regulatorVoltRegAddr = switchVoltRegTab[module][status];
|
|
regulatorVoltRegContent = PF3000_SW3_VOLT_CTRL(regulatorVoltRegContent);
|
|
regulatorVoltRegMask = PF3000_SW3_VOLT_CTRL_MASK;
|
|
break;
|
|
|
|
/* Process Switch Boost. */
|
|
case kPF3000_ModuleSwitchBoost:
|
|
regulatorVoltRegAddr = PF3000_SWBST_CTRL;
|
|
regulatorVoltRegContent = PF3000_SW_BST_CTRL_VOLT(regulatorVoltRegContent);
|
|
regulatorVoltRegMask = PF3000_SW_BST_CTRL_VOLT_MASK;
|
|
break;
|
|
|
|
/* Process LDO1, LDO2, LDO3, LDO4. */
|
|
case kPF3000_ModuleLdo1:
|
|
case kPF3000_ModuleLdo2:
|
|
case kPF3000_ModuleLdo3:
|
|
case kPF3000_ModuleLdo4:
|
|
regulatorVoltRegAddr = regulatorCtrlRegTab[module];
|
|
regulatorVoltRegContent = PF3000_LDO_VOLT_CTRL(regulatorVoltRegContent);
|
|
regulatorVoltRegMask = PF3000_LDO_VOLT_CTRL_MASK;
|
|
break;
|
|
|
|
/* Process Vcc_sd. */
|
|
case kPF3000_ModuleVcc_sd:
|
|
regulatorVoltRegAddr = regulatorCtrlRegTab[module];
|
|
regulatorVoltRegContent = PF3000_VCC_SD_VOLT_CTRL(regulatorVoltRegContent);
|
|
regulatorVoltRegMask = PF3000_VCC_SD_VOLT_CTRL_MASK;
|
|
break;
|
|
|
|
/* Process V33. */
|
|
case kPF3000_ModuleV33:
|
|
regulatorVoltRegAddr = regulatorCtrlRegTab[module];
|
|
regulatorVoltRegContent = PF3000_V33_VOLT_CTRL(regulatorVoltRegContent);
|
|
regulatorVoltRegMask = PF3000_V33_VOLT_CTRL_MASK;
|
|
break;
|
|
|
|
default:
|
|
regulatorVoltRegAddr = 0x00U;
|
|
regulatorVoltRegMask = 0x00U;
|
|
break;
|
|
}
|
|
|
|
/* Modify corresponding registers. */
|
|
PF3000_ModifyReg(handle, regulatorVoltRegAddr, regulatorVoltRegMask, regulatorVoltRegContent);
|
|
}
|
|
|
|
uint32_t PF3000_GetRegulatorOutputVoltage(pf3000_handle_t *handle,
|
|
pf3000_module_t module,
|
|
pf3000_operating_status_t status)
|
|
{
|
|
uint8_t regulatorVoltRegAddr;
|
|
uint8_t regulatorVoltRegContent;
|
|
uint8_t regulatorVoltRegMask;
|
|
uint32_t voltage = 0U;
|
|
|
|
assert(handle);
|
|
assert((kPF3000_ModuleSwitch1A == module) || (kPF3000_ModuleSwitch1B == module) ||
|
|
(kPF3000_ModuleSwitch2 == module) || (kPF3000_ModuleSwitch3 == module) ||
|
|
(kPF3000_ModuleSwitchBoost == module) || (kPF3000_ModuleLdo1 == module) || (kPF3000_ModuleLdo2 == module) ||
|
|
(kPF3000_ModuleLdo3 == module) || (kPF3000_ModuleLdo4 == module) || (kPF3000_ModuleVcc_sd == module) ||
|
|
(kPF3000_ModuleV33 == module) || (kPF3000_ModuleVsnvs == module));
|
|
|
|
assert((kPF3000_OperatingStatusSystemOn == status) || (kPF3000_OperatingStatusStandby == status) ||
|
|
(kPF3000_OperatingStatusOff == status));
|
|
|
|
switch (module)
|
|
{
|
|
/* Process SW1A, SW1B. */
|
|
case kPF3000_ModuleSwitch1A:
|
|
case kPF3000_ModuleSwitch1B:
|
|
regulatorVoltRegAddr = switchVoltRegTab[module][status];
|
|
regulatorVoltRegMask = PF3000_SW1X_VOLT_CTRL_MASK;
|
|
break;
|
|
|
|
/* Process SW2. */
|
|
case kPF3000_ModuleSwitch2:
|
|
regulatorVoltRegAddr = switchVoltRegTab[module][status];
|
|
regulatorVoltRegMask = PF3000_SW2_VOLT_CTRL_MASK;
|
|
break;
|
|
|
|
/* Process SW3. */
|
|
case kPF3000_ModuleSwitch3:
|
|
regulatorVoltRegAddr = switchVoltRegTab[module][status];
|
|
regulatorVoltRegMask = PF3000_SW3_VOLT_CTRL_MASK;
|
|
break;
|
|
|
|
/* Process Switch Boost. */
|
|
case kPF3000_ModuleSwitchBoost:
|
|
regulatorVoltRegAddr = regulatorCtrlRegTab[module];
|
|
regulatorVoltRegMask = PF3000_SW_BST_CTRL_VOLT_MASK;
|
|
break;
|
|
|
|
/* Process LDO1, LDO2, LDO3, LDO4. */
|
|
case kPF3000_ModuleLdo1:
|
|
case kPF3000_ModuleLdo2:
|
|
case kPF3000_ModuleLdo3:
|
|
case kPF3000_ModuleLdo4:
|
|
regulatorVoltRegAddr = regulatorCtrlRegTab[module];
|
|
regulatorVoltRegMask = PF3000_LDO_VOLT_CTRL_MASK;
|
|
break;
|
|
|
|
/* Process Vcc_sd. */
|
|
case kPF3000_ModuleVcc_sd:
|
|
regulatorVoltRegAddr = regulatorCtrlRegTab[module];
|
|
regulatorVoltRegMask = PF3000_VCC_SD_VOLT_CTRL_MASK;
|
|
break;
|
|
|
|
/* Process V33. */
|
|
case kPF3000_ModuleV33:
|
|
regulatorVoltRegAddr = regulatorCtrlRegTab[module];
|
|
regulatorVoltRegMask = PF3000_V33_VOLT_CTRL_MASK;
|
|
break;
|
|
|
|
/* Process Vsnvs. */
|
|
case kPF3000_ModuleVsnvs:
|
|
regulatorVoltRegAddr = regulatorCtrlRegTab[module];
|
|
regulatorVoltRegMask = PF3000_VSNVS_VOLT_CTRL_MASK;
|
|
break;
|
|
|
|
default:
|
|
regulatorVoltRegAddr = 0x00U;
|
|
regulatorVoltRegMask = 0x00U;
|
|
break;
|
|
}
|
|
|
|
/* Get Register Value. */
|
|
PF3000_ReadReg(handle, regulatorVoltRegAddr, ®ulatorVoltRegContent);
|
|
/* Modify Register Value. */
|
|
regulatorVoltRegContent = regulatorVoltRegContent & regulatorVoltRegMask;
|
|
/* Get LDO Voltage Control Value. */
|
|
voltage = PF3000_GetRegulatorOutputVolt(handle, module, regulatorVoltRegContent);
|
|
|
|
return voltage;
|
|
}
|
|
|
|
void PF3000_EnableRegulator(pf3000_handle_t *handle, pf3000_module_t module, bool enable)
|
|
{
|
|
uint8_t regulatorCtrlRegAddr;
|
|
|
|
assert(handle);
|
|
assert((kPF3000_ModuleSwitch1A == module) || (kPF3000_ModuleSwitch1B == module) ||
|
|
(kPF3000_ModuleSwitch2 == module) || (kPF3000_ModuleSwitch3 == module) ||
|
|
(kPF3000_ModuleSwitchBoost == module) || (kPF3000_ModuleLdo1 == module) || (kPF3000_ModuleLdo2 == module) ||
|
|
(kPF3000_ModuleLdo3 == module) || (kPF3000_ModuleLdo4 == module) || (kPF3000_ModuleVcc_sd == module) ||
|
|
(kPF3000_ModuleV33 == module) || (kPF3000_ModuleVsnvs == module) || (kPF3000_ModuleVrefDdr == module));
|
|
|
|
switch (module)
|
|
{
|
|
case kPF3000_ModuleLdo1:
|
|
case kPF3000_ModuleLdo2:
|
|
case kPF3000_ModuleLdo3:
|
|
case kPF3000_ModuleLdo4:
|
|
case kPF3000_ModuleVcc_sd:
|
|
case kPF3000_ModuleV33:
|
|
/* Get LDO Control Register Address. */
|
|
regulatorCtrlRegAddr = regulatorCtrlRegTab[module];
|
|
/* Modify LDO Control Register Value. */
|
|
PF3000_ModifyReg(handle, regulatorCtrlRegAddr, PF3000_LDO_ENABLE_MASK,
|
|
(enable ? PF3000_LDO_ENABLE_MASK : 0x0U));
|
|
break;
|
|
|
|
case kPF3000_ModuleVrefDdr:
|
|
/* Modify Vrefddr Control Register Value. */
|
|
PF3000_ModifyReg(handle, PF3000_VREFDDR_CTRL, PF3000_VREFDDR_SUPPLY_ENABLE_MASK,
|
|
(enable ? PF3000_VREFDDR_SUPPLY_ENABLE_MASK : 0x0U));
|
|
break;
|
|
|
|
case kPF3000_ModuleSwitch1A:
|
|
case kPF3000_ModuleSwitch1B:
|
|
case kPF3000_ModuleSwitch2:
|
|
case kPF3000_ModuleSwitch3:
|
|
case kPF3000_ModuleSwitchBoost:
|
|
case kPF3000_ModuleVsnvs:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool PF3000_IsRegulatorEnabled(pf3000_handle_t *handle, pf3000_module_t module)
|
|
{
|
|
bool result;
|
|
uint8_t regulatorCtrlRegAddr;
|
|
uint8_t regulatorCtrlRegContent;
|
|
|
|
assert(handle);
|
|
assert((kPF3000_ModuleSwitch1A == module) || (kPF3000_ModuleSwitch1B == module) ||
|
|
(kPF3000_ModuleSwitch2 == module) || (kPF3000_ModuleSwitch3 == module) ||
|
|
(kPF3000_ModuleSwitchBoost == module) || (kPF3000_ModuleLdo1 == module) || (kPF3000_ModuleLdo2 == module) ||
|
|
(kPF3000_ModuleLdo3 == module) || (kPF3000_ModuleLdo4 == module) || (kPF3000_ModuleVcc_sd == module) ||
|
|
(kPF3000_ModuleV33 == module) || (kPF3000_ModuleVsnvs == module) || (kPF3000_ModuleVrefDdr == module));
|
|
|
|
switch (module)
|
|
{
|
|
case kPF3000_ModuleLdo1:
|
|
case kPF3000_ModuleLdo2:
|
|
case kPF3000_ModuleLdo3:
|
|
case kPF3000_ModuleLdo4:
|
|
case kPF3000_ModuleVcc_sd:
|
|
case kPF3000_ModuleV33:
|
|
/* Get LDO Control Register Content. */
|
|
regulatorCtrlRegAddr = regulatorCtrlRegTab[module];
|
|
/* Read LDO Control Register Value. */
|
|
PF3000_ReadReg(handle, regulatorCtrlRegAddr, ®ulatorCtrlRegContent);
|
|
/* LDO enable judge */
|
|
result = (regulatorCtrlRegContent & PF3000_LDO_ENABLE_MASK) ? true : false;
|
|
break;
|
|
|
|
case kPF3000_ModuleVrefDdr:
|
|
/* Get Vrefddr Control Register Content. */
|
|
regulatorCtrlRegAddr = regulatorCtrlRegTab[module];
|
|
/* Read Vrefddr Control Register Value. */
|
|
PF3000_ReadReg(handle, regulatorCtrlRegAddr, ®ulatorCtrlRegContent);
|
|
/* Vrefddr enable judge */
|
|
result = (regulatorCtrlRegContent & PF3000_VREFDDR_SUPPLY_ENABLE_MASK) ? true : false;
|
|
break;
|
|
|
|
case kPF3000_ModuleSwitch1A:
|
|
case kPF3000_ModuleSwitch1B:
|
|
case kPF3000_ModuleSwitch2:
|
|
case kPF3000_ModuleSwitch3:
|
|
case kPF3000_ModuleSwitchBoost:
|
|
case kPF3000_ModuleVsnvs:
|
|
/* They are enabled by default */
|
|
result = true;
|
|
break;
|
|
|
|
default:
|
|
result = false;
|
|
break;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void PF3000_SetSwitchAttribute(pf3000_handle_t *handle,
|
|
pf3000_module_t module,
|
|
const pf3000_switch_attribute_t *attribute)
|
|
{
|
|
uint8_t switchModeRegAddr;
|
|
uint8_t switchCtrlRegAddr;
|
|
uint8_t temp;
|
|
|
|
assert(handle);
|
|
assert(attribute);
|
|
assert((kPF3000_ModuleSwitch1A == module) || (kPF3000_ModuleSwitch1B == module) ||
|
|
(kPF3000_ModuleSwitch2 == module) || (kPF3000_ModuleSwitch3 == module));
|
|
|
|
/* Set Switch Mode Register. */
|
|
switch (module)
|
|
{
|
|
case kPF3000_ModuleSwitch1A:
|
|
switchModeRegAddr = PF3000_SW1A_MODE;
|
|
break;
|
|
|
|
case kPF3000_ModuleSwitch1B:
|
|
switchModeRegAddr = PF3000_SW1B_MODE;
|
|
break;
|
|
|
|
case kPF3000_ModuleSwitch2:
|
|
switchModeRegAddr = PF3000_SW2_MODE;
|
|
break;
|
|
|
|
case kPF3000_ModuleSwitch3:
|
|
switchModeRegAddr = PF3000_SW3_MODE;
|
|
break;
|
|
|
|
default:
|
|
switchModeRegAddr = 0x00U;
|
|
break;
|
|
}
|
|
|
|
/* Modify Switch Mode Register Value. */
|
|
temp = ((attribute->offMode ? PF3000_SW_MODE_OFF_MASK : 0U) | (PF3000_SW_MODE_SELECTOR(attribute->mode)));
|
|
|
|
PF3000_ModifyReg(handle, switchModeRegAddr, PF3000_SW_MODE_OFF_MASK | PF3000_SW_MODE_SELECTOR_MASK, temp);
|
|
|
|
/* Set Switch Control Register. */
|
|
switchCtrlRegAddr = regulatorCtrlRegTab[module];
|
|
|
|
/* Modify Switch Control Register Value. */
|
|
temp = ((attribute->dvsSpeed ? PF3000_SW_CTRL_DVSSPEED_MASK : 0U) | (PF3000_SW_CTRL_PHASE(attribute->phaseClock)) |
|
|
(PF3000_SW_CTRL_FREQUENCY(attribute->frequency)) |
|
|
(attribute->currentLimit ? PF3000_SW_CTRL_CURRENT_LIMIT_MASK : 0U));
|
|
|
|
PF3000_ModifyReg(handle, switchCtrlRegAddr,
|
|
PF3000_SW_CTRL_DVSSPEED_MASK | PF3000_SW_CTRL_PHASE_MASK | PF3000_SW_CTRL_FREQUENCY_MASK |
|
|
PF3000_SW_CTRL_CURRENT_LIMIT_MASK,
|
|
temp);
|
|
}
|
|
|
|
void PF3000_SetSwitchBoostAttribute(pf3000_handle_t *handle, const pf3000_switch_boost_attribute_t *attribute)
|
|
{
|
|
uint8_t switchBoostCtrlRegAddr;
|
|
uint8_t temp;
|
|
|
|
assert(handle);
|
|
assert(attribute);
|
|
|
|
switchBoostCtrlRegAddr = regulatorCtrlRegTab[kPF3000_ModuleSwitchBoost];
|
|
|
|
temp = (PF3000_SW_BST_CTRL_STANDBY_MODE(attribute->standbyMode) |
|
|
PF3000_SW_BST_CTRL_NORMAL_MODE(attribute->normalMode));
|
|
|
|
PF3000_ModifyReg(handle, switchBoostCtrlRegAddr,
|
|
PF3000_SW_BST_CTRL_STANDBY_MODE_MASK | PF3000_SW_BST_CTRL_NORMAL_MODE_MASK, temp);
|
|
}
|
|
|
|
void PF3000_SetLdoAttribute(pf3000_handle_t *handle, pf3000_module_t module, const pf3000_ldo_attribute_t *attribute)
|
|
{
|
|
uint8_t ldoCtrlRegAddr;
|
|
uint8_t temp;
|
|
|
|
assert(handle);
|
|
assert(attribute);
|
|
assert((kPF3000_ModuleLdo1 == module) || (kPF3000_ModuleLdo2 == module) || (kPF3000_ModuleLdo3 == module) ||
|
|
(kPF3000_ModuleLdo4 == module) || (kPF3000_ModuleVcc_sd == module) || (kPF3000_ModuleV33 == module));
|
|
|
|
/* Set LDO to load switch mode. */
|
|
ldoCtrlRegAddr = regulatorCtrlRegTab[module];
|
|
|
|
temp = ((attribute->offMode ? PF3000_LDO_OFF_MODE_MASK : 0) |
|
|
(attribute->enableLowPower ? PF3000_LDO_LOW_POWER_MODE_MASK : 0) |
|
|
((attribute->standbyOnOff == kPF3000_LdoOffDuringStandby) ? PF3000_LDO_STANDBY_ON_OFF_MASK : 0));
|
|
|
|
PF3000_ModifyReg(handle, ldoCtrlRegAddr,
|
|
PF3000_LDO_OFF_MODE_MASK | PF3000_LDO_LOW_POWER_MODE_MASK | PF3000_LDO_STANDBY_ON_OFF_MASK, temp);
|
|
}
|
|
|
|
void PF3000_SetCoinCellAttribute(pf3000_handle_t *handle, const pf3000_coin_cell_attribute_t *attribute)
|
|
{
|
|
uint8_t temp;
|
|
|
|
assert(handle);
|
|
assert(attribute);
|
|
|
|
temp = ((attribute->enableCoinCellCharger ? PF3000_COIN_CTRL_ENABLE_MASK : 0) |
|
|
PF3000_COIN_CTRL_VOLT(attribute->coinCellChargingVoltage));
|
|
|
|
/* Set Coin Cell Control Register. */
|
|
PF3000_ModifyReg(handle, PF3000_COIN_CTRL, PF3000_COIN_CTRL_ENABLE_MASK | PF3000_COIN_CTRL_VOLT_MASK, temp);
|
|
}
|
|
|
|
void PF3000_SetStandbyPadAttribute(pf3000_handle_t *handle, const pf3000_standby_attribute_t *attribute)
|
|
{
|
|
uint8_t temp;
|
|
|
|
assert(handle);
|
|
assert(attribute);
|
|
|
|
temp = ((attribute->standbyPolarity ? PF3000_PWR_CTRL_STANDBYINV_MASK : 0U) |
|
|
PF3000_PWR_CTRL_STBYDLY(attribute->standbyDelay));
|
|
|
|
/* Set Coin Cell Control Register. */
|
|
PF3000_ModifyReg(handle, PF3000_PWR_CTRL, PF3000_PWR_CTRL_STANDBYINV_MASK | PF3000_PWR_CTRL_STBYDLY_MASK, temp);
|
|
}
|
|
|
|
void PF3000_SetPwrOnPadAttibute(pf3000_handle_t *handle, const pf3000_power_on_attribute_t *attribute)
|
|
{
|
|
uint8_t temp;
|
|
|
|
assert(handle);
|
|
assert(attribute);
|
|
|
|
temp = (PF3000_PWR_CTRL_PWRONDBNC(attribute->debounce) |
|
|
(attribute->longPressAllowOffMode ? PF3000_PWR_CTRL_PWRONRSTEN_MASK : 0U) |
|
|
(attribute->longPressRestart ? PF3000_PWR_CTRL_RESTARTEN_MASK : 0U));
|
|
|
|
/* Set Coin Cell Control Register. */
|
|
PF3000_ModifyReg(handle, PF3000_PWR_CTRL,
|
|
PF3000_PWR_CTRL_PWRONDBNC_MASK | PF3000_PWR_CTRL_PWRONRSTEN_MASK | PF3000_PWR_CTRL_RESTARTEN_MASK,
|
|
temp);
|
|
}
|
|
/*******************************************************************************
|
|
* EOF
|
|
******************************************************************************/
|