drivers: minimize additional I2C retries

This commit is contained in:
Daniel Agar
2021-06-27 12:52:36 -04:00
parent 8a8171c7aa
commit cb610caf1e
18 changed files with 44 additions and 109 deletions
-2
View File
@@ -115,8 +115,6 @@ RGBLED_NCP5623C::init()
int int
RGBLED_NCP5623C::probe() RGBLED_NCP5623C::probe()
{ {
_retries = 4;
return write(NCP5623_LED_CURRENT, 0x00); return write(NCP5623_LED_CURRENT, 0x00);
} }
@@ -72,20 +72,18 @@ int LPS22HB_I2C::probe()
{ {
uint8_t id = 0; uint8_t id = 0;
_retries = 10;
if (read(WHO_AM_I, &id, 1)) { if (read(WHO_AM_I, &id, 1)) {
DEVICE_DEBUG("read_reg fail"); DEVICE_DEBUG("read_reg fail");
return -EIO; return -EIO;
} }
_retries = 2;
if (id != LPS22HB_ID_WHO_AM_I) { if (id != LPS22HB_ID_WHO_AM_I) {
DEVICE_DEBUG("ID byte mismatch (%02x != %02x)", LPS22HB_ID_WHO_AM_I, id); DEVICE_DEBUG("ID byte mismatch (%02x != %02x)", LPS22HB_ID_WHO_AM_I, id);
return -EIO; return -EIO;
} }
_retries = 1;
return PX4_OK; return PX4_OK;
} }
+2 -4
View File
@@ -71,20 +71,18 @@ int LPS25H_I2C::probe()
{ {
uint8_t id; uint8_t id;
_retries = 10;
if (read(ADDR_WHO_AM_I, &id, 1)) { if (read(ADDR_WHO_AM_I, &id, 1)) {
DEVICE_DEBUG("read_reg fail"); DEVICE_DEBUG("read_reg fail");
return -EIO; return -EIO;
} }
_retries = 2;
if (id != ID_WHO_AM_I) { if (id != ID_WHO_AM_I) {
DEVICE_DEBUG("ID byte mismatch (%02x != %02x)", ID_WHO_AM_I, id); DEVICE_DEBUG("ID byte mismatch (%02x != %02x)", ID_WHO_AM_I, id);
return -EIO; return -EIO;
} }
_retries = 1;
return OK; return OK;
} }
+3 -11
View File
@@ -85,18 +85,15 @@ int MPL3115A2::init()
int MPL3115A2::probe() int MPL3115A2::probe()
{ {
_retries = 10;
uint8_t whoami = 0; uint8_t whoami = 0;
if ((RegisterRead(MPL3115A2_REG_WHO_AM_I, &whoami) > 0) && (whoami == MPL3115A2_WHO_AM_I)) { if ((RegisterRead(MPL3115A2_REG_WHO_AM_I, &whoami) > 0) && (whoami == MPL3115A2_WHO_AM_I)) {
/*
* Disable retries; we may enable them selectively in some cases,
* but the device gets confused if we retry some of the commands.
*/
_retries = 0;
return PX4_OK; return PX4_OK;
} }
_retries = 1;
return -EIO; return -EIO;
} }
@@ -198,11 +195,6 @@ int MPL3115A2::measure()
// Send the command to read the ADC for P and T. // Send the command to read the ADC for P and T.
unsigned addr = (MPL3115A2_CTRL_REG1 << 8) | MPL3115A2_CTRL_TRIGGER; unsigned addr = (MPL3115A2_CTRL_REG1 << 8) | MPL3115A2_CTRL_TRIGGER;
/*
* Disable retries on this command; we can't know whether failure
* means the device did or did not see the command.
*/
_retries = 0;
int ret = RegisterWrite((addr >> 8) & 0xff, addr & 0xff); int ret = RegisterWrite((addr >> 8) & 0xff, addr & 0xff);
if (ret == -EIO) { if (ret == -EIO) {
+4 -14
View File
@@ -141,18 +141,14 @@ MS5611_I2C::ioctl(unsigned operation, unsigned &arg)
int int
MS5611_I2C::probe() MS5611_I2C::probe()
{ {
_retries = 10;
if ((PX4_OK == _probe_address(MS5611_ADDRESS_1)) || if ((PX4_OK == _probe_address(MS5611_ADDRESS_1)) ||
(PX4_OK == _probe_address(MS5611_ADDRESS_2))) { (PX4_OK == _probe_address(MS5611_ADDRESS_2))) {
/*
* Disable retries; we may enable them selectively in some cases,
* but the device gets confused if we retry some of the commands.
*/
_retries = 0;
return PX4_OK; return PX4_OK;
} }
_retries = 1;
return -EIO; return -EIO;
} }
@@ -183,7 +179,7 @@ MS5611_I2C::_reset()
int result; int result;
/* bump the retry count */ /* bump the retry count */
_retries = 10; _retries = 3;
result = transfer(&cmd, 1, nullptr, 0); result = transfer(&cmd, 1, nullptr, 0);
_retries = old_retrycount; _retries = old_retrycount;
@@ -193,12 +189,6 @@ MS5611_I2C::_reset()
int int
MS5611_I2C::_measure(unsigned addr) MS5611_I2C::_measure(unsigned addr)
{ {
/*
* Disable retries on this command; we can't know whether failure
* means the device did or did not see the command.
*/
_retries = 0;
uint8_t cmd = addr; uint8_t cmd = addr;
return transfer(&cmd, 1, nullptr, 0); return transfer(&cmd, 1, nullptr, 0);
} }
@@ -49,8 +49,6 @@ LidarLiteI2C::LidarLiteI2C(const I2CSPIDriverConfig &config) :
_px4_rangefinder.set_min_distance(LL40LS_MIN_DISTANCE); _px4_rangefinder.set_min_distance(LL40LS_MIN_DISTANCE);
_px4_rangefinder.set_max_distance(LL40LS_MAX_DISTANCE); _px4_rangefinder.set_max_distance(LL40LS_MAX_DISTANCE);
_px4_rangefinder.set_fov(0.008); // Divergence 8 mRadian _px4_rangefinder.set_fov(0.008); // Divergence 8 mRadian
// up the retries since the device misses the first measure attempts
_retries = 3;
_px4_rangefinder.set_device_type(DRV_DIST_DEVTYPE_LL40LS); /// TODO _px4_rangefinder.set_device_type(DRV_DIST_DEVTYPE_LL40LS); /// TODO
} }
@@ -126,9 +124,6 @@ LidarLiteI2C::probe()
uint8_t id_high = 0; uint8_t id_high = 0;
uint8_t id_low = 0; uint8_t id_low = 0;
// more retries for detection
_retries = 10;
for (uint8_t i = 0; i < sizeof(addresses); i++) { for (uint8_t i = 0; i < sizeof(addresses); i++) {
set_device_address(addresses[i]); set_device_address(addresses[i]);
@@ -196,7 +191,7 @@ LidarLiteI2C::probe()
} }
} }
_retries = 3; _retries = 1;
return OK; return OK;
} }
@@ -78,9 +78,6 @@ TERARANGER::TERARANGER(const I2CSPIDriverConfig &config) :
I2CSPIDriver(config), I2CSPIDriver(config),
_px4_rangefinder(get_device_id(), config.rotation) _px4_rangefinder(get_device_id(), config.rotation)
{ {
// up the retries since the device misses the first measure attempts
I2C::_retries = 3;
_px4_rangefinder.set_device_type(DRV_DIST_DEVTYPE_TERARANGER); _px4_rangefinder.set_device_type(DRV_DIST_DEVTYPE_TERARANGER);
_px4_rangefinder.set_rangefinder_type(distance_sensor_s::MAV_DISTANCE_SENSOR_LASER); _px4_rangefinder.set_rangefinder_type(distance_sensor_s::MAV_DISTANCE_SENSOR_LASER);
} }
@@ -242,6 +239,7 @@ int TERARANGER::probe()
// Can't use a single transfer as Teraranger needs a bit of time for internal processing. // Can't use a single transfer as Teraranger needs a bit of time for internal processing.
if (transfer(&cmd, 1, nullptr, 0) == OK) { if (transfer(&cmd, 1, nullptr, 0) == OK) {
if (transfer(nullptr, 0, &who_am_i, 1) == OK && who_am_i == TERARANGER_WHO_AM_I_REG_VAL) { if (transfer(nullptr, 0, &who_am_i, 1) == OK && who_am_i == TERARANGER_WHO_AM_I_REG_VAL) {
_retries = 1;
return measure(); return measure();
} }
} }
@@ -69,8 +69,8 @@ VL53L0X::VL53L0X(const I2CSPIDriverConfig &config) :
_px4_rangefinder.set_max_distance(2.f); _px4_rangefinder.set_max_distance(2.f);
_px4_rangefinder.set_fov(math::radians(25.f)); _px4_rangefinder.set_fov(math::radians(25.f));
// Allow 3 retries as the device typically misses the first measure attempts. // Allow retries as the device typically misses the first measure attempts.
I2C::_retries = 3; I2C::_retries = 1;
_px4_rangefinder.set_device_type(DRV_DIST_DEVTYPE_VL53L0X); _px4_rangefinder.set_device_type(DRV_DIST_DEVTYPE_VL53L0X);
} }
@@ -150,9 +150,6 @@ VL53L1X::VL53L1X(const I2CSPIDriverConfig &config) :
_px4_rangefinder.set_max_distance(2.f); _px4_rangefinder.set_max_distance(2.f);
_px4_rangefinder.set_fov(math::radians(25.f)); _px4_rangefinder.set_fov(math::radians(25.f));
// Allow 3 retries as the device typically misses the first measure attempts.
I2C::_retries = 3;
_px4_rangefinder.set_device_type(DRV_DIST_DEVTYPE_VL53L1X); _px4_rangefinder.set_device_type(DRV_DIST_DEVTYPE_VL53L1X);
} }
@@ -215,6 +212,8 @@ int VL53L1X::probe()
return -EIO; return -EIO;
} }
_retries = 1;
return PX4_OK; return PX4_OK;
} }
+1 -13
View File
@@ -134,25 +134,13 @@ RGBLED::probe()
bool on, powersave; bool on, powersave;
uint8_t r, g, b; uint8_t r, g, b;
/**
this may look strange, but is needed. There is a serial
EEPROM (Microchip-24aa01) that responds to a bunch of I2C
addresses, including the 0x55 used by this LED device. So
we need to do enough operations to be sure we are talking
to the right device. These 3 operations seem to be enough,
as the 3rd one consistently fails if no RGBLED is on the bus.
*/
unsigned prevretries = _retries;
_retries = 4;
if ((ret = get(on, powersave, r, g, b)) != OK || if ((ret = get(on, powersave, r, g, b)) != OK ||
(ret = send_led_enable(false) != OK) || (ret = send_led_enable(false) != OK) ||
(ret = send_led_enable(false) != OK)) { (ret = send_led_enable(false) != OK)) {
return ret; return ret;
} }
_retries = prevretries; _retries = 1;
return ret; return ret;
} }
@@ -78,6 +78,10 @@ public:
void RunImpl(); void RunImpl();
private: private:
int send_led_rgb();
void update_params();
int write(uint8_t reg, uint8_t data);
float _brightness{1.0f}; float _brightness{1.0f};
float _max_brightness{1.0f}; float _max_brightness{1.0f};
@@ -93,22 +97,14 @@ private:
LedController _led_controller; LedController _led_controller;
int send_led_rgb(); uint8_t _red{NCP5623_LED_PWM0};
void update_params(); uint8_t _green{NCP5623_LED_PWM1};
uint8_t _blue{NCP5623_LED_PWM2};
int write(uint8_t reg, uint8_t data);
uint8_t red;
uint8_t green;
uint8_t blue;
}; };
RGBLED_NCP5623C::RGBLED_NCP5623C(const I2CSPIDriverConfig &config) : RGBLED_NCP5623C::RGBLED_NCP5623C(const I2CSPIDriverConfig &config) :
I2C(config), I2C(config),
I2CSPIDriver(config), I2CSPIDriver(config)
red(NCP5623_LED_PWM0),
green(NCP5623_LED_PWM1),
blue(NCP5623_LED_PWM2)
{ {
} }
@@ -144,17 +140,15 @@ RGBLED_NCP5623C::init()
int int
RGBLED_NCP5623C::probe() RGBLED_NCP5623C::probe()
{ {
int status = PX4_ERROR; int status = write(NCP5623_LED_CURRENT, NCP5623_LED_OFF);
_retries = 4;
status = write(NCP5623_LED_CURRENT, NCP5623_LED_OFF);
if (status == PX4_ERROR) { if (status == PX4_ERROR) {
set_device_address(ALT_ADDR); set_device_address(ALT_ADDR);
status = write(NCP5623_LED_CURRENT, NCP5623_LED_OFF); status = write(NCP5623_LED_CURRENT, NCP5623_LED_OFF);
if (status == PX4_OK) { if (status == PX4_OK) {
red = NCP5623_LED_PWM2; _red = NCP5623_LED_PWM2;
blue = NCP5623_LED_PWM0; _blue = NCP5623_LED_PWM0;
} }
} }
@@ -230,14 +224,13 @@ RGBLED_NCP5623C::RunImpl()
int int
RGBLED_NCP5623C::send_led_rgb() RGBLED_NCP5623C::send_led_rgb()
{ {
uint8_t msg[7] = {0x20, 0x70, 0x40, 0x70, 0x60, 0x70, 0x80}; uint8_t msg[7] = {0x20, 0x70, 0x40, 0x70, 0x60, 0x70, 0x80};
uint8_t brightness = 0x1f * _max_brightness; uint8_t brightness = 0x1f * _max_brightness;
msg[0] = NCP5623_LED_CURRENT | (brightness & 0x1f); msg[0] = NCP5623_LED_CURRENT | (brightness & 0x1f);
msg[2] = red | (uint8_t(_r * _brightness) & 0x1f); msg[2] = _red | (uint8_t(_r * _brightness) & 0x1f);
msg[4] = green | (uint8_t(_g * _brightness) & 0x1f); msg[4] = _green | (uint8_t(_g * _brightness) & 0x1f);
msg[6] = blue | (uint8_t(_b * _brightness) & 0x1f); msg[6] = _blue | (uint8_t(_b * _brightness) & 0x1f);
return transfer(&msg[0], 7, nullptr, 0); return transfer(&msg[0], 7, nullptr, 0);
} }
@@ -72,7 +72,7 @@ int HMC5883_I2C::probe()
{ {
uint8_t data[3] = {0, 0, 0}; uint8_t data[3] = {0, 0, 0};
_retries = 10; _retries = 1;
if (read(ADDR_ID_A, &data[0], 1) || if (read(ADDR_ID_A, &data[0], 1) ||
read(ADDR_ID_B, &data[1], 1) || read(ADDR_ID_B, &data[1], 1) ||
@@ -81,8 +81,6 @@ int HMC5883_I2C::probe()
return -EIO; return -EIO;
} }
_retries = 2;
if ((data[0] != ID_A_WHO_AM_I) || if ((data[0] != ID_A_WHO_AM_I) ||
(data[1] != ID_B_WHO_AM_I) || (data[1] != ID_B_WHO_AM_I) ||
(data[2] != ID_C_WHO_AM_I)) { (data[2] != ID_C_WHO_AM_I)) {
@@ -86,12 +86,11 @@ void IST8308::print_status()
int IST8308::probe() int IST8308::probe()
{ {
_retries = 2;
for (int retry = 0; retry < 3; retry++) { for (int retry = 0; retry < 3; retry++) {
const uint8_t WAI = RegisterRead(Register::WAI); const uint8_t WAI = RegisterRead(Register::WAI);
if (WAI == Device_ID) { if (WAI == Device_ID) {
_retries = 1;
return PX4_OK; return PX4_OK;
} else { } else {
@@ -86,15 +86,13 @@ LIS2MDL_I2C::probe()
{ {
uint8_t data = 0; uint8_t data = 0;
_retries = 10; _retries = 1;
if (read(ADDR_WHO_AM_I, &data, 1)) { if (read(ADDR_WHO_AM_I, &data, 1)) {
DEVICE_DEBUG("read_reg fail"); DEVICE_DEBUG("read_reg fail");
return -EIO; return -EIO;
} }
_retries = 2;
if (data != ID_WHO_AM_I) { if (data != ID_WHO_AM_I) {
DEVICE_DEBUG("LIS2MDL bad ID: %02x", data); DEVICE_DEBUG("LIS2MDL bad ID: %02x", data);
return -EIO; return -EIO;
@@ -85,20 +85,18 @@ int LIS3MDL_I2C::probe()
{ {
uint8_t data = 0; uint8_t data = 0;
_retries = 10;
if (read(ADDR_WHO_AM_I, &data, 1)) { if (read(ADDR_WHO_AM_I, &data, 1)) {
DEVICE_DEBUG("read_reg fail"); DEVICE_DEBUG("read_reg fail");
return -EIO; return -EIO;
} }
_retries = 2;
if (data != ID_WHO_AM_I) { if (data != ID_WHO_AM_I) {
DEVICE_DEBUG("LIS3MDL bad ID: %02x", data); DEVICE_DEBUG("LIS3MDL bad ID: %02x", data);
return -EIO; return -EIO;
} }
_retries = 1;
return OK; return OK;
} }
@@ -84,20 +84,18 @@ int RM3100_I2C::probe()
{ {
uint8_t data = 0; uint8_t data = 0;
_retries = 10;
if (read(ADDR_REVID, &data, 1)) { if (read(ADDR_REVID, &data, 1)) {
DEVICE_DEBUG("RM3100 read_reg fail"); DEVICE_DEBUG("RM3100 read_reg fail");
return -EIO; return -EIO;
} }
_retries = 2;
if (data != RM3100_REVID) { if (data != RM3100_REVID) {
DEVICE_DEBUG("RM3100 bad ID: %02x", data); DEVICE_DEBUG("RM3100 bad ID: %02x", data);
return -EIO; return -EIO;
} }
_retries = 1;
return OK; return OK;
} }
+1 -4
View File
@@ -185,9 +185,6 @@ BST::BST(const I2CSPIDriverConfig &config) :
int BST::probe() int BST::probe()
{ {
int retries_prev = _retries;
_retries = 3;
BSTPacket<BSTDeviceInfoRequest> dev_info_req = {}; BSTPacket<BSTDeviceInfoRequest> dev_info_req = {};
dev_info_req.type = 0x0A; dev_info_req.type = 0x0A;
dev_info_req.payload.cmd = 0x04; dev_info_req.payload.cmd = 0x04;
@@ -213,7 +210,7 @@ int BST::probe()
(int)swap_uint32(dev_info_reply.payload.hw_id), (int)swap_uint16(dev_info_reply.payload.fw_id), (int)swap_uint32(dev_info_reply.payload.hw_id), (int)swap_uint16(dev_info_reply.payload.fw_id),
dev_info_reply.payload.dev_name); dev_info_reply.payload.dev_name);
_retries = retries_prev; _retries = 1;
return OK; return OK;
} }
+1 -3
View File
@@ -104,11 +104,9 @@ Airspeed::probe()
for detection. Once it is running the number of retries can for detection. Once it is running the number of retries can
be reduced be reduced
*/ */
_retries = 4; _retries = 1;
int ret = measure(); int ret = measure();
// drop back to 2 retries once initialised
_retries = 2;
return ret; return ret;
} }