BERGSONNE

Power.L.1T

Li-Ion charge controller driver for the Power.L.1T tile (rev a).

Embeds the Texas Instruments BQ25150, a single-cell Li-Ion charge controller with programmable 1.8 V LDO output and 12-bit ADC for battery and system monitoring.

Datasheet

Examples

Quick start

  #include "core_tiles.h"

  tile_t battery;
  tile_power_l_1t_init(core_tiles_pal(&core_i2c1), 0, &battery, NULL);
  if (tile_is_ready(&battery)) {
      tile_power_l_1t_set_charge_current_ma(&battery, 100);
      tile_power_l_1t_set_charge_voltage_mv(&battery, 4200);
      uint16_t vbat = tile_power_l_1t_get_vbat_mv(&battery);
      if (tile_power_l_1t_is_battery_low(&battery, 10)) {
          // go to sleep, save the cell
      }
  }

API reference

Initialization

tile_power_l_1t_find

uint8_t tile_power_l_1t_find(tiles_pal_t* hal, uint8_t instance)

Check whether a BQ25150 is present on the I2C bus.

hal
Platform HAL handle
instance
Instance index (0 = default, see mapping table)

Returns 1 if device ACKs, 0 otherwise

tile_power_l_1t_init

void tile_power_l_1t_init(tiles_pal_t* hal, uint8_t instance, tile_t* tile, const power_l_1t_cfg_t *cfg)

Verifies the device ID, disables the I²C watchdog (the chip otherwise resets all charge parameters every 50 s), enables all 6 ADC channels, configures sane charge defaults, and exits ship mode. Pass cfg=NULL for defaults.

hal
Platform HAL handle
instance
Instance index (0 = default, see mapping table)
tile
Pointer to tile handle (populated by this function)
cfg
Optional config, or NULL for defaults

Runtime

tile_power_l_1t_get_vbat_mv

Studio
uint16_t tile_power_l_1t_get_vbat_mv(tile_t* tile)

Replaces the deprecated raw-counts API; performs a 2-byte burst read to avoid torn samples.

tile
Initialised tile handle

Returns Battery voltage in mV (0–6000)

tile_power_l_1t_get_vin_mv

Studio
uint16_t tile_power_l_1t_get_vin_mv(tile_t* tile)

Read input (VIN) voltage from the ADC.

tile
Initialised tile handle

Returns VIN in mV (0–6000)

tile_power_l_1t_get_pmid_mv

Studio
uint16_t tile_power_l_1t_get_pmid_mv(tile_t* tile)

Read PMID (system rail) voltage from the ADC.

tile
Initialised tile handle

Returns PMID in mV (0–6000)

tile_power_l_1t_get_charge_current_ma

Studio
uint16_t tile_power_l_1t_get_charge_current_ma(tile_t* tile)

Scaled relative to the configured ICHG fast-charge limit; returns actual mA flowing into the cell.

tile
Initialised tile handle

Returns Charge current in mA (0–500)

tile_power_l_1t_get_input_current_ma

Studio
uint16_t tile_power_l_1t_get_input_current_ma(tile_t* tile)

Range scales with ILIMCTRL: ≤150 mA range gives 0–375 mA full scale; >150 mA range gives 0–750 mA full scale.

tile
Initialised tile handle

Returns Input current in mA (0–750)

tile_power_l_1t_get_ts_mv

Studio
uint16_t tile_power_l_1t_get_ts_mv(tile_t* tile)

Returns the millivolt reading on the TS pin (0–1200 mV). Convert to °C using the NTC's resistance/temperature curve in firmware — the chip doesn't expose temperature directly.

tile
Initialised tile handle

Returns TS voltage in mV (0–1200)

tile_power_l_1t_get_adcin_mv

Studio
uint16_t tile_power_l_1t_get_adcin_mv(tile_t* tile)

Optional auxiliary input (0–1.2 V range). Useful for monitoring an external sensor (e.g., separate NTC, voltage divider).

tile
Initialised tile handle

Returns ADCIN voltage in mV (0–1200)

tile_power_l_1t_get_percent

Studio
uint8_t tile_power_l_1t_get_percent(tile_t* tile)

Derived from VBAT using a linear curve (3000 mV = 0%, 4200 mV = 100%). Coarse — a real fuel gauge would integrate Coulombs.

tile
Initialised tile handle

Returns Battery percentage (0–100)

tile_power_l_1t_get_charge_status

Studio
void tile_power_l_1t_get_charge_status(tile_t* tile, power_l_1t_status_t *out)

Reads STAT0/STAT1 (live state) and FLAG0/FLAG1/FLAG3 (event flags which clear on read) into the supplied struct. Call once per polling cycle — multiple reads will lose flag transitions.

