Title: Hardware Integration Description: Understanding hardware quirks and bus conflicts in GhostESP. URL: /v2.1/development/hardware-integration/ Version: v2.1 Section: Development Search index: /search-index.json # Hardware Integration > Understanding hardware quirks and bus conflicts in GhostESP. ## On this page - [IO Expander (TCA9535 / CH422G)](#io-expander-tca9535--ch422g) - [Shared I2C Bus](#shared-i2c-bus) - [Configuration](#configuration) - [Code Considerations](#code-considerations) - [Shared TFT/SD SPI Bus](#shared-tftsd-spi-bus) - [When It Applies](#when-it-applies) - [How It Works](#how-it-works) - [Performance Impact](#performance-impact) - [Configuring](#configuring) - [Multiple SPI Buses](#multiple-spi-buses) - [Conflicts to Avoid](#conflicts-to-avoid) - [NRF24 SPI Configuration](#nrf24-spi-configuration) - [GhostLink Multi-Device Setup](#ghostlink-multi-device-setup) - [Use Cases](#use-cases) - [UART Configuration](#uart-configuration) - [Remote Commands](#remote-commands) - [Display Menu Integration](#display-menu-integration) - [BadUSB (ESP32-S3 Only)](#badusb-esp32-s3-only) - [Pin Configuration](#pin-configuration) - [USB Mode Conflicts](#usb-mode-conflicts) - [Ethernet (W5500)](#ethernet-w5500) - [Pin Configuration](#pin-configuration-1) - [SPI Bus Sharing](#spi-bus-sharing) - [Infrared](#infrared) - [Pin Configuration](#pin-configuration-2) - [No Bus Conflicts](#no-bus-conflicts) - [Troubleshooting Bus Conflicts](#troubleshooting-bus-conflicts) - [Symptoms](#symptoms) - [Solutions](#solutions) --- GhostESP supports many hardware configurations, but some combinations require special handling due to shared resources. ## IO Expander (TCA9535 / CH422G) Some boards use an I2C IO expander to provide additional GPIO pins for buttons, joysticks, or other peripherals. ### Shared I2C Bus The IO expander typically shares its I2C bus with: - Status display (OLED) — Secondary display on boards like Heltec V3 - Compass (QMC6309) — If configured on the expander ### Configuration In menuconfig under Ghost ESP Options → Misc Options: - CONFIG_USE_IO_EXPANDER — Enable TCA9535 IO expander - CONFIG_IO_EXPANDER_SDA_PIN / CONFIG_IO_EXPANDER_SCL_PIN — I2C pins - CONFIG_IO_EXPANDER_I2C_ADDR — I2C address (default 0x74) ### Code Considerations When the compass is on the IO expander (CONFIG_COMPASS_ON_EXPANDER), I2C communication uses bit-banged GPIO through the expander rather than hardware I2C. This is slower but allows pin expansion. ## Shared TFT/SD SPI Bus Some boards share SPI pins between the TFT display and SD card to reduce pin count. ### When It Applies Enable CONFIG_SHARED_TFT_SD_SPI in menuconfig when: - MOSI, MISO, and CLK pins are the same for both display and SD - Only CS pins differ between the two devices ### How It Works The SD card manager coordinates with LVGL to avoid bus conflicts by suspending the LVGL display task during SD operations: ### Performance Impact - Shared bus limits SPI clock to 4 MHz for reliability - Display may flicker or pause during heavy SD operations - Separate SPI buses are recommended for best performance ### Configuring In menuconfig under Ghost ESP Options → SPI and MMC Configuration: - CONFIG_SHARED_TFT_SD_SPI — Enable shared bus coordination ## Multiple SPI Buses ESP32 chips have multiple SPI controllers, but they must be allocated carefully: SPI Host | Typical Use | Notes | SPI1_HOST | Flash (internal) | Do not use | SPI2_HOST | Display, SD, or NRF24 | Most common for peripherals | SPI3_HOST | Alternative peripheral | Available on most chips | ### Conflicts to Avoid - Display + SD on same SPI: Use CONFIG_SHARED_TFT_SD_SPI - NRF24 + Display on same SPI: Possible but requires coordination - SD in 1-bit SDIO mode: Uses separate pins, no SPI conflict ### NRF24 SPI Configuration NRF24 can use SPI2 or SPI3: CONFIG_NRF24_SPI_HOST=2 # SPI2_HOST CONFIG_NRF24_SPI_MOSI_PIN=14 CONFIG_NRF24_SPI_MISO_PIN=21 CONFIG_NRF24_SPI_SCK_PIN=13 CONFIG_NRF24_CSN_PIN=12 CONFIG_NRF24_CE_PIN=11 ## GhostLink Multi-Device Setup GhostLink allows two ESP32 devices to communicate via UART, enabling split workloads. ### Use Cases - Display controller + attack radio: C5 with screen controls S3 that runs Wi-Fi attacks - WebUI + scanning: One device hosts AP, other performs scans - GPS routing: S3 receives GPS data, streams to C5 via GhostLink ### UART Configuration Default pins vary by chip: Chip | TX Pin | RX Pin | ESP32-S3 | GPIO 6 | GPIO 7 | ESP32 (base) | GPIO 17 | GPIO 16 | Change via CLI: commsetpins <tx> <rx> ### Remote Commands Use commsend to route commands to the peer device: commsend scanap # Scan on peer commsend karma start # Start karma on peer commsend gpsinfo # Get GPS info from peer ### Display Menu Integration When GhostLink is active, the options screen shows a GhostLink menu with remote attack controls. These automatically wrap commands with commsend: // options_screen.c simulateCommand("commsend scanap"); simulateCommand("commsend karma start"); ## BadUSB (ESP32-S3 Only) BadUSB uses TinyUSB in device mode, which conflicts with USB Host mode. ### Pin Configuration CONFIG_HAS_BADUSB=y CONFIG_BADUSB_VSENSE_PIN=-1 # Or valid GPIO for VBUS sense ### USB Mode Conflicts - BadUSB active: USB port acts as HID keyboard to host PC - USB Host mode: USB port reads from external USB keyboard - CDC Console: USB serial for debugging These modes are mutually exclusive. The device typically defaults to CDC console and switches modes on demand. ## Ethernet (W5500) Ethernet uses SPI, which may conflict with other SPI peripherals. ### Pin Configuration CONFIG_WITH_ETHERNET=y CONFIG_ETH_W5500_MOSI_PIN=6 CONFIG_ETH_W5500_MISO_PIN=5 CONFIG_ETH_W5500_SCK_PIN=4 CONFIG_ETH_W5500_CS_PIN=15 CONFIG_ETH_W5500_INT_PIN=7 # Optional, -1 to disable ### SPI Bus Sharing If Ethernet shares SPI with display or SD: - Use a different CS pin for each device - Consider SPI clock speed compatibility - May require CONFIG_SHARED_TFT_SD_SPI style coordination ## Infrared IR TX/RX uses RMT (Remote Control Transceiver) peripheral, which is separate from SPI. ### Pin Configuration CONFIG_HAS_INFRARED=y CONFIG_INFRARED_LED_PIN=0 # TX pin CONFIG_HAS_INFRARED_RX=y CONFIG_INFRARED_RX_PIN=0 # RX pin ### No Bus Conflicts RMT is independent of SPI and I2C, so IR can operate alongside display, SD, and other peripherals without coordination. ## Troubleshooting Bus Conflicts ### Symptoms - Display corruption during SD writes - SD card mount failures when display active - SPI devices not responding - Random crashes during multi-peripheral operations ### Solutions - Check pin assignments: Ensure no two devices use the same CS pin - Enable shared bus coordination: CONFIG_SHARED_TFT_SD_SPI - Reduce SPI clock speed: Lower CONFIG_NRF24_SPI_CLOCK_HZ or SD clock - Separate SPI buses: Move one device to SPI3_HOST if available - Check I2C address conflicts: IO expander, status display, and compass must have unique addresses