PF1550 Driver
API reference
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | List of all members
pf1550::PF1550< BusType > Class Template Reference

CRTP-based PF1550 PMIC driver. More...

#include <pf1550.hpp>

Public Types

enum class  Error : uint16_t {
  None = 0 , I2cWrite = 1 << 0 , I2cRead = 1 << 1 , InvalidParam = 1 << 2 ,
  DeviceNotFound = 1 << 3 , NotInitialized = 1 << 4 , WrongDeviceId = 1 << 5 , ProfileApply = 1 << 6 ,
  DiagnosticRead = 1 << 7 , SelfTestFailed = 1 << 8
}
 Bitmask error codes accumulated in error_flags_. More...
 

Public Member Functions

 PF1550 (BusType *bus, uint8_t address=kDefaultI2cAddress) noexcept
 Construct a driver instance bound to a CRTP bus adapter.
 
bool EnsureInitialized () noexcept
 Idempotently initialise the bus and verify the device.
 
bool IsInitialized () const noexcept
 Idempotently initialise the bus and verify the device. — query without re-running the bus init.
 
uint8_t GetI2cAddress () const noexcept
 Currently configured 7-bit I²C address.
 
bool ReadDeviceId (uint8_t &id) noexcept
 Read DEVICE_ID (Reg 0x00).
 
bool VerifyDevice () noexcept
 Read DEVICE_ID and assert it matches kExpectedDeviceId.
 
bool ReadRegister (Register reg, uint8_t &value) noexcept
 Read any PF1550 register by enumerated address.
 
bool WriteRegister (Register reg, uint8_t value) noexcept
 Write any PF1550 register by enumerated address.
 
bool ApplyProfile (std::span< const profiles::RegisterWrite > profile) noexcept
 Apply an arbitrary profile (sequence of register writes).
 
bool ApplyPortentaH7DefaultProfile () noexcept
 Apply the legacy VFR-heritage Portenta H7 default profile.
 
bool ApplyPortentaH7CarrierProfile () noexcept
 Apply the Portenta-H7-on-carrier profile.
 
bool SetPowerMode (PowerMode mode) noexcept
 Drive the STANDBY strap pin to RUN or STANDBY.
 
bool SetUsbRails (bool vbus_en, bool otg_en) noexcept
 Drive USB_VBUS_EN and USB_OTG_EN straps (HIGH = enabled on Portenta).
 
bool ReadPmicStatus (uint8_t &status) noexcept
 Read STATE_INFO (Reg 0x67) and return the raw byte.
 
bool ReadPmicState (PmicState &state) noexcept
 Decoded variant of ReadPmicStatus.
 
bool ReadChargerState (ChargerState &state, uint8_t *raw_reg=nullptr) noexcept
 Read CHG_SNS (Reg 0x87) — charger sub-state. Returns decoded enum.
 
bool ReadOtpByte (uint8_t otp_addr, uint8_t &value) noexcept
 Read a single OTP byte via FMRADDR/FMRDATA indirection.
 
bool ReadOtpRegion (uint8_t *buffer, size_t len, uint8_t start=OtpRegion::kStart) noexcept
 Read a contiguous region of OTP memory (default: full 0x1C..0x36 range).
 
bool SetSwVoltage (uint8_t sw_index, SwVoltageCode run_code) noexcept
 Set the RUN voltage of SW1 or SW2 from a SwVoltageCode.
 
bool SetSwVoltageMv (uint8_t sw_index, uint16_t mv) noexcept
 Set the RUN voltage of a DVS-enabled SW1 or SW2 in millivolts.
 
bool SetLdoVoltage (uint8_t ldo_index, LdoVoltageCode code) noexcept
 Write LDOn_VOLT for n=1..3. Returns false if ldo_index is invalid.
 
bool SetVbusCurrentLimitMa (uint16_t limit_ma) noexcept
 Convenience: write VBUS_IN_LIM_CNFG (0x94) from a mA value.
 
bool ReadInterruptCategory (uint8_t &category) noexcept
 Read INT_CATEGORY (Reg 0x06).
 
bool ReadLatchedFaults (FaultFlags &faults) noexcept
 Read every category STAT register and aggregate latched faults.
 
bool ClearLatchedFaults () noexcept
 Write 0xFF to every category STAT register to clear all RW1C bits.
 
bool SetInterruptMaskAll (bool masked) noexcept
 Mask (1) or unmask (0) all interrupt categories at once.
 
bool ReadDiagnosticSnapshot (DiagnosticSnapshot &out) noexcept
 Build a full diagnostic snapshot (≈30 register reads).
 
bool RefreshStatusSnapshot (DiagnosticSnapshot &snap) noexcept
 Refresh only the status part of a snapshot (≈14 register reads).
 