tile
Initialised tile handle
out
Caller-allocated status struct (zeroed on entry)

tile_power_l_1t_is_charging

Studio
uint8_t tile_power_l_1t_is_charging(tile_t* tile)

Convenience over @ref tile_power_l_1t_get_charge_status — returns the `charging` field as a bool. Note this reads (and clears) FLAG3 as a side effect; if you also poll the full status struct, alternate with this rather than calling both per cycle.

tile
Initialised tile handle

Returns 1 if charging, 0 otherwise

tile_power_l_1t_is_charge_done

Studio
uint8_t tile_power_l_1t_is_charge_done(tile_t* tile)

Returns the `charge_done` bit from STAT0 — set when the cell reaches VBATREG and current tapers below the termination threshold.

tile
Initialised tile handle

Returns 1 if charge cycle has finished, 0 otherwise

tile_power_l_1t_is_battery_low

Studio
uint8_t tile_power_l_1t_is_battery_low(tile_t* tile, uint8_t threshold_pct)

The classic "go to sleep" trigger. Equivalent to `get_percent() < threshold_pct`. Quick: one ADC read.

tile
Initialised tile handle
threshold_pct
Threshold in percent (0–100)

Returns 1 if battery percent is strictly below threshold, 0 otherwise

tile_power_l_1t_is_powered

Studio
uint8_t tile_power_l_1t_is_powered(tile_t* tile)

Returns the `vin_pgood` bit — true when VIN is in the valid operating range (3.4–5.5 V). Use to branch behaviour between "plugged in" and "battery only" modes.

tile
Initialised tile handle

Returns 1 if VIN is good, 0 if running off battery only

tile_power_l_1t_wait_for_charge_done

Studio
uint8_t tile_power_l_1t_wait_for_charge_done(tile_t* tile, uint32_t timeout_ms)

Polls the charge_done bit at a 1 s cadence (charge state changes on the order of minutes for a typical cell — faster polling wastes MCU cycles and bus bandwidth without finer-grained answers). Returns 1 immediately if the cycle is already finished.

tile
Initialised tile handle
timeout_ms
Maximum time to wait, in milliseconds

Returns 1 if charge_done was observed, 0 on timeout

tile_power_l_1t_get_adc_comparators

Studio
uint8_t tile_power_l_1t_get_adc_comparators(tile_t* tile)

Read (and clear) the ADC comparator alarm flags.

Returns BQ25150_FLAG2_COMPn_ALARM bits that have tripped since last read.

Config

tile_power_l_1t_set_charge_current_ma

Studio
void tile_power_l_1t_set_charge_current_ma(tile_t* tile, uint16_t ma)

Programs ICHG_CTRL with the appropriate ICHARGE_RANGE bit so the resolution scales: ≤318 mA uses 1.25 mA steps, >318 mA uses 2.5 mA steps. Values clamp to 1.25–500 mA.

tile
Initialised tile handle
ma
Target charge current in mA (1.25–500)

tile_power_l_1t_set_charge_voltage_mv

Studio
void tile_power_l_1t_set_charge_voltage_mv(tile_t* tile, uint16_t mv)

VBATREG = 3600 + code × 10 mV. Values outside 3600–4600 mV clamp to that range. Use 4200 for typical Li-Ion, 3650 for LFP, 4350+ for high-voltage NMC variants.

tile
Initialised tile handle
mv
Target battery voltage in mV (3600–4600)

tile_power_l_1t_set_pre_charge_ma

Studio
void tile_power_l_1t_set_pre_charge_ma(tile_t* tile, uint8_t ma)

Pre-charge applies to deeply-discharged cells; usually 10–20 % of the fast-charge rate. Values clamp to 1.25–77.5 mA.

tile
Initialised tile handle
ma
Target pre-charge current in mA (1.25–77.5)

tile_power_l_1t_set_termination_percent

Studio
void tile_power_l_1t_set_termination_percent(tile_t* tile, uint8_t pct)

Charging ends when the cell's current draw drops below this threshold during the CV phase. 0 disables termination (charges continuously until VBATREG is reached). Values clamp to 1–31 %.

tile
Initialised tile handle
pct
Termination current as % of ICHG (0 = disabled, 1–31)

tile_power_l_1t_set_input_current_limit_ma

Studio
void tile_power_l_1t_set_input_current_limit_ma(tile_t* tile, uint16_t ma)

When the adapter can't supply more than this, charge current folds back to keep VIN above the DPM threshold. Values clamp to 5–500 mA in 5 mA steps.

tile
Initialised tile handle
ma
Input current limit in mA (5–500)

tile_power_l_1t_set_ts_cold

Studio
void tile_power_l_1t_set_ts_cold(tile_t* tile, uint8_t code)

