From de9f930a742b28346fce02355da6e8e2a6469ad5 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 30 Mar 2023 10:24:15 +0200 Subject: [PATCH 1/5] Add API for configuring SW1 of PF1550 PMIC. --- src/PF1550.cpp | 21 +++++++++++++++++++++ src/PF1550.h | 8 ++++++++ src/PF1550/PF1550_Control.cpp | 35 +++++++++++++++++++++++++++++++++++ src/PF1550/PF1550_Control.h | 8 ++++++++ src/PF1550/PF1550_Defines.h | 8 ++++++++ src/PF1550/PF1550_Types.h | 31 +++++++++++++++++++++++++++++++ 6 files changed, 111 insertions(+) diff --git a/src/PF1550.cpp b/src/PF1550.cpp index ac6ed6c..8d6eb21 100644 --- a/src/PF1550.cpp +++ b/src/PF1550.cpp @@ -125,6 +125,27 @@ void PF1550::configLDO3(Ldo3Voltage const ldo_3_volt, bool const enable, bool co else _control.turnLDO3Off(Ldo3Mode::Sleep); } +void PF1550::configSw1(Sw1Voltage const sw1_volt, + Sw1Voltage const sw1_volt_standby, + Sw1Voltage const sw1_volt_sleep, + Sw1CurrentLimit const sw1_current_limit, + bool const enable, + bool const enable_in_standby, + bool const enable_in_sleep) +{ + _control.setSw1Voltage (sw1_volt); + _control.setSw1VoltageStandby(sw1_volt_standby); + _control.setSw1VoltageSleep (sw1_volt_sleep); + _control.setSw1CurrentLimit (sw1_current_limit); + + if(enable) _control.turnSw1On (Sw1Mode::Normal); + else _control.turnSw1Off(Sw1Mode::Normal); + if(enable_in_standby) _control.turnSw1On (Sw1Mode::Standby); + else _control.turnSw1Off(Sw1Mode::Standby); + if(enable_in_sleep) _control.turnSw1On (Sw1Mode::Sleep); + else _control.turnSw1Off(Sw1Mode::Sleep); +} + void PF1550::configSw2(Sw2Voltage const sw2_volt, Sw2Voltage const sw2_volt_standby, Sw2Voltage const sw2_volt_sleep, diff --git a/src/PF1550.h b/src/PF1550.h index 12df37d..642e2b8 100644 --- a/src/PF1550.h +++ b/src/PF1550.h @@ -61,6 +61,14 @@ class PF1550 void configLDO2(Ldo2Voltage const ldo_2_volt, bool const enable, bool const enable_in_standby, bool const enable_in_sleep); void configLDO3(Ldo3Voltage const ldo_3_volt, bool const enable, bool const enable_in_standby, bool const enable_in_sleep); + void configSw1(Sw1Voltage const sw1_volt, + Sw1Voltage const sw1_volt_standby, + Sw1Voltage const sw1_volt_sleep, + Sw1CurrentLimit const sw1_current_limit, + bool const enable, + bool const enable_in_standby, + bool const enable_in_sleep); + void configSw2(Sw2Voltage const sw2_volt, Sw2Voltage const sw2_volt_standby, Sw2Voltage const sw2_volt_sleep, diff --git a/src/PF1550/PF1550_Control.cpp b/src/PF1550/PF1550_Control.cpp index f78b536..dec157b 100644 --- a/src/PF1550/PF1550_Control.cpp +++ b/src/PF1550/PF1550_Control.cpp @@ -118,6 +118,41 @@ void PF1550_Control::turnLDO3Off(Ldo3Mode const mode) _io.clrBit(Register::PMIC_LDO3_CTRL, static_cast(mode)); } +void PF1550_Control::setSw1Voltage(Sw1Voltage const sw1_volt) +{ + writeReg(Register::PMIC_SW1_VOLT, static_cast(sw1_volt)); +} + +void PF1550_Control::setSw1VoltageStandby(Sw1Voltage const sw1_volt_standby) +{ + writeReg(Register::PMIC_SW1_STBY_VOLT, static_cast(sw1_volt_standby)); +} + +void PF1550_Control::setSw1VoltageSleep(Sw1Voltage const sw1_volt_sleep) +{ + writeReg(Register::PMIC_SW1_SLP_VOLT, static_cast(sw1_volt_sleep)); +} + +void PF1550_Control::setSw1CurrentLimit(Sw1CurrentLimit const sw1_current_limit) +{ + uint8_t sw1_ctrl1_reg; + _io.readRegister(Register::PMIC_SW1_CTRL1, &sw1_ctrl1_reg); + sw1_ctrl1_reg &= ~REG_SW1_CTRL1_SW1_ILIM_mask; + sw1_ctrl1_reg |= static_cast(sw1_current_limit); + + writeReg(Register::PMIC_SW1_CTRL1, sw1_ctrl1_reg); +} + +void PF1550_Control::turnSw1On(Sw1Mode const mode) +{ + _io.setBit(Register::PMIC_SW1_CTRL, static_cast(mode)); +} + +void PF1550_Control::turnSw1Off(Sw1Mode const mode) +{ + _io.clrBit(Register::PMIC_SW1_CTRL, static_cast(mode)); +} + void PF1550_Control::setSw2Voltage(Sw2Voltage const sw2_volt) { writeReg(Register::PMIC_SW2_VOLT, static_cast(sw2_volt)); diff --git a/src/PF1550/PF1550_Control.h b/src/PF1550/PF1550_Control.h index 1c63558..81a36ae 100644 --- a/src/PF1550/PF1550_Control.h +++ b/src/PF1550/PF1550_Control.h @@ -65,6 +65,14 @@ class PF1550_Control void turnLDO3On (Ldo3Mode const mode); void turnLDO3Off (Ldo3Mode const mode); + /* SW1 Configuration ********************************************************/ + void setSw1Voltage (Sw1Voltage const sw1_volt); + void setSw1VoltageStandby(Sw1Voltage const sw1_volt_standby); + void setSw1VoltageSleep (Sw1Voltage const sw1_volt_sleep); + void setSw1CurrentLimit (Sw1CurrentLimit const sw1_current_limit); + void turnSw1On (Sw1Mode const mode); + void turnSw1Off (Sw1Mode const mode); + /* SW2 Configuration ********************************************************/ void setSw2Voltage (Sw2Voltage const sw2_volt); void setSw2VoltageStandby(Sw2Voltage const sw2_volt_standby); diff --git a/src/PF1550/PF1550_Defines.h b/src/PF1550/PF1550_Defines.h index 67a536b..a0aa484 100644 --- a/src/PF1550/PF1550_Defines.h +++ b/src/PF1550/PF1550_Defines.h @@ -33,6 +33,14 @@ #define REG_INT_CATEGORY_TEMP_INT_bp (6) #define REG_INT_CATEGORY_MISC_INT_bp (7) +/* SW1_CTRL1 ******************************************************************/ +#define REG_SW1_CTRL1_SW1_ILIM_mask (0x03) + +/* SW1_CTRL *******************************************************************/ +#define REG_SW1_CTRL_SW1_EN_bp (0) +#define REG_SW1_CTRL_SW1_STBY_EN_bp (1) +#define REG_SW1_CTRL_SW1_OMODE_bp (2) + /* SW2_CTRL *******************************************************************/ #define REG_SW2_CTRL_SW2_EN_bp (0) #define REG_SW2_CTRL_SW2_STBY_EN_bp (1) diff --git a/src/PF1550/PF1550_Types.h b/src/PF1550/PF1550_Types.h index da41553..9d25f9f 100644 --- a/src/PF1550/PF1550_Types.h +++ b/src/PF1550/PF1550_Types.h @@ -219,6 +219,37 @@ enum class IInputCurrentLimit : uint8_t I_1500_mA = (0x14 << 3), }; +enum class Sw1Voltage : uint8_t +{ + /* Output voltage with DVS disabled (OTP_SWx_DVS_SEL = 1). + * This is necessary because otherwise we won't reach the + * voltages required by Envie H747/C33 which is 3V1/3V3 for SW1. + */ + V_1_10 = 0x00, + V_1_20 = 0x01, + V_1_35 = 0x02, + V_1_50 = 0x03, + V_1_80 = 0x04, + V_2_50 = 0x05, + V_3_00 = 0x06, + V_3_30 = 0x07, +}; + +enum class Sw1CurrentLimit : uint8_t +{ + I_1_0_A = 0x00, + I_1_2_A = 0x01, + I_1_5_A = 0x02, + I_2_0_A = 0x03, +}; + +enum class Sw1Mode : uint8_t +{ + Normal = REG_SW1_CTRL_SW1_EN_bp, + Standby = REG_SW1_CTRL_SW1_STBY_EN_bp, + Sleep = REG_SW1_CTRL_SW1_OMODE_bp, +}; + enum class Sw2Voltage : uint8_t { /* Output voltage with DVS disabled (OTP_SWx_DVS_SEL = 1). From 4b68e61adfd18e35a4af31088cacf419ff270c10 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 30 Mar 2023 10:28:32 +0200 Subject: [PATCH 2/5] Visibly warn of the dangers of using this API. --- src/PF1550.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PF1550.h b/src/PF1550.h index 642e2b8..d0f7253 100644 --- a/src/PF1550.h +++ b/src/PF1550.h @@ -67,7 +67,7 @@ class PF1550 Sw1CurrentLimit const sw1_current_limit, bool const enable, bool const enable_in_standby, - bool const enable_in_sleep); + bool const enable_in_sleep) __attribute__ ((error("Erroneus usage of this API can cause board damage."))); void configSw2(Sw2Voltage const sw2_volt, Sw2Voltage const sw2_volt_standby, From c6e1bd49e349843946e15035491ce15966fa7a38 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 30 Mar 2023 10:30:38 +0200 Subject: [PATCH 3/5] Fix spelling mistake. --- src/PF1550.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PF1550.h b/src/PF1550.h index d0f7253..a7e1b2c 100644 --- a/src/PF1550.h +++ b/src/PF1550.h @@ -67,7 +67,7 @@ class PF1550 Sw1CurrentLimit const sw1_current_limit, bool const enable, bool const enable_in_standby, - bool const enable_in_sleep) __attribute__ ((error("Erroneus usage of this API can cause board damage."))); + bool const enable_in_sleep) __attribute__ ((error("Erroneous usage of this API can cause board damage."))); void configSw2(Sw2Voltage const sw2_volt, Sw2Voltage const sw2_volt_standby, From 30672ae846f5eaaa4bbb9d7cfa2e66b494b90751 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 30 Mar 2023 10:44:58 +0200 Subject: [PATCH 4/5] Only enable error message for boards that are known critical, i.e. C33/H7/Nicla Vision. --- src/PF1550.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/PF1550.h b/src/PF1550.h index a7e1b2c..8342cef 100644 --- a/src/PF1550.h +++ b/src/PF1550.h @@ -67,7 +67,11 @@ class PF1550 Sw1CurrentLimit const sw1_current_limit, bool const enable, bool const enable_in_standby, - bool const enable_in_sleep) __attribute__ ((error("Erroneous usage of this API can cause board damage."))); + bool const enable_in_sleep) +#if defined(ARDUINO_PORTENTA_H33) || defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) || defined(ARDUINO_NICLA_VISION) + __attribute__ ((error("Erroneous usage of this API can cause board damage."))) +#endif + ; void configSw2(Sw2Voltage const sw2_volt, Sw2Voltage const sw2_volt_standby, From 4cc32a188b4a6eca8cca2d44af509484f6a2c25a Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 30 Mar 2023 10:57:02 +0200 Subject: [PATCH 5/5] On Portenta C33 only provide a warning of what's going to happen if turning off SW. --- src/PF1550.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/PF1550.h b/src/PF1550.h index 8342cef..460b171 100644 --- a/src/PF1550.h +++ b/src/PF1550.h @@ -68,8 +68,10 @@ class PF1550 bool const enable, bool const enable_in_standby, bool const enable_in_sleep) -#if defined(ARDUINO_PORTENTA_H33) || defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) || defined(ARDUINO_NICLA_VISION) +#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) || defined(ARDUINO_NICLA_VISION) __attribute__ ((error("Erroneous usage of this API can cause board damage."))) +#elif defined(ARDUINO_PORTENTA_H33) + __attribute__ ((warning("Using this API you can turn off ESP32 (WiFi), SE051 (Crypto) and Ethernet PHY. Proceed with caution."))) #endif ;