PF1550 Driver
API reference
Loading...
Searching...
No Matches
pf1550_voltage_tables.hpp
Go to the documentation of this file.
1
21#pragma once
22
23#include <cstdint>
24
25#include "pf1550_registers.hpp"
26
27namespace pf1550 {
28
47constexpr uint16_t SwCodeToMillivolts(uint8_t code) noexcept {
48 constexpr uint16_t kTable[7] = {1100, 1200, 1350, 1500, 1800, 2500, 3000};
49 const uint8_t c = static_cast<uint8_t>(code & 0x3FU);
50 return c < 7U ? kTable[c] : 3300U;
51}
52
57constexpr uint16_t SwDvsCodeToMillivolts(uint8_t code) noexcept {
58 return static_cast<uint16_t>(600U + (static_cast<uint32_t>(code & 0x3FU) * 25U + 1U) / 2U);
59}
60
69constexpr uint8_t SwDvsMillivoltsToCode(uint16_t mv) noexcept {
70 for (uint8_t code = 0; code < 64U; ++code) {
71 if (SwDvsCodeToMillivolts(code) == mv) {
72 return code;
73 }
74 }
75 return 0xFFU;
76}
77
82constexpr uint16_t Sw3CodeToMillivolts(uint8_t code) noexcept {
83 return static_cast<uint16_t>(1800U + 100U * (code & 0x0FU));
84}
85
92constexpr uint8_t SwMillivoltsToCode(uint16_t mv) noexcept {
93 switch (mv) {
94 case 1100: return 0x00;
95 case 1200: return 0x01;
96 case 1350: return 0x02;
97 case 1500: return 0x03;
98 case 1800: return 0x04;
99 case 2500: return 0x05;
100 case 3000: return 0x06;
101 case 3300: return 0x07;
102 default: return 0xFFU;
103 }
104}
105
118constexpr uint16_t LdoCodeToMillivolts(uint8_t code, bool is_ldo2) noexcept {
119 const uint8_t c = static_cast<uint8_t>(code & 0x1FU);
120 if (is_ldo2) {
121 if (c <= 0x0FU) {
122 return static_cast<uint16_t>(1800U + 100U * c);
123 }
124 return 0U;
125 }
126 if (c <= 0x0FU) {
127 return static_cast<uint16_t>(750U + 50U * c);
128 }
129 return static_cast<uint16_t>(1800U + 100U * (c - 0x10U));
130}
131
158constexpr uint16_t VbusLimitRegToMilliamps(uint8_t reg_value) noexcept {
159 const uint8_t code = static_cast<uint8_t>((reg_value >> 3U) & 0x1FU);
160 // First 9 entries: 10, 15, 20, 25, 30, 35, 40, 45, 50 mA (5 mA step from 10).
161 if (code <= 0x08U) {
162 return static_cast<uint16_t>(10U + 5U * code);
163 }
164 // 0x09..0x0F: 100, 150, 200, 300, 400, 500, 600 mA.
165 switch (code) {
166 case 0x09: return 100;
167 case 0x0A: return 150;
168 case 0x0B: return 200;
169 case 0x0C: return 300;
170 case 0x0D: return 400;
171 case 0x0E: return 500;
172 case 0x0F: return 600;
173 case 0x10: return 700;
174 case 0x11: return 800;
175 case 0x12: return 900;
176 case 0x13: return 1000;
177 case 0x14: return 1500; // Portenta default
178 default: return 0; // codes 21..31 are reserved (Table 58)
179 }
180}
181
188constexpr uint8_t VbusLimitMilliampsToReg(uint16_t mA) noexcept {
189 uint8_t code = 0xFFU;
190 switch (mA) {
191 case 10: code = 0x00; break;
192 case 100: code = 0x09; break;
193 case 500: code = 0x0E; break;
194 case 1000: code = 0x13; break;
195 case 1500: code = 0x14; break; // Portenta default
196 }
197 return (code == 0xFFU) ? 0xFFU : static_cast<uint8_t>(code << 3U);
198}
199
209constexpr uint16_t SwCurrentLimitCodeToMilliamps(uint8_t code) noexcept {
210 switch (code & 0x03U) {
211 case 0: return 1000;
212 case 1: return 1200;
213 case 2: return 1500;
214 case 3: return 2000;
215 }
216 return 0;
217}
218
224constexpr PmicState DecodeStateInfo(uint8_t reg) noexcept {
225 switch (reg & 0x3FU) {
226 case 0b000000: return PmicState::Wait;
227 case 0b001100: return PmicState::Run;
228 case 0b001101: return PmicState::Standby;
229 case 0b001110: return PmicState::Sleep;
230 case 0b101011: return PmicState::RegsDisable;
231 default: return PmicState::Unknown;
232 }
233}
234
236constexpr ChargerState DecodeChargerSense(uint8_t reg) noexcept {
237 switch (reg & 0x0FU) {
238 case 0: return ChargerState::PreCharge;
239 case 1: return ChargerState::FastCC;
240 case 2: return ChargerState::FastCV;
241 case 3: return ChargerState::EndOfCharge;
242 case 4: return ChargerState::Done;
243 case 6: return ChargerState::TimerFault;
244 case 7: return ChargerState::ThermSuspend;
245 case 8: return ChargerState::Off;
246 case 9: return ChargerState::BatteryOv;
247 case 10: return ChargerState::TempShutdown;
248 case 12: return ChargerState::LinearOnly;
249 default: return ChargerState::Unknown;
250 }
251}
252
258static_assert(SwCodeToMillivolts(0x06) == 3000, "SW code 0x06 → 3.00 V (Portenta SW1 RUN)");
259static_assert(SwCodeToMillivolts(static_cast<uint8_t>(SwVoltageCode::V3_3)) == 3300,
260 "SwVoltageCode::V3_3 must decode to 3.30 V");
261static_assert(Sw3CodeToMillivolts(static_cast<uint8_t>(SwVoltageCode::V3_1)) == 3100,
262 "SW3 code 0x0D → 3.10 V (Table 37)");
263static_assert(SwCodeToMillivolts(0x0D) == 3300, "SW1/SW2 DVS-disabled: every code ≥ 7 is 3.30 V");
264static_assert(SwDvsCodeToMillivolts(0x00) == 600 && SwDvsCodeToMillivolts(0x3F) == 1388 &&
265 SwDvsCodeToMillivolts(0x20) == 1000,
266 "SW1/SW2 DVS-enabled: 0.6 V + 12.5 mV steps");
267static_assert(SwDvsMillivoltsToCode(1100) == 40 && SwDvsMillivoltsToCode(1388) == 0x3F &&
268 SwDvsMillivoltsToCode(1006) == 0xFFU,
269 "DVS encode is the inverse of SwDvsCodeToMillivolts");
270static_assert(Sw3CodeToMillivolts(0x0F) == 3300 && Sw3CodeToMillivolts(0x00) == 1800, "SW3 Table 37");
271static_assert(SwMillivoltsToCode(3300) == 0x07, "3300 mV round-trip → 0x07");
272static_assert(LdoCodeToMillivolts(static_cast<uint8_t>(LdoVoltageCode::V1_0), /*is_ldo2=*/false) == 1000,
273 "LDO1 code 0x05 → 1.0 V");
274static_assert(LdoCodeToMillivolts(static_cast<uint8_t>(LdoVoltageCode::V1_8), /*is_ldo2=*/true) == 1800,
275 "LDO2 code 0x00 → 1.8 V");
276static_assert(LdoCodeToMillivolts(static_cast<uint8_t>(LdoVoltageCode::V1_2), /*is_ldo2=*/false) == 1200,
277 "LDO3 code 0x09 → 1.2 V");
278static_assert(VbusLimitRegToMilliamps(0xA0) == 1500,
279 "Portenta sets 0xA0 (code 0x14) → 1500 mA per VBUS_IN_LIM_CNFG lookup");
280static_assert(VbusLimitMilliampsToReg(1500) == 0xA0,
281 "VbusLimitMilliampsToReg(1500) must round-trip to 0xA0");
282
283} // namespace pf1550
Definition pf1550.hpp:40
constexpr uint8_t SwMillivoltsToCode(uint16_t mv) noexcept
Build a 6-bit SW voltage code from millivolts (Portenta-verified codes).
Definition pf1550_voltage_tables.hpp:92
@ V1_2
1.200 V (LDO3)
@ V1_8
1.800 V (LDO2 — code 0)
@ V1_0
1.000 V (LDO1)
constexpr uint8_t SwDvsMillivoltsToCode(uint16_t mv) noexcept
Encode a DVS-enabled SW1 / SW2 voltage (Table 31, left column).
Definition pf1550_voltage_tables.hpp:69
constexpr ChargerState DecodeChargerSense(uint8_t reg) noexcept
Convert CHG_SNS (0x87) into a typed ChargerState.
Definition pf1550_voltage_tables.hpp:236
constexpr uint16_t VbusLimitRegToMilliamps(uint8_t reg_value) noexcept
Decode VBUS_IN_LIM_CNFG (absolute address 0x94) register byte to mA.
Definition pf1550_voltage_tables.hpp:158
constexpr uint16_t SwCodeToMillivolts(uint8_t code) noexcept
SW1 / SW2 output voltage, DVS disabled (OTP_SWx_DVS_SEL = 1).
Definition pf1550_voltage_tables.hpp:47
constexpr uint16_t LdoCodeToMillivolts(uint8_t code, bool is_ldo2) noexcept
Decode a 5-bit LDO voltage register field to millivolts.
Definition pf1550_voltage_tables.hpp:118
constexpr uint16_t SwDvsCodeToMillivolts(uint8_t code) noexcept
SW1 / SW2 output voltage, DVS enabled (OTP_SWx_DVS_SEL = 0): 0.6000 V + 12.5 mV × code (Table 31,...
Definition pf1550_voltage_tables.hpp:57
constexpr uint16_t Sw3CodeToMillivolts(uint8_t code) noexcept
SW3 output voltage (Table 37): 1.80 V + 100 mV × SW3_VOLT[3:0].
Definition pf1550_voltage_tables.hpp:82
PmicState
STATE_INFO[5:0] values (Reg 0x67) describing the PMIC state machine.
Definition pf1550_registers.hpp:226
@ Wait
Wait / start-up before regulators are sequenced.
@ RegsDisable
REGS_DISABLE — all regulators off (post PWRON long-press).
@ Sleep
SLEEP / LPSR — minimal regulators.
@ Standby
STANDBY — standby-enabled regulators only.
@ Run
RUN — all OTP-sequenced regulators enabled.
ChargerState
CHG_SNS[3:0] values (Reg 0x87) describing the charger sub-state.
Definition pf1550_registers.hpp:236
@ LinearOnly
Linear-only mode, no charge.
@ TempShutdown
Off because TJ > TSHDN.
@ FastCC
Fast-charge constant-current.
@ ThermSuspend
Thermistor suspend.
@ PreCharge
Precharge mode (V_BATT < V_PRECHG.LB).
@ EndOfCharge
End-of-charge (I_BAT = I_EOC).
@ Off
Input invalid or charger disabled.
@ BatteryOv
Battery overvoltage.
@ TimerFault
Timer fault.
@ Done
Done — battery full.
@ FastCV
Fast-charge constant-voltage.
constexpr uint8_t VbusLimitMilliampsToReg(uint16_t mA) noexcept
Encode mA → VBUS_IN_LIM_CNFG (0x94) register byte (bits 7:3).
Definition pf1550_voltage_tables.hpp:188
@ V3_1
SW3 Table 37 code for 3.100 V (SW3 is OTP-loaded, read-only; SW1/SW2 decode 0x0D as 3....
@ V3_3
3.300 V (SW2 RUN on Portenta — carrier +3V3)
constexpr PmicState DecodeStateInfo(uint8_t reg) noexcept
Convert STATE_INFO (0x67) full byte into a typed PmicState.
Definition pf1550_voltage_tables.hpp:224
constexpr uint16_t SwCurrentLimitCodeToMilliamps(uint8_t code) noexcept
Decode the SW3_CTRL1[1:0] (or SW1/SW2_CTRL1) current limit field.
Definition pf1550_voltage_tables.hpp:209
NXP PF1550 family I2C register map, bit-field constants, and OTP keys.