BERGSONNE

Power.L.1T

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

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

Vibe Settings

What Studio’s Vibe interface lets you change on this tile, in plain language or from the tile inspector. Each one is an argument of a driver function below, so the same setting is available from Blocks, the DSL and C. Basic settings are shown by default; advanced ones sit behind the inspector’s Advanced toggle.

SettingTierValuesDefaultFunction
Charge currentbasic2 to 500 mA80set_charge_current_ma(ma)
Input current limitbasic50 to 600 mA100set_input_current_limit_ma(ma)
Charge the batterybasicon / offoncharger_enable(on)
Charge toadvanced3.6 to 4.6 V4200set_charge_voltage_mv(mv)

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 charge defaults (80 mA fast charge, 18.75 mA pre-charge, 4.20 V regulation, 2.6 V battery UVLO, TS on, 6 h safety timer) and clears the ship-mode request. Input limit, termination, LDO and charger-enable are left as the chip holds them. Pass cfg=NULL for defaults. On battery alone, LP (pad 2) must be high for this to find the chip (I²C is off in low-power mode).

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.

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.

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.

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.

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.

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). On Power-L-1T-b TS is a fixed 5 kΩ to ground (no thermistor), so this reads a constant ~400 mV (5 kΩ x 80 µA bias); it is not a temperature. Not measured in low-power mode.

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).

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.

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.

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: VIN good, not done, charger not disabled over I²C, PMID in AUTO, no UVLO / OVP / TS cold / TS hot. 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.

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.

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.

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.

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.

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 (rounded down). Values clamp to 500 mA. Crossing 318 mA also doubles the pre-charge step, so the pre-charge current doubles. Keep it at or below 1C for the cell fitted; there is no thermistor.

ma
[2..500] mA Target charge current in mA (below 2 the code is 0: no charge).

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.

mv
[3600..4600] mV Target battery voltage in millivolts.

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.

ma
[2..77] mA Target pre-charge current (38 mA max below 318 mA fast charge).

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 %.

pct
[0..31] % Termination current as % of ICHG (0 = disabled).

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)

ILIMCTRL is a discrete table: 50, 100, 150, 200, 300, 400, 500 or 600 mA. The largest level not above the request is used (50 mA floor). The chip powers up at 100 mA and init() leaves it there; when the load plus charge current reach the limit, charge current folds back first. The tile is rated for 500 mA on SUPPLY+.

ma
[50..600] mA Input current limit.

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. No practical effect on Power-L-1T-b: TS is a fixed 5 kΩ, not a thermistor.

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).

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).

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).

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 TS pin for charge control (monitoring continues). Default at init: enabled. No practical effect on Power-L-1T-b: TS is a fixed 5 kΩ, not a thermistor.

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 (rounded down). Values clamp to 600–3700 mV. changed when the EN_LS_LDO ... have disabled the output". This call writes the code without disabling the LDO, so a change made while V+ is on may not apply until the LDO is next disabled and enabled. V+ also drives the pad 1 ground switch gate (SI8806, VGS(th) up to 1.0 V, RDS(on) specified from 1.8 V): below ~1.8 V the downstream ground is not reliably closed.

mv
[600..3700] mV Target LDO voltage.

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; in load-switch mode it connects VINLS straight through. VINLS is tied to PMID on this tile, so pad 10 then carries PMID (VIN or VBAT, up to 5.5 V). 100 mA max either way (datasheet 7.3). The datasheet (8.3.5) requires the LDO to be disabled before the mode changes; this call does not do that.

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+) is pulled down by the chip, and because V+ feeds the pad 1 ground-switch gate, the downstream ground (pad 1) opens too: everything on this tile's output powers off. Default: enabled (chip reset value; init does not touch it).

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
[2200..3000] mV Desired UVLO.

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)

The timer stops a charge that has not terminated in time; with no battery thermistor on this tile it is one of the few backstops, so prefer not to choose OFF. Changing it while charging restarts it.

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)

BAT_ONLY stops charging. FLOAT and PULLDOWN disconnect PMID and turn the LDO off, so V+ (pad 10) and the pad 1 ground go off; the datasheet (8.3.6) says those modes exit only through I²C or an /MR reset, and /MR is not routed here. Do not use them if the Core runs from V+.

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 (flag when the measurement falls below the threshold).

comp
[1..3] Comparator index.
channel
power_l_1t_adc_channel_t to monitor.
threshold
Raw left-justified ADC threshold (top 12 bits used).

Advanced

tile_power_l_1t_enter_ship_mode

Studio
void tile_power_l_1t_enter_ship_mode(tile_t* tile)

Sets EN_SHIP_MODE. If SUPPLY+ is present the chip waits until it is removed, then disconnects the battery (10 nA typ). /MR is not routed on this tile, so the only way out is applying SUPPLY+ again; the output (pad 10, and the pad 1 ground) stays off until then. Registers return to reset values on exit. Use only for storage / shipping. re-insertion) to recover. Marked `section=advanced` for the same posture as other one-way / hardware-gated operations.

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.

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.

reg
Register address
value
Value to write

Driver gaps · 2

Chip capabilities this driver doesn’t expose yet.

advancedBattery NTC / JEITAHardware-gated (not a driver gap). The BQ25150 can pause or derate charging from a battery thermistor on TS, but Power-L-1T-b straps TS to a fixed 5 kΩ resistor (the datasheet's "TS not used" connection), which reads a constant ~0.40 V: always the normal band. Battery temperature is therefore NOT monitored; set_ts_* and set_ts_enabled have no practical effect. The chip's die thermal foldback (80 °C) still applies.
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_MINOR3
TILE_POWER_L_1T_VERSION_PATCH0
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.