2023-03-08 19:13:46 -08:00
|
|
|
#include "ScanI2CTwoWire.h"
|
|
|
|
|
|
2024-07-26 03:16:21 +02:00
|
|
|
#if !MESHTASTIC_EXCLUDE_I2C
|
|
|
|
|
|
2023-03-08 19:13:46 -08:00
|
|
|
#include "concurrency/LockGuard.h"
|
2024-01-12 02:00:31 -06:00
|
|
|
#if defined(ARCH_PORTDUINO)
|
2023-11-29 00:48:30 -06:00
|
|
|
#include "linux/LinuxHardwareI2C.h"
|
|
|
|
|
#endif
|
2023-03-08 19:13:46 -08:00
|
|
|
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
2024-10-24 21:58:24 +02:00
|
|
|
#include "meshUtils.h" // vformat
|
2023-03-08 19:13:46 -08:00
|
|
|
#endif
|
|
|
|
|
|
2024-05-25 12:37:55 +02:00
|
|
|
bool in_array(uint8_t *array, int size, uint8_t lookfor)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < size; i++)
|
|
|
|
|
if (lookfor == array[i])
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-08 19:13:46 -08:00
|
|
|
ScanI2C::FoundDevice ScanI2CTwoWire::find(ScanI2C::DeviceType type) const
|
|
|
|
|
{
|
|
|
|
|
concurrency::LockGuard guard((concurrency::Lock *)&lock);
|
|
|
|
|
|
|
|
|
|
return exists(type) ? ScanI2C::FoundDevice(type, deviceAddresses.at(type)) : DEVICE_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ScanI2CTwoWire::exists(ScanI2C::DeviceType type) const
|
|
|
|
|
{
|
|
|
|
|
return deviceAddresses.find(type) != deviceAddresses.end();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ScanI2C::FoundDevice ScanI2CTwoWire::firstOfOrNONE(size_t count, DeviceType types[]) const
|
|
|
|
|
{
|
|
|
|
|
concurrency::LockGuard guard((concurrency::Lock *)&lock);
|
|
|
|
|
|
|
|
|
|
for (size_t k = 0; k < count; k++) {
|
|
|
|
|
ScanI2C::DeviceType current = types[k];
|
|
|
|
|
|
|
|
|
|
if (exists(current)) {
|
|
|
|
|
return ScanI2C::FoundDevice(current, deviceAddresses.at(current));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return DEVICE_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ScanI2C::DeviceType ScanI2CTwoWire::probeOLED(ScanI2C::DeviceAddress addr) const
|
|
|
|
|
{
|
|
|
|
|
TwoWire *i2cBus = fetchI2CBus(addr);
|
|
|
|
|
|
|
|
|
|
uint8_t r = 0;
|
|
|
|
|
uint8_t r_prev = 0;
|
|
|
|
|
uint8_t c = 0;
|
|
|
|
|
ScanI2C::DeviceType o_probe = ScanI2C::DeviceType::SCREEN_UNKNOWN;
|
|
|
|
|
do {
|
|
|
|
|
r_prev = r;
|
|
|
|
|
i2cBus->beginTransmission(addr.address);
|
|
|
|
|
i2cBus->write((uint8_t)0x00);
|
|
|
|
|
i2cBus->endTransmission();
|
|
|
|
|
i2cBus->requestFrom((int)addr.address, 1);
|
|
|
|
|
if (i2cBus->available()) {
|
|
|
|
|
r = i2cBus->read();
|
|
|
|
|
}
|
|
|
|
|
r &= 0x0f;
|
|
|
|
|
|
|
|
|
|
if (r == 0x08 || r == 0x00) {
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("SH1106", (uint8_t)addr.address);
|
2023-03-08 19:13:46 -08:00
|
|
|
o_probe = SCREEN_SH1106; // SH1106
|
|
|
|
|
} else if (r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) {
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("SSD1306", (uint8_t)addr.address);
|
2023-03-08 19:13:46 -08:00
|
|
|
o_probe = SCREEN_SSD1306; // SSD1306
|
|
|
|
|
}
|
|
|
|
|
c++;
|
|
|
|
|
} while ((r != r_prev) && (c < 4));
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_DEBUG("0x%x subtype probed in %i tries ", r, c);
|
2023-03-08 19:13:46 -08:00
|
|
|
|
|
|
|
|
return o_probe;
|
|
|
|
|
}
|
|
|
|
|
uint16_t ScanI2CTwoWire::getRegisterValue(const ScanI2CTwoWire::RegisterLocation ®isterLocation,
|
2025-01-18 14:10:13 +01:00
|
|
|
ScanI2CTwoWire::ResponseWidth responseWidth, bool zeropad = false) const
|
2023-03-08 19:13:46 -08:00
|
|
|
{
|
|
|
|
|
uint16_t value = 0x00;
|
|
|
|
|
TwoWire *i2cBus = fetchI2CBus(registerLocation.i2cAddress);
|
|
|
|
|
|
|
|
|
|
i2cBus->beginTransmission(registerLocation.i2cAddress.address);
|
|
|
|
|
i2cBus->write(registerLocation.registerAddress);
|
2025-01-18 14:10:13 +01:00
|
|
|
if (zeropad) {
|
|
|
|
|
// Lark Commands need the argument list length in 2 bytes.
|
|
|
|
|
i2cBus->write((int)0);
|
|
|
|
|
i2cBus->write((int)0);
|
|
|
|
|
}
|
2023-03-08 19:13:46 -08:00
|
|
|
i2cBus->endTransmission();
|
|
|
|
|
delay(20);
|
|
|
|
|
i2cBus->requestFrom(registerLocation.i2cAddress.address, responseWidth);
|
2025-01-18 14:10:13 +01:00
|
|
|
if (i2cBus->available() > 1) {
|
2023-03-08 19:13:46 -08:00
|
|
|
// Read MSB, then LSB
|
|
|
|
|
value = (uint16_t)i2cBus->read() << 8;
|
|
|
|
|
value |= i2cBus->read();
|
|
|
|
|
} else if (i2cBus->available()) {
|
|
|
|
|
value = i2cBus->read();
|
|
|
|
|
}
|
2025-01-18 14:10:13 +01:00
|
|
|
// Drain excess bytes
|
|
|
|
|
for (uint8_t i = 0; i < responseWidth - 1; i++) {
|
|
|
|
|
if (i2cBus->available())
|
|
|
|
|
i2cBus->read();
|
|
|
|
|
}
|
2023-03-08 19:13:46 -08:00
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define SCAN_SIMPLE_CASE(ADDR, T, ...) \
|
|
|
|
|
case ADDR: \
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice(__VA_ARGS__); \
|
2023-03-08 19:13:46 -08:00
|
|
|
type = T; \
|
|
|
|
|
break;
|
|
|
|
|
|
2024-05-25 12:37:55 +02:00
|
|
|
void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
2023-03-08 19:13:46 -08:00
|
|
|
{
|
|
|
|
|
concurrency::LockGuard guard((concurrency::Lock *)&lock);
|
|
|
|
|
|
2024-11-04 12:16:25 -06:00
|
|
|
LOG_DEBUG("Scan for I2C devices on port %d", port);
|
2023-03-08 19:13:46 -08:00
|
|
|
|
|
|
|
|
uint8_t err;
|
|
|
|
|
|
|
|
|
|
DeviceAddress addr(port, 0x00);
|
|
|
|
|
|
|
|
|
|
uint16_t registerValue = 0x00;
|
|
|
|
|
ScanI2C::DeviceType type;
|
|
|
|
|
TwoWire *i2cBus;
|
|
|
|
|
#ifdef RV3028_RTC
|
|
|
|
|
Melopero_RV3028 rtc;
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-09-18 03:28:23 +12:00
|
|
|
#if WIRE_INTERFACES_COUNT == 2
|
2023-03-08 19:13:46 -08:00
|
|
|
if (port == I2CPort::WIRE1) {
|
|
|
|
|
i2cBus = &Wire1;
|
|
|
|
|
} else {
|
|
|
|
|
#endif
|
|
|
|
|
i2cBus = &Wire;
|
2024-09-18 03:28:23 +12:00
|
|
|
#if WIRE_INTERFACES_COUNT == 2
|
2023-03-08 19:13:46 -08:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-10-26 12:03:28 +02:00
|
|
|
// We only need to scan 112 addresses, the rest is reserved for special purposes
|
|
|
|
|
// 0x00 General Call
|
|
|
|
|
// 0x01 CBUS addresses
|
|
|
|
|
// 0x02 Reserved for different bus formats
|
|
|
|
|
// 0x03 Reserved for future purposes
|
|
|
|
|
// 0x04-0x07 High Speed Master Code
|
|
|
|
|
// 0x78-0x7B 10-bit slave addressing
|
|
|
|
|
// 0x7C-0x7F Reserved for future purposes
|
|
|
|
|
|
|
|
|
|
for (addr.address = 8; addr.address < 120; addr.address++) {
|
2024-06-17 15:09:38 +02:00
|
|
|
if (asize != 0) {
|
2024-11-26 13:59:50 -06:00
|
|
|
if (!in_array(address, asize, (uint8_t)addr.address))
|
2024-05-25 12:37:55 +02:00
|
|
|
continue;
|
2024-11-26 13:59:50 -06:00
|
|
|
LOG_DEBUG("Scan address 0x%x", (uint8_t)addr.address);
|
2024-06-17 15:09:38 +02:00
|
|
|
}
|
2023-03-08 19:13:46 -08:00
|
|
|
i2cBus->beginTransmission(addr.address);
|
2023-11-29 00:48:30 -06:00
|
|
|
#ifdef ARCH_PORTDUINO
|
2024-12-22 22:53:54 -06:00
|
|
|
err = 2;
|
|
|
|
|
if ((addr.address >= 0x30 && addr.address <= 0x37) || (addr.address >= 0x50 && addr.address <= 0x5F)) {
|
|
|
|
|
if (i2cBus->read() != -1)
|
|
|
|
|
err = 0;
|
|
|
|
|
} else {
|
|
|
|
|
err = i2cBus->writeQuick((uint8_t)0);
|
|
|
|
|
}
|
|
|
|
|
if (err != 0)
|
2023-11-29 00:48:30 -06:00
|
|
|
err = 2;
|
|
|
|
|
#else
|
2023-03-08 19:13:46 -08:00
|
|
|
err = i2cBus->endTransmission();
|
2023-11-29 00:48:30 -06:00
|
|
|
#endif
|
2023-03-08 19:13:46 -08:00
|
|
|
type = NONE;
|
|
|
|
|
if (err == 0) {
|
|
|
|
|
switch (addr.address) {
|
|
|
|
|
case SSD1306_ADDRESS:
|
|
|
|
|
type = probeOLED(addr);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
#ifdef RV3028_RTC
|
|
|
|
|
case RV3028_RTC:
|
|
|
|
|
// foundDevices[addr] = RTC_RV3028;
|
|
|
|
|
type = RTC_RV3028;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("RV3028", (uint8_t)addr.address);
|
2023-03-08 19:13:46 -08:00
|
|
|
rtc.initI2C(*i2cBus);
|
2025-08-04 18:42:39 +02:00
|
|
|
// Update RTC EEPROM settings, if necessary
|
|
|
|
|
if (rtc.readEEPROMRegister(0x35) != 0x07) {
|
|
|
|
|
rtc.writeEEPROMRegister(0x35, 0x07); // no Clkout
|
|
|
|
|
}
|
|
|
|
|
if (rtc.readEEPROMRegister(0x37) != 0xB4) {
|
|
|
|
|
rtc.writeEEPROMRegister(0x37, 0xB4);
|
|
|
|
|
}
|
2023-03-08 19:13:46 -08:00
|
|
|
break;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef PCF8563_RTC
|
2024-11-26 13:59:50 -06:00
|
|
|
SCAN_SIMPLE_CASE(PCF8563_RTC, RTC_PCF8563, "PCF8563", (uint8_t)addr.address)
|
2023-03-08 19:13:46 -08:00
|
|
|
#endif
|
2025-09-30 13:00:01 -05:00
|
|
|
#ifdef RX8130CE_RTC
|
|
|
|
|
SCAN_SIMPLE_CASE(RX8130CE_RTC, RTC_RX8130CE, "RX8130CE", (uint8_t)addr.address)
|
|
|
|
|
#endif
|
2023-03-08 19:13:46 -08:00
|
|
|
|
|
|
|
|
case CARDKB_ADDR:
|
|
|
|
|
// Do we have the RAK14006 instead?
|
|
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x04), 1);
|
|
|
|
|
if (registerValue == 0x02) {
|
|
|
|
|
// KEYPAD_VERSION
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("RAK14004", (uint8_t)addr.address);
|
2023-03-08 19:13:46 -08:00
|
|
|
type = RAK14004;
|
|
|
|
|
} else {
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("M5 cardKB", (uint8_t)addr.address);
|
2023-03-08 19:13:46 -08:00
|
|
|
type = CARDKB;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2025-07-21 19:33:24 +02:00
|
|
|
case TDECK_KB_ADDR:
|
|
|
|
|
// Do we have the T-Deck keyboard or the T-Deck Pro battery sensor?
|
|
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x04), 1);
|
|
|
|
|
if (registerValue != 0) {
|
|
|
|
|
logFoundDevice("BQ27220", (uint8_t)addr.address);
|
|
|
|
|
type = BQ27220;
|
|
|
|
|
} else {
|
|
|
|
|
logFoundDevice("TDECKKB", (uint8_t)addr.address);
|
|
|
|
|
type = TDECKKB;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2024-11-26 13:59:50 -06:00
|
|
|
SCAN_SIMPLE_CASE(BBQ10_KB_ADDR, BBQ10KB, "BB Q10", (uint8_t)addr.address);
|
2024-10-21 16:53:36 +10:00
|
|
|
|
2024-11-26 13:59:50 -06:00
|
|
|
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "ST7567", (uint8_t)addr.address);
|
2023-07-03 16:34:32 +02:00
|
|
|
#ifdef HAS_NCP5623
|
2024-11-26 13:59:50 -06:00
|
|
|
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623", (uint8_t)addr.address);
|
2023-07-03 16:34:32 +02:00
|
|
|
#endif
|
2025-04-01 22:39:40 +02:00
|
|
|
#ifdef HAS_LP5562
|
|
|
|
|
SCAN_SIMPLE_CASE(LP5562_ADDR, LP5562, "LP5562", (uint8_t)addr.address);
|
|
|
|
|
#endif
|
2025-04-03 19:18:18 +00:00
|
|
|
case XPOWERS_AXP192_AXP2101_ADDRESS:
|
|
|
|
|
// Do we have the axp2101/192 or the TCA8418
|
|
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x90), 1);
|
|
|
|
|
if (registerValue == 0x0) {
|
|
|
|
|
logFoundDevice("TCA8418", (uint8_t)addr.address);
|
|
|
|
|
type = TCA8418KB;
|
|
|
|
|
} else {
|
|
|
|
|
logFoundDevice("AXP192/AXP2101", (uint8_t)addr.address);
|
|
|
|
|
type = PMU_AXP192_AXP2101;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2023-03-08 19:13:46 -08:00
|
|
|
case BME_ADDR:
|
|
|
|
|
case BME_ADDR_ALTERNATE:
|
|
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xD0), 1); // GET_ID
|
|
|
|
|
switch (registerValue) {
|
|
|
|
|
case 0x61:
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("BME680", (uint8_t)addr.address);
|
2023-03-08 19:13:46 -08:00
|
|
|
type = BME_680;
|
|
|
|
|
break;
|
|
|
|
|
case 0x60:
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("BME280", (uint8_t)addr.address);
|
2023-03-08 19:13:46 -08:00
|
|
|
type = BME_280;
|
|
|
|
|
break;
|
2024-03-02 22:14:34 +01:00
|
|
|
case 0x55:
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("BMP085/BMP180", (uint8_t)addr.address);
|
2024-03-02 22:14:34 +01:00
|
|
|
type = BMP_085;
|
|
|
|
|
break;
|
2025-03-05 22:58:18 -05:00
|
|
|
case 0x00:
|
|
|
|
|
// do we have a DPS310 instead?
|
|
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0D), 1);
|
|
|
|
|
switch (registerValue) {
|
|
|
|
|
case 0x10:
|
|
|
|
|
logFoundDevice("DPS310", (uint8_t)addr.address);
|
|
|
|
|
type = DPS310;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2023-03-08 19:13:46 -08:00
|
|
|
default:
|
2024-08-17 16:19:39 +10:00
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1); // GET_ID
|
2024-09-02 10:23:31 +02:00
|
|
|
switch (registerValue) {
|
2024-08-17 16:19:39 +10:00
|
|
|
case 0x50: // BMP-388 should be 0x50
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("BMP-388", (uint8_t)addr.address);
|
2024-08-17 16:19:39 +10:00
|
|
|
type = BMP_3XX;
|
|
|
|
|
break;
|
2025-02-20 14:36:49 +01:00
|
|
|
case 0x60: // BMP-390 should be 0x60
|
|
|
|
|
logFoundDevice("BMP-390", (uint8_t)addr.address);
|
|
|
|
|
type = BMP_3XX;
|
|
|
|
|
break;
|
2024-08-17 16:19:39 +10:00
|
|
|
case 0x58: // BMP-280 should be 0x58
|
|
|
|
|
default:
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("BMP-280", (uint8_t)addr.address);
|
2024-08-17 16:19:39 +10:00
|
|
|
type = BMP_280;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-09-02 10:23:31 +02:00
|
|
|
break;
|
2023-03-08 19:13:46 -08:00
|
|
|
}
|
|
|
|
|
break;
|
2024-05-31 18:17:53 +02:00
|
|
|
#ifndef HAS_NCP5623
|
|
|
|
|
case AHT10_ADDR:
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("AHT10", (uint8_t)addr.address);
|
2024-05-31 18:17:53 +02:00
|
|
|
type = AHT10;
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
2025-09-17 22:40:55 +02:00
|
|
|
#if !defined(M5STACK_UNITC6L)
|
2023-03-08 19:13:46 -08:00
|
|
|
case INA_ADDR:
|
|
|
|
|
case INA_ADDR_ALTERNATE:
|
2024-03-16 16:01:43 +01:00
|
|
|
case INA_ADDR_WAVESHARE_UPS:
|
2023-03-08 19:13:46 -08:00
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
|
2024-10-14 06:11:43 +02:00
|
|
|
LOG_DEBUG("Register MFG_UID: 0x%x", registerValue);
|
2023-03-08 19:13:46 -08:00
|
|
|
if (registerValue == 0x5449) {
|
2024-12-21 12:24:29 +11:00
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFF), 2);
|
|
|
|
|
LOG_DEBUG("Register DIE_UID: 0x%x", registerValue);
|
|
|
|
|
|
|
|
|
|
if (registerValue == 0x2260) {
|
|
|
|
|
logFoundDevice("INA226", (uint8_t)addr.address);
|
|
|
|
|
type = INA226;
|
|
|
|
|
} else {
|
|
|
|
|
logFoundDevice("INA260", (uint8_t)addr.address);
|
|
|
|
|
type = INA260;
|
|
|
|
|
}
|
2023-03-08 19:13:46 -08:00
|
|
|
} else { // Assume INA219 if INA260 ID is not found
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("INA219", (uint8_t)addr.address);
|
2023-03-08 19:13:46 -08:00
|
|
|
type = INA219;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2023-11-04 19:07:00 -06:00
|
|
|
case INA3221_ADDR:
|
2024-04-20 14:58:21 -06:00
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
|
2024-11-23 16:56:40 +01:00
|
|
|
LOG_DEBUG("Register MFG_UID FE: 0x%x", registerValue);
|
2024-04-20 14:58:21 -06:00
|
|
|
if (registerValue == 0x5449) {
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("INA3221", (uint8_t)addr.address);
|
2024-04-20 14:58:21 -06:00
|
|
|
type = INA3221;
|
2024-06-03 21:50:28 -05:00
|
|
|
} else {
|
2024-11-23 16:56:40 +01:00
|
|
|
/* check the first 2 bytes of the 6 byte response register
|
|
|
|
|
LARK FW 1.0 should return:
|
|
|
|
|
RESPONSE_STATUS STATUS_SUCCESS (0x53)
|
|
|
|
|
RESPONSE_CMD CMD_GET_VERSION (0x05)
|
|
|
|
|
RESPONSE_LEN_L 0x02
|
|
|
|
|
RESPONSE_LEN_H 0x00
|
|
|
|
|
RESPONSE_PAYLOAD 0x01
|
|
|
|
|
RESPONSE_PAYLOAD+1 0x00
|
|
|
|
|
*/
|
2025-01-18 14:10:13 +01:00
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x05), 6, true);
|
2024-11-23 16:56:40 +01:00
|
|
|
LOG_DEBUG("Register MFG_UID 05: 0x%x", registerValue);
|
|
|
|
|
if (registerValue == 0x5305) {
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("DFRobot Lark", (uint8_t)addr.address);
|
2024-11-23 16:56:40 +01:00
|
|
|
type = DFROBOT_LARK;
|
|
|
|
|
}
|
|
|
|
|
// else: probably a RAK12500/UBLOX GPS on I2C
|
2024-04-20 14:58:21 -06:00
|
|
|
}
|
2024-04-21 11:35:42 -06:00
|
|
|
break;
|
2025-09-17 22:40:55 +02:00
|
|
|
#endif
|
2023-03-23 11:32:04 -05:00
|
|
|
case MCP9808_ADDR:
|
2024-09-12 01:53:17 +02:00
|
|
|
// We need to check for STK8BAXX first, since register 0x07 is new data flag for the z-axis and can produce some
|
|
|
|
|
// weird result. and register 0x00 doesn't seems to be colliding with MCP9808 and LIS3DH chips.
|
|
|
|
|
{
|
2024-11-23 17:18:22 -06:00
|
|
|
#ifdef HAS_STK8XXX
|
2024-09-12 01:53:17 +02:00
|
|
|
// Check register 0x00 for 0x8700 response to ID STK8BA53 chip.
|
|
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 2);
|
|
|
|
|
if (registerValue == 0x8700) {
|
|
|
|
|
type = STK8BAXX;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("STK8BAXX", (uint8_t)addr.address);
|
2024-09-12 01:53:17 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2024-11-23 17:18:22 -06:00
|
|
|
#endif
|
2023-03-23 11:32:04 -05:00
|
|
|
|
2024-09-12 01:53:17 +02:00
|
|
|
// Check register 0x07 for 0x0400 response to ID MCP9808 chip.
|
|
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
|
|
|
|
|
if (registerValue == 0x0400) {
|
|
|
|
|
type = MCP9808;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("MCP9808", (uint8_t)addr.address);
|
2024-09-12 01:53:17 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check register 0x0F for 0x3300 response to ID LIS3DH chip.
|
|
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 2);
|
2024-09-23 18:40:54 -05:00
|
|
|
if (registerValue == 0x3300 || registerValue == 0x3333) { // RAK4631 WisBlock has LIS3DH register at 0x3333
|
2024-09-12 01:53:17 +02:00
|
|
|
type = LIS3DH;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("LIS3DH", (uint8_t)addr.address);
|
2024-09-12 01:53:17 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-03-06 20:49:55 -05:00
|
|
|
case SHT31_4x_ADDR: // same as OPT3001_ADDR_ALT
|
|
|
|
|
case SHT31_4x_ADDR_ALT: // same as OPT3001_ADDR
|
2024-05-10 07:13:12 -05:00
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x89), 2);
|
2025-10-12 03:35:00 -07:00
|
|
|
if (registerValue == 0x11a2 || registerValue == 0x11da || registerValue == 0x11f3 || registerValue == 0xe9c ||
|
|
|
|
|
registerValue == 0xc8d) {
|
2024-05-10 07:13:12 -05:00
|
|
|
type = SHT4X;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("SHT4X", (uint8_t)addr.address);
|
2024-06-02 07:39:08 -05:00
|
|
|
} else if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2) == 0x5449) {
|
|
|
|
|
type = OPT3001;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("OPT3001", (uint8_t)addr.address);
|
2024-05-10 07:13:12 -05:00
|
|
|
} else {
|
|
|
|
|
type = SHT31;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("SHT31", (uint8_t)addr.address);
|
2024-05-10 07:13:12 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
2024-11-26 13:59:50 -06:00
|
|
|
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3", (uint8_t)addr.address)
|
2024-10-07 19:50:44 -05:00
|
|
|
case RCWL9620_ADDR:
|
|
|
|
|
// get MAX30102 PARTID
|
|
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFF), 1);
|
|
|
|
|
if (registerValue == 0x15) {
|
|
|
|
|
type = MAX30102;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("MAX30102", (uint8_t)addr.address);
|
2024-10-07 19:50:44 -05:00
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
type = RCWL9620;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("RCWL9620", (uint8_t)addr.address);
|
2024-10-07 19:50:44 -05:00
|
|
|
}
|
|
|
|
|
break;
|
2023-03-08 19:13:46 -08:00
|
|
|
|
|
|
|
|
case LPS22HB_ADDR_ALT:
|
2024-11-26 13:59:50 -06:00
|
|
|
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB", (uint8_t)addr.address)
|
|
|
|
|
SCAN_SIMPLE_CASE(QMC6310_ADDR, QMC6310, "QMC6310", (uint8_t)addr.address)
|
2024-04-05 13:20:22 +01:00
|
|
|
|
|
|
|
|
case QMI8658_ADDR:
|
|
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0A), 1); // get ID
|
|
|
|
|
if (registerValue == 0xC0) {
|
|
|
|
|
type = BQ24295;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("BQ24295", (uint8_t)addr.address);
|
2024-04-15 13:30:45 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2025-07-21 19:33:24 +02:00
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x14), 1); // get ID
|
|
|
|
|
if ((registerValue & 0b00000011) == 0b00000010) {
|
|
|
|
|
type = BQ25896;
|
|
|
|
|
logFoundDevice("BQ25896", (uint8_t)addr.address);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-04-15 13:30:45 +01:00
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 1); // get ID
|
|
|
|
|
if (registerValue == 0x6A) {
|
|
|
|
|
type = LSM6DS3;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("LSM6DS3", (uint8_t)addr.address);
|
2024-04-05 13:20:22 +01:00
|
|
|
} else {
|
|
|
|
|
type = QMI8658;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("QMI8658", (uint8_t)addr.address);
|
2024-04-05 13:20:22 +01:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2024-11-26 13:59:50 -06:00
|
|
|
SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L", (uint8_t)addr.address)
|
|
|
|
|
SCAN_SIMPLE_CASE(HMC5883L_ADDR, HMC5883L, "HMC5883L", (uint8_t)addr.address)
|
2024-10-26 12:03:28 +02:00
|
|
|
#ifdef HAS_QMA6100P
|
2024-11-26 13:59:50 -06:00
|
|
|
SCAN_SIMPLE_CASE(QMA6100P_ADDR, QMA6100P, "QMA6100P", (uint8_t)addr.address)
|
2024-10-26 12:03:28 +02:00
|
|
|
#else
|
2024-11-26 13:59:50 -06:00
|
|
|
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031", (uint8_t)addr.address)
|
2024-10-26 12:03:28 +02:00
|
|
|
#endif
|
2024-11-07 18:01:58 +01:00
|
|
|
case BMA423_ADDR: // this can also be LIS3DH_ADDR_ALT
|
|
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 2);
|
|
|
|
|
if (registerValue == 0x3300 || registerValue == 0x3333) { // RAK4631 WisBlock has LIS3DH register at 0x3333
|
|
|
|
|
type = LIS3DH;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("LIS3DH", (uint8_t)addr.address);
|
2024-11-07 18:01:58 +01:00
|
|
|
} else {
|
|
|
|
|
type = BMA423;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("BMA423", (uint8_t)addr.address);
|
2024-11-07 18:01:58 +01:00
|
|
|
}
|
|
|
|
|
break;
|
Add rak12035 VB Soil Monitor Tested & Working (#6741)
* [WIP] Add RAK12035VB Soil Moisture Sensor support
Introduce the RAK12035 sensor as an environmental telemetry sensor,
including necessary calibration checks and default values. Update
relevant files to integrate the sensor into the existing telemetry system.
This hardware is not just one module, but a couple.. RAK12023 and
RAK12035 is the component stack, the RAK12023 does not seem to matter
much and allows for multiple RAK12035 devices to be used.
Co-Authored-By: @Justin-Mann
* [WIP] Add RAK12035VB Soil Moisture Sensor support
Introduce the RAK12035 sensor as an environmental telemetry sensor,
including necessary calibration checks and default values. Update
relevant files to integrate the sensor into the existing telemetry system.
This hardware is not just one module, but a couple.. RAK12023 and
RAK12035 is the component stack, the RAK12023 does not seem to matter
much and allows for multiple RAK12035 devices to be used.
Co-Authored-By: @Justin-Mann
* [WIP] Add RAK12035VB Soil Moisture Sensor support
Introduce the RAK12035 sensor as an environmental telemetry sensor,
including necessary calibration checks and default values. Update
relevant files to integrate the sensor into the existing telemetry system.
This hardware is not just one module, but a couple.. RAK12023 and
RAK12035 is the component stack, the RAK12023 does not seem to matter
much and allows for multiple RAK12035 devices to be used.
Co-Authored-By: @Justin-Mann
* [WIP] Add RAK12035VB Soil Moisture Sensor support
Introduce the RAK12035 sensor as an environmental telemetry sensor,
including necessary calibration checks and default values. Update
relevant files to integrate the sensor into the existing telemetry system.
This hardware is not just one module, but a couple.. RAK12023 and
RAK12035 is the component stack, the RAK12023 does not seem to matter
much and allows for multiple RAK12035 devices to be used.
Co-Authored-By: @Justin-Mann
* Update to 1.0.4 release of RAK12035_SoilMoisture
* cleanup
* cool
* .
* ..
* little bit of cleanup and recompile/upload/test on RAK WISBLAOCK STACK: RAK19007/RAK4631/RAK12035VB/RAK12500
looks like soil monitor is working correctly, new environmental metrics are comming thru [new protos soil_moisture, soil_temperature] and GPS is working again with the RAK 12500.
improvements could be made around the configuration of the monitor.
next steps include updating the client(s) to react to, log and display the new proto metrics for soil temp and humidity.
* . comments about current limitations and TODOs
* trunk update
* trying to autoformat..
* fix formatting attempt 2
* ..
* ...
* ...
* .
* some corrections and local build success
* correction in temp code
* grr formatting
* cleanup after a few experiments
* remove temp code to overwrite values for temp and humidity protos.. next step just update the clients to know about soil_temperature and soil_humidity protos.
* update some values in varient for rak wistap
* working out trunk formatting..
* wip
. corrections to other build variants
* .
* protobuffs?
* protobufs?
* Update protobufs ref
* Protobufs ref
* Trunk
* Update RAK12035Sensor.cpp
* Fmt
* comment changes
* dumb mistakes... resolved, actually built and tested.. all good..
* Update src/modules/Telemetry/Sensor/RAK12035Sensor.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/modules/Telemetry/Sensor/RAK12035Sensor.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* . proto submod
* proto
* proto
* merge master
* mabe a fix for GPS pin conflict, waiting on a new gps module to try
* merge master, attempt to fix gps (RAK12500) pin conflict with RAK12023/12035
* .
* .
---------
Co-authored-by: Tom Fifield <tom@tomfifield.net>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-06-19 17:51:03 -06:00
|
|
|
case TCA9535_ADDR:
|
|
|
|
|
case RAK120352_ADDR:
|
|
|
|
|
case RAK120353_ADDR:
|
|
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x02), 1);
|
|
|
|
|
if (registerValue == addr.address) { // RAK12035 returns its I2C address at 0x02 (eg 0x20)
|
|
|
|
|
type = RAK12035;
|
|
|
|
|
logFoundDevice("RAK12035", (uint8_t)addr.address);
|
|
|
|
|
} else {
|
|
|
|
|
type = TCA9535;
|
|
|
|
|
logFoundDevice("TCA9535", (uint8_t)addr.address);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
2024-11-07 18:01:58 +01:00
|
|
|
|
2024-11-26 13:59:50 -06:00
|
|
|
SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3", (uint8_t)addr.address);
|
|
|
|
|
SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555", (uint8_t)addr.address);
|
|
|
|
|
SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700", (uint8_t)addr.address);
|
2025-09-03 23:25:45 -07:00
|
|
|
case TSL25911_ADDR:
|
|
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x12), 1);
|
|
|
|
|
if (registerValue == 0x50) {
|
|
|
|
|
type = TSL2591;
|
|
|
|
|
logFoundDevice("TSL25911", (uint8_t)addr.address);
|
|
|
|
|
} else {
|
|
|
|
|
type = TSL2561;
|
|
|
|
|
logFoundDevice("TSL2561", (uint8_t)addr.address);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2024-11-26 13:59:50 -06:00
|
|
|
SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632", (uint8_t)addr.address);
|
|
|
|
|
SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802", (uint8_t)addr.address);
|
|
|
|
|
SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048", (uint8_t)addr.address);
|
2025-01-18 14:10:13 +01:00
|
|
|
SCAN_SIMPLE_CASE(DFROBOT_RAIN_ADDR, DFROBOT_RAIN, "DFRobot Rain Gauge", (uint8_t)addr.address);
|
2025-03-07 18:51:38 +08:00
|
|
|
SCAN_SIMPLE_CASE(LTR390UV_ADDR, LTR390UV, "LTR390UV", (uint8_t)addr.address);
|
2025-05-25 14:29:02 +02:00
|
|
|
SCAN_SIMPLE_CASE(PCT2075_ADDR, PCT2075, "PCT2075", (uint8_t)addr.address);
|
2025-07-21 19:33:24 +02:00
|
|
|
SCAN_SIMPLE_CASE(CST328_ADDR, CST328, "CST328", (uint8_t)addr.address);
|
|
|
|
|
SCAN_SIMPLE_CASE(LTR553ALS_ADDR, LTR553ALS, "LTR553ALS", (uint8_t)addr.address);
|
|
|
|
|
SCAN_SIMPLE_CASE(BHI260AP_ADDR, BHI260AP, "BHI260AP", (uint8_t)addr.address);
|
2025-07-01 19:34:03 +10:00
|
|
|
SCAN_SIMPLE_CASE(SCD4X_ADDR, SCD4X, "SCD4X", (uint8_t)addr.address);
|
Unify the native display config between legacy display and MUI (#6838)
* Add missed include
* Another Warning fix
* Add another HAS_SCREEN
* Namespace fixes
* Removed depricated destination types and re-factored destination screen
* Get rid of Arduino Strings
* Clean up after Copilot
* SixthLine Def, Screen Rename
Added Sixth Line Definition Screen Rename, and Automatic Line Adjustment
* Consistency is hard - fixed "Sixth"
* System Frame Updates
Adjusted line construction to ensure we fit maximum content per screen.
* Fix up notifications
* Add a couple more ifdef HAS_SCREEN lines
* Add screen->isOverlayBannerShowing()
* Don't forget the invert!
* Adjust Nodelist Center Divider
Adjust Nodelist Center Divider
* Fix variable casting
* Fix entryText variable as empty before update to fix validation
* Altitude is int32_t
* Update PowerTelemetry to have correct data type
* Fix cppcheck warnings (#6945)
* Fix cppcheck warnings
* Adjust logic in Power.cpp for power sensor
---------
Co-authored-by: Jason P <applewiz@mac.com>
* More pixel wrangling so things line up NodeList edition
* Adjust NodeList alignments and plumb some background padding for a possible title fix
* Better alignment for banner notifications
* Move title into drawCommonHeader; initial screen tested
* Fonts make spacing items difficult
* Improved beeping booping and other buzzer based feedback (#6947)
* Improved beeping booping and other buzzer based feedback
* audible button feedback (#6949)
* Refactor
---------
Co-authored-by: todd-herbert <herbert.todd@gmail.com>
* Sandpapered the corners of the notification popup
* Finalize drawCommonHeader migration
* Update Title of Favorite Node Screens
* Update node metric alignment on LoRa screen
* Update the border for popups to separate it from background
* Update PaxcounterModule.cpp with CommonHeader
* Update WiFi screen with CommonHeader and related data reflow
* It was not, in fact, pointing up
* Fix build on wismeshtap
* T-deck trackball debounce
* Fix uptime on Device Focused page to actually detail
* Update Sys screen for new uptime, add label to Freq/Chan on LoRa
* Don't display DOP any longer, make Uptime consistent
* Revert Uptime change on Favorites, Apply to Device Focused
* Label the satelite number to avoid confusion
* Boop boop boop boop
* Correct GPS positioning and string consistency across strings for GPS
* Fix GPS text alignment
* Enable canned messages by default
* Don't wake screen on new nodes
* Cannedmessage list emote support added
* Fn+e emote picker for freetext screen
* Actually block CannedInput actions while display is shown
* Add selection menu to bannerOverlay
* Off by one
* Move to unified text layouts and spacing
* Still my Fav without an "e"
* Fully remove EVENT_NODEDB_UPDATED
* Simply LoRa screen
* Make some char pointers const to fix compilation on native targets
* Update drawCompassNorth to include radius
* Fix warning
* button thread cleanup
* Pull OneButton handling from PowerFSM and add MUI switch (#6973)
* Trunk
* Onebutton Menu Support
* Add temporary clock icon
* Add gps location to fsi
* Banner message state reset
* Cast to char to satisfy compiler
* Better fast handling of input during banner
* Fix warning
* Derp
* oops
* Update ref
* Wire buzzer_mode
* remove legacy string->print()
* Only init screen if one found
* Unsigned Char
* More buttonThread cleaning
* screen.cpp button handling cleanup
* The Great Event Rename of 2025
* Fix the Radiomaster
* Missed trackball type change
* Remove unused function
* Make ButtonThread an InputBroker
* Coffee hadn't kicked in yet
* Add clock icon for Navigation Bar
* Restore clock screen definition code - whoops
* ExternalNotifications now observe inputBroker
* Clock rework (#6992)
* Move Clock bits into ClockRenderer space
* Rework clock into all device navigation
* T-Watch Actually Builds Different
* Compile fix
---------
Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
* Add AM/PM to Digital Clock
* Flip Seconds and AM/PM on Clock Display
* Tik-tok pixels are hard
* Fix builds on Thinknode M1
* Check for GPS and don't crash
* Don't endif til the end
* Rework the OneButton thread to be much less of a mess. (#6997)
* Rework the OneButton thread to be much less of a mess. And break lots of targets temporarily
* Update src/input/ButtonThread.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix GPS toggle
* Send the shutdown event, not just the kbchar
* Honor the back button in a notificaiton popup
* Draw the right size box for popup with options
* Try to un-break all the things
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* 24-hour Clock Should have leading zero, but not 12-hour
* Fixup some compile errors
* Add intRoutine to ButtonThread init, to get more responsive user button back
* Add Timezone picker
* Fix Warning
* Optionally set the initial selection for the chooser popup
* Make back buttons work in canned messages
* Drop the wrapper classes
* LonPressTime now configurable
* Clock Frame can not longer be blank; just add valid time
* Back buttons everywhere!
* Key Verification confirm banner
* Make Elecrow M* top button a back button
* Add settings saves
* EInk responsiveness fixes
* Linux Input Fixes
* Add Native Trackball/Joystick support, and move UserButton to Input
* No Flight Stick Mode
* Send input event
* Add Channel Utilization to Device Focused frame
* Don't shift screens when we draw new ones
* Add showOverlayBanner arguments to no-op
* trunk
* Default Native trackball to NC
* Fix crash in simulator mode
* Add longLong button press
* Get the args right
* Adjust Bluetooth Pairing Screen to account for bottom navigation.
* Trackball everywhere, and unPhone buttons
* Remap visionmaster secondary button to TB_UP
* Kill ScanAndSelect
* trunk
* No longer need the canned messages input filter
* All Canned All the time
* Fix stm32 compile error regarding inputBroker
* Unify tft lineheights (#7033)
* Create variable line heights based upon SCREEN_HEIGHT
* Refactor textPositions into method -> getTextPositions
* Update SharedUIDisplay.h
---------
Co-authored-by: Jason P <applewiz@mac.com>
* Adjust top distance for larger displays
* Adjust icon sizes for larger displays
* Fix Paxcounter compile errors after code updates
* Pixel wrangling to make larger screens fit better
* Alert frame has precedence over banner -- for now
* Unify on ALT_BUTTON
* Align AM/PM to the digit, not the segment on larger displays
* Move some global pin defines into configuration.h
* Scaffolding for BMM150 9-axis gyro
* Alt button behavior
* Don't add the blank GPS frames without HAS_GPS
* EVENT_NODEDB_UPDATED has been retired
* Clean out LOG_WARN messages from debugging
* Add dismiss message function
* Minor buttonThread cleanup
* Add BMM150 support
* Clean up last warning from dev
* Simplify bmm150 init return logic
* Add option to reply to messages
* Add minimal menu upon selecting home screen
* Move Messages to slot 2, rename GPS to Position, move variables nearer functional usage in Screen.cpp
* Properly dismiss message
* T-Deck Trackball press is not user button
* Add select on favorite frame to launch cannedMessage DM
* Minor wording change
* Less capital letters
* Fix empty message check, time isn't reliable
* drop dead code
* Make UIRenderer a static class instead of namespace
* Fix the select on favorite
* Check if message is empty early and then 'return'
* Add kb_found, and show the option to launch freetype if appropriate
* Ignore impossible touchscreen touches
* Auto scroll fix
* Move linebreak after "from" for banners to maximize screen usage.
* Center "No messages to show" on Message frame
* Start consolidating buzzer behavior
* Fixed signed / unsigned warning
* Cast second parameter of max() to make some targets happy
* Cast kbchar to (char) to make arduino string happy
* Shorten the notice of "No messages"
* Add buzzer mode chooser
* Add regionPicker to Lora icon
* Reduce line spacing and reorder Position screen to resolve overlapping issues
* Update message titles, fix GPS icons, add Back options
* Leftover boops
* Remove chirp
* Make the region selection dismissable when a region is already set
* Add read-aloud functionality on messages w/ esp8266sam
* "Last Heard" is a better label
* tweak the beep
* 5 options
* properly tear down freetext upon cancel
* de-convelute canned messages just a bit
* Correct height of Mail icon in navigation bar
* Remove unused warning
* Consolidate time methods into TimeFormatters
* Oops
* Change LoRa Picker Cancel to Back
* Tweak selection characters on Banner
* Message render not scrolling on 5th line
* More fixes for message scrolling
* Remove the safety next on text overflow - we found that root cause
* Add pin definitions to fix compilation for obscure target
* Don't let the touchscreen send unitialized kbchar values
* Make virtual KB just a bit quicker
* No more double tap, swipe!
* Left is left, and Right is right
* Update horizontal lightning bolt design
* Move from solid to dashed separator for Message Frame
* Single emote feature fix
* Manually sort overlapping elements for now
* Freetext and clearer choices
* Fix ESP32 InkHUD builds on the unify-tft branch (#7087)
* Remove BaseUI branding
* Capitalization is fun
* Revert Meshtastic Boot Frame Changes
* Add ANZ_433 LoRa region to picker
* Update settings.json
---------
Co-authored-by: HarukiToreda <116696711+HarukiToreda@users.noreply.github.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Jason P <applewiz@mac.com>
Co-authored-by: todd-herbert <herbert.todd@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-06-21 06:36:04 -05:00
|
|
|
SCAN_SIMPLE_CASE(BMM150_ADDR, BMM150, "BMM150", (uint8_t)addr.address);
|
2024-10-08 14:05:13 +02:00
|
|
|
#ifdef HAS_TPS65233
|
2024-11-26 13:59:50 -06:00
|
|
|
SCAN_SIMPLE_CASE(TPS65233_ADDR, TPS65233, "TPS65233", (uint8_t)addr.address);
|
2024-10-08 14:05:13 +02:00
|
|
|
#endif
|
2024-10-21 16:53:36 +10:00
|
|
|
|
|
|
|
|
case MLX90614_ADDR_DEF:
|
|
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0e), 1);
|
|
|
|
|
if (registerValue == 0x5a) {
|
|
|
|
|
type = MLX90614;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("MLX90614", (uint8_t)addr.address);
|
2024-10-21 16:53:36 +10:00
|
|
|
} else {
|
2025-08-26 16:35:25 +02:00
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1); // DRV2605_REG_STATUS
|
|
|
|
|
if (registerValue == 0xe0) {
|
|
|
|
|
type = DRV2605;
|
|
|
|
|
logFoundDevice("DRV2605", (uint8_t)addr.address);
|
|
|
|
|
} else {
|
|
|
|
|
type = MPR121KB;
|
|
|
|
|
logFoundDevice("MPR121KB", (uint8_t)addr.address);
|
|
|
|
|
}
|
2024-10-21 16:53:36 +10:00
|
|
|
}
|
|
|
|
|
break;
|
2023-03-08 19:13:46 -08:00
|
|
|
|
2024-09-25 21:25:31 +10:00
|
|
|
case ICM20948_ADDR: // same as BMX160_ADDR
|
|
|
|
|
case ICM20948_ADDR_ALT: // same as MPU6050_ADDR
|
|
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
|
|
|
|
|
if (registerValue == 0xEA) {
|
|
|
|
|
type = ICM20948;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("ICM20948", (uint8_t)addr.address);
|
2024-09-25 21:25:31 +10:00
|
|
|
break;
|
|
|
|
|
} else if (addr.address == BMX160_ADDR) {
|
|
|
|
|
type = BMX160;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("BMX160", (uint8_t)addr.address);
|
2024-09-25 21:25:31 +10:00
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
type = MPU6050;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("MPU6050", (uint8_t)addr.address);
|
2024-09-25 21:25:31 +10:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2024-11-24 07:53:52 -05:00
|
|
|
case CGRADSENS_ADDR:
|
|
|
|
|
// Register 0x00 of the RadSens sensor contains is product identifier 0x7D
|
2024-12-09 20:46:13 -05:00
|
|
|
// Undocumented, but some devices return a product identifier of 0x7A
|
2024-11-24 07:53:52 -05:00
|
|
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
|
2024-12-09 20:46:13 -05:00
|
|
|
if (registerValue == 0x7D || registerValue == 0x7A) {
|
2024-11-24 07:53:52 -05:00
|
|
|
type = CGRADSENS;
|
2024-11-26 13:59:50 -06:00
|
|
|
logFoundDevice("ClimateGuard RadSens", (uint8_t)addr.address);
|
2024-11-24 07:53:52 -05:00
|
|
|
break;
|
2024-12-09 20:46:13 -05:00
|
|
|
} else {
|
|
|
|
|
LOG_DEBUG("Unexpected Device ID for RadSense: addr=0x%x id=0x%x", CGRADSENS_ADDR, registerValue);
|
2024-11-24 07:53:52 -05:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2024-12-22 22:53:54 -06:00
|
|
|
case 0x48: {
|
|
|
|
|
i2cBus->beginTransmission(addr.address);
|
|
|
|
|
uint8_t getInfo[] = {0x5A, 0xC0, 0x00, 0xFF, 0xFC};
|
|
|
|
|
uint8_t expectedInfo[] = {0xa5, 0xE0, 0x00, 0x3F, 0x19};
|
|
|
|
|
uint8_t info[5];
|
|
|
|
|
size_t len = 0;
|
|
|
|
|
i2cBus->write(getInfo, 5);
|
|
|
|
|
i2cBus->endTransmission();
|
|
|
|
|
len = i2cBus->readBytes(info, 5);
|
|
|
|
|
if (len == 5 && memcmp(expectedInfo, info, len) == 0) {
|
2024-12-27 18:01:02 +11:00
|
|
|
LOG_INFO("NXP SE050 crypto chip found");
|
2024-12-22 22:53:54 -06:00
|
|
|
type = NXP_SE050;
|
|
|
|
|
|
|
|
|
|
} else {
|
2024-12-27 18:01:02 +11:00
|
|
|
LOG_INFO("FT6336U touchscreen found");
|
2024-12-22 22:53:54 -06:00
|
|
|
type = FT6336U;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-08 19:13:46 -08:00
|
|
|
default:
|
2024-11-26 13:59:50 -06:00
|
|
|
LOG_INFO("Device found at address 0x%x was not able to be enumerated", (uint8_t)addr.address);
|
2023-03-08 19:13:46 -08:00
|
|
|
}
|
|
|
|
|
} else if (err == 4) {
|
2024-11-26 13:59:50 -06:00
|
|
|
LOG_ERROR("Unknown error at address 0x%x", (uint8_t)addr.address);
|
2023-03-08 19:13:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if a type was found for the enumerated device - save, if so
|
|
|
|
|
if (type != NONE) {
|
|
|
|
|
deviceAddresses[type] = addr;
|
|
|
|
|
foundDevices[addr] = type;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-19 19:32:08 +02:00
|
|
|
void ScanI2CTwoWire::scanPort(I2CPort port)
|
|
|
|
|
{
|
2024-05-25 12:37:55 +02:00
|
|
|
scanPort(port, nullptr, 0);
|
2024-05-19 19:32:08 +02:00
|
|
|
}
|
|
|
|
|
|
2025-10-13 18:09:33 +02:00
|
|
|
TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address)
|
2023-03-08 19:13:46 -08:00
|
|
|
{
|
2023-05-30 11:22:29 +08:00
|
|
|
if (address.port == ScanI2C::I2CPort::WIRE) {
|
2023-03-08 19:13:46 -08:00
|
|
|
return &Wire;
|
|
|
|
|
} else {
|
2024-09-18 03:28:23 +12:00
|
|
|
#if WIRE_INTERFACES_COUNT == 2
|
2023-03-08 19:13:46 -08:00
|
|
|
return &Wire1;
|
|
|
|
|
#else
|
|
|
|
|
return &Wire;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t ScanI2CTwoWire::countDevices() const
|
|
|
|
|
{
|
|
|
|
|
return foundDevices.size();
|
2024-07-02 20:03:51 +08:00
|
|
|
}
|
2024-11-26 13:59:50 -06:00
|
|
|
|
|
|
|
|
void ScanI2CTwoWire::logFoundDevice(const char *device, uint8_t address)
|
|
|
|
|
{
|
|
|
|
|
LOG_INFO("%s found at address 0x%x", device, address);
|
|
|
|
|
}
|
2025-07-01 19:34:03 +10:00
|
|
|
#endif
|