Analog Devices LTC4013 battery charger
The LTC4013 driver (drivers/power/battery/ltc4013.c) is a lower half of
the battery charger driver (include/nuttx/power/battery_charger.h) for the
Analog Devices LTC4013, a synchronous buck multi-chemistry battery charger
controller for lead-acid and Li-Ion batteries. It is enabled with
CONFIG_LTC4013, which needs CONFIG_BATTERY_CHARGER.
The chip has no digital interface. The driver controls it through four kinds of pins, which the board provides:
Pin |
Use |
|---|---|
|
Enable. It may also be an input UVLO, depending on the divider of the board. |
|
Three-state pins (low, high or floating) that select the charge algorithm. |
|
Open drain status outputs. |
|
Feedback of the battery voltage. The divider from the battery to this pin sets the charge voltage. |
Board interface
The board registers the charger with:
int ltc4013_register(const char *devpath,
const struct ltc4013_config_s *config);
and describes the hardware in struct ltc4013_config_s:
Field |
Description |
|---|---|
|
Programs the feedback network. Optional. See below. |
|
Resistors of a fixed divider, in ohms. Optional, only |
|
used without |
|
Limits of the charge voltage that the application may
request, in mV, 0 for none. They apply to the
|
|
Algorithm selected at registration. |
|
Drives |
|
Sets |
|
Reads |
|
Argument of the callbacks. |
enable, mode and stat are required. The callbacks are called from
the context of the caller of the upper half, never from an interrupt. They
must be provided by the board because the pins are the ones of its GPIO.
The charger is left disabled when it is registered. A board that must not
charge before the driver starts has to hold ENAB low by itself: the
default level of the pin depends on the board.
Charge voltage
The charge voltage is set by the divider from the battery to the FB pin
and by Vfb, the regulation voltage of that pin, which depends on the
algorithm (Table 1 of the datasheet). How the divider is changed is up to the
board, so the driver does not assume a topology:
int voltage(void *arg, int mv, int vfb_mv);
The driver calls it with the battery voltage that the application asked for
and the Vfb of the selected algorithm, and the board programs its network
(a digital potentiometer, a DAC, …) for them. For example, with a divider
of r_top from the battery to FB and r_bottom from FB to
ground, the voltage is:
Vbat = Vfb * (r_top + r_bottom) / r_bottom
The callback returns a negated errno value if the network cannot reach the
voltage, for example -EINVAL, and then it must leave the hardware as it
was. It is called again with the same voltage and the new Vfb when the
algorithm changes, so the battery voltage does not move.
If the board has no voltage callback the divider is fixed by the hardware.
BATIOC_VOLTAGE returns -ENOSYS and the charger may be enabled at any
time. If the board gives r_top and r_bottom, BATIOC_GET_VOLTAGE
reports the voltage that the divider programs with the selected algorithm (the
computation is done in 32 bits, so the sum of the two must stay below
1.7 Mohm); otherwise it returns -ENODATA.
A digital potentiometer has a wide tolerance of its end-to-end resistance, so
a voltage computed from its nominal value is not an absolute one. An
application that needs a precise voltage measures the battery and adjusts
BATIOC_VOLTAGE.
The LB pin (low battery) compares a voltage set by a resistor with the
FB pin, so the battery voltage it detects moves with the divider and
with the algorithm, like the charge voltage does.
Usage
The application chooses the charge profile, the driver provides the mechanisms:
BATIOC_OPERATEwithoperate_typeLTC4013_OPRTN_ALGOand the algorithm (enum ltc4013_algo_e) inu8[0]. The algorithms are the rows of Table 1 of the datasheet: Li-Ion, 2, 3 and 4 stages, with the normal or the wide voltage spread. Changing the algorithm changes the regulation voltage of theFBpin, so the driver programs the voltage again, and it is refused with-EBUSYwhile the charger is enabled.BATIOC_VOLTAGEwith the charge voltage in mV. It is the voltage of theVFLOATcolumn of Table 1, the one of the last stage of the algorithm (for the Li-Ion algorithms, the charge voltage). The absorption and equalization voltages follow from the same divider, in the proportions of the datasheet. It is checked againstv_minandv_maxand refused with-EINVALoutside of them, and also when the board cannot reach it. It may be changed while the charger is enabled.BATIOC_OPERATEwithBATIO_OPRTN_CHARGEandu8[0]nonzero to enable the charger, zero to disable it. When the voltage is set by the board, enabling is refused with-EINVALuntil a voltage has been set, because the network may hold any value after a reset.BATIOC_GET_VOLTAGEreturns the voltage that was last requested (or the one of a fixed divider, see above). It is the setpoint, not a measurement of the battery.BATIOC_STATEreadsSTAT0andSTAT1(Table 2 of the datasheet): both off isBATTERY_IDLE,STAT0aloneBATTERY_CHARGINGandSTAT1aloneBATTERY_FAULT. Both on is constant voltage for the Li-Ion and 2-stage algorithms (BATTERY_CHARGING) and float charging for the 3 and 4-stage ones (BATTERY_FULL).BATIOC_HEALTHreturnsBATTERY_HEALTH_UNSPEC_FAILfor the fault pattern of the status pins, which the chip uses both for a low battery and for a thermal shutdown, andBATTERY_HEALTH_GOODotherwise.BATIOC_ONLINEreports if the charger is enabled: the chip cannot tell if a battery is connected.
The charge current is set by the sense resistor of the board and the input
current by its input stage, so BATIOC_CURRENT and
BATIOC_INPUT_CURRENT return -ENOSYS, like BATIOC_CHIPID.