Skip to content

Commit 1190a80

Browse files
committed
AP_BattMonitor: TIBQ provides cell voltages
1 parent a25534b commit 1190a80

File tree

2 files changed

+52
-24
lines changed

2 files changed

+52
-24
lines changed

libraries/AP_BattMonitor/AP_BattMonitor_TIBQ76952.cpp

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ extern const AP_HAL::HAL& hal;
4646
#define DISABLE_TS1
4747
#define DISABLE_TS3
4848

49+
#define CELL_COUNT 3
50+
4951
// Expected device IDs
5052
#define DEVICE_ID_TIBQ7695 0x7695
5153

@@ -146,6 +148,12 @@ bool AP_BattMonitor_TIBQ76952::configure() const
146148
sub_command(TIBQ769x2_SLEEP_DISABLE);
147149
hal.scheduler->delay_microseconds(10000);
148150

151+
// Clear any remaining permanent failure alerts
152+
direct_command(TIBQ769x2_PFAlertA, 0xFF, WRITE);
153+
direct_command(TIBQ769x2_PFAlertB, 0xFF, WRITE);
154+
direct_command(TIBQ769x2_PFAlertC, 0xFF, WRITE);
155+
direct_command(TIBQ769x2_PFAlertD, 0xFF, WRITE);
156+
149157
// enable FETs so we can switch between charging and discharging
150158
sub_command(TIBQ769x2_FET_ENABLE);
151159

@@ -190,7 +198,7 @@ bool AP_BattMonitor_TIBQ76952::configure() const
190198

191199
// 'VCell Mode' - Enable 16 cells - 0x9304
192200
// Writing 0x0000 sets the default of 16 cells, but we'll calculate based on actual cell count
193-
uint16_t vcell_mode = 0xFFFF; // Enable all 16 cells by default
201+
uint16_t vcell_mode = (1 << CELL_COUNT) - 1;
194202
set_register(TIBQ769x2_VCellMode, vcell_mode, 2);
195203

196204
#if defined(DISABLE_PROTECTION_A)
@@ -267,10 +275,7 @@ void AP_BattMonitor_TIBQ76952::read(void)
267275
_state.last_time_micros = tnow;
268276
*/
269277
_state.healthy = true;
270-
_state.voltage = accumulate.voltage;
271-
_state.current_amps = accumulate.current;
272-
_state.temperature = accumulate.temp;
273-
_state.last_time_micros = AP_HAL::micros();
278+
_state.voltage = accumulate.voltage / accumulate.count;
274279

275280
// debug toggle 1st LED on each read (10hz)
276281
// hal.gpio->toggle(HAL_GPIO_PIN_BMS_LED1);
@@ -398,7 +403,7 @@ uint8_t AP_BattMonitor_TIBQ76952::checksum(const uint8_t *data, uint8_t len) con
398403

399404
bool AP_BattMonitor_TIBQ76952::sub_command(uint16_t command) const
400405
{
401-
printf("BQ76952: sub_command called - cmd=0x%04X\n", command);
406+
//printf("BQ76952: sub_command called - cmd=0x%04X\n", command);
402407
uint8_t tx_buffer[2] = {0,0};
403408
tx_buffer[0] = command & 0xFF;
404409
tx_buffer[1] = (command >> 8) & 0xFF;
@@ -408,7 +413,7 @@ bool AP_BattMonitor_TIBQ76952::sub_command(uint16_t command) const
408413

409414
bool AP_BattMonitor_TIBQ76952::sub_command(uint16_t command, uint16_t data, SubcommandType type, uint8_t *rx_data, uint8_t rx_len) const
410415
{
411-
printf("BQ76952: sub_command called - cmd=0x%04X, type=%d\n", command, (int)type);
416+
//printf("BQ76952: sub_command called - cmd=0x%04X, type=%d\n", command, (int)type);
412417

413418
uint8_t tx_reg[4] = {0};
414419
uint8_t tx_buffer[2] = {0};
@@ -485,14 +490,19 @@ bool AP_BattMonitor_TIBQ76952::sub_command(uint16_t command, uint16_t data, Subc
485490

486491
bool AP_BattMonitor_TIBQ76952::direct_command(uint16_t command, uint16_t data, SubcommandType type, uint8_t *rx_data, uint8_t rx_len) const
487492
{
488-
printf("BQ76952: direct_command called - cmd=0x%04X, data=0x%04X, type=%d\n", command, data, (int)type);
493+
//printf("BQ76952: direct_command called - cmd=0x%04X, data=0x%04X, type=%d\n", command, data, (int)type);
494+
495+
// sanity check read buffer
496+
if (type == READ && rx_data == nullptr) {
497+
return false;
498+
}
489499

490500
uint8_t tx_buffer[2] = {0, 0};
491501
tx_buffer[0] = data & 0xFF;
492502
tx_buffer[1] = (data >> 8) & 0xFF;
493503

494504
if (type == READ) {
495-
read_register(command, tx_buffer, rx_len);
505+
read_register(command, rx_data, rx_len);
496506
} else if (type == WRITE) {
497507
write_register(command, tx_buffer, rx_len);
498508
}
@@ -578,8 +588,11 @@ uint32_t AP_BattMonitor_TIBQ76952::read_hv_version(void) const
578588

579589
uint16_t AP_BattMonitor_TIBQ76952::read_voltage(uint8_t command) const
580590
{
581-
if (command != TIBQ769x2_StackVoltage && command != TIBQ769x2_PACKPinVoltage && command != TIBQ769x2_LDPinVoltage &&
591+
if (command != TIBQ769x2_StackVoltage &&
592+
command != TIBQ769x2_PACKPinVoltage &&
593+
command != TIBQ769x2_LDPinVoltage &&
582594
(command < TIBQ769x2_Cell1Voltage || command > TIBQ769x2_Cell16Voltage)) {
595+
printf("BQ76952: Invalid voltage command: 0x%02X\n", command);
583596
return 0;
584597
}
585598
uint8_t rx_data[2];
@@ -590,6 +603,7 @@ uint16_t AP_BattMonitor_TIBQ76952::read_voltage(uint8_t command) const
590603
return 10 * (rx_data[1] << 8 | rx_data[0]);
591604
}
592605
}
606+
printf("BQ76952: Failed to read voltage: 0x%02X\n", command);
593607
return 0;
594608
}
595609

@@ -605,8 +619,8 @@ uint16_t AP_BattMonitor_TIBQ76952::read_alarm_status(void) const
605619
void AP_BattMonitor_TIBQ76952::alarm_status_update(void)
606620
{
607621
uint16_t alarm_status = read_alarm_status();
608-
/*printf("BQ76952: Alarm status: 0x%04X\n", alarm_status);
609-
if (alarm_status & 0x8000) {
622+
printf("BQ76952: Alarm status: 0x%04X\n", alarm_status);
623+
/*if (alarm_status & 0x8000) {
610624
printf("BQ76952: Alarm status protection triggered\n");
611625
}
612626
if (alarm_status & 0x4000) {
@@ -631,13 +645,26 @@ void AP_BattMonitor_TIBQ76952::alarm_status_update(void)
631645
printf("cell_voltage[%d]: %d mV\n", i, cell_voltages[i]);
632646
}*/
633647

648+
// read voltage
649+
WITH_SEMAPHORE(accumulate.sem);
650+
uint16_t pack_voltage_mv = read_voltage(TIBQ769x2_PACKPinVoltage);
651+
uint16_t stack_voltage_mv = read_voltage(TIBQ769x2_StackVoltage);
652+
uint16_t ld_voltage_mv = read_voltage(TIBQ769x2_LDPinVoltage);
653+
printf("pack_voltage: %f mV\n", pack_voltage_mv);
654+
printf("stack_voltage: %f mV\n", stack_voltage_mv);
655+
printf("ld_voltage: %f mV\n", ld_voltage_mv);
656+
657+
uint16_t cell_voltage_mv[CELL_COUNT];
658+
uint32_t cell_voltage_sum_mv = 0;
659+
for (uint8_t i = 0; i < CELL_COUNT; i++) {
660+
cell_voltage_mv[i] = read_voltage(TIBQ769x2_Cell1Voltage + i*2);
661+
printf("cell_voltage[%d]: %d mV\n", i, cell_voltage_mv[i]);
662+
cell_voltage_sum_mv += cell_voltage_mv[i];
663+
_state.cell_voltages.cells[i] = cell_voltage_mv[i];
664+
}
665+
accumulate.voltage += cell_voltage_sum_mv * 0.001;
666+
accumulate.count++;
634667
}
635-
// read voltage
636-
WITH_SEMAPHORE(accumulate.sem);
637-
uint16_t pack_voltage_mv = read_voltage(TIBQ769x2_PACKPinVoltage);
638-
printf("pack_voltage: %f mV\n", pack_voltage_mv);
639-
accumulate.voltage = pack_voltage_mv * 0.001;
640-
accumulate.count = 1;
641668

642669
/*if (alarm_status & 0x0001) {
643670
printf("BQ76952: Alarm status wakened from SLEEP mode\n");
@@ -682,7 +709,7 @@ uint16_t AP_BattMonitor_TIBQ76952::read_permanent_fail_status_D(void) const
682709

683710
void AP_BattMonitor_TIBQ76952::permanent_fail_status_update(void) const
684711
{
685-
uint16_t status_A = read_permanent_fail_status_A();
712+
/*uint16_t status_A = read_permanent_fail_status_A();
686713
uint16_t status_B = read_permanent_fail_status_B();
687714
uint16_t status_C = read_permanent_fail_status_C();
688715
uint16_t status_D = read_permanent_fail_status_D();
@@ -691,6 +718,7 @@ void AP_BattMonitor_TIBQ76952::permanent_fail_status_update(void) const
691718
printf("BQ76952: Permanent Fail Status B: 0x%04X\n", status_B);
692719
printf("BQ76952: Permanent Fail Status C: 0x%04X\n", status_C);
693720
printf("BQ76952: Permanent Fail Status D: 0x%04X\n", status_D);
721+
*/
694722
}
695723

696724
uint16_t AP_BattMonitor_TIBQ76952::read_battery_status(void) const
@@ -704,7 +732,7 @@ uint16_t AP_BattMonitor_TIBQ76952::read_battery_status(void) const
704732

705733
void AP_BattMonitor_TIBQ76952::battery_status_update(void) const
706734
{
707-
uint16_t battery_status = read_battery_status();
735+
/*uint16_t battery_status = read_battery_status();
708736
printf("BQ76952: Battery status: 0x%04X\n", battery_status);
709737
if (battery_status & 0x8000) {
710738
printf("BQ76952: Battery status: in sleep mode\n");
@@ -723,7 +751,7 @@ void AP_BattMonitor_TIBQ76952::battery_status_update(void) const
723751
}
724752
if (battery_status & 0x0200) {
725753
printf("BQ76952: Battery status: fuse pin inactive\n");
726-
}
754+
}*/
727755
}
728756

729757
#endif // AP_BATTERY_TIBQ76952_ENABLED

libraries/AP_BattMonitor/AP_BattMonitor_TIBQ76952.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,9 +430,9 @@ class AP_BattMonitor_TIBQ76952 : public AP_BattMonitor_Backend
430430
AP_BattMonitor::BattMonitor_State &mon_state,
431431
AP_BattMonitor_Params &params);
432432

433-
bool has_cell_voltages() const override { return false; } // TODO: BQ76952 can read individual cells
434-
bool has_temperature() const override { return true; } // TODO: BQ76952 has temperature sensors
435-
bool has_current() const override { return true; } // For now, only voltage implemented
433+
bool has_cell_voltages() const override { return true; } // TODO: BQ76952 can read individual cells
434+
bool has_temperature() const override { return false; } // TODO: BQ76952 has temperature sensors
435+
bool has_current() const override { return false; } // For now, only voltage implemented
436436
bool get_cycle_count(uint16_t &cycles) const override { return false; }
437437

438438
void init(void) override;

0 commit comments

Comments
 (0)