CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/libraries/AP_BattMonitor/AP_BattMonitor_SMBus_NeoDesign.cpp
Views: 1798
1
#include "AP_BattMonitor_config.h"
2
3
#if AP_BATTERY_SMBUS_NEODESIGN_ENABLED
4
5
#include <AP_HAL/AP_HAL.h>
6
#include <AP_Common/AP_Common.h>
7
#include "AP_BattMonitor.h"
8
9
#include "AP_BattMonitor_SMBus_NeoDesign.h"
10
11
#define BATTMONITOR_ND_CELL_COUNT 0x5C // cell-count register
12
#define BATTMONITOR_ND_CELL_START 0x30 // first cell register
13
14
// Constructor
15
AP_BattMonitor_SMBus_NeoDesign::AP_BattMonitor_SMBus_NeoDesign(AP_BattMonitor &mon,
16
AP_BattMonitor::BattMonitor_State &mon_state,
17
AP_BattMonitor_Params &params)
18
: AP_BattMonitor_SMBus(mon, mon_state, params, AP_BATTMONITOR_SMBUS_BUS_INTERNAL)
19
{
20
_pec_supported = true;
21
}
22
23
void AP_BattMonitor_SMBus_NeoDesign::timer()
24
{
25
uint16_t data;
26
// Get the cell count once, it's not likely to change in flight
27
if (_cell_count == 0) {
28
if (!read_word(BATTMONITOR_ND_CELL_COUNT, data)) {
29
return; // something wrong, don't try anything else
30
}
31
// constrain maximum cellcount in case of i2c corruption
32
if (data > max_cell_count) {
33
_cell_count = max_cell_count;
34
} else {
35
_cell_count = data;
36
}
37
}
38
39
bool read_all_cells = true;
40
for(uint8_t i = 0; i < _cell_count; ++i) {
41
if(read_word(BATTMONITOR_ND_CELL_START + i, data)) {
42
_state.cell_voltages.cells[i] = data;
43
_has_cell_voltages = true;
44
} else {
45
read_all_cells = false;
46
}
47
}
48
49
const uint32_t tnow = AP_HAL::micros();
50
51
if (read_all_cells && (_cell_count > 0)) {
52
uint32_t summed = 0;
53
for (int i = 0; i < _cell_count; i++) {
54
summed += _state.cell_voltages.cells[i];
55
}
56
_state.voltage = (float)summed * 1e-3f;
57
_state.last_time_micros = tnow;
58
_state.healthy = true;
59
} else if (read_word(BATTMONITOR_SMBUS_VOLTAGE, data)) {
60
// fallback to the voltage register if we didn't manage to poll the cells
61
_state.voltage = (float)data * 1e-3f;
62
_state.last_time_micros = tnow;
63
_state.healthy = true;
64
}
65
66
// timeout after 5 seconds
67
if ((tnow - _state.last_time_micros) > AP_BATTMONITOR_SMBUS_TIMEOUT_MICROS) {
68
_state.healthy = false;
69
// do not attempt to read any more data from battery
70
return;
71
}
72
73
// read current (A)
74
if (read_word(BATTMONITOR_SMBUS_CURRENT, data)) {
75
_state.current_amps = -(float)((int16_t)data) * 1e-3f;
76
_state.last_time_micros = tnow;
77
}
78
79
read_full_charge_capacity();
80
read_remaining_capacity();
81
read_temp();
82
}
83
84
#endif // AP_BATTERY_SMBUS_NEODESIGN_ENABLED
85
86