mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-26 03:03:34 +08:00
SMbus battery driver - a lot of updates and optimizations
- added support for BQ40Z80 based battery - added performance counter for interface errors - added SMART_BATTERY_INFO mavlink message - general code cleanups and optimization - fixed: void flooding the log in case of interface error - fixed: using _batt_startup_capacity instead of _batt_capacity for discharged_mah - update: read manufacture_date - update: get _cell_count from parameter and not const 4 - update: avoid re-reading data that has already been read and stored on class already - currently the battery type defined by BAT_SMBUS_MODEL parameter and not by auto detection
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
* SMBus v2.0 protocol implementation.
|
||||
*
|
||||
* @author Jacob Dahl <dahl.jakejacob@gmail.com>
|
||||
* @author Bazooka Joe <BazookaJoe1900@gmail.com>
|
||||
*
|
||||
* TODO
|
||||
* - Enable SMBus mode at the NuttX level. This may be tricky sharing the bus with i2c.
|
||||
@@ -50,6 +51,11 @@ SMBus::SMBus(int bus_num, uint16_t address) :
|
||||
{
|
||||
}
|
||||
|
||||
SMBus::~SMBus()
|
||||
{
|
||||
perf_free(_interface_errors);
|
||||
}
|
||||
|
||||
int SMBus::read_word(const uint8_t cmd_code, uint16_t &data)
|
||||
{
|
||||
uint8_t buf[6];
|
||||
@@ -68,7 +74,11 @@ int SMBus::read_word(const uint8_t cmd_code, uint16_t &data)
|
||||
|
||||
if (pec != buf[sizeof(buf) - 1]) {
|
||||
result = -EINVAL;
|
||||
perf_count(_interface_errors);
|
||||
}
|
||||
|
||||
} else {
|
||||
perf_count(_interface_errors);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -87,10 +97,14 @@ int SMBus::write_word(const uint8_t cmd_code, uint16_t data)
|
||||
|
||||
int result = transfer(&buf[1], 4, nullptr, 0);
|
||||
|
||||
if (result != PX4_OK) {
|
||||
perf_count(_interface_errors);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int SMBus::block_read(const uint8_t cmd_code, void *data, const uint8_t length, bool use_pec)
|
||||
int SMBus::block_read(const uint8_t cmd_code, void *data, const uint8_t length, const bool use_pec)
|
||||
{
|
||||
unsigned byte_count = 0;
|
||||
// addr(wr), cmd_code, addr(r), byte_count, data (32 bytes max), pec
|
||||
@@ -99,6 +113,7 @@ int SMBus::block_read(const uint8_t cmd_code, void *data, const uint8_t length,
|
||||
int result = transfer(&cmd_code, 1, (uint8_t *)&rx_data[3], length + 2);
|
||||
|
||||
if (result != PX4_OK) {
|
||||
perf_count(_interface_errors);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -115,13 +130,14 @@ int SMBus::block_read(const uint8_t cmd_code, void *data, const uint8_t length,
|
||||
|
||||
if (pec != rx_data[byte_count + 4]) {
|
||||
result = -EINVAL;
|
||||
perf_count(_interface_errors);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int SMBus::block_write(const uint8_t cmd_code, void *data, uint8_t byte_count, bool use_pec)
|
||||
int SMBus::block_write(const uint8_t cmd_code, const void *data, uint8_t byte_count, const bool use_pec)
|
||||
{
|
||||
// cmd code[1], byte count[1], data[byte_count] (32max), pec[1] (optional)
|
||||
uint8_t buf[32 + 2];
|
||||
@@ -141,11 +157,11 @@ int SMBus::block_write(const uint8_t cmd_code, void *data, uint8_t byte_count, b
|
||||
|
||||
// If block_write fails, try up to 10 times.
|
||||
while (i < 10 && ((result = transfer((uint8_t *)buf, byte_count + 2, nullptr, 0)) != PX4_OK)) {
|
||||
perf_count(_interface_errors);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i == 10 || result) {
|
||||
PX4_WARN("Block_write failed %d times", i);
|
||||
result = -EINVAL;
|
||||
}
|
||||
|
||||
@@ -154,6 +170,8 @@ int SMBus::block_write(const uint8_t cmd_code, void *data, uint8_t byte_count, b
|
||||
|
||||
uint8_t SMBus::get_pec(uint8_t *buff, const uint8_t len)
|
||||
{
|
||||
// TODO: use "return crc8ccitt(buff, len);"
|
||||
|
||||
// Initialise CRC to zero.
|
||||
uint8_t crc = 0;
|
||||
uint8_t shift_register = 0;
|
||||
|
||||
@@ -36,10 +36,11 @@
|
||||
* SMBus v2.0 protocol implementation.
|
||||
*
|
||||
* @author Jacob Dahl <dahl.jakejacob@gmail.com>
|
||||
* @author Bazooka Joe <BazookaJoe1900@gmail.com>
|
||||
*/
|
||||
|
||||
#include <drivers/device/i2c.h>
|
||||
|
||||
#include <perf/perf_counter.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SMBUS_PEC_POLYNOMIAL 0x07 ///< Polynomial for calculating PEC
|
||||
@@ -48,7 +49,7 @@ class SMBus : public device::I2C
|
||||
{
|
||||
public:
|
||||
SMBus(int bus_num, uint16_t address);
|
||||
~SMBus() override = default;
|
||||
~SMBus() override;
|
||||
|
||||
/**
|
||||
* @brief Sends a block write command.
|
||||
@@ -57,7 +58,7 @@ public:
|
||||
* @param length The number of bytes being written.
|
||||
* @return Returns PX4_OK on success, -errno on failure.
|
||||
*/
|
||||
int block_write(const uint8_t cmd_code, void *data, uint8_t byte_count, bool use_pec);
|
||||
int block_write(const uint8_t cmd_code, const void *data, uint8_t byte_count, const bool use_pec);
|
||||
|
||||
/**
|
||||
* @brief Sends a block read command.
|
||||
@@ -66,7 +67,7 @@ public:
|
||||
* @param length The number of bytes being read.
|
||||
* @return Returns PX4_OK on success, -errno on failure.
|
||||
*/
|
||||
int block_read(const uint8_t cmd_code, void *data, const uint8_t length, bool use_pec);
|
||||
int block_read(const uint8_t cmd_code, void *data, const uint8_t length, const bool use_pec);
|
||||
|
||||
/**
|
||||
* @brief Sends a read word command.
|
||||
@@ -92,4 +93,6 @@ public:
|
||||
*/
|
||||
uint8_t get_pec(uint8_t *buffer, uint8_t length);
|
||||
|
||||
perf_counter_t _interface_errors{perf_alloc(PC_COUNT, MODULE_NAME": errors")};
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user