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

View File

@ -115,8 +115,6 @@ RGBLED_NCP5623C::init()
int
RGBLED_NCP5623C::probe()
{
_retries = 4;
return write(NCP5623_LED_CURRENT, 0x00);
}

View File

@ -72,20 +72,18 @@ int LPS22HB_I2C::probe()
{
uint8_t id = 0;
_retries = 10;
if (read(WHO_AM_I, &id, 1)) {
DEVICE_DEBUG("read_reg fail");
return -EIO;
}
_retries = 2;
if (id != LPS22HB_ID_WHO_AM_I) {
DEVICE_DEBUG("ID byte mismatch (%02x != %02x)", LPS22HB_ID_WHO_AM_I, id);
return -EIO;
}
_retries = 1;
return PX4_OK;
}

View File

@ -71,20 +71,18 @@ int LPS25H_I2C::probe()
{
uint8_t id;
_retries = 10;
if (read(ADDR_WHO_AM_I, &id, 1)) {
DEVICE_DEBUG("read_reg fail");
return -EIO;
}
_retries = 2;
if (id != ID_WHO_AM_I) {
DEVICE_DEBUG("ID byte mismatch (%02x != %02x)", ID_WHO_AM_I, id);
return -EIO;
}
_retries = 1;
return OK;
}

View File

@ -85,18 +85,15 @@ int MPL3115A2::init()
int MPL3115A2::probe()
{
_retries = 10;
uint8_t whoami = 0;
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;
}
_retries = 1;
return -EIO;
}
@ -198,11 +195,6 @@ int MPL3115A2::measure()
// Send the command to read the ADC for P and T.
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);
if (ret == -EIO) {

View File

@ -141,18 +141,14 @@ MS5611_I2C::ioctl(unsigned operation, unsigned &arg)
int
MS5611_I2C::probe()
{
_retries = 10;
if ((PX4_OK == _probe_address(MS5611_ADDRESS_1)) ||
(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;
}
_retries = 1;
return -EIO;
}
@ -183,7 +179,7 @@ MS5611_I2C::_reset()
int result;
/* bump the retry count */
_retries = 10;
_retries = 3;
result = transfer(&cmd, 1, nullptr, 0);
_retries = old_retrycount;
@ -193,12 +189,6 @@ MS5611_I2C::_reset()
int
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;
return transfer(&cmd, 1, nullptr, 0);
}

View File

@ -49,8 +49,6 @@ LidarLiteI2C::LidarLiteI2C(const I2CSPIDriverConfig &config) :
_px4_rangefinder.set_min_distance(LL40LS_MIN_DISTANCE);
_px4_rangefinder.set_max_distance(LL40LS_MAX_DISTANCE);
_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
}
@ -126,9 +124,6 @@ LidarLiteI2C::probe()
uint8_t id_high = 0;
uint8_t id_low = 0;
// more retries for detection
_retries = 10;
for (uint8_t i = 0; i < sizeof(addresses); i++) {
set_device_address(addresses[i]);
@ -196,7 +191,7 @@ LidarLiteI2C::probe()
}
}
_retries = 3;
_retries = 1;
return OK;
}

View File

@ -78,9 +78,6 @@ TERARANGER::TERARANGER(const I2CSPIDriverConfig &config) :
I2CSPIDriver(config),
_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_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.
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) {
_retries = 1;
return measure();
}
}

View File

@ -69,8 +69,8 @@ VL53L0X::VL53L0X(const I2CSPIDriverConfig &config) :
_px4_rangefinder.set_max_distance(2.f);
_px4_rangefinder.set_fov(math::radians(25.f));
// Allow 3 retries as the device typically misses the first measure attempts.
I2C::_retries = 3;
// Allow retries as the device typically misses the first measure attempts.
I2C::_retries = 1;
_px4_rangefinder.set_device_type(DRV_DIST_DEVTYPE_VL53L0X);
}

View File

@ -150,9 +150,6 @@ VL53L1X::VL53L1X(const I2CSPIDriverConfig &config) :
_px4_rangefinder.set_max_distance(2.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);
}
@ -215,6 +212,8 @@ int VL53L1X::probe()
return -EIO;
}
_retries = 1;
return PX4_OK;
}

View File

@ -134,25 +134,13 @@ RGBLED::probe()
bool on, powersave;
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 ||
(ret = send_led_enable(false) != OK) ||
(ret = send_led_enable(false) != OK)) {
return ret;
}
_retries = prevretries;
_retries = 1;
return ret;
}

View File

@ -78,13 +78,17 @@ public:
void RunImpl();
private:
int send_led_rgb();
void update_params();
int write(uint8_t reg, uint8_t data);
float _brightness{1.0f};
float _max_brightness{1.0f};
uint8_t _r{0};
uint8_t _g{0};
uint8_t _b{0};
uint8_t _r{0};
uint8_t _g{0};
uint8_t _b{0};
volatile bool _running{false};
volatile bool _should_run{true};
bool _leds_enabled{true};
@ -93,22 +97,14 @@ private:
LedController _led_controller;
int send_led_rgb();
void update_params();
int write(uint8_t reg, uint8_t data);
uint8_t red;
uint8_t green;
uint8_t blue;
uint8_t _red{NCP5623_LED_PWM0};
uint8_t _green{NCP5623_LED_PWM1};
uint8_t _blue{NCP5623_LED_PWM2};
};
RGBLED_NCP5623C::RGBLED_NCP5623C(const I2CSPIDriverConfig &config) :
I2C(config),
I2CSPIDriver(config),
red(NCP5623_LED_PWM0),
green(NCP5623_LED_PWM1),
blue(NCP5623_LED_PWM2)
I2CSPIDriver(config)
{
}
@ -144,17 +140,15 @@ RGBLED_NCP5623C::init()
int
RGBLED_NCP5623C::probe()
{
int status = PX4_ERROR;
_retries = 4;
status = write(NCP5623_LED_CURRENT, NCP5623_LED_OFF);
int status = write(NCP5623_LED_CURRENT, NCP5623_LED_OFF);
if (status == PX4_ERROR) {
set_device_address(ALT_ADDR);
status = write(NCP5623_LED_CURRENT, NCP5623_LED_OFF);
if (status == PX4_OK) {
red = NCP5623_LED_PWM2;
blue = NCP5623_LED_PWM0;
_red = NCP5623_LED_PWM2;
_blue = NCP5623_LED_PWM0;
}
}
@ -230,14 +224,13 @@ RGBLED_NCP5623C::RunImpl()
int
RGBLED_NCP5623C::send_led_rgb()
{
uint8_t msg[7] = {0x20, 0x70, 0x40, 0x70, 0x60, 0x70, 0x80};
uint8_t brightness = 0x1f * _max_brightness;
msg[0] = NCP5623_LED_CURRENT | (brightness & 0x1f);
msg[2] = red | (uint8_t(_r * _brightness) & 0x1f);
msg[4] = green | (uint8_t(_g * _brightness) & 0x1f);
msg[6] = blue | (uint8_t(_b * _brightness) & 0x1f);
msg[2] = _red | (uint8_t(_r * _brightness) & 0x1f);
msg[4] = _green | (uint8_t(_g * _brightness) & 0x1f);
msg[6] = _blue | (uint8_t(_b * _brightness) & 0x1f);
return transfer(&msg[0], 7, nullptr, 0);
}

View File

@ -72,7 +72,7 @@ int HMC5883_I2C::probe()
{
uint8_t data[3] = {0, 0, 0};
_retries = 10;
_retries = 1;
if (read(ADDR_ID_A, &data[0], 1) ||
read(ADDR_ID_B, &data[1], 1) ||
@ -81,8 +81,6 @@ int HMC5883_I2C::probe()
return -EIO;
}
_retries = 2;
if ((data[0] != ID_A_WHO_AM_I) ||
(data[1] != ID_B_WHO_AM_I) ||
(data[2] != ID_C_WHO_AM_I)) {

View File

@ -86,12 +86,11 @@ void IST8308::print_status()
int IST8308::probe()
{
_retries = 2;
for (int retry = 0; retry < 3; retry++) {
const uint8_t WAI = RegisterRead(Register::WAI);
if (WAI == Device_ID) {
_retries = 1;
return PX4_OK;
} else {

View File

@ -86,15 +86,13 @@ LIS2MDL_I2C::probe()
{
uint8_t data = 0;
_retries = 10;
_retries = 1;
if (read(ADDR_WHO_AM_I, &data, 1)) {
DEVICE_DEBUG("read_reg fail");
return -EIO;
}
_retries = 2;
if (data != ID_WHO_AM_I) {
DEVICE_DEBUG("LIS2MDL bad ID: %02x", data);
return -EIO;

View File

@ -85,20 +85,18 @@ int LIS3MDL_I2C::probe()
{
uint8_t data = 0;
_retries = 10;
if (read(ADDR_WHO_AM_I, &data, 1)) {
DEVICE_DEBUG("read_reg fail");
return -EIO;
}
_retries = 2;
if (data != ID_WHO_AM_I) {
DEVICE_DEBUG("LIS3MDL bad ID: %02x", data);
return -EIO;
}
_retries = 1;
return OK;
}

View File

@ -84,20 +84,18 @@ int RM3100_I2C::probe()
{
uint8_t data = 0;
_retries = 10;
if (read(ADDR_REVID, &data, 1)) {
DEVICE_DEBUG("RM3100 read_reg fail");
return -EIO;
}
_retries = 2;
if (data != RM3100_REVID) {
DEVICE_DEBUG("RM3100 bad ID: %02x", data);
return -EIO;
}
_retries = 1;
return OK;
}

View File

@ -185,9 +185,6 @@ BST::BST(const I2CSPIDriverConfig &config) :
int BST::probe()
{
int retries_prev = _retries;
_retries = 3;
BSTPacket<BSTDeviceInfoRequest> dev_info_req = {};
dev_info_req.type = 0x0A;
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),
dev_info_reply.payload.dev_name);
_retries = retries_prev;
_retries = 1;
return OK;
}

View File

@ -104,11 +104,9 @@ Airspeed::probe()
for detection. Once it is running the number of retries can
be reduced
*/
_retries = 4;
_retries = 1;
int ret = measure();
// drop back to 2 retries once initialised
_retries = 2;
return ret;
}