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.
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.
| Setting | Tier | Values | Default | Function |
|---|---|---|---|---|
| Charge current | basic | 2 to 500 mA | 80 | set_charge_current_ma(ma) |
| Input current limit | basic | 50 to 600 mA | 100 | set_input_current_limit_ma(ma) |
| Charge the battery | basic | on / off | on | charger_enable(on) |
| Charge to | advanced | 3.6 to 4.6 V | 4200 | set_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
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.
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.
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.
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.
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.
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). 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
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).
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.
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.
- 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: 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
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.
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.
- 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.
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.
- 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 (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
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.
- mv
- [3600..4600] mV Target battery voltage in millivolts.
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.
- ma
- [2..77] mA Target pre-charge current (38 mA max below 318 mA fast charge).
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 %.
- pct
- [0..31] % Termination current as % of ICHG (0 = disabled).
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)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
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. 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
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; 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
Studiovoid 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
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
- [2200..3000] mV Desired UVLO.
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)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
Studiovoid 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
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 (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
Studiovoid 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
Studiouint8_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
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.
- reg
- Register address
- value
- Value to write
Driver gaps · 2
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 | 3 | |
| TILE_POWER_L_1T_VERSION_PATCH | 0 | |
| 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. |