The TS register codes are bit-positional (1, 2, 4, 8, 16, ... encode multiples of 4.688 mV up to 600 mV). Datasheet section 8.5.1.49–52 describes the exact mapping; users tuning JEITA thresholds should consult the chip's NTC profile guide.

tile
Initialised tile handle
code
Raw 8-bit TS_COLD register value

tile_power_l_1t_set_ts_cool

Studio
void tile_power_l_1t_set_ts_cool(tile_t* tile, uint8_t code)

Set the cool-temperature TS threshold (raw register value).

tile
Initialised tile handle
code
Raw 8-bit TS_COOL register value

tile_power_l_1t_set_ts_warm

Studio
void tile_power_l_1t_set_ts_warm(tile_t* tile, uint8_t code)

Set the warm-temperature TS threshold (raw register value).

tile
Initialised tile handle
code
Raw 8-bit TS_WARM register value

tile_power_l_1t_set_ts_hot

Studio
void tile_power_l_1t_set_ts_hot(tile_t* tile, uint8_t code)

Set the hot-temperature TS threshold (raw register value).

tile
Initialised tile handle
code
Raw 8-bit TS_HOT register value

tile_power_l_1t_set_ts_enabled

Studio
void tile_power_l_1t_set_ts_enabled(tile_t* tile, uint8_t enabled)

When disabled, the chip ignores the NTC entirely (charging proceeds regardless of battery temperature). Default at init: enabled.

tile
Initialised tile handle
enabled
1 = TS thermal protection on, 0 = off

tile_power_l_1t_set_ldo_voltage_mv

Studio
void tile_power_l_1t_set_ldo_voltage_mv(tile_t* tile, uint16_t mv)

VLDO = 600 + code × 100 mV. Values clamp to 600–3700 mV. Tile design gates this rail to a fixed 1.8 V at the connector — changing the LDO voltage breaks downstream peripherals expecting 1.8 V on pad 10. Useful for non-default tile variants or load-switch-mode pass-through use.

tile
Initialised tile handle
mv
Target LDO voltage in mV (600–3700)

tile_power_l_1t_set_ldo_mode

Studio
void tile_power_l_1t_set_ldo_mode(tile_t* tile, power_l_1t_ldo_mode_t mode)

In LDO mode the chip regulates pad 10 to the configured voltage (10 mA max). In load-switch mode it pass-through-connects PMID via a FET (up to 150 mA, but VINLS must be tied to the desired supply on the tile PCB).

tile
Initialised tile handle
mode
LDO mode (POWER_L_1T_LDO_MODE_LDO or _LOAD_SWITCH)

tile_power_l_1t_set_ldo_enabled

Studio
void tile_power_l_1t_set_ldo_enabled(tile_t* tile, uint8_t enabled)

When disabled, pad 10 (V+) goes high-impedance — downstream rails expecting 1.8 V will drop. Default at init: enabled (chip default).

tile
Initialised tile handle
enabled
1 = output on, 0 = output off (high-Z)

tile_power_l_1t_charger_enable

Studio
void tile_power_l_1t_charger_enable(tile_t* tile, uint8_t on)