bool RunPowerSelfTest (SelfTestResult &out) noexcept
 Boot-time self-test.
 
uint16_t GetErrorFlags () const noexcept
 Read all sticky error bits (see Error).
 
void ClearErrorFlags (uint16_t mask=0xFFFF) noexcept
 Clear sticky error bits matching mask.
 
void SetSwDvsEnabled (uint8_t sw_index, bool enabled) noexcept
 Declare the SW1 / SW2 voltage encoding the part's OTP selects.
 

Static Public Member Functions

static constexpr const char * GetDriverVersion () noexcept
 Driver version (string).
 

Detailed Description

template<typename BusType>
class pf1550::PF1550< BusType >

CRTP-based PF1550 PMIC driver.

Template Parameters
BusTypePlatform bus type inheriting from pf1550::BusInterface<BusType>. Must implement Write(addr, reg, data, len), Read(addr, reg, data, len), EnsureInitialized(), GpioSet(CtrlPin, GpioSignal), and DelayUs(uint32_t).
Thread-safety
The driver itself is not thread-safe by design — it expects the BusType adapter (or a host mutex wrapping it) to enforce single-writer access. Concurrent reads from another core are tolerated provided the bus adapter serialises I²C transactions.
Single-point-of-failure mitigation
See pf1550::FaultSeverityPortentaH7 — that mapping is the Portenta H7 MCU-on-SW3 eval tree. Other hosts supply their own severity table.

Member Enumeration Documentation

◆ Error

template<typename BusType >
enum class pf1550::PF1550::Error : uint16_t
strong

Bitmask error codes accumulated in error_flags_.

Enumerator
None 
I2cWrite 

Last I²C write transaction failed.

I2cRead 

Last I²C read transaction failed.

InvalidParam 

Caller-side argument validation failed.

DeviceNotFound 

DEVICE_ID read returned NACK / wrong address.

NotInitialized 

Called before EnsureInitialized() succeeded.

WrongDeviceId 

Returned DEVICE_ID ≠ kExpectedDeviceId (0x7C).

ProfileApply 

At least one write in the last applied profile failed.

DiagnosticRead 

One or more reads while building a snapshot failed.

SelfTestFailed 

RunPowerSelfTest() reported a non-Info severity.

Constructor & Destructor Documentation

◆ PF1550()

template<typename BusType >
pf1550::PF1550< BusType >::PF1550 ( BusType *  bus,
uint8_t  address = kDefaultI2cAddress 
)
noexcept

Construct a driver instance bound to a CRTP bus adapter.

Parameters
busPointer to a BusType instance (lifetime: longer than the driver). May be nullptr only for testing; all methods will then return false and set Error::InvalidParam.
address7-bit I²C address. Defaults to kDefaultI2cAddress.

Member Function Documentation

◆ ApplyPortentaH7CarrierProfile()

template<typename BusType >
bool pf1550::PF1550< BusType >::ApplyPortentaH7CarrierProfile ( )
noexcept

Apply the Portenta-H7-on-carrier profile.

Differences from the default:

  1. SW1 (+3V1SW) sequenced first — feeds LDO inputs on Portenta.
  2. SW2_CTRL = 0x0F — full enable including STANDBY (carrier +3V3 stable).
  3. SW1_CTRL = 0x0F — SW1 stays on in STANDBY and SLEEP as well.

◆ ApplyPortentaH7DefaultProfile()

template<typename BusType >
bool pf1550::PF1550< BusType >::ApplyPortentaH7DefaultProfile ( )
noexcept

Apply the legacy VFR-heritage Portenta H7 default profile.

◆ ApplyProfile()

template<typename BusType >
bool pf1550::PF1550< BusType >::ApplyProfile ( std::span< const profiles::RegisterWrite >  profile)
noexcept

Apply an arbitrary profile (sequence of register writes).

The profile is applied in order, observing each entry's delay_us setting. Used for the Portenta H7 default and carrier variants below, and for board-specific profiles in downstream projects.

Note
PF1550 state survives MCU reset — voltage changes typically require a full power cycle to take effect. Soft reset alone is insufficient.

◆ ClearErrorFlags()

template<typename BusType >
void pf1550::PF1550< BusType >::ClearErrorFlags ( uint16_t  mask = 0xFFFF)
inlinenoexcept

Clear sticky error bits matching mask.

◆ ClearLatchedFaults()

template<typename BusType >
bool pf1550::PF1550< BusType >::ClearLatchedFaults ( )
noexcept

Write 0xFF to every category STAT register to clear all RW1C bits.

Call after handling a fault to re-arm the interrupt path.

◆ EnsureInitialized()

template<typename BusType >
bool pf1550::PF1550< BusType >::EnsureInitialized ( )
noexcept

Idempotently initialise the bus and verify the device.

Calls bus_->EnsureInitialized(), then performs VerifyDevice. After success, subsequent calls are O(1) no-ops.

Returns
true if a PF1550-family device was found at the configured address.

◆ GetDriverVersion()

template<typename BusType >
static constexpr const char * pf1550::PF1550< BusType >::GetDriverVersion ( )
inlinestaticconstexprnoexcept

Driver version (string).

◆ GetErrorFlags()

template<typename BusType >
uint16_t pf1550::PF1550< BusType >::GetErrorFlags ( ) const
inlinenoexcept

Read all sticky error bits (see Error).

◆ GetI2cAddress()

template<typename BusType >
uint8_t pf1550::PF1550< BusType >::GetI2cAddress ( ) const
inlinenoexcept

Currently configured 7-bit I²C address.

◆ IsInitialized()

template<typename BusType >
bool pf1550::PF1550< BusType >::IsInitialized ( ) const
inlinenoexcept

Idempotently initialise the bus and verify the device. — query without re-running the bus init.

Calls bus_->EnsureInitialized(), then performs VerifyDevice. After success, subsequent calls are O(1) no-ops.

Returns
true if a PF1550-family device was found at the configured address. — query without re-running the bus init.

◆ ReadChargerState()

template<typename BusType >
bool pf1550::PF1550< BusType >::ReadChargerState ( ChargerState &  state,
uint8_t *  raw_reg = nullptr 
)
noexcept

Read CHG_SNS (Reg 0x87) — charger sub-state. Returns decoded enum.

◆ ReadDeviceId()

template<typename BusType >
bool pf1550::PF1550< BusType >::ReadDeviceId ( uint8_t &  id)
noexcept

Read DEVICE_ID (Reg 0x00).

Expected value: kExpectedDeviceId. Other family IDs cause Error::WrongDeviceId to be set.

◆ ReadDiagnosticSnapshot()

template<typename BusType >
bool pf1550::PF1550< BusType >::ReadDiagnosticSnapshot ( DiagnosticSnapshot &  out)
noexcept

Build a full diagnostic snapshot (≈30 register reads).

Safe to call from a periodic monitor thread. If any read fails, the snapshot is returned with read_ok = false and Error::DiagnosticRead is set; partial fields are still populated for forensic logging.

◆ ReadInterruptCategory()

template<typename BusType >
bool pf1550::PF1550< BusType >::ReadInterruptCategory ( uint8_t &  category)
noexcept

Read INT_CATEGORY (Reg 0x06).

Top-level summary of pending interrupt categories — useful for fast polling before reading individual STAT registers.

◆ ReadLatchedFaults()

template<typename BusType >
bool pf1550::PF1550< BusType >::ReadLatchedFaults ( FaultFlags &  faults)
noexcept

Read every category STAT register and aggregate latched faults.

Does not clear the STAT bits. Use ClearLatchedFaults for that.

◆ ReadOtpByte()

template<typename BusType >
bool pf1550::PF1550< BusType >::ReadOtpByte ( uint8_t  otp_addr,
uint8_t &  value 
)
noexcept

Read a single OTP byte via FMRADDR/FMRDATA indirection.

◆ ReadOtpRegion()

template<typename BusType >
bool pf1550::PF1550< BusType >::ReadOtpRegion ( uint8_t *  buffer,
size_t  len,
uint8_t  start = OtpRegion::kStart 
)
noexcept

Read a contiguous region of OTP memory (default: full 0x1C..0x36 range).

◆ ReadPmicState()

template<typename BusType >
bool pf1550::PF1550< BusType >::ReadPmicState ( PmicState &  state)
noexcept

Decoded variant of ReadPmicStatus.

◆ ReadPmicStatus()

template<typename BusType >
bool pf1550::PF1550< BusType >::ReadPmicStatus ( uint8_t &  status)
noexcept

Read STATE_INFO (Reg 0x67) and return the raw byte.

Use ReadPmicState for a decoded PmicState enumerator.

◆ ReadRegister()

template<typename BusType >
bool pf1550::PF1550< BusType >::ReadRegister ( Register  reg,
uint8_t &  value 
)
noexcept

Read any PF1550 register by enumerated address.

◆ RefreshStatusSnapshot()

template<typename BusType >
bool pf1550::PF1550< BusType >::RefreshStatusSnapshot ( DiagnosticSnapshot &  snap)
noexcept

Refresh only the status part of a snapshot (≈14 register reads).

Re-reads what can change without a register write: INT_CATEGORY, STATE_INFO, charger and VBUS sense, and the latched + live fault registers (with the per-rail fault marks). Identity, rail set points and enables and the VBUS input limit are kept from the last ReadDiagnosticSnapshot into snap — a monitor polling at 20 Hz does a full read now and then (say once a second) to catch a configuration change, and the status in between at half the bus time.

Parameters
[in,out]snapSnapshot from a previous full read.
Returns
true when every status read succeeded (sets read_ok).

◆ RunPowerSelfTest()

template<typename BusType >
bool pf1550::PF1550< BusType >::RunPowerSelfTest ( SelfTestResult &  out)
noexcept

Boot-time self-test.

Reads a fresh snapshot and classifies it against the Portenta-H7-carrier expectations (PMIC in RUN, all SW/LDO enabled, no MCU-affecting faults latched). Used by the SystemBootRecipe row.

◆ SetInterruptMaskAll()

template<typename BusType >
bool pf1550::PF1550< BusType >::SetInterruptMaskAll ( bool  masked)
noexcept

Mask (1) or unmask (0) all interrupt categories at once.

Parameters
maskedtrue = silence all interrupts (powers up like this); false = allow events to propagate to INTB.

◆ SetLdoVoltage()

template<typename BusType >
bool pf1550::PF1550< BusType >::SetLdoVoltage ( uint8_t  ldo_index,
LdoVoltageCode  code 
)
noexcept

Write LDOn_VOLT for n=1..3. Returns false if ldo_index is invalid.

◆ SetPowerMode()

template<typename BusType >
bool pf1550::PF1550< BusType >::SetPowerMode ( PowerMode  mode)
noexcept

Drive the STANDBY strap pin to RUN or STANDBY.

Only meaningful if the bus adapter wires CtrlPin::Standby to a real GPIO. STANDBY polarity follows the PF1550 STANDBYINV bit (RUN = LOW on Portenta).

◆ SetSwDvsEnabled()

template<typename BusType >
void pf1550::PF1550< BusType >::SetSwDvsEnabled ( uint8_t  sw_index,
bool  enabled 
)
inlinenoexcept

Declare the SW1 / SW2 voltage encoding the part's OTP selects.

Decides how the snapshot decodes SWx_VOLT and whether SetSwVoltage / SetSwVoltageMv may write it.

OTP_SWx_DVS_SEL decides between two tables (datasheet Table 31): DVS enabled 0.6–1.3875 V in 12.5 mV steps, DVS disabled an 8-point table up to 3.3 V. It lives in OTP (indirect access only), so the board declares it; the default is disabled (Portenta H7: SW1 3.0 V / SW2 3.3 V exist only in that table).

Parameters
sw_index1 or 2.

◆ SetSwVoltage()

template<typename BusType >
bool pf1550::PF1550< BusType >::SetSwVoltage ( uint8_t  sw_index,
SwVoltageCode  run_code 
)
noexcept

Set the RUN voltage of SW1 or SW2 from a SwVoltageCode.

SwVoltageCode values name DVS-disabled set points (Table 31, right column). SWx_VOLT is writable only when the buck runs with DVS enabled (declare it with SetSwDvsEnabled), so the driver converts the code's voltage to the DVS encoding (0.6 V + 12.5 mV × code) and writes that.

Returns
false with Error::InvalidParam, writing nothing, when sw_index is not 1..3, when the register is read-only (SW3 always, Table 37; SW1 / SW2 with DVS disabled, Table 31) or when the voltage is outside the DVS range (0.6 V to 1.3875 V).

◆ SetSwVoltageMv()

template<typename BusType >
bool pf1550::PF1550< BusType >::SetSwVoltageMv ( uint8_t  sw_index,
uint16_t  mv 
)
noexcept

Set the RUN voltage of a DVS-enabled SW1 or SW2 in millivolts.

Parameters
mvA value on the DVS grid: 600 + 12.5 × code, rounded to mV (see SwDvsMillivoltsToCode).
Returns
false with Error::InvalidParam under the same conditions as SetSwVoltage.

◆ SetUsbRails()

template<typename BusType >
bool pf1550::PF1550< BusType >::SetUsbRails ( bool  vbus_en,
bool  otg_en 
)
noexcept

Drive USB_VBUS_EN and USB_OTG_EN straps (HIGH = enabled on Portenta).

◆ SetVbusCurrentLimitMa()

template<typename BusType >
bool pf1550::PF1550< BusType >::SetVbusCurrentLimitMa ( uint16_t  limit_ma)
noexcept

Convenience: write VBUS_IN_LIM_CNFG (0x94) from a mA value.

◆ VerifyDevice()

template<typename BusType >
bool pf1550::PF1550< BusType >::VerifyDevice ( )
noexcept

Read DEVICE_ID and assert it matches kExpectedDeviceId.

Returns
true on a positive match; false on NACK or wrong ID.

◆ WriteRegister()

template<typename BusType >
bool pf1550::PF1550< BusType >::WriteRegister ( Register  reg,
uint8_t  value 
)
noexcept

Write any PF1550 register by enumerated address.


The documentation for this class was generated from the following files: