fix detection of SCD30 by checking if the size of the return from a 2 byte register read is correct (#9664)
* fix detection of SCD30 by checking if thee size of the return from a 2 byte register read is correct fix signedness warning in PMSA003 sensor code. * Add alternate path for LPS22HB Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * check EndTransmission for errors and compare returned length to expected value Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
GitHub
Copilot
parent
5feba46b53
commit
6b44b5786e
@@ -117,6 +117,25 @@ uint16_t ScanI2CTwoWire::getRegisterValue(const ScanI2CTwoWire::RegisterLocation
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScanI2CTwoWire::i2cCommandResponseLength(ScanI2C::DeviceAddress addr, uint16_t command, uint8_t expectedLength) const
|
||||||
|
{
|
||||||
|
TwoWire *i2cBus = fetchI2CBus(addr);
|
||||||
|
i2cBus->beginTransmission(addr.address);
|
||||||
|
if (command > 0xFF) {
|
||||||
|
i2cBus->write((uint8_t)(command >> 8));
|
||||||
|
}
|
||||||
|
i2cBus->write((uint8_t)(command & 0xFF));
|
||||||
|
if (i2cBus->endTransmission() != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
delay(20);
|
||||||
|
uint8_t received = i2cBus->requestFrom(addr.address, expectedLength);
|
||||||
|
bool match = (received == expectedLength);
|
||||||
|
while (i2cBus->available())
|
||||||
|
i2cBus->read();
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
/// for SEN5X detection
|
/// for SEN5X detection
|
||||||
// Note, this code needs to be called before setting the I2C bus speed
|
// Note, this code needs to be called before setting the I2C bus speed
|
||||||
// for the screen at high speed. The speed needs to be at 100kHz, otherwise
|
// for the screen at high speed. The speed needs to be at 100kHz, otherwise
|
||||||
@@ -432,8 +451,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2) == 0x5449) {
|
if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2) == 0x5449) {
|
||||||
type = OPT3001;
|
type = OPT3001;
|
||||||
logFoundDevice("OPT3001", (uint8_t)addr.address);
|
logFoundDevice("OPT3001", (uint8_t)addr.address);
|
||||||
} else if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x89), 6) !=
|
} else if (i2cCommandResponseLength(addr, 0x89, 6)) { // SHT4x serial number (6 bytes inc. CRC)
|
||||||
0) { // unique SHT4x serial number (6 bytes inc. CRC)
|
|
||||||
type = SHT4X;
|
type = SHT4X;
|
||||||
logFoundDevice("SHT4X", (uint8_t)addr.address);
|
logFoundDevice("SHT4X", (uint8_t)addr.address);
|
||||||
} else {
|
} else {
|
||||||
@@ -458,13 +476,19 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LPS22HB_ADDR_ALT:
|
case LPS22HB_ADDR_ALT:
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xD060), 48); // get device marking
|
// SFA30 detection: send 2-byte command 0xD060 (Get Device Marking) and check for 48-byte response
|
||||||
if (registerValue != 0) {
|
if (i2cCommandResponseLength(addr, 0xD060, 48)) {
|
||||||
type = SFA30;
|
type = SFA30;
|
||||||
logFoundDevice("SFA30", (uint8_t)addr.address);
|
logFoundDevice("SFA30", (uint8_t)addr.address);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// TODO - What happens with these two?
|
// Fallback: LPS22HB detection at alternate address using WHO_AM_I register (0x0F == 0xB1)
|
||||||
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 1);
|
||||||
|
if (registerValue == 0xB1) {
|
||||||
|
type = LPS22HB;
|
||||||
|
logFoundDevice("LPS22HB", (uint8_t)addr.address);
|
||||||
|
}
|
||||||
|
break;
|
||||||
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB", (uint8_t)addr.address)
|
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB", (uint8_t)addr.address)
|
||||||
SCAN_SIMPLE_CASE(QMC6310U_ADDR, QMC6310U, "QMC6310U", (uint8_t)addr.address)
|
SCAN_SIMPLE_CASE(QMC6310U_ADDR, QMC6310U, "QMC6310U", (uint8_t)addr.address)
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ class ScanI2CTwoWire : public ScanI2C
|
|||||||
|
|
||||||
uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth, bool) const;
|
uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth, bool) const;
|
||||||
|
|
||||||
|
bool i2cCommandResponseLength(DeviceAddress addr, uint16_t command, uint8_t expectedLength) const;
|
||||||
|
|
||||||
DeviceType probeOLED(ScanI2C::DeviceAddress) const;
|
DeviceType probeOLED(ScanI2C::DeviceAddress) const;
|
||||||
|
|
||||||
static void logFoundDevice(const char *device, uint8_t address);
|
static void logFoundDevice(const char *device, uint8_t address);
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ bool PMSA003ISensor::getMetrics(meshtastic_Telemetry *measurement)
|
|||||||
#endif /* CAN_RECLOCK_I2C */
|
#endif /* CAN_RECLOCK_I2C */
|
||||||
#endif /* PMSA003I_I2C_CLOCK_SPEED */
|
#endif /* PMSA003I_I2C_CLOCK_SPEED */
|
||||||
|
|
||||||
_bus->requestFrom(_address, PMSA003I_FRAME_LENGTH);
|
_bus->requestFrom(_address, (uint8_t)PMSA003I_FRAME_LENGTH);
|
||||||
if (_bus->available() < PMSA003I_FRAME_LENGTH) {
|
if (_bus->available() < PMSA003I_FRAME_LENGTH) {
|
||||||
LOG_WARN("%s read failed: incomplete data (%d bytes)", sensorName, _bus->available());
|
LOG_WARN("%s read failed: incomplete data (%d bytes)", sensorName, _bus->available());
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user