Sets/clears ICCTRL2.CHARGER_DISABLE. Note the hardware /CE pin still gates charging: when /CE is high, charging is off regardless of this bit; this only takes effect when /CE is held low (the tile's default).

on
1 = allow charging, 0 = disable charging.

tile_power_l_1t_set_battery_uvlo_mv

Studio
void tile_power_l_1t_set_battery_uvlo_mv(tile_t* tile, uint16_t mv)

BUVLO[2:0]: 3.0 / 2.8 / 2.6 / 2.4 / 2.2 V (nearest below `mv` is chosen); deeper cutoff trades battery life for runtime. Other BUVLO fields (precharge threshold, OCP limit) are preserved.

mv
Desired UVLO in mV (2200-3000).

tile_power_l_1t_set_safety_timer

Studio
void tile_power_l_1t_set_safety_timer(tile_t* tile, power_l_1t_safety_timer_t mode)

Set the charge safety-timer limit.

mode
power_l_1t_safety_timer_t (3h / 6h / 12h / off).

tile_power_l_1t_set_pmid_mode

Studio
void tile_power_l_1t_set_pmid_mode(tile_t* tile, power_l_1t_pmid_mode_t mode)

Set the PMID power-path mode (ICCTRL1[1:0]).

mode
power_l_1t_pmid_mode_t.

tile_power_l_1t_set_adc_comparator

Studio
void tile_power_l_1t_set_adc_comparator(tile_t* tile, uint8_t comp, power_l_1t_adc_channel_t channel, uint16_t threshold)

Routes ADC channel `channel` to comparator `comp` (1-3) and sets its 16-bit threshold (left-justified, same scale as the channel's ADC result). When the measurement crosses the threshold, the matching COMPn_ALARM bit latches in FLAG2 (read via get_adc_comparators()). Pass channel = POWER_L_1T_ADC_CH_DISABLED to turn a comparator off. Note: the chip's above/below polarity bit (ADCALARM_ABOVE) is not exposed by this driver yet — the comparator uses its default sense.

comp
Comparator index 1-3.
channel
power_l_1t_adc_channel_t to monitor.
threshold
16-bit raw ADC threshold.

Advanced

tile_power_l_1t_enter_ship_mode

Studio
void tile_power_l_1t_enter_ship_mode(tile_t* tile)

Disconnects the battery internally; only an MR press or VIN insertion will wake the chip. Charge parameters reset to defaults on exit. Use only for long-term storage / end-of-line packaging. re-insertion) to recover. Marked `section=advanced` for the same posture as other one-way / hardware-gated operations.

tile
Initialised tile handle

tile_power_l_1t_read_status

Studio
uint8_t tile_power_l_1t_read_status(tile_t* tile, uint8_t reg)

Read any 8-bit BQ25150 register.

tile
Initialised tile handle
reg
Register address

Returns 8-bit register value

tile_power_l_1t_write_reg

Studio
void tile_power_l_1t_write_reg(tile_t* tile, uint8_t reg, uint8_t value)

Escape hatch for advanced users wanting to touch registers the driver doesn't expose. Caller is responsible for not bricking the chip — most useful registers have typed setters above.

tile
Initialised tile handle
reg
Register address
value
Value to write

Driver gaps · 1

Chip capabilities this driver doesn’t expose yet.

advancedMR button + INT pin handlingThe chip's MR (push-button) and INT (interrupt) pins aren't routed to tile pads on the current revision — nothing for a Core GPIO to attach to. Closing this gap requires a tile hardware revision that routes at least INT to a connector pad. Until then, MASK0–3 / MRCTRL register writes have no external effect.

Enums

power_l_1t_safety_timer_t

Charge safety-timer limit (CHARGERCTRL0[2:1]).

POWER_L_1T_SAFETY_3H
3-hour fast-charge timer
POWER_L_1T_SAFETY_6H
6-hour (default)
POWER_L_1T_SAFETY_12H
12-hour
POWER_L_1T_SAFETY_OFF
disabled

power_l_1t_pmid_mode_t

PMID power-path mode (ICCTRL1[1:0]).

POWER_L_1T_PMID_AUTO
powered from BAT or VIN (default)
POWER_L_1T_PMID_BAT_ONLY
forced from BAT even when VIN present
POWER_L_1T_PMID_FLOAT
disconnected, floating
POWER_L_1T_PMID_PULLDOWN
disconnected, pulled down

power_l_1t_adc_channel_t

ADC channel selector for the programmable comparators (ADC_COMPn).

POWER_L_1T_ADC_CH_DISABLED
POWER_L_1T_ADC_CH_ADCIN
POWER_L_1T_ADC_CH_TS
POWER_L_1T_ADC_CH_VBAT
POWER_L_1T_ADC_CH_ICHARGE
POWER_L_1T_ADC_CH_VIN
POWER_L_1T_ADC_CH_PMID
POWER_L_1T_ADC_CH_IIN

power_l_1t_ldo_mode_t

LDO output mode — regulated voltage vs pass-through load switch.

POWER_L_1T_LDO_MODE_LDO
Regulated LDO output
POWER_L_1T_LDO_MODE_LOAD_SWITCH
Pass-through load switch

Constants

TILE_POWER_L_1T_VERSION_MAJOR3
TILE_POWER_L_1T_VERSION_MINOR2
TILE_POWER_L_1T_VERSION_PATCH1
BQ25150_I2C_ADDR_DEFAULT0x6B
BQ25150_FLAG2_ADC_READY0x80FLAG2 bit7: ADC conversion completed (clear-on-read)
BQ25150_ADCCTRL0_RATE_1S0x80ADC_READ_RATE = every 1 s (battery mode)
BQ25150_ADCCTRL0_RATE_MANUAL0x00ADC_READ_RATE = manual (convert on CONV_START)
BQ25150_ADCCTRL0_CONV_START0x20bit5: trigger one ADC conversion
BQ25150_ADCCTRL0_COMP1_DEFAULT0x02ADC_COMP1[2:0] reset value
BQ25150_FLAG2_COMP1_ALARM0x40Comparator 1 threshold crossed
BQ25150_FLAG2_COMP2_ALARM0x20Comparator 2 threshold crossed
BQ25150_FLAG2_COMP3_ALARM0x10Comparator 3 threshold crossed
BQ25150_DEVICE_ID_DEFAULT0x20Expected DEVICE_ID register value.