51 ScheduledWorkItem(MODULE_NAME,
px4::device_bus_to_wq(interface->get_device_id())),
90 const char *myoptarg =
nullptr;
92 while ((ch = px4_getopt(argc, argv,
"XTRIA", &myoptind, &myoptarg)) != EOF) {
124 SMBus *
interface = new SMBus(smbus_bus_options[i].busnum, BATT_SMBUS_ADDR);
127 int result = dev->get_startup_info();
129 if (result != PX4_OK) {
136 _task_id = task_id_is_work_queue;
145 PX4_WARN(
"Not found.");
176 new_report.
voltage_v = ((float)result) / 1000.0f;
182 new_report.
current_a = (-1.0f * ((float)(*(int16_t *)&result)) / 1000.0f);
188 float average_current = (-1.0f * ((float)(*(int16_t *)&result)) / 1000.0f);
216 new_report.
warning = battery_status_s::BATTERY_WARNING_CRITICAL;
222 new_report.
warning = battery_status_s::BATTERY_WARNING_NONE;
225 new_report.
warning = battery_status_s::BATTERY_WARNING_LOW;
228 new_report.
warning = battery_status_s::BATTERY_WARNING_CRITICAL;
231 new_report.
warning = battery_status_s::BATTERY_WARNING_EMERGENCY;
314 PX4_WARN(
"Disabled CUV");
317 PX4_WARN(
"Failed to disable CUV");
330 PX4_WARN(
"Enabled CUV");
333 PX4_WARN(
"Failed to enable CUV");
349 if (result != PX4_OK) {
369 tx_buf[0] = ((uint8_t *)&address)[0];
370 tx_buf[1] = ((uint8_t *)&address)[1];
371 memcpy(&tx_buf[2], data, length);
383 const unsigned name_length = 22;
387 char man_name[name_length] = {};
390 if (result != PX4_OK) {
391 PX4_WARN(
"Failed to get manufacturer name");
401 uint16_t remaining_cap;
404 uint16_t cycle_count;
423 PX4_WARN(
"Battery Damaged Will Not Fly. Lifetime max voltage difference: %4.2f",
429 PX4_WARN(
"Failed to flush lifetime data");
442 uint16_t serial_num = 0;
456 if (result != PX4_OK) {
466 uint8_t rx_buf[21] = {};
471 memcpy(man_name, rx_buf,
sizeof(rx_buf));
489 uint8_t address[2] = {};
490 address[0] = ((uint8_t *)&cmd_code)[0];
491 address[1] = ((uint8_t *)&cmd_code)[1];
495 if (result != PX4_OK) {
501 memcpy(data, &((uint8_t *)data)[2], length);
510 uint8_t address[2] = {};
511 address[0] = ((uint8_t *)&cmd_code)[0];
512 address[1] = ((uint8_t *)&cmd_code)[1];
515 memcpy(tx_buf, address, 2);
517 if (data !=
nullptr) {
518 memcpy(&tx_buf[2], data, length);
529 uint16_t keys[2] = {0x0414, 0x3672};
556 uint8_t lifetime_block_one[32] = {};
559 PX4_INFO(
"Failed to read lifetime block 1.");
573 const char *input = argv[0];
574 uint8_t man_name[22];
578 PX4_ERR(
"not running");
584 if (!strcmp(input,
"man_info")) {
587 PX4_INFO(
"The manufacturer name: %s", man_name);
590 PX4_INFO(
"The manufacturer date: %d", result);
592 uint16_t serial_num = 0;
594 PX4_INFO(
"The serial number: %d", serial_num);
599 if (!strcmp(input,
"unseal")) {
604 if (!strcmp(input,
"seal")) {
609 if (!strcmp(input,
"suspend")) {
614 if (!strcmp(input,
"resume")) {
619 if (!strcmp(input,
"serial_num")) {
621 PX4_INFO(
"Serial number: %d", serial_num);
625 if (!strcmp(input,
"write_flash")) {
627 uint16_t address = atoi(argv[1]);
628 unsigned length = atoi(argv[2]);
629 uint8_t tx_buf[32] = {};
632 PX4_WARN(
"Data length out of range: Max 32 bytes");
637 for (
unsigned i = 0; i < length; i++) {
638 if ((
unsigned)argc <= 3 + i) {
639 tx_buf[i] = atoi(argv[3 + i]);
644 PX4_INFO(
"Dataflash write failed: %d", address);
662 PRINT_MODULE_DESCRIPTION(
665 Smart battery driver for the BQ40Z50 fuel gauge IC. 668 To write to flash to set parameters. address, number_of_bytes, byte0, ... , byteN 669 $ batt_smbus -X write_flash 19069 2 27 0 673 PRINT_MODULE_USAGE_NAME("batt_smbus",
"driver");
675 PRINT_MODULE_USAGE_COMMAND(
"start");
676 PRINT_MODULE_USAGE_PARAM_FLAG(
'X',
"BATT_SMBUS_BUS_I2C_EXTERNAL",
true);
677 PRINT_MODULE_USAGE_PARAM_FLAG(
'T',
"BATT_SMBUS_BUS_I2C_EXTERNAL1",
true);
678 PRINT_MODULE_USAGE_PARAM_FLAG(
'R',
"BATT_SMBUS_BUS_I2C_EXTERNAL2",
true);
679 PRINT_MODULE_USAGE_PARAM_FLAG(
'I',
"BATT_SMBUS_BUS_I2C_INTERNAL",
true);
680 PRINT_MODULE_USAGE_PARAM_FLAG(
'A',
"BATT_SMBUS_BUS_ALL",
true);
682 PRINT_MODULE_USAGE_COMMAND_DESCR(
"man_info",
"Prints manufacturer info.");
683 PRINT_MODULE_USAGE_COMMAND_DESCR(
"unseal",
"Unseals the devices flash memory to enable write_flash commands.");
684 PRINT_MODULE_USAGE_COMMAND_DESCR(
"seal",
"Seals the devices flash memory to disbale write_flash commands.");
685 PRINT_MODULE_USAGE_COMMAND_DESCR(
"suspend",
"Suspends the driver from rescheduling the cycle.");
686 PRINT_MODULE_USAGE_COMMAND_DESCR(
"resume",
"Resumes the driver from suspension.");
688 PRINT_MODULE_USAGE_COMMAND_DESCR(
"write_flash",
"Writes to flash. The device must first be unsealed with the unseal command.");
689 PRINT_MODULE_USAGE_ARG(
"address",
"The address to start writing.",
true);
690 PRINT_MODULE_USAGE_ARG(
"number of bytes",
"Number of bytes to send.",
true);
691 PRINT_MODULE_USAGE_ARG(
"data[0]...data[n]",
"One byte of data at a time separated by spaces.",
true);
692 PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
int lifetime_data_flush()
This command flushes the RAM Lifetime Data to data flash to help streamline evaluation testing...
#define BATT_SMBUS_SERIAL_NUMBER
serial number register
float max_cell_voltage_delta
int unseal()
Unseals the battery to allow writing to restricted flash.
static int task_spawn(int argc, char *argv[])
static constexpr float CONSTANTS_ABSOLUTE_NULL_CELSIUS
__EXPORT int batt_smbus_main(int argc, char *argv[])
#define BATT_SMBUS_CELL_3_VOLTAGE
uint16_t _batt_startup_capacity
#define BATT_SMBUS_MEASUREMENT_INTERVAL_US
time in microseconds, measure at 10Hz
__EXPORT int param_get(param_t param, void *val)
Copy the value of a parameter.
#define BATT_SMBUS_LIFETIME_BLOCK_ONE
int block_read(const uint8_t cmd_code, void *data, const uint8_t length, bool use_pec)
Sends a block read command.
int main(int argc, char **argv)
float _max_cell_voltage_delta
int block_write(const uint8_t cmd_code, void *data, uint8_t byte_count, bool use_pec)
Sends a block write command.
void set_undervoltage_protection(float average_current)
Enables or disables the cell under voltage protection emergency shut off.
__EXPORT int param_set(param_t param, const void *val)
Set the value of a parameter.
int read_word(const uint8_t cmd_code, uint16_t &data)
Sends a read word command.
#define BATT_SMBUS_ENABLED_PROTECTIONS_A_CUV_DISABLED
int manufacturer_name(uint8_t *manufacturer_name, const uint8_t length)
Gets the SBS manufacturer name of the battery device.
#define BATT_SMBUS_CELL_1_VOLTAGE
orb_advert_t orb_advertise(const struct orb_metadata *meta, const void *data)
#define BATT_SMBUS_CELL_4_VOLTAGE
#define BATT_SMBUS_CYCLE_COUNT
number of cycles the battery has experienced
BATT_SMBUS(SMBus *interface, const char *path)
#define BATT_CURRENT_UNDERVOLTAGE_THRESHOLD
Threshold in amps to disable undervoltage protection.
#define BATT_SMBUS_ENABLED_PROTECTIONS_A_DEFAULT
battery_status_s _last_report
static int custom_command(int argc, char *argv[])
Global flash based parameter store.
char * _manufacturer_name
#define BATT_SMBUS_TEMP
temperature register
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
#define BATT_SMBUS_REMAINING_CAPACITY
predicted remaining battery capacity as a percentage
#define BATT_SMBUS_CELL_2_VOLTAGE
int write_word(const uint8_t cmd_code, uint16_t data)
Sends a write word command.
#define BATT_SMBUS_MANUFACTURER_BLOCK_ACCESS
void perf_free(perf_counter_t handle)
Free a counter.
#define BATT_SMBUS_VOLTAGE
voltage register
#define BATT_SMBUS_CURRENT
current register
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
#define BATT_SMBUS_MANUFACTURE_DATE
manufacture date register
struct batt_smbus_bus_option smbus_bus_options[]
uint16_t get_serial_number()
Returns the SBS serial number of the battery device.
#define BATT_SMBUS_AVERAGE_TIME_TO_EMPTY
predicted remaining battery capacity based on the present rate of discharge in min ...
uint8_t _cell_undervoltage_protection_status
int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data)
#define BATT_CELL_VOLTAGE_THRESHOLD_FAILED
Threshold in volts to Land if cells are imbalanced.
int seal()
Seals the battery to disallow writing to restricted flash.
constexpr _Tp min(_Tp a, _Tp b)
__EXPORT param_t param_find(const char *name)
Look up a parameter by name.
#define BATT_SMBUS_AVERAGE_CURRENT
current register
int get_startup_info()
Read info from battery on startup.
Header for a battery monitor connected via SMBus (I2C).
float _lifetime_max_delta_cell_voltage
constexpr _Tp max(_Tp a, _Tp b)
int manufacturer_read(const uint16_t cmd_code, void *data, const unsigned length)
Performs a ManufacturerBlockAccess() read command.
int print_status() override
int orb_unadvertise(orb_advert_t handle)
#define BATT_SMBUS_MANUFACTURER_ACCESS
int get_cell_voltages()
Reads the cell voltages.
#define BATT_SMBUS_LIFETIME_FLUSH
uint16_t run_time_to_empty
#define BATT_VOLTAGE_UNDERVOLTAGE_THRESHOLD
Threshold in volts to re-enable undervoltage protection.
#define BATT_SMBUS_ENABLED_PROTECTIONS_A_ADDRESS
int dataflash_read(uint16_t &address, void *data)
Reads data from flash.
int manufacture_date()
Gets the SBS manufacture date of the battery.
int dataflash_write(uint16_t &address, void *data, const unsigned length)
Writes data to flash.
uint16_t average_time_to_empty
#define BATT_SMBUS_RUN_TIME_TO_EMPTY
predicted remaining battery capacity based on the present rate of discharge in min ...
#define BATT_SMBUS_MANUFACTURER_NAME
manufacturer name
#define BATT_SMBUS_FULL_CHARGE_CAPACITY
capacity when fully charged
int lifetime_read_block_one()
Reads the lifetime data from block 1.
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
int manufacturer_write(const uint16_t cmd_code, void *data, const unsigned length)
Performs a ManufacturerBlockAccess() write command.