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.
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
Studiouint16_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
Studiouint16_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
Studiouint16_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
Studiouint16_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
Studiouint16_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
Studiouint16_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
Studiouint16_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
Studiouint8_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
Studiovoid 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
Studiouint8_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
Studiouint8_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
Studiouint8_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
Studiouint8_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
Studiouint8_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
Studiouint8_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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiouint8_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
Studiovoid 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.
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_MAJOR | 3 | |
| TILE_POWER_L_1T_VERSION_MINOR | 2 | |
| TILE_POWER_L_1T_VERSION_PATCH | 1 | |
| BQ25150_I2C_ADDR_DEFAULT | 0x6B | |
| BQ25150_FLAG2_ADC_READY | 0x80 | FLAG2 bit7: ADC conversion completed (clear-on-read) |
| BQ25150_ADCCTRL0_RATE_1S | 0x80 | ADC_READ_RATE = every 1 s (battery mode) |
| BQ25150_ADCCTRL0_RATE_MANUAL | 0x00 | ADC_READ_RATE = manual (convert on CONV_START) |
| BQ25150_ADCCTRL0_CONV_START | 0x20 | bit5: trigger one ADC conversion |
| BQ25150_ADCCTRL0_COMP1_DEFAULT | 0x02 | ADC_COMP1[2:0] reset value |
| BQ25150_FLAG2_COMP1_ALARM | 0x40 | Comparator 1 threshold crossed |
| BQ25150_FLAG2_COMP2_ALARM | 0x20 | Comparator 2 threshold crossed |
| BQ25150_FLAG2_COMP3_ALARM | 0x10 | Comparator 3 threshold crossed |
| BQ25150_DEVICE_ID_DEFAULT | 0x20 | Expected DEVICE_ID register value. |

