From 11598beb160d590cf10948423a7341cda69df007 Mon Sep 17 00:00:00 2001 From: Todd Herbert Date: Tue, 17 Sep 2024 22:12:12 +1200 Subject: [PATCH 1/4] Implement optional second I2C bus for NRF52840 Enabled at compile-time if WIRE_INFERFACES_COUNT defined as 2 --- src/detect/ScanI2CTwoWire.cpp | 6 +++--- src/gps/RTC.cpp | 8 ++++---- src/input/cardKbI2cImpl.cpp | 2 +- src/input/kbI2cBase.cpp | 2 +- src/main.cpp | 4 ++++ 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index f09eb3b95..472a9d70a 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -162,13 +162,13 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) Melopero_RV3028 rtc; #endif -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) if (port == I2CPort::WIRE1) { i2cBus = &Wire1; } else { #endif i2cBus = &Wire; -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) } #endif @@ -423,7 +423,7 @@ TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const if (address.port == ScanI2C::I2CPort::WIRE) { return &Wire; } else { -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) return &Wire1; #else return &Wire; diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index 728284242..98dea4674 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -29,7 +29,7 @@ void readFromRTC() if (rtc_found.address == RV3028_RTC) { uint32_t now = millis(); Melopero_RV3028 rtc; -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) rtc.initI2C(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.initI2C(); @@ -58,7 +58,7 @@ void readFromRTC() uint32_t now = millis(); PCF8563_Class rtc; -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) rtc.begin(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.begin(); @@ -150,7 +150,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate) #ifdef RV3028_RTC if (rtc_found.address == RV3028_RTC) { Melopero_RV3028 rtc; -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) rtc.initI2C(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.initI2C(); @@ -164,7 +164,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate) if (rtc_found.address == PCF8563_RTC) { PCF8563_Class rtc; -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) rtc.begin(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.begin(); diff --git a/src/input/cardKbI2cImpl.cpp b/src/input/cardKbI2cImpl.cpp index 8aaebcb45..1f7fd284d 100644 --- a/src/input/cardKbI2cImpl.cpp +++ b/src/input/cardKbI2cImpl.cpp @@ -16,7 +16,7 @@ void CardKbI2cImpl::init() uint8_t i2caddr_asize = 3; auto i2cScanner = std::unique_ptr(new ScanI2CTwoWire()); -#if defined(I2C_SDA1) +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1, i2caddr_scan, i2caddr_asize); #endif i2cScanner->scanPort(ScanI2C::I2CPort::WIRE, i2caddr_scan, i2caddr_asize); diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 2692fc80d..a25a85d82 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -33,7 +33,7 @@ int32_t KbI2cBase::runOnce() if (!i2cBus) { switch (cardkb_found.port) { case ScanI2C::WIRE1: -#ifdef I2C_SDA1 +#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) LOG_DEBUG("Using I2C Bus 1 (the second one)\n"); i2cBus = &Wire1; if (cardkb_found.address == BBQ10_KB_ADDR) { diff --git a/src/main.cpp b/src/main.cpp index e24ba68b3..0ab9c0e34 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -360,6 +360,8 @@ void setup() Wire1.begin(); #elif defined(I2C_SDA1) && !defined(ARCH_RP2040) Wire1.begin(I2C_SDA1, I2C_SCL1); +#elif defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2) + Wire1.begin(); #endif #if defined(I2C_SDA) && defined(ARCH_RP2040) @@ -427,6 +429,8 @@ void setup() #elif defined(I2C_SDA1) && !defined(ARCH_RP2040) Wire1.begin(I2C_SDA1, I2C_SCL1); i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1); +#elif defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2) + i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1); #endif #if defined(I2C_SDA) && defined(ARCH_RP2040) From f960164c0e68a02c6a66546e470295619efb10d4 Mon Sep 17 00:00:00 2001 From: Todd Herbert Date: Tue, 17 Sep 2024 22:17:53 +1200 Subject: [PATCH 2/4] Add I2C bus to Heltec T114 header pins SDA: P0.13 SCL: P0.16 Uses bus 1, leaving bus 0 routed to the unpopulated footprint for the RTC (general future-proofing) --- variants/heltec_mesh_node_t114/variant.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/variants/heltec_mesh_node_t114/variant.h b/variants/heltec_mesh_node_t114/variant.h index 454e66931..6a7c85b92 100644 --- a/variants/heltec_mesh_node_t114/variant.h +++ b/variants/heltec_mesh_node_t114/variant.h @@ -92,13 +92,22 @@ No longer populated on PCB #define PIN_SERIAL2_TX (0 + 10) // #define PIN_SERIAL2_EN (0 + 17) -/** - Wire Interfaces - */ -#define WIRE_INTERFACES_COUNT 1 +/* + * I2C + */ -#define PIN_WIRE_SDA (26) -#define PIN_WIRE_SCL (27) +#define WIRE_INTERFACES_COUNT 2 + +// I2C bus 0 +// Routed to footprint for PCF8563TS RTC +// Not populated on T114 V1, maybe in future? +#define PIN_WIRE_SDA (0 + 26) // P0.26 +#define PIN_WIRE_SCL (0 + 27) // P0.27 + +// I2C bus 1 +// Available on header pins, for general use +#define PIN_WIRE1_SDA (0 + 13) // P0.13 +#define PIN_WIRE1_SCL (0 + 16) // P0.16 // QSPI Pins #define PIN_QSPI_SCK (32 + 14) From 1487ca2a3025267a5fb3150935863001fc82a5e4 Mon Sep 17 00:00:00 2001 From: Todd Herbert Date: Wed, 18 Sep 2024 03:28:23 +1200 Subject: [PATCH 3/4] Tidier macros --- src/configuration.h | 10 ++++++++++ src/detect/ScanI2CTwoWire.cpp | 6 +++--- src/gps/RTC.cpp | 8 ++++---- src/input/cardKbI2cImpl.cpp | 2 +- src/input/kbI2cBase.cpp | 2 +- src/main.cpp | 2 +- 6 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/configuration.h b/src/configuration.h index 349bd2870..7416e0a3e 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -210,6 +210,16 @@ along with this program. If not, see . #define MINIMUM_SAFE_FREE_HEAP 1500 #endif +#ifndef WIRE_INTERFACES_COUNT +// Officially an NRF52 macro +// Repurposed cross-platform to identify devices using Wire1 +#if defined(I2C_SDA1) || defined(PIN_WIRE_SDA) +#define WIRE_INTERFACES_COUNT 2 +#elif HAS_WIRE +#define WIRE_INTERFACES_COUNT 1 +#endif +#endif + /* Step #3: mop up with disabled values for HAS_ options not handled by the above two */ #ifndef HAS_WIFI diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 472a9d70a..98f40be76 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -162,13 +162,13 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) Melopero_RV3028 rtc; #endif -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 if (port == I2CPort::WIRE1) { i2cBus = &Wire1; } else { #endif i2cBus = &Wire; -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 } #endif @@ -423,7 +423,7 @@ TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const if (address.port == ScanI2C::I2CPort::WIRE) { return &Wire; } else { -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 return &Wire1; #else return &Wire; diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index 98dea4674..b6cab5a6e 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -29,7 +29,7 @@ void readFromRTC() if (rtc_found.address == RV3028_RTC) { uint32_t now = millis(); Melopero_RV3028 rtc; -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 rtc.initI2C(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.initI2C(); @@ -58,7 +58,7 @@ void readFromRTC() uint32_t now = millis(); PCF8563_Class rtc; -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 rtc.begin(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.begin(); @@ -150,7 +150,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate) #ifdef RV3028_RTC if (rtc_found.address == RV3028_RTC) { Melopero_RV3028 rtc; -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 rtc.initI2C(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.initI2C(); @@ -164,7 +164,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate) if (rtc_found.address == PCF8563_RTC) { PCF8563_Class rtc; -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 rtc.begin(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire); #else rtc.begin(); diff --git a/src/input/cardKbI2cImpl.cpp b/src/input/cardKbI2cImpl.cpp index 1f7fd284d..f1df6b137 100644 --- a/src/input/cardKbI2cImpl.cpp +++ b/src/input/cardKbI2cImpl.cpp @@ -16,7 +16,7 @@ void CardKbI2cImpl::init() uint8_t i2caddr_asize = 3; auto i2cScanner = std::unique_ptr(new ScanI2CTwoWire()); -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1, i2caddr_scan, i2caddr_asize); #endif i2cScanner->scanPort(ScanI2C::I2CPort::WIRE, i2caddr_scan, i2caddr_asize); diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index a25a85d82..1d8154bcf 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -33,7 +33,7 @@ int32_t KbI2cBase::runOnce() if (!i2cBus) { switch (cardkb_found.port) { case ScanI2C::WIRE1: -#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)) +#if WIRE_INTERFACES_COUNT == 2 LOG_DEBUG("Using I2C Bus 1 (the second one)\n"); i2cBus = &Wire1; if (cardkb_found.address == BBQ10_KB_ADDR) { diff --git a/src/main.cpp b/src/main.cpp index 0ab9c0e34..447e12a62 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -360,7 +360,7 @@ void setup() Wire1.begin(); #elif defined(I2C_SDA1) && !defined(ARCH_RP2040) Wire1.begin(I2C_SDA1, I2C_SCL1); -#elif defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2) +#elif WIRE_INTERFACES_COUNT == 2 Wire1.begin(); #endif From 76900555e8382baab00ed95ea40de5fc12e0c707 Mon Sep 17 00:00:00 2001 From: Todd Herbert Date: Thu, 19 Sep 2024 02:49:24 +1200 Subject: [PATCH 4/4] Swap SDA and SCL SDA=P0.16, SCL=P0.13 --- variants/heltec_mesh_node_t114/variant.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/variants/heltec_mesh_node_t114/variant.h b/variants/heltec_mesh_node_t114/variant.h index 6a7c85b92..2cea3ef2f 100644 --- a/variants/heltec_mesh_node_t114/variant.h +++ b/variants/heltec_mesh_node_t114/variant.h @@ -106,8 +106,8 @@ No longer populated on PCB // I2C bus 1 // Available on header pins, for general use -#define PIN_WIRE1_SDA (0 + 13) // P0.13 -#define PIN_WIRE1_SCL (0 + 16) // P0.16 +#define PIN_WIRE1_SDA (0 + 16) // P0.16 +#define PIN_WIRE1_SCL (0 + 13) // P0.13 // QSPI Pins #define PIN_QSPI_SCK (32 + 14)