Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AP_BattMonitor/AP_BattMonitor_SMBus_Solo.cpp
Views: 1798
#include "AP_BattMonitor_config.h"12#if AP_BATTERY_SMBUS_SOLO_ENABLED34#include <AP_HAL/AP_HAL.h>5#include <AP_Common/AP_Common.h>6#include <AP_Math/AP_Math.h>7#include "AP_BattMonitor.h"8#include <utility>910#include "AP_BattMonitor_SMBus_Solo.h"1112#define BATTMONITOR_SMBUS_SOLO_CELL_VOLTAGE 0x28 // cell voltage register13#define BATTMONITOR_SMBUS_SOLO_CELL_VOLTAGE_EXT 0x29 // cell voltage register up to 6s14#define BATTMONITOR_SMBUS_SOLO_CURRENT 0x2a // current register15#define BATTMONITOR_SMBUS_SOLO_BUTTON_DEBOUNCE 6 // button held down for 5 intervals will cause a power off event16#define BATTMONITOR_SMBUS_SOLO_NUM_CELLS 4 // solo's battery pack is 4S17#define BATTMONITOR_SMBUS_SOLO_NUM_CELLS_EXT 6 // extended BMS supports up to 6s1819/*20* Other potentially useful registers, listed here for future use21* #define BATTMONITOR_SMBUS_SOLO_VOLTAGE 0x09 // voltage register22* #define BATTMONITOR_SMBUS_SOLO_BATTERY_STATUS 0x16 // battery status register including alarms23* #define BATTMONITOR_SMBUS_SOLO_DESIGN_CAPACITY 0x18 // design capacity register24* #define BATTMONITOR_SMBUS_SOLO_DESIGN_VOLTAGE 0x19 // design voltage register25* #define BATTMONITOR_SMBUS_SOLO_SERIALNUM 0x1c // serial number register26* #define BATTMONITOR_SMBUS_SOLO_MANUFACTURE_NAME 0x20 // manufacturer name27* #define BATTMONITOR_SMBUS_SOLO_DEVICE_NAME 0x21 // device name28* #define BATTMONITOR_SMBUS_SOLO_DEVICE_CHEMISTRY 0x22 // device chemistry29* #define BATTMONITOR_SMBUS_SOLO_MANUFACTURE_INFO 0x25 // manufacturer info including cell voltage30*/3132// Constructor33AP_BattMonitor_SMBus_Solo::AP_BattMonitor_SMBus_Solo(AP_BattMonitor &mon,34AP_BattMonitor::BattMonitor_State &mon_state,35AP_BattMonitor_Params ¶ms)36: AP_BattMonitor_SMBus(mon, mon_state, params, AP_BATTMONITOR_SMBUS_BUS_INTERNAL)37{38_pec_supported = true;39}4041void AP_BattMonitor_SMBus_Solo::timer()42{43uint8_t buff[12];44uint32_t tnow = AP_HAL::micros();454647// read cell voltages48if (!_use_extended && read_block(BATTMONITOR_SMBUS_SOLO_CELL_VOLTAGE, buff, 8)) {49float pack_voltage_mv = 0.0f;50for (uint8_t i = 0; i < BATTMONITOR_SMBUS_SOLO_NUM_CELLS; i++) {51uint16_t cell = buff[(i * 2) + 1] << 8 | buff[i * 2];52_state.cell_voltages.cells[i] = cell;53pack_voltage_mv += (float)cell;54}55_has_cell_voltages = true;5657// accumulate the pack voltage out of the total of the cells58// because the Solo's I2C bus is so noisy, it's worth not spending the59// time and bus bandwidth to request the pack voltage as a separate60// transaction61_state.voltage = pack_voltage_mv * 1e-3f;62_state.last_time_micros = tnow;63_state.healthy = true;64}656667// read extended cell voltages68if (read_block(BATTMONITOR_SMBUS_SOLO_CELL_VOLTAGE_EXT, buff, 12)) {69float pack_voltage_mv = 0.0f;70for (uint8_t i = 0; i < BATTMONITOR_SMBUS_SOLO_NUM_CELLS_EXT; i++) {71uint16_t cell = buff[(i * 2) + 1] << 8 | buff[i * 2];72_state.cell_voltages.cells[i] = cell;73pack_voltage_mv += (float)cell;74}75_has_cell_voltages = true;7677// accumulate the pack voltage out of the total of the cells78_state.voltage = pack_voltage_mv * 1e-3f;79_state.last_time_micros = tnow;80_state.healthy = true;81// stop requesting 4-cell packets.82_use_extended = true;83}8485// timeout after 5 seconds86if ((tnow - _state.last_time_micros) > AP_BATTMONITOR_SMBUS_TIMEOUT_MICROS) {87_state.healthy = false;88// do not attempt to ready any more data from battery89return;90}9192// read current93if (read_block(BATTMONITOR_SMBUS_SOLO_CURRENT, buff, 4) == 4) {94_state.current_amps = -(float)((int32_t)((uint32_t)buff[3]<<24 | (uint32_t)buff[2]<<16 | (uint32_t)buff[1]<<8 | (uint32_t)buff[0])) * 0.001f;95_state.last_time_micros = tnow;96}9798read_full_charge_capacity();99read_remaining_capacity();100101// read the button press indicator102if (read_block(BATTMONITOR_SMBUS_MANUFACTURE_DATA, buff, 6) == 6) {103bool pressed = (buff[1] >> 3) & 0x01;104105if (_button_press_count >= BATTMONITOR_SMBUS_SOLO_BUTTON_DEBOUNCE) {106// vehicle will power off, set state flag107_state.is_powering_off = true;108} else if (pressed) {109// battery will power off if the button is held110_button_press_count++;111} else {112// button released, reset counters113_button_press_count = 0;114}115}116117read_temp();118119read_serial_number();120121read_cycle_count();122}123124#endif // AP_BATTERY_SMBUS_SOLO_ENABLED125126127