batt_smbus.h
11.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
/****************************************************************************
*
* Copyright (c) 2012-2018 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @file batt_smbus.h
*
* Header for a battery monitor connected via SMBus (I2C).
* Designed for BQ40Z50-R1/R2 or BQ40Z80
*
* @author Jacob Dahl <dahl.jakejacob@gmail.com>
* @author Alex Klimaj <alexklimaj@gmail.com>
* @author Bazooka Joe <BazookaJoe1900@gmail.com>
*/
#pragma once
#include <ecl/geo/geo.h>
#include <lib/drivers/smbus/SMBus.hpp>
#include <mathlib/mathlib.h>
#include <perf/perf_counter.h>
#include <px4_platform_common/module.h>
#include <px4_platform_common/param.h>
#include <px4_platform_common/getopt.h>
#include <px4_platform_common/i2c_spi_buses.h>
#include <uORB/topics/battery_status.h>
#include <board_config.h>
using namespace time_literals;
#define BATT_SMBUS_MEASUREMENT_INTERVAL_US 100_ms ///< time in microseconds, measure at 10Hz
#define MAC_DATA_BUFFER_SIZE 32
#define BATT_CELL_VOLTAGE_THRESHOLD_RTL 0.5f ///< Threshold in volts to RTL if cells are imbalanced
#define BATT_CELL_VOLTAGE_THRESHOLD_FAILED 1.5f ///< Threshold in volts to Land if cells are imbalanced
#define BATT_CURRENT_UNDERVOLTAGE_THRESHOLD 5.0f ///< Threshold in amps to disable undervoltage protection
#define BATT_VOLTAGE_UNDERVOLTAGE_THRESHOLD 3.4f ///< Threshold in volts to re-enable undervoltage protection
#define BATT_SMBUS_ADDR 0x0B ///< Default 7 bit address I2C address. 8 bit = 0x16
#define BATT_SMBUS_TEMP 0x08 ///< temperature register
#define BATT_SMBUS_VOLTAGE 0x09 ///< voltage register
#define BATT_SMBUS_CURRENT 0x0A ///< current register
#define BATT_SMBUS_AVERAGE_CURRENT 0x0B ///< average current register
#define BATT_SMBUS_MAX_ERROR 0x0C ///< max error
#define BATT_SMBUS_RELATIVE_SOC 0x0D ///< Relative State Of Charge
#define BATT_SMBUS_ABSOLUTE_SOC 0x0E ///< Absolute State of charge
#define BATT_SMBUS_REMAINING_CAPACITY 0x0F ///< predicted remaining battery capacity as a percentage
#define BATT_SMBUS_FULL_CHARGE_CAPACITY 0x10 ///< capacity when fully charged
#define BATT_SMBUS_RUN_TIME_TO_EMPTY 0x11 ///< predicted remaining battery capacity based on the present rate of discharge in min
#define BATT_SMBUS_AVERAGE_TIME_TO_EMPTY 0x12 ///< predicted remaining battery capacity based on the present rate of discharge in min
#define BATT_SMBUS_CYCLE_COUNT 0x17 ///< number of cycles the battery has experienced
#define BATT_SMBUS_DESIGN_CAPACITY 0x18 ///< design capacity register
#define BATT_SMBUS_DESIGN_VOLTAGE 0x19 ///< design voltage register
#define BATT_SMBUS_MANUFACTURER_NAME 0x20 ///< manufacturer name
#define BATT_SMBUS_MANUFACTURER_NAME_SIZE 21 ///< manufacturer name data size
#define BATT_SMBUS_MANUFACTURE_DATE 0x1B ///< manufacture date register
#define BATT_SMBUS_SERIAL_NUMBER 0x1C ///< serial number register
#define BATT_SMBUS_BQ40Z50_CELL_4_VOLTAGE 0x3C
#define BATT_SMBUS_BQ40Z50_CELL_3_VOLTAGE 0x3D
#define BATT_SMBUS_BQ40Z50_CELL_2_VOLTAGE 0x3E
#define BATT_SMBUS_BQ40Z50_CELL_1_VOLTAGE 0x3F
#define BATT_SMBUS_BQ40Z80_CELL_7_VOLTAGE 0x3C
#define BATT_SMBUS_BQ40Z80_CELL_6_VOLTAGE 0x3D
#define BATT_SMBUS_BQ40Z80_CELL_5_VOLTAGE 0x3E
#define BATT_SMBUS_BQ40Z80_CELL_4_VOLTAGE 0x3F
#define BATT_SMBUS_STATE_OF_HEALTH 0x4F ///< State of Health. The SOH information of the battery in percentage of Design Capacity
#define BATT_SMBUS_MANUFACTURER_ACCESS 0x00
#define BATT_SMBUS_MANUFACTURER_DATA 0x23
#define BATT_SMBUS_MANUFACTURER_BLOCK_ACCESS 0x44
#define BATT_SMBUS_SECURITY_KEYS 0x0035
#define BATT_SMBUS_LIFETIME_FLUSH 0x002E
#define BATT_SMBUS_LIFETIME_BLOCK_ONE 0x0060
#define BATT_SMBUS_ENABLED_PROTECTIONS_A_ADDRESS 0x4938
#define BATT_SMBUS_SEAL 0x0030
#define BATT_SMBUS_DASTATUS1 0x0071
#define BATT_SMBUS_DASTATUS2 0x0072
#define BATT_SMBUS_DASTATUS3 0x007B
#define BATT_SMBUS_ENABLED_PROTECTIONS_A_DEFAULT 0xcf
#define BATT_SMBUS_ENABLED_PROTECTIONS_A_CUV_DISABLED 0xce
enum class SMBUS_DEVICE_TYPE {
UNDEFINED = 0,
BQ40Z50 = 1,
BQ40Z80 = 2,
};
class BATT_SMBUS : public I2CSPIDriver<BATT_SMBUS>
{
public:
BATT_SMBUS(I2CSPIBusOption bus_option, const int bus, SMBus *interface);
~BATT_SMBUS();
static I2CSPIDriverBase *instantiate(const BusCLIArguments &cli, const BusInstanceIterator &iterator,
int runtime_instance);
static void print_usage();
friend SMBus;
void RunImpl();
void custom_method(const BusCLIArguments &cli) override;
/**
* @brief Reads data from flash.
* @param address The address to start the read from.
* @param data The returned data.
* @return Returns PX4_OK on success, PX4_ERROR on failure.
*/
int dataflash_read(const uint16_t address, void *data, const unsigned length);
/**
* @brief Writes data to flash.
* @param address The start address of the write.
* @param data The data to be written.
* @param length The number of bytes being written.
* @return Returns PX4_OK on success, PX4_ERROR on failure.
*/
int dataflash_write(const uint16_t address, void *data, const unsigned length);
/**
* @brief Read info from battery on startup.
* @return Returns PX4_OK on success, PX4_ERROR on failure.
*/
int get_startup_info();
/**
* @brief Performs a ManufacturerBlockAccess() read command.
* @param cmd_code The command code.
* @param data The returned data.
* @param length The number of bytes being written.
* @return Returns PX4_OK on success, PX4_ERROR on failure.
*/
int manufacturer_read(const uint16_t cmd_code, void *data, const unsigned length);
/**
* @brief Performs a ManufacturerBlockAccess() write command.
* @param cmd_code The command code.
* @param data The sent data.
* @param length The number of bytes being written.
* @return Returns PX4_OK on success, PX4_ERROR on failure.
*/
int manufacturer_write(const uint16_t cmd_code, void *data, const unsigned length);
/**
* @brief Unseals the battery to allow writing to restricted flash.
* @return Returns PX4_OK on success, PX4_ERROR on failure.
*/
int unseal();
/**
* @brief Seals the battery to disallow writing to restricted flash.
* @return Returns PX4_OK on success, PX4_ERROR on failure.
*/
int seal();
/**
* @brief This command flushes the RAM Lifetime Data to data flash to help streamline evaluation testing.
* @return Returns PX4_OK on success, PX4_ERROR on failure.
*/
int lifetime_data_flush();
/**
* @brief Reads the lifetime data from block 1.
* @return Returns PX4_OK on success, PX4_ERROR on failure.
*/
int lifetime_read_block_one();
/**
* @brief Reads the cell voltages.
* @return Returns PX4_OK on success or associated read error code on failure.
*/
int get_cell_voltages();
/**
* @brief Enables or disables the cell under voltage protection emergency shut off.
*/
void set_undervoltage_protection(float average_current);
void suspend();
void resume();
private:
SMBus *_interface;
SMBUS_DEVICE_TYPE _device_type{SMBUS_DEVICE_TYPE::UNDEFINED};
perf_counter_t _cycle{perf_alloc(PC_ELAPSED, "batt_smbus_cycle")};
static const uint8_t MAX_NUM_OF_CELLS = 7;
float _cell_voltages[MAX_NUM_OF_CELLS] {};
float _max_cell_voltage_delta{0};
float _min_cell_voltage{0};
float _pack_power{0};
float _pack_average_power{0};
/** @param _last_report Last published report, used for test(). */
battery_status_s _last_report{};
/** @param _batt_topic uORB battery topic. */
orb_advert_t _batt_topic{nullptr};
/** @param _cell_count Number of series cell. */
uint8_t _cell_count{0};
/** @param _batt_capacity Battery design capacity in mAh (0 means unknown). */
uint16_t _batt_capacity{0};
/** @param _batt_startup_capacity Battery remaining capacity in mAh on startup. */
uint16_t _batt_startup_capacity{0};
/** @param _cycle_count The number of cycles the battery has experienced. */
uint16_t _cycle_count{0};
/** @param _serial_number Serial number register. */
uint16_t _serial_number{0};
/** @param _crit_thr Critical battery threshold param. */
float _crit_thr{0.f};
/** @param _emergency_thr Emergency battery threshold param. */
float _emergency_thr{0.f};
/** @param _low_thr Low battery threshold param. */
float _low_thr{0.f};
/** @parama _c_mult Capacity/current multiplier param */
float _c_mult{0.f};
/** @param _manufacturer_name Name of the battery manufacturer. */
char _manufacturer_name[BATT_SMBUS_MANUFACTURER_NAME_SIZE + 1] {}; // Plus one for terminator
/** @param _manufacture_date Date of the battery manufacturing. */
uint16_t _manufacture_date{0};
/** @param _state_of_health state of health as read on connection */
float _state_of_health{0.f};
/** @param _lifetime_max_delta_cell_voltage Max lifetime delta of the battery cells */
float _lifetime_max_delta_cell_voltage{0.f};
/** @param _cell_undervoltage_protection_status 0 if protection disabled, 1 if enabled */
uint8_t _cell_undervoltage_protection_status{1};
BATT_SMBUS(const BATT_SMBUS &) = delete;
BATT_SMBUS operator=(const BATT_SMBUS &) = delete;
};