Configuration¶
What you can configure, where: board profiles, run-time rail settings, the SW1 / SW2 code table, interrupt masks and the build.
The snippets are compiled by the host CI from tests/docs/configuration.cpp.
Where configuration lives¶
| Layer | Where | Changes |
|---|---|---|
| OTP | Inside the PF1550 | Start-up sequence and set points; fixed on programmed parts, empty on A0EP |
| Profile | A profiles::RegisterWrite table |
Everything your board needs after power-up, in order |
| Run time | Set*() and WriteRegister() calls |
One register at a time |
| Driver | SetSwDvsEnabled(), the constructor address |
How the driver decodes and addresses, not the chip |
Write your own profile¶
#include "pf1550_profiles.hpp"
constexpr std::array<pf1550::profiles::RegisterWrite, 4> kMyBoardProfile = {{
{0x4F, 0x0F, 0}, // LDO2_VOLT: 3.3 V (Table 43)
{0x52, 0x10, 0}, // LDO3_VOLT: 1.8 V (Table 41)
{0x53, 0x0F, 0}, // LDO3_CTRL: on in RUN, STANDBY and SLEEP, low power
{0x50, 0x0F, 1000}, // LDO2_CTRL last, then wait 1 ms
}};
bool apply_my_board(pf1550::PF1550<MyI2c>& pmic) {
return pmic.ApplyProfile(kMyBoardProfile);
}
Each entry is {reg, value, delay_us}: the register address, the byte, and how long to wait after writing it
(0 for none). The driver writes them in order and stops at the first failure, so put a rail's set point before its
enable and a supply before the rails it feeds. The waits go through your port's DelayUs(); a port that does not
define it skips them.
Rules worth following in a profile:
- Write a rail's voltage register before its control register.
- Leave out SW voltage registers the part treats as read-only: SW3's always, SW1's and SW2's when DVS is disabled (Rails and OTP).
- Setting
LDOx_LS_EN(bit 4 ofLDO1_CTRL/LDO3_CTRL) turns the LDO into a load switch; the data sheet does not allow clearing it again.
Run-time settings¶
| Setting | Call | Register |
|---|---|---|
| SW1 / SW2 RUN set point (DVS-enabled bucks only) | SetSwVoltageMv(n, mv), SetSwVoltage(n, SwVoltageCode) |
SWn_VOLT |
| LDO1 / LDO2 / LDO3 set point | SetLdoVoltage(n, LdoVoltageCode) |
LDOn_VOLT |
| VBUS input current limit | SetVbusCurrentLimitMa(10 / 100 / 500 / 1000 / 1500) |
VBUS_INLIM_CNFG (0x94) |
| Rail enables per mode | WriteRegister(Register::Sw2Ctrl, SwCtrlBits::kEn | ...) |
SWn_CTRL, LDOn_CTRL |
| Buck current limit | WriteRegister(Register::Sw3Ctrl1, 0..3) |
SWn_CTRL1 bits 1:0 |
| STANDBY polarity and delay | WriteRegister(Register::PwrCtrl0, ...) |
PWRCTRL0 (0x58) |
| Interrupt masks | SetInterruptMaskAll(bool), or WriteRegister(Register::LdoIntMask0, ...) per group |
*_INT_MASK* |
Declare the SW1 / SW2 code table¶
// SW1 on this part runs from the DVS table (0.6 V + 12.5 mV per code): decode it that way.
pmic.SetSwDvsEnabled(1, true);
pf1550::DiagnosticSnapshot snap{};
return pmic.ReadDiagnosticSnapshot(snap);
SetSwDvsEnabled(n, enabled) decides how the snapshot turns SW1_VOLT and SW2_VOLT into millivolts and whether
SetSwVoltage() / SetSwVoltageMv() may write them; it writes nothing itself. Set it to what the part's
OTP_SWx_DVS_SEL says. The default (both disabled) matches the Portenta H7.
Address¶
The constructor's second argument is the 7-bit address, 0x08 by default. A part whose OTP selects another address
(0x09 to 0x0F) needs it there; I2C_ADDR (0x68) shows which one the part uses.
Build options¶
| Option | Default | Effect |
|---|---|---|
HF_PF1550_ENABLE_WARNINGS |
OFF |
-Wall -Wextra -Wpedantic on targets that link the driver |
HF_PF1550_BUILD_TESTS |
OFF |
Host unit tests and the documentation snippets (Testing and CI) |
HF_PF1550_VERSION_MAJOR / MINOR / PATCH |
in cmake/hf_pf1550_build_settings.cmake |
Written into pf1550_version.h; GetDriverVersion() returns it |
The ESP32 examples add their own Kconfig options (I2C pins and speed, profile choice, strap GPIOs); they are listed on External provisioning.