add bus scan with storage for results, not hooked into ctroler

This commit is contained in:
brentru 2025-03-19 11:02:23 -04:00
parent d3f04623aa
commit c2f471fbff
3 changed files with 345 additions and 5 deletions

View file

@ -63,7 +63,9 @@ void I2cHardware::TogglePowerPin() {
/***********************************************************************/
void I2cHardware::InitBus(bool is_default, const char *sda, const char *scl) {
uint8_t pin_sda, pin_scl;
if (!is_default && (sda == nullptr || scl == nullptr)) {
strcpy(_sda, sda);
strcpy(_scl, scl);
if (!is_default && (_sda == nullptr || _scl == nullptr)) {
_bus_status = wippersnapper_i2c_I2cBusStatus_I2C_BUS_STATUS_UNSPECIFIED;
return;
}
@ -85,8 +87,8 @@ void I2cHardware::InitBus(bool is_default, const char *sda, const char *scl) {
pin_scl = PIN_WIRE0_SCL;
#endif
} else {
pin_sda = atoi(sda);
pin_scl = atoi(scl);
pin_sda = atoi(_sda);
pin_scl = atoi(_scl);
}
// Enable pullups
@ -145,6 +147,88 @@ void I2cHardware::InitBus(bool is_default, const char *sda, const char *scl) {
/***********************************************************************/
TwoWire *I2cHardware::GetBus() { return _bus; }
/***********************************************************************/
/*!
@brief Scans the I2C bus for devices.
@param scan_results
The results of the I2C bus scan.
@returns True if the bus was successfully scanned, False otherwise.
*/
/***********************************************************************/
bool I2cHardware::ScanBus(wippersnapper_i2c_I2cBusScanned *scan_results) {
if (!scan_results)
return false;
// TODO: WS object needs to be added for this to work?
/* #ifndef ARDUINO_ARCH_ESP32
// Set I2C WDT timeout to catch I2C hangs, SAMD-specific
WS.enableWDT(I2C_WDT_TIMEOUT_MS);
WS.feedWDT();
#endif */
// Perform a bus scan
WS_DEBUG_PRINTLN("[i2c]: Scanning I2C Bus for Devices...");
for (uint8_t address = 1; address < 127; ++address) {
WS_DEBUG_PRINT("[i2c] 0x");
WS_DEBUG_PRINTLN(address, HEX);
_bus->beginTransmission(address);
uint8_t endTransmissionRC = _bus->endTransmission();
if (endTransmissionRC == 0) {
WS_DEBUG_PRINTLN("[i2c] Found Device!");
scan_results
->i2c_bus_found_devices[scan_results->i2c_bus_found_devices_count]
.i2c_device_address = address;
strcpy(
scan_results
->i2c_bus_found_devices[scan_results->i2c_bus_found_devices_count]
.i2c_bus_sda,
_sda);
strcpy(
scan_results
->i2c_bus_found_devices[scan_results->i2c_bus_found_devices_count]
.i2c_bus_scl,
_scl);
scan_results->i2c_bus_found_devices_count++;
}
#if defined(ARDUINO_ARCH_ESP32)
// Check endTransmission()'s return code (Arduino-ESP32 ONLY)
else if (endTransmissionRC == 3) {
WS_DEBUG_PRINTLN("[i2c] Did not find device: NACK on transmit of data!");
return false;
} else if (endTransmissionRC == 2) {
// WS_DEBUG_PRINTLN("[i2c] Did not find device: NACK on transmit of
// address!");
continue;
} else if (endTransmissionRC == 1) {
WS_DEBUG_PRINTLN(
"[i2c] Did not find device: data too long to fit in xmit buffer!");
return false;
} else if (endTransmissionRC == 4) {
WS_DEBUG_PRINTLN(
"[i2c] Did not find device: Unspecified bus error occured!");
return false;
} else if (endTransmissionRC == 5) {
WS_DEBUG_PRINTLN("[i2c] Did not find device: Bus timed out!");
continue;
}
#endif // ARDUINO_ARCH_ESP32
else {
WS_DEBUG_PRINTLN(
"[i2c] Did not find device: Unknown bus error has occured!");
continue;
}
}
// TODO: Re-enable this?
/* #ifndef ARDUINO_ARCH_ESP32
// re-enable WipperSnapper SAMD WDT global timeout
WS.enableWDT(WS_WDT_TIMEOUT);
WS.feedWDT();
#endif */
return true;
}
/***********************************************************************/
/*!
@brief Adds a MUX to the I2C bus.

View file

@ -35,18 +35,20 @@ public:
const char *scl = nullptr);
TwoWire *GetBus();
wippersnapper_i2c_I2cBusStatus GetBusStatus();
bool ScanBus(wippersnapper_i2c_I2cBusScanned *scan_results);
// MUX
bool AddMuxToBus(uint32_t address_register, const char *name);
void SelectMuxChannel(uint32_t channel);
bool HasMux();
void ClearMuxChannel();
private:
void TogglePowerPin();
wippersnapper_i2c_I2cBusStatus _bus_status; ///< I2C bus status
TwoWire *_bus = nullptr; ///< I2C bus
bool _has_mux; ///< Is a MUX present on the bus?
uint32_t _mux_address_register; ///< I2C address for the MUX
int _mux_max_channels; ///< Maximum possible number of MUX channels
int _mux_max_channels; ///< Maximum possible number of MUX channels
char *_sda; ///< SDA pin
char *_scl; ///< SCL pin
};
#endif // WS_I2C_HARDWARE_H

254
src/ws_boards.h Normal file
View file

@ -0,0 +1,254 @@
/*!
* @file ws_boards.h
*
* This file determines hardware/board type at compile-time.
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* Copyright (c) Brent Rubell 2020-2025 for Adafruit Industries.
*
* BSD license, all text here must be included in any redistribution.
*
*/
#ifndef ADAFRUIT_WIPPERSNAPPER_BOARDS_H
#define ADAFRUIT_WIPPERSNAPPER_BOARDS_H
#if defined(ADAFRUIT_PYPORTAL)
#define BOARD_ID "pyportal-tinyusb"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN 2
#define STATUS_NEOPIXEL_NUM 1
#define SD_CS_PIN 10
#elif defined(ADAFRUIT_PYPORTAL_M4_TITANO)
#define BOARD_ID "pyportal-titano-tinyusb"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN 2
#define STATUS_NEOPIXEL_NUM 1
#define SD_CS_PIN 10
#elif defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE)
#define BOARD_ID "metro-m4-airliftlite-tinyusb"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN 40
#define STATUS_NEOPIXEL_NUM 1
#define SD_CS_PIN 10
#elif defined(ARDUINO_FUNHOUSE_ESP32S2)
#define BOARD_ID "funhouse" ///< Board ID
#define USE_TINYUSB ///< Enable TinyUSB
#define USE_STATUS_DOTSTAR ///< Enable DotStar
#define USE_DISPLAY ///< Enable Display
#define STATUS_DOTSTAR_PIN_DATA PIN_DOTSTAR_DATA ///< DotStar Data Pin
#define STATUS_DOTSTAR_PIN_CLK PIN_DOTSTAR_CLOCK ///< DotStar Clock Pin
#define STATUS_DOTSTAR_NUM 5 ///< Number of DotStar LEDs
#define STATUS_DOTSTAR_COLOR_ORDER DOTSTAR_GBR ///< DotStar Color Order
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
#define SD_CS_PIN 33
#elif defined(ARDUINO_METRO_ESP32S2)
#define BOARD_ID "metroesp32s2"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN 45
#define STATUS_NEOPIXEL_NUM 1
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
#define SD_CS_PIN 33
#elif defined(ARDUINO_METRO_ESP32S3)
#define BOARD_ID "metroesp32s3"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN 46
#define STATUS_NEOPIXEL_NUM 1
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
#define SD_CS_PIN 33
#elif defined(ARDUINO_MAGTAG29_ESP32S2)
#define BOARD_ID "magtag"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN 1
#define STATUS_NEOPIXEL_NUM 4
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
#define SD_CS_PIN 33
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2)
#define BOARD_ID "feather-esp32s2"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN 33
#define STATUS_NEOPIXEL_NUM 1
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
#define SD_CS_PIN 33
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2_TFT)
#define BOARD_ID "feather-esp32s2-tft"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN 33
#define STATUS_NEOPIXEL_NUM 1
#define PIN_I2C_POWER_INVERTED 7
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
#define SD_CS_PIN 33
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2_REVTFT)
#define BOARD_ID "feather-esp32s2-reverse-tft"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
#define STATUS_NEOPIXEL_NUM NEOPIXEL_NUM
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
#define SD_CS_PIN 33
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_NOPSRAM)
#define BOARD_ID "feather-esp32s3"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
#define STATUS_NEOPIXEL_NUM NEOPIXEL_NUM
#define SD_CS_PIN 33
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3)
#define BOARD_ID "feather-esp32s3-4mbflash-2mbpsram"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
#define STATUS_NEOPIXEL_NUM NEOPIXEL_NUM
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
#define SD_CS_PIN 33
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_TFT)
#define BOARD_ID "feather-esp32s3-tft"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
#define STATUS_NEOPIXEL_NUM NEOPIXEL_NUM
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
#define SD_CS_PIN 33
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_REVTFT)
#define BOARD_ID "feather-esp32s3-reverse-tft"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
#define STATUS_NEOPIXEL_NUM NEOPIXEL_NUM
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
#define SD_CS_PIN 33
#elif defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2)
#define BOARD_ID "qtpy-esp32s2"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
#define STATUS_NEOPIXEL_NUM 1
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
#define I2c_STEMMA_WIRE1
#define SD_CS_PIN 33
#elif defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM)
#define BOARD_ID "qtpy-esp32s3"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_NUM 1
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
#define I2c_STEMMA_WIRE1
#define SD_CS_PIN 33
#elif defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_N4R2)
#define BOARD_ID "qtpy-esp32s3-n4r2"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
#define STATUS_NEOPIXEL_NUM 1
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
#define I2c_STEMMA_WIRE1
#define SD_CS_PIN 33
#elif defined(ARDUINO_ADAFRUIT_QTPY_ESP32C3)
#define BOARD_ID "qtpy-esp32c3"
#define USE_LITTLEFS
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
#define STATUS_NEOPIXEL_NUM 1
#define SD_CS_PIN 33
#elif defined(ARDUINO_ESP8266_ADAFRUIT_HUZZAH)
#define BOARD_ID "feather-esp8266"
#define USE_LITTLEFS
#define USE_STATUS_LED
#define STATUS_LED_PIN 0
#define SD_CS_PIN 33
#elif defined(ARDUINO_ADAFRUIT_ITSYBITSY_ESP32)
#define BOARD_ID "itsybitsy-esp32"
#define USE_LITTLEFS
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
#define STATUS_NEOPIXEL_NUM 1
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
#define SD_CS_PIN 33
#elif defined(ARDUINO_FEATHER_ESP32)
#define BOARD_ID "feather-esp32"
#define USE_LITTLEFS
#define USE_STATUS_LED
#define STATUS_LED_PIN 13
#define SD_CS_PIN 33
#elif defined(ARDUINO_ESP32_DEV) || defined(ESP32_DEV)
#define BOARD_ID "feather-esp32"
#define USE_STATUS_LED
#define STATUS_LED_PIN 13
#define SD_CS_PIN 33
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
#define BOARD_ID "feather-esp32-v2"
#define USE_LITTLEFS
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
#define STATUS_NEOPIXEL_NUM 1
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
#define SD_CS_PIN 33
#elif defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO)
#define BOARD_ID "qtpy-esp32"
#define USE_LITTLEFS
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
#define STATUS_NEOPIXEL_NUM 1
#define USE_PSRAM ///< Board has PSRAM, use it for dynamic memory allocation
#define I2c_STEMMA_WIRE1
#define SD_CS_PIN 33
#elif defined(ARDUINO_SAMD_NANO_33_IOT)
#define BOARD_ID "nano-33-iot"
#define USE_STATUS_LED
#define STATUS_LED_PIN 13
#define SD_CS_PIN 33
#elif defined(ARDUINO_SAMD_MKRWIFI1010)
#define BOARD_ID "mkrwifi1010"
#define USE_STATUS_LED
#define STATUS_LED_PIN 6
#define SD_CS_PIN 33
#elif defined(ARDUINO_RASPBERRY_PI_PICO_W)
#define BOARD_ID "rpi-pico-w"
#define USE_TINYUSB
#define USE_STATUS_LED
#define STATUS_LED_PIN 32
#define SD_CS_PIN 33
#elif defined(ARDUINO_RASPBERRY_PI_PICO)
#define BOARD_ID "rpi-pico"
#define USE_TINYUSB
#define USE_STATUS_LED
#define STATUS_LED_PIN LED_BUILTIN
#define SD_CS_PIN 33
#elif defined(ARDUINO_RASPBERRY_PI_PICO_2)
#define BOARD_ID "rpi-pico-2"
#define USE_TINYUSB
#define USE_STATUS_LED
#define STATUS_LED_PIN LED_BUILTIN
#define SD_CS_PIN 33
#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_ADALOGGER)
#define BOARD_ID "feather-rp2040-adalogger"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
#define STATUS_NEOPIXEL_NUM 1
#define SD_USE_SPI_1
#define SD_CS_PIN 23
#elif defined(ARDUINO_ADAFRUIT_METRO_RP2350)
#define BOARD_ID "metro-rp2350"
#define USE_TINYUSB
#define USE_STATUS_NEOPIXEL
#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL
#define STATUS_NEOPIXEL_NUM NUM_NEOPIXEL
#define SD_USE_SPI_1
#define SD_CS_PIN 39
#else
#warning "Board type not identified within Wippersnapper_Boards.h!"
#endif
#endif // ADAFRUIT_WIPPERSNAPPER_BOARDS_H