diff --git a/.github/workflows/buil_parallel.yml b/.github/workflows/buil_parallel.yml index 08fb9432b7..15f6b5a00e 100644 --- a/.github/workflows/buil_parallel.yml +++ b/.github/workflows/buil_parallel.yml @@ -21,7 +21,7 @@ jobs: - { env: "m5stack-sticks3", family: "ESP32-S3",} - { env: "m5stack-cplus2", family: "ESP32",} - { env: "m5stack-cplus1_1", family: "ESP32",} - - { env: "LAUNCHER_m5stack-cplus1_1", family: "ESP32",} + # - { env: "LAUNCHER_m5stack-cplus1_1", family: "ESP32",} - { env: "m5stack-core2", family: "ESP32",} - { env: "m5stack-core16mb", family: "ESP32",} - { env: "m5stack-core4mb", family: "ESP32",} @@ -29,6 +29,7 @@ jobs: - { env: "esp32-s3-devkitc-1", family: "ESP32-S3",} - { env: "esp32-c5", family: "ESP32-C5",} - { env: "esp32-c5-tft", family: "ESP32-C5",} + - { env: "nm-cyd-c5", family: "ESP32-C5",} - { env: "CYD-2432S028", family: "ESP32",} - { env: "CYD-2USB", family: "ESP32",} - { env: "CYD-2432W328C", family: "ESP32",} @@ -55,6 +56,8 @@ jobs: - { env: "lilygo-t-display-ttgo", family: "ESP32",} - { env: "lilygo-t-hmi", family: "ESP32-S3",} - { env: "lilygo-t-lora-pager", family: "ESP32-S3",} + - { env: "elecrow-24B", family: "ESP32",} + - { env: "elecrow-28B", family: "ESP32",} - { env: "smoochiee-board", family: "ESP32-S3",} - { env: "reaper", family: "ESP32-S3",} - { env: "Phantom_S024R", family: "ESP32",} diff --git a/.github/workflows/manual_build_sel_env.yml b/.github/workflows/manual_build_sel_env.yml index 08accee001..9081eba190 100644 --- a/.github/workflows/manual_build_sel_env.yml +++ b/.github/workflows/manual_build_sel_env.yml @@ -85,6 +85,11 @@ jobs: with: python-version: "3.13" + - name: Install build deps (multilib) + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends gcc-multilib libc6-dev-i386 + - name: Cache pip uses: actions/cache@v4 with: diff --git a/.gitignore b/.gitignore index db25b5ed35..243b5b105e 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ docker-logs lib/mquickjs_headers/mqjs_stdlib_generator lib/mquickjs_headers/mqjs_stdlib_generator.exe .github/agents/Bruce-AI.agent.md +.idea +.ai \ No newline at end of file diff --git a/README.md b/README.md index da6d9d7d17..b46e35989a 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,11 @@ It also supports M5stack and Lilygo products and works great with Cardputer, Sti ## :building_construction: How to install ### The easiest way to install Bruce is using our official Web Flasher! + ### Check out: https://bruce.computer/flasher Alternatively, you can download the latest binary from releases or actions and flash locally using esptool.py + ```sh esptool.py --port /dev/ttyACM0 write_flash 0x00000 Bruce-.bin ``` @@ -23,15 +25,14 @@ If you already use M5Launcher to manage your m5stack device, you can install it Or you can burn it directly from the [m5burner tool](https://docs.m5stack.com/en/download), just search for 'Bruce' (My official builds will be uploaded by "owner" and have photos.) on the device category you want to and click on burn - ## :keyboard: Discord Server Contact us in our [Discord Server](https://discord.gg/WJ9XF9czVT)! ## :bookmark_tabs: Wiki -For more information on each function supported by Bruce, [read our wiki here](https://github.com/pr3y/Bruce/wiki). -Also, [read our FAQ](https://github.com/pr3y/Bruce/wiki/FAQ) +For more information on each function supported by Bruce, [read our wiki here](https://wiki.bruce.computer/). +Also, [read our FAQ](https://wiki.bruce.computer/faq/) ## :computer: List of Features @@ -41,25 +42,25 @@ Also, [read our FAQ](https://github.com/pr3y/Bruce/wiki/FAQ) - [x] Connect to WiFi - [x] WiFi AP - [x] Disconnect WiFi -- [x] [WiFi Atks](https://github.com/pr3y/Bruce/wiki/WiFi#wifi-atks) - - [x] [Beacon Spam](https://github.com/pr3y/Bruce/wiki/WiFi#beacon-spam) - - [x] [Target Atk](https://github.com/pr3y/Bruce/wiki/WiFi#target-atk) +- [x] [WiFi Atks](https://wiki.bruce.computer/features/wifi/#wifi-atks) + - [x] [Beacon Spam](https://wiki.bruce.computer/features/wifi/#beacon-spam) + - [x] [Target Atk](https://wiki.bruce.computer/features/wifi/#target-atks) - [x] Information - [x] Target Deauth - [x] EvilPortal + Deauth - [x] Deauth Flood (More than one target) -- [x] [Wardriving](https://github.com/pr3y/Bruce/wiki/Wardriving) -- [x] [TelNet](https://github.com/pr3y/Bruce/wiki/WiFi#telnet) -- [x] [SSH](https://github.com/pr3y/Bruce/wiki/WiFi#ssh) -- [x] [RAW Sniffer](https://github.com/pr3y/Bruce/wiki/WiFi#raw-sniffer) -- [x] [TCP Client](https://github.com/pr3y/Bruce/wiki/WiFi#tcp-client) -- [x] [TCP Listener](https://github.com/pr3y/Bruce/wiki/WiFi#tcp-listener) -- [x] [Evil Portal](https://github.com/pr3y/Bruce/wiki/WiFi#evil-portal) -- [x] [Scan Hosts](https://github.com/pr3y/Bruce/wiki/WiFi#evil-portal) (with TCP Port scanning) -- [x] [Responder](https://github.com/BruceDevices/firmware/wiki/WiFi#responder) -- [x] [Arp Spoofing](https://github.com/BruceDevices/firmware/wiki/WiFi#arp-spoofing) -- [x] [Arp Poisoning](https://github.com/BruceDevices/firmware/wiki/WiFi#arp-poisoning) -- [x] [Wireguard Tunneling](https://github.com/pr3y/Bruce/wiki/WiFi#wireguard-tunneling) +- [x] [Wardriving](https://wiki.bruce.computer/features/gps/#wardriving) +- [x] [TelNet](https://wiki.bruce.computer/features/wifi/#telnet) +- [x] [SSH](https://wiki.bruce.computer/features/wifi/#ssh) +- [x] [RAW Sniffer](https://wiki.bruce.computer/features/wifi/#raw-sniffer) +- [x] [TCP Client](https://wiki.bruce.computer/features/wifi/#client-tcp) +- [x] [TCP Listener](https://wiki.bruce.computer/features/wifi/#listen-tcp) +- [x] [Evil Portal](https://wiki.bruce.computer/features/wifi/#evil-portal) +- [x] [Scan Hosts](https://wiki.bruce.computer/features/wifi/#scan-hosts) (with TCP Port scanning) +- [x] [Responder](https://wiki.bruce.computer/features/wifi/#responder) +- [x] [Arp Spoofing](https://wiki.bruce.computer/features/wifi/#arp-spoofing) +- [x] [Arp Poisoning](https://wiki.bruce.computer/features/wifi/#arp-poisoning) +- [x] [Wireguard Tunneling](https://wiki.bruce.computer/features/wifi/#wireguard-tunneling) - [x] Brucegotchi - [x] Pwnagotchi friend - [x] Pwngrid spam faces & names @@ -71,32 +72,31 @@ Also, [read our FAQ](https://github.com/pr3y/Bruce/wiki/FAQ)

BLE

-- [X] [BLE Scan](https://github.com/pr3y/Bruce/wiki/BLE#ble-scan) -- [X] Bad BLE - Run Ducky scripts, similar to [BadUsb](https://github.com/pr3y/Bruce/wiki/Others#badusb) -- [X] BLE Keyboard - Cardputer and T-Deck Only -- [X] iOS Spam -- [X] Windows Spam -- [X] Samsung Spam -- [X] Android Spam -- [X] Spam All +- [x] [BLE Scan](https://wiki.bruce.computer/features/ble/#ble-scan) +- [x] Bad BLE - Run Ducky scripts, similar to [BadUsb](https://wiki.bruce.computer/features/ble/#badble) +- [x] BLE Keyboard - Cardputer and T-Deck Only +- [x] iOS Spam +- [x] Windows Spam +- [x] Samsung Spam +- [x] Android Spam +- [x] Spam All
-

RF

- [x] Scan/Copy -- [x] [Custom SubGhz](https://github.com/pr3y/Bruce/wiki/RF#replay-payloads-like-flipper) +- [x] [Custom SubGhz](https://wiki.bruce.computer/features/rf/#replay-payloads-like-flipper) - [x] Spectrum - [x] Jammer Full (sends a full squared wave into output) - [x] Jammer Intermittent (sends PWM signal into output) - [x] Config - - [X] RF TX Pin - - [X] RF RX Pin - - [X] RF Module - - [x] RF433 T/R M5Stack - - [x] [CC1101 (Sub-Ghz)](https://github.com/pr3y/Bruce/wiki/CC1101) - - [X] RF Frequency + - [x] RF TX Pin + - [x] RF RX Pin + - [x] RF Module + - [x] RF433 T/R M5Stack + - [x] [CC1101 (Sub-Ghz)](https://wiki.bruce.computer/features/rf/#cc1101) + - [x] RF Frequency - [x] Replay
@@ -114,9 +114,9 @@ Also, [read our FAQ](https://github.com/pr3y/Bruce/wiki/FAQ) - [x] Save file - [x] Load file - [x] Config - - [X] [RFID Module](https://github.com/pr3y/Bruce/wiki/RFID#supported-modules) - - [x] PN532 - - [x] PN532Killer + - [x] [RFID Module](https://wiki.bruce.computer/features/rfid/#supported-modules) + - [x] PN532 + - [x] PN532Killer - [ ] Emulate tag @@ -125,78 +125,76 @@ Also, [read our FAQ](https://github.com/pr3y/Bruce/wiki/FAQ) - [x] TV-B-Gone - [x] IR Receiver -- [x] [Custom IR (NEC, NECext, SIRC, SIRC15, SIRC20, Samsung32, RC5, RC5X, RC6)](https://github.com/pr3y/Bruce/wiki/IR#replay-payloads-like-flipper) -- [x] Config - - [X] Ir TX Pin - - [X] Ir RX Pin +- [x] [Custom IR (NEC, NECext, SIRC, SIRC15, SIRC20, Samsung32, RC5, RC5X, RC6)](https://wiki.bruce.computer/features/ir/#replay-payloads-like-flipper) +- [x] Config - [X] Ir TX Pin - [X] Ir RX Pin

FM

-- [x] [Broadcast standard](https://github.com/pr3y/Bruce/wiki/FM#play_or_pause_button-broadcast-standard) -- [x] [Broadcast reserved](https://github.com/pr3y/Bruce/wiki/FM#no_entry_sign-broadcast-rerserved) -- [x] [Broadcast stop](https://github.com/pr3y/Bruce/wiki/FM#stop_button-broadcast-stop) -- [ ] [FM Spectrum](https://github.com/pr3y/Bruce/wiki/FM#ocean-fm-spectrum) -- [ ] [Hijack Traffic Announcements](https://github.com/pr3y/Bruce/wiki/FM#car-hijack-ta) -- [ ] [Config](https://github.com/pr3y/Bruce/wiki/FM#bookmark_tabs-config) +- [x] [Broadcast standard](https://wiki.bruce.computer/features/fm/#broadcast-standard) +- [x] [Broadcast reserved](https://wiki.bruce.computer/features/fm/#broadcast-standard) +- [x] [Broadcast stop](https://wiki.bruce.computer/features/fm/#broadcast-stop) +- [ ] [FM Spectrum](https://wiki.bruce.computer/features/fm/#fm-spectrum) +- [ ] [Hijack Traffic Announcements](https://wiki.bruce.computer/features/fm/#hijack-ta) +- [ ] [Config](https://wiki.bruce.computer/features/fm/#bookmark_tabs-config)

NRF24

-- [X] [NRF24 Jammer](https://github.com/pr3y/Bruce/wiki/BLE#nrf24-jammer) -- [X] 2.4G Spectrum +- [x] [NRF24 Jammer](https://wiki.bruce.computer/features/nrf24/) +- [x] 2.4G Spectrum - [ ] Mousejack

Scripts

-- [X] [JavaScript Interpreter](https://github.com/pr3y/Bruce/wiki/Interpreter) [Credits to justinknight93](https://github.com/justinknight93/Doolittle) +- [x] [JavaScript Interpreter](https://wiki.bruce.computer/features/js-interpreter/) [Credits to justinknight93](https://github.com/justinknight93/Doolittle)

Others

-- [X] Mic Spectrum -- [X] QRCodes - - [x] Custom - - [x] PIX (Brazil bank transfer system) +- [x] Mic Spectrum +- [x] [QRCodes](https://wiki.bruce.computer/features/others/#qrcodes) + - [x] Custom + - [x] PIX (Brazil bank transfer system) - [x] [SD Card Mngr](https://github.com/pr3y/Bruce/wiki/Others#sd-card-mngr) - - [x] View image (jpg) - - [x] File Info - - [x] [Wigle Upload](https://github.com/pr3y/Bruce/wiki/Wardriving#how-to-upload) - - [x] Play Audio - - [x] View File -- [x] [LittleFS Mngr](https://github.com/pr3y/Bruce/wiki/Others#littlefs-mngr) -- [x] [WebUI](https://github.com/pr3y/Bruce/wiki/Others#webui) - - [x] Server Structure - - [x] Html - - [x] SDCard Mngr - - [x] Spiffs Mngr + - [x] View image (jpg) + - [x] File Info + - [x] [Wigle Upload](https://wiki.bruce.computer/features/gps/#how-to-use-wigle) + - [x] Play Audio + - [x] View File +- [x] LittleFS Mngr +- [x] [WebUI](https://wiki.bruce.computer/controlling-device/webui/) + - [x] Server Structure + - [x] Html + - [x] SDCard Mngr + - [x] Spiffs Mngr - [x] Megalodon -- [x] [BADUsb (New features, LittleFS and SDCard)](https://github.com/pr3y/Bruce/wiki/Others#badusb) +- [x] [BADUsb (New features, LittleFS and SDCard)](https://wiki.bruce.computer/features/others/#badusb) - [x] USB Keyboard - Cardputer and T-Deck Only -- [x] [iButton](https://github.com/pr3y/Bruce/wiki/Others#ibutton) -- [x] [LED Control](https://github.com/pr3y/Bruce/wiki/Others#led-control) +- [x] [iButton](https://wiki.bruce.computer/features/others/#ibutton) +- [x] LED Control

Clock

-- [X] RTC Support -- [X] NTP time adjust -- [X] Manual adjust +- [x] RTC Support +- [x] NTP time adjust +- [x] Manual adjust

Connect (ESPNOW)

-- [X] Send File -- [X] Receive File -- [X] Send Commands -- [X] Receive Commands +- [x] Send File +- [x] Receive File +- [x] Send Commands +- [x] Receive Commands
@@ -205,7 +203,7 @@ Also, [read our FAQ](https://github.com/pr3y/Bruce/wiki/FAQ) - [x] Brightness - [x] Dim Time - [x] Orientation -- [X] UI Color +- [x] UI Color - [x] Boot Sound on/off - [x] Clock - [x] Sleep @@ -213,30 +211,30 @@ Also, [read our FAQ](https://github.com/pr3y/Bruce/wiki/FAQ)
## Specific functions per Device, the ones not mentioned here are available to all. -| Device | CC1101 | NRF24 | FM Radio | PN532 | Mic | BadUSB | RGB Led | Speaker | Fuel Guage | LITE_VERSION | -| --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | -| [M5Stack Cardputer](https://shop.m5stack.com/products/m5stack-cardputer-kit-w-m5stamps) (and ADV) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | NS4168 | :x: | :x: | -| [M5Stack M5StickC PLUS2](https://shop.m5stack.com/products/m5stickc-plus2-esp32-mini-iot-development-kit) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | Tone | :x: | :x: | -| [M5Stack M5StickC PLUS](https://shop.m5stack.com/products/m5stickc-plus-esp32-pico-mini-iot-development-kit) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | Tone | :x: | :x:² | -| [M5Stack M5Core BASIC](https://shop.m5stack.com/products/basic-core-iot-development-kit) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | Tone | :x: | :x: | -| [M5Stack M5Core2](https://shop.m5stack.com/products/m5stack-core2-esp32-iot-development-kit-v1-1) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | :x: | :x: | :x: | -| [M5Stack M5CoreS3](https://shop.m5stack.com/products/m5stack-cores3-esp32s3-lotdevelopment-kit)/[SE](https://shop.m5stack.com/products/m5stack-cores3-se-iot-controller-w-o-battery-bottom) | :ok: | :ok: | :ok: | :ok: | :x: | :ok: | :x: | :x: | :x: | :x: | -| [JCZN CYD‑2432S028](https://www.aliexpress.us/item/3256804774970998.html) | :ok: | :ok: | :ok: | :ok: | :x: | :ok:¹ | :x: | :x: | :x: | :x:² | -| [Lilygo T‑Embed CC1101](https://lilygo.cc/products/t-embed-cc1101) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :x: | -| [Lilygo T‑Embed](https://lilygo.cc/products/t-embed) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :x: | :x: | -| [Lilygo T-Display-S3](https://lilygo.cc/products/t-display-s3) | :ok: | :ok: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | -| [Lilygo T‑Deck](https://lilygo.cc/products/t-deck) ([and pro](https://lilygo.cc/products/t-deck-plus-1)) | :ok: | :x: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | -| [Lilygo T-Watch-S3](https://lilygo.cc/products/t-watch-s3) | :x: | :x: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | -| [Lilygo T-LoRa Pager](https://lilygo.cc/products/t-lora-pager) | :x: | :x: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | -| [Smoochiee V2](https://www.pcbway.com/project/shareproject/Bruce_PCB_Smoochiee_d6a0284b.html) | :ok: | :ok: | :x: | :ok: | :x: | :ok: | :x: | :x: | :x: | :x: | -| [ESP32-C5](https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32c5/esp32-c5-devkitc-1/user_guide.html) | :ok: | :ok: | :x: | :ok: | :x: | :x: | :x: | :x: | :x: | :x: | -| [Bruce RF Reaper](https://www.elecrow.com/bruce-pcb-rf-reaper.html) | :ok: | :ok: | :x: | :x: but w/ ST25R3916 | :x: | :ok: | :ok: | :x: | :ok: | :x: | -² CYD have a LITE_VERSION version for Launcher Compatibility -¹ Core, CYD and StickCs Bad-USB: [here](https://github.com/pr3y/Bruce/wiki/Others#badusb) +| Device | CC1101 | NRF24 | FM Radio | PN532 | Mic | BadUSB | RGB Led | Speaker | Fuel Guage | LITE_VERSION | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----: | :---: | :------: | :------------------: | :--: | :----: | :-----: | :-----: | :--------: | :----------: | +| [M5Stack Cardputer](https://shop.m5stack.com/products/m5stack-cardputer-kit-w-m5stamps) (and ADV) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | NS4168 | :x: | :x: | +| [M5Stack M5StickC PLUS2](https://shop.m5stack.com/products/m5stickc-plus2-esp32-mini-iot-development-kit) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | Tone | :x: | :x: | +| [M5Stack M5StickC PLUS](https://shop.m5stack.com/products/m5stickc-plus-esp32-pico-mini-iot-development-kit) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | Tone | :x: | :x:² | +| [M5Stack M5Core BASIC](https://shop.m5stack.com/products/basic-core-iot-development-kit) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | Tone | :x: | :x: | +| [M5Stack M5Core2](https://shop.m5stack.com/products/m5stack-core2-esp32-iot-development-kit-v1-1) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | :x: | :x: | :x: | +| [M5Stack M5CoreS3](https://shop.m5stack.com/products/m5stack-cores3-esp32s3-lotdevelopment-kit)/[SE](https://shop.m5stack.com/products/m5stack-cores3-se-iot-controller-w-o-battery-bottom) | :ok: | :ok: | :ok: | :ok: | :x: | :ok: | :x: | :x: | :x: | :x: | +| [JCZN CYD‑2432S028](https://www.aliexpress.us/item/3256804774970998.html) | :ok: | :ok: | :ok: | :ok: | :x: | :ok:¹ | :x: | :x: | :x: | :x:² | +| [Lilygo T‑Embed CC1101](https://lilygo.cc/products/t-embed-cc1101) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :x: | +| [Lilygo T‑Embed](https://lilygo.cc/products/t-embed) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :x: | :x: | +| [Lilygo T-Display-S3](https://lilygo.cc/products/t-display-s3) | :ok: | :ok: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | +| [Lilygo T‑Deck](https://lilygo.cc/products/t-deck) ([and pro](https://lilygo.cc/products/t-deck-plus-1)) | :ok: | :x: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | +| [Lilygo T-Watch-S3](https://lilygo.cc/products/t-watch-s3) | :x: | :x: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | +| [Lilygo T-LoRa Pager](https://lilygo.cc/products/t-lora-pager) | :x: | :x: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | +| [Smoochiee V2](https://www.pcbway.com/project/shareproject/Bruce_PCB_Smoochiee_d6a0284b.html) | :ok: | :ok: | :x: | :ok: | :x: | :ok: | :x: | :x: | :x: | :x: | +| [ESP32-C5](https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32c5/esp32-c5-devkitc-1/user_guide.html) | :ok: | :ok: | :x: | :ok: | :x: | :x: | :x: | :x: | :x: | :x: | +| [Bruce RF Reaper](https://www.elecrow.com/bruce-pcb-rf-reaper.html) | :ok: | :ok: | :x: | :x: but w/ ST25R3916 | :x: | :ok: | :ok: | :x: | :ok: | :x: | -*LITE_VERSION*: TelNet, SSH, WireGuard, ScanHosts, RawSniffer, Brucegotchi, BLEBacon, BLEScan and Interpreter are NOT available for M5Launcher Compatibility +² CYD have a LITE_VERSION version for Launcher Compatibility +¹ Core, CYD and StickCs Bad-USB: [here](https://wiki.bruce.computer/features/others/#badusb) +_LITE_VERSION_: TelNet, SSH, WireGuard, ScanHosts, RawSniffer, Brucegotchi, BLEBacon, BLEScan and Interpreter are NOT available for M5Launcher Compatibility ## :sparkles: Why and how does it look? @@ -251,19 +249,18 @@ Other media can be [found here](./media/). ## :clap: Acknowledgements -+ [@bmorcelli](https://github.com/bmorcelli) for new core and a bunch of new features, also porting to many devices! -+ [@IncursioHack](https://github.com/IncursioHack) for adding RF and RFID modules features. -+ [@Luidiblu](https://github.com/Luidiblu) for logo and UI design assistance. -+ [@eadmaster](https://github.com/eadmaster) for adding a lot of features. -+ [@rennancockles](https://github.com/rennancockles) for a lot of RFID code, refactoring and others features. -+ [@7h30th3r0n3](https://github.com/7h30th3r0n3) refactoring and a lot of help with WiFi attacks. -+ [@Tawank](https://github.com/Tawank) refactoring interpreter among many other things -+ [@pablonymous]() new RF functions to read RAW Data -+ [Smoochiee]() for Bruce PCB design. -+ [TH3_KR4K3N]() for Stick cplus extender PCB design. -+ Everyone who contributed in some way to the project, thanks :heart: +- [@bmorcelli](https://github.com/bmorcelli) for new core and a bunch of new features, also porting to many devices! +- [@IncursioHack](https://github.com/IncursioHack) for adding RF and RFID modules features. +- [@Luidiblu](https://github.com/Luidiblu) for logo and UI design assistance. +- [@eadmaster](https://github.com/eadmaster) for adding a lot of features. +- [@rennancockles](https://github.com/rennancockles) for a lot of RFID code, refactoring and others features. +- [@7h30th3r0n3](https://github.com/7h30th3r0n3) refactoring and a lot of help with WiFi attacks. +- [@Tawank](https://github.com/Tawank) refactoring interpreter among many other things +- [@pablonymous]() new RF functions to read RAW Data +- [Smoochiee]() for Bruce PCB design. +- [TH3_KR4K3N]() for Stick cplus extender PCB design. +- Everyone who contributed in some way to the project, thanks :heart: ## :construction: Disclaimer Bruce is a tool for cyber offensive and red team operations, distributed under the terms of the Affero General Public License (AGPL). It is intended for legal and authorized security testing purposes only. Use of this software for any malicious or unauthorized activities is strictly prohibited. By downloading, installing, or using Bruce, you agree to comply with all applicable laws and regulations. This software is provided free of charge, and we do not accept payments for copies or modifications. The developers of Bruce assume no liability for any misuse of the software. Use at your own risk. - diff --git a/boards/_boards_json/elecrow-esp32-24B.json b/boards/_boards_json/elecrow-esp32-24B.json new file mode 100644 index 0000000000..7fc6dc8a0a --- /dev/null +++ b/boards/_boards_json/elecrow-esp32-24B.json @@ -0,0 +1,39 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": [ + "-DELECROW_WROOM32", + "-DBOARD_HAS_PSRAM", + "-mfix-esp32-psram-cache-issue", + "-mfix-esp32-psram-cache-strategy=memw" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "pinouts" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "ELECROW 2.4R", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://en.wikipedia.org/wiki/ESP32", + "vendor": "ELECROW" +} diff --git a/boards/_boards_json/m5stack-sticks3.json b/boards/_boards_json/m5stack-sticks3.json index 0d39c99d7e..6d159957c3 100644 --- a/boards/_boards_json/m5stack-sticks3.json +++ b/boards/_boards_json/m5stack-sticks3.json @@ -2,7 +2,8 @@ "build": { "arduino": { "ldscript": "esp32s3_out.ld", - "partitions": "default_8MB.csv" + "partitions": "default_8MB.csv", + "memory_type": "qio_opi" }, "core": "esp32", "extra_flags": [ diff --git a/boards/elecrow/elecrow.ini b/boards/elecrow/elecrow.ini new file mode 100644 index 0000000000..fa1e5f2ace --- /dev/null +++ b/boards/elecrow/elecrow.ini @@ -0,0 +1,262 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +#################################### ELECROW MODELS ################################################ +; Elecrow CrowPanel ESP32 HMI Display boards (2.4", 2.8", 3.5", 3.5" v2.2) +; Hardware: ESP32-WROOM-32, resistive XPT2046 touch (shared HSPI with TFT), SD on VSPI +; TFT SPI (HSPI): MISO=12, MOSI=13, SCLK=14, CS=15, DC=2, RST=-1, BL=27 +; Touch: CS=33, IRQ=36 (shared with TFT SPI bus) +; SD Card: CS=5, SCK=18, MISO=19, MOSI=23 +; Free GPIOs: 0(boot), 1(TX), 3(RX), 4, 21, 22, 25, 26 + +[elecrow_base] +board = elecrow-esp32-24B +board_build.partitions = custom_4Mb_full.csv +build_src_filter = ${env.build_src_filter} +<../boards/elecrow> +build_flags = + ${env.build_flags} + ${env_4mb.build_flags} + -Iboards/elecrow + + -DELECROW + + ;No microphone + -DPIN_CLK=-1 + -DI2S_SCLK_PIN=-1 + -DI2S_DATA_PIN=-1 + -DPIN_DATA=-1 + + ;No RGB LED + -DRGB_LED=-1 + + ;No speaker + -DBCLK=-1 + -DWCLK=-1 + -DDOUT=-1 + + ;BadUSB on GROVE pins + -DBAD_TX=GROVE_SDA + -DBAD_RX=GROVE_SCL + + ;Serial/GPS + -DSERIAL_TX=1 + -DSERIAL_RX=3 + -DGPS_SERIAL_TX=SERIAL_TX + -DGPS_SERIAL_RX=SERIAL_RX + + ;Buttons - touch only + -DHAS_BTN=0 + -DBTN_ALIAS='"Ok"' + -DBTN_PIN=0 + + ;Infrared / RF pins + -DIR_TX_PINS='{{"Pin 21", 21}, {"Pin 22", 22}, {"Pin 25", 25}, {"Pin 26", 26}}' + -DIR_RX_PINS='{{"Pin 21", 21}, {"Pin 22", 22}, {"Pin 25", 25}, {"Pin 26", 26}}' + -DTXLED=22 + -DLED_ON=HIGH + -DLED_OFF=LOW + + ;Radio Frequency (one pin modules) + -DRF_TX_PINS='{{"Pin 21", 21}, {"Pin 22", 22}, {"Pin 25", 25}, {"Pin 26", 26}}' + -DRF_RX_PINS='{{"Pin 21", 21}, {"Pin 22", 22}, {"Pin 25", 25}, {"Pin 26", 26}}' + + ;CC1101 on VSPI (shared with SD card, different CS) + -DUSE_CC1101_VIA_SPI + -DCC1101_GDO0_PIN=22 + -DCC1101_SS_PIN=25 + -DCC1101_MOSI_PIN=SPI_MOSI_PIN + -DCC1101_SCK_PIN=SPI_SCK_PIN + -DCC1101_MISO_PIN=SPI_MISO_PIN + + ;NRF24 on VSPI + -DUSE_NRF24_VIA_SPI + -DNRF24_CE_PIN=22 + -DNRF24_SS_PIN=25 + -DNRF24_MOSI_PIN=SPI_MOSI_PIN + -DNRF24_SCK_PIN=SPI_SCK_PIN + -DNRF24_MISO_PIN=SPI_MISO_PIN + + ;W5500 on VSPI + -DUSE_W5500_VIA_SPI + -DW5500_SS_PIN=25 + -DW5500_MOSI_PIN=SPI_MOSI_PIN + -DW5500_SCK_PIN=SPI_SCK_PIN + -DW5500_MISO_PIN=SPI_MISO_PIN + -DW5500_INT_PIN=22 + + ;Font sizes + -DFP=1 + -DFM=2 + -DFG=3 + + ;Screen + -DHAS_SCREEN=1 + -DROTATION=1 + -DBACKLIGHT=27 + -DMINBRIGHT=190 + + ;TFT_eSPI - HSPI bus (pins 12/13/14) + -DUSER_SETUP_LOADED=1 + -DUSE_HSPI_PORT=1 + -DTFT_MISO=12 + -DTFT_MOSI=13 + -DTFT_SCLK=14 + -DTFT_CS=15 + -DTFT_DC=2 + -DTFT_RST=-1 + -DTFT_BL=27 + -DTFT_BACKLIGHT_ON=HIGH + -DSMOOTH_FONT=1 + -DSPI_FREQUENCY=40000000 + -DSPI_READ_FREQUENCY=16000000 + -DSPI_TOUCH_FREQUENCY=2500000 + + ;Touch (XPT2046, shared HSPI with TFT) + -DHAS_TOUCH=1 + -DTOUCH_CS=33 + -DCYD28_TouchR_IRQ=36 + -DCYD28_TouchR_MISO=12 + -DCYD28_TouchR_MOSI=13 + -DCYD28_TouchR_CSK=14 + -DCYD28_TouchR_CS=33 + + ;SD Card + -DSDCARD_CS=5 + -DSDCARD_SCK=18 + -DSDCARD_MISO=19 + -DSDCARD_MOSI=23 + + ;Backlight PWM + -DTFT_BRIGHT_CHANNEL=0 + -DTFT_BRIGHT_Bits=8 + -DTFT_BRIGHT_FREQ=5000 + + ;I2C / GROVE + -DGROVE_SDA=21 + -DGROVE_SCL=22 + + ;External SPI (VSPI, shared with SD card) + -DSPI_SCK_PIN=18 + -DSPI_MOSI_PIN=23 + -DSPI_MISO_PIN=19 + -DSPI_SS_PIN=25 + +lib_deps = + ${env.lib_deps} + +lib_ignore = + ${env_4mb.lib_ignore} + + +#################################### 2.4" and 2.8" (ILI9341, 240x320) ############################## + +[env:elecrow-24B] +extends = elecrow_base +build_flags = + ${elecrow_base.build_flags} + -DILI9341_DRIVER=1 + -DTFT_WIDTH=240 + -DTFT_HEIGHT=320 + -DHAS_RESISTIVE_TOUCH=1 + -DCYD28_TouchR_ROT=6 + -DCYD28_TouchR_CAL_XMIN=1 + -DCYD28_TouchR_CAL_XMAX=5000 + -DCYD28_TouchR_CAL_YMIN=1 + -DCYD28_TouchR_CAL_YMAX=5000 + -DDEVICE_NAME='"Elecrow 2.4B"' + +[env:LAUNCHER_elecrow-24B] +extends = env:elecrow-24B +board_build.partitions = custom_4Mb.csv +build_flags = + ${env:elecrow-24B.build_flags} + ${env_light.build_flags} +lib_deps = + ${env_light.lib_deps} + + +[env:elecrow-28B] +extends = elecrow_base +build_flags = + ${elecrow_base.build_flags} + -DILI9341_DRIVER=1 + -DTFT_WIDTH=240 + -DTFT_HEIGHT=320 + -DHAS_RESISTIVE_TOUCH=1 + -DCYD28_TouchR_ROT=6 + -DCYD28_TouchR_CAL_XMIN=189 + -DCYD28_TouchR_CAL_XMAX=3416 + -DCYD28_TouchR_CAL_YMIN=359 + -DCYD28_TouchR_CAL_YMAX=3439 + -DDEVICE_NAME='"Elecrow 2.8B"' + +[env:LAUNCHER_elecrow-28B] +extends = env:elecrow-28B +board_build.partitions = custom_4Mb.csv +build_flags = + ${env:elecrow-28B.build_flags} + ${env_light.build_flags} +lib_deps = + ${env_light.lib_deps} + + +#################################### 3.5" (ILI9488, 320x480) ###################################### + +[env:elecrow-35B] +extends = elecrow_base +build_flags = + ${elecrow_base.build_flags} + -DILI9488_DRIVER=1 + -DTFT_WIDTH=320 + -DTFT_HEIGHT=480 + -DHAS_RESISTIVE_TOUCH=1 + -DCYD28_TouchR_ROT=6 + -DCYD28_TouchR_CAL_XMIN=353 + -DCYD28_TouchR_CAL_XMAX=3568 + -DCYD28_TouchR_CAL_YMIN=269 + -DCYD28_TouchR_CAL_YMAX=3491 + -DDEVICE_NAME='"Elecrow 3.5B"' + +[env:LAUNCHER_elecrow-35B] +extends = env:elecrow-35B +board_build.partitions = custom_4Mb.csv +build_flags = + ${env:elecrow-35B.build_flags} + ${env_light.build_flags} +lib_deps = + ${env_light.lib_deps} + + +[env:elecrow-35Bv2_2] +extends = env:elecrow-35B +build_flags = + ${env:elecrow-35B.build_flags} + -DCYD28_TouchR_CS=12 + -DTFT_MISO=33 + -DCYD28_TouchR_MISO=33 + -DTOUCH_CS=12 + -DDEVICE_NAME='"Elecrow 3.5B v2.2"' +build_unflags = + -DCYD28_TouchR_CS=33 + -DCYD28_TouchR_MISO=12 + -DTFT_MISO=12 + -DTOUCH_CS=33 + -DDEVICE_NAME='"Elecrow 3.5B"' + +[env:LAUNCHER_elecrow-35Bv2_2] +extends = env:elecrow-35Bv2_2 +board_build.partitions = custom_4Mb.csv +build_flags = + ${env:elecrow-35Bv2_2.build_flags} + ${env_light.build_flags} +lib_deps = + ${env_light.lib_deps} + +################################## END ELECROW MODELS ############################################## diff --git a/boards/elecrow/interface.cpp b/boards/elecrow/interface.cpp new file mode 100644 index 0000000000..628dd5711f --- /dev/null +++ b/boards/elecrow/interface.cpp @@ -0,0 +1,108 @@ +#include "core/powerSave.h" +#include "core/utils.h" +#include + +#include +CYD28_TouchR touch(TFT_HEIGHT, TFT_WIDTH); + +/*************************************************************************************** +** Function name: _setup_gpio() +** Location: main.cpp +** Description: initial setup for the device +***************************************************************************************/ +void _setup_gpio() { + pinMode(TOUCH_CS, OUTPUT); + digitalWrite(TOUCH_CS, HIGH); + bruceConfig.colorInverted = 0; +} + +/*************************************************************************************** +** Function name: _post_setup_gpio() +** Location: main.cpp +** Description: second stage gpio setup to make a few functions work +***************************************************************************************/ +void _post_setup_gpio() { + if (!touch.begin(&tft.getSPIinstance())) { + Serial.println("Touch IC not Started"); + log_i("Touch IC not Started"); + } else Serial.println("Touch IC Started"); + + pinMode(TFT_BL, OUTPUT); + ledcAttach(TFT_BL, TFT_BRIGHT_FREQ, TFT_BRIGHT_Bits); + ledcWrite(TFT_BL, 255); +} + +/*************************************************************************************** +** Function name: getBattery() +** location: display.cpp +** Description: Delivers the battery value from 1-100 +***************************************************************************************/ +int getBattery() { return 0; } + +/********************************************************************* +** Function: setBrightness +** location: settings.cpp +** set brightness value +**********************************************************************/ +void _setBrightness(uint8_t brightval) { + int dutyCycle; + if (brightval == 100) dutyCycle = 255; + else if (brightval == 75) dutyCycle = 130; + else if (brightval == 50) dutyCycle = 70; + else if (brightval == 25) dutyCycle = 20; + else if (brightval == 0) dutyCycle = 0; + else dutyCycle = ((brightval * 255) / 100); + ledcWrite(TFT_BL, dutyCycle); +} + +/********************************************************************* +** Function: InputHandler +** Handles the variables PrevPress, NextPress, SelPress, AnyKeyPress and EscPress +**********************************************************************/ +void InputHandler(void) { + static unsigned long tm = millis(); + if (!(millis() - tm > 200 || LongPress)) return; + + if (touch.touched()) { + auto t = touch.getPointScaled(); + t = touch.getPointScaled(); + if (bruceConfigPins.rotation == 3) { + t.y = (tftHeight + 20) - t.y; + t.x = tftWidth - t.x; + } + if (bruceConfigPins.rotation == 0) { + int tmp = t.x; + t.x = tftWidth - t.y; + t.y = tmp; + } + if (bruceConfigPins.rotation == 2) { + int tmp = t.x; + t.x = t.y; + t.y = (tftHeight + 20) - tmp; + } + tm = millis(); + if (!wakeUpScreen()) AnyKeyPress = true; + else return; + touchPoint.x = t.x; + touchPoint.y = t.y; + touchPoint.pressed = true; + touchHeatMap(touchPoint); + } else touchPoint.pressed = false; +} + +/********************************************************************* +** Function: powerOff +** location: mykeyboard.cpp +** Turns off the device (or try to) +**********************************************************************/ +void powerOff() { + esp_sleep_enable_ext0_wakeup(GPIO_NUM_0, LOW); + esp_deep_sleep_start(); +} + +/********************************************************************* +** Function: checkReboot +** location: mykeyboard.cpp +** Btn logic to turn off the device (name is odd btw) +**********************************************************************/ +void checkReboot() {} diff --git a/boards/elecrow/pins_arduino.h b/boards/elecrow/pins_arduino.h new file mode 100644 index 0000000000..c9b863a823 --- /dev/null +++ b/boards/elecrow/pins_arduino.h @@ -0,0 +1,52 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +static const uint8_t TX = 1; +static const uint8_t RX = 3; + +static const uint8_t SDA = 21; +static const uint8_t SCL = 22; + +static const uint8_t SS = 5; +static const uint8_t MOSI = 23; +static const uint8_t MISO = 19; +static const uint8_t SCK = 18; + +static const uint8_t A0 = 36; +static const uint8_t A3 = 39; +static const uint8_t A4 = 32; +static const uint8_t A5 = 33; +static const uint8_t A6 = 34; +static const uint8_t A7 = 35; +static const uint8_t A10 = 4; +static const uint8_t A11 = 0; +static const uint8_t A12 = 2; +static const uint8_t A13 = 15; +static const uint8_t A14 = 13; +static const uint8_t A15 = 12; +static const uint8_t A16 = 14; +static const uint8_t A17 = 27; +static const uint8_t A18 = 25; +static const uint8_t A19 = 26; + +static const uint8_t T0 = 4; +static const uint8_t T1 = 0; +static const uint8_t T2 = 2; +static const uint8_t T3 = 15; +static const uint8_t T4 = 13; +static const uint8_t T5 = 12; +static const uint8_t T6 = 14; +static const uint8_t T7 = 27; +static const uint8_t T8 = 33; +static const uint8_t T9 = 32; + +static const uint8_t DAC1 = 25; +static const uint8_t DAC2 = 26; + +// Deepsleep wakeup via touch IRQ +#define DEEPSLEEP_WAKEUP_PIN 36 +#define DEEPSLEEP_PIN_ACT LOW + +#endif /* Pins_Arduino_h */ diff --git a/boards/m5stack-sticks3/interface.cpp b/boards/m5stack-sticks3/interface.cpp index 8be8e8b631..c816a27547 100644 --- a/boards/m5stack-sticks3/interface.cpp +++ b/boards/m5stack-sticks3/interface.cpp @@ -221,10 +221,45 @@ bool isCharging() { ** location: modules/others/audio.cpp ** Handles audio CODEC to enable/disable speaker **********************************************************************/ +static TimerHandle_t speaker_off_timer = NULL; + +static void speaker_off_timer_cb(TimerHandle_t xTimer) { + if (!speaker_off_timer) return; + static constexpr const uint8_t disabled_bulk_data[] = {0}; + i2c_bulk_write(&Wire1, ES8311_ADDR, disabled_bulk_data); // Shutdown ES8311 + M5.In_I2C.bitOff(0x6E, 0x11, 1 << 3, 100000); // Set gpio3 output low (turn off PA) +} + void _setup_codec_speaker(bool enable) { - M5.Speaker.setVolume(bruceConfig.soundVolume); - if (enable) M5.Speaker.begin(); - else M5.Speaker.end(); + + static constexpr const uint8_t enabled_bulk_data[] = { + 2, 0x00, 0x80, // 0x00 RESET/ CSM POWER ON + 2, 0x01, 0xB5, // 0x01 CLOCK_MANAGER/ MCLK=BCLK + 2, 0x02, 0x18, // 0x02 CLOCK_MANAGER/ MULT_PRE=3 + 2, 0x0D, 0x01, // 0x0D SYSTEM/ Power up analog circuitry + 2, 0x12, 0x00, // 0x12 SYSTEM/ power-up DAC - NOT default + 2, 0x13, 0x10, // 0x13 SYSTEM/ Enable output to HP drive - NOT default + 2, 0x32, 0xBF, // 0x32 DAC/ DAC volume (0xBF == +-0 dB ) + 2, 0x37, 0x08, // 0x37 DAC/ Bypass DAC equalizer - NOT default + 0 + }; + + if (speaker_off_timer == NULL) { + speaker_off_timer = xTimerCreate("SpkOffTimer", pdMS_TO_TICKS(100), pdFALSE, (void *)0, speaker_off_timer_cb); + } + + if (enable) { + if (speaker_off_timer != NULL && xTimerIsTimerActive(speaker_off_timer)) { + xTimerStop(speaker_off_timer, 0); // Cancel pending shutdown + } else { + i2c_bulk_write(&Wire1, ES8311_ADDR, enabled_bulk_data); + M5.In_I2C.bitOn(0x6E, 0x11, 1 << 3, 100000); // Set gpio3 output high (turn on PA) + } + } else { + if (speaker_off_timer != NULL) { + xTimerReset(speaker_off_timer, 0); // Start/reset shutdown timeout for 100ms + } + } } /********************************************************************* @@ -233,8 +268,32 @@ void _setup_codec_speaker(bool enable) { ** Handles audio CODEC to enable/disable microphone **********************************************************************/ void _setup_codec_mic(bool enable) { - if (enable) M5.Mic.begin(); - else M5.Mic.end(); - + // Set microfone pin for ADV mic_bclk_pin = (gpio_num_t)17; + + static constexpr const uint8_t enabled_bulk_data[] = { + 2, 0x00, 0x80, // 0x00 RESET/ CSM POWER ON + 2, 0x01, 0xBA, // 0x01 CLOCK_MANAGER/ MCLK=BCLK + 2, 0x02, 0x18, // 0x02 CLOCK_MANAGER/ MULT_PRE=3 + 2, 0x0D, 0x01, // 0x0D SYSTEM/ Power up analog circuitry + 2, 0x0E, 0x02, // 0x0E SYSTEM/ : Enable analog PGA, enable ADC modulator + 2, 0x14, 0x10, // ES8311_ADC_REG14 : select Mic1p-Mic1n / PGA GAIN (minimum) + 2, 0x17, 0xBF, // ES8311_ADC_REG17 : ADC_VOLUME 0xBF == +- 0 dB + 2, 0x1C, 0x6A, // ES8311_ADC_REG1C : ADC Equalizer bypass, cancel DC offset in digital domain + 0 + }; + static constexpr const uint8_t disabled_bulk_data[] = { + 2, + 0x0D, + 0xFC, // 0x0D SYSTEM/ Power down analog circuitry + 2, + 0x0E, + 0x6A, // 0x0E SYSTEM + 2, + 0x00, + 0x00, // 0x00 RESET/ CSM POWER DOWN + 0 + }; + + i2c_bulk_write(&Wire1, ES8311_ADDR, enable ? enabled_bulk_data : disabled_bulk_data); } diff --git a/boards/m5stack-sticks3/m5stack-sticks3.ini b/boards/m5stack-sticks3/m5stack-sticks3.ini index bae2800ce6..6209bce1b5 100644 --- a/boards/m5stack-sticks3/m5stack-sticks3.ini +++ b/boards/m5stack-sticks3/m5stack-sticks3.ini @@ -10,12 +10,23 @@ [env:m5stack-sticks3] board = m5stack-sticks3 +board_build.psram = enabled +board_build.flash_mode = qio +board_build.flash_size = 8MB +board_build.psram_type = opi board_build.partitions = custom_8Mb.csv build_src_filter =${env.build_src_filter} +<../boards/m5stack-sticks3> build_flags = ${env.build_flags} + -DBOARD_HAS_PSRAM -Iboards/m5stack-sticks3 -DCORE_DEBUG_LEVEL=1 + -DCONFIG_SPIRAM=y + -DCONFIG_SPIRAM_MODE_OCT=1 + -DCONFIG_SPIRAM_TYPE_OPI=1 + -DCONFIG_SPIRAM_USE_MALLOC=1 + -DCONFIG_SPIRAM_BOOT_INIT=1 + -DCONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=1 ;Features Enabled ;-DLITE_VERSION=1 ;limits some features to save space for M5Launcher Compatibility diff --git a/boards/nm-cyd-c5/connections.md b/boards/nm-cyd-c5/connections.md new file mode 100644 index 0000000000..300b4a8ab0 --- /dev/null +++ b/boards/nm-cyd-c5/connections.md @@ -0,0 +1,39 @@ +# Pinouts diagram to use Bruce + +## USING NM-CYD-C5, with SPI / CC1101 and NRF24 work with NM-RF-HAT + +| Device | SCK | MISO | MOSI | CS | GDO0/CE | TFT_DC | TFT_RST | TFT_BL | +| --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| Display | 6 | 2 | 7 | 23 | --- | 24 | C5 RST | 25 | +| SD Card | 6 | 2 | 7 | 10 | --- | --- | --- | --- | +| CC1101 | 6 | 2 | 7 | 9* | 8* | --- | --- | --- | +| NRF24 | 6 | 2 | 7 | 9* | 8* | --- | --- | --- | + +(*) CC1101, NRF24, W5500 use the same pinouts, need to add a switch on CS and CE/GDO0 to choose which to use. + + +If using ST7789 with XPT2046 fo touchscreen, in this case you have 2 GPIO available (0 and 28) to use on CC1101/NRF24 +| Device | SCK | MISO | MOSI | CS | IRQ | +| --- | :---: | :---: | :---: | :---: | :---: | +| Display | 6 | 2 | 7 | 23 | --- | +| Touch | 6 | 2 | 7 | 1 | --- | + + +| Device | RX | TX | GPIO | +| --- | :---: | :---: | :---: | +| GPS | 4 | 5 | --- | +| IR RX | --- | --- | 9 | +| IR TX | --- | --- | 8 | +| LED | --- | --- | 27 | +| 433 RX | --- | --- | 9 | +| 433 TX | --- | --- | 8 | + +ESP32-C5 doesn't support USB-OTG, for BadUSB you need to use a CH9329 module + +FM Radio, PN532 on I2C, other I2C devices, CH9329, Temperature and humidity sensor: BME280. +I2C SDA: 9 +I2C SCL: 8 + +Serial interface to other devices (Flipper) - USB TypeC interface on NM-CYD-C5 +Serial Tx: 11 +Serial Rx: 12 diff --git a/boards/nm-cyd-c5/interface.cpp b/boards/nm-cyd-c5/interface.cpp new file mode 100644 index 0000000000..46a6144fc9 --- /dev/null +++ b/boards/nm-cyd-c5/interface.cpp @@ -0,0 +1,174 @@ +#include "core/powerSave.h" +#include "core/utils.h" +#include + +/*************************************************************************************** +** Function name: _setup_gpio() +** Location: main.cpp +** Description: initial setup for the device +***************************************************************************************/ +void _setup_gpio() { + + pinMode(TFT_CS, OUTPUT); + digitalWrite(TFT_CS, HIGH); + pinMode(TFT_MOSI, OUTPUT); + digitalWrite(TFT_MOSI, HIGH); + pinMode(TFT_SCLK, OUTPUT); + + pinMode(TFT_BL, OUTPUT); + digitalWrite(TFT_BL, HIGH); + pinMode(TFT_RST, OUTPUT); + pinMode(TFT_DC, OUTPUT); + digitalWrite(TFT_DC, HIGH); + +#ifdef HAS_3_BUTTONS + pinMode(UP_BTN, INPUT_PULLUP); // Sets the power btn as an INPUT + pinMode(SEL_BTN, INPUT_PULLUP); + pinMode(DW_BTN, INPUT_PULLUP); +#endif + pinMode(NRF24_SS_PIN, OUTPUT); + pinMode(CC1101_SS_PIN, OUTPUT); + pinMode(SDCARD_CS, OUTPUT); + pinMode(W5500_SS_PIN, OUTPUT); + pinMode(TFT_CS, OUTPUT); + + digitalWrite(NRF24_SS_PIN, HIGH); + digitalWrite(CC1101_SS_PIN, HIGH); + digitalWrite(SDCARD_CS, HIGH); + digitalWrite(W5500_SS_PIN, HIGH); + digitalWrite(TFT_CS, HIGH); +#ifdef ST7789_DRIVER + bruceConfig.colorInverted = 0; +#endif +#ifdef ILI9341_DRIVER + bruceConfig.colorInverted = 0; +#endif +} +/*************************************************************************************** +** Function name: _post_setup_gpio() +** Location: main.cpp +** Description: second stage gpio setup to make a few functions work +***************************************************************************************/ +void _post_setup_gpio() { +#ifdef HAS_TOUCH + pinMode(TOUCH_CS, OUTPUT); + uint16_t calData[5] = {225, 3413, 403, 3334, 1}; + tft.setTouch(calData); +#endif + bruceConfigPins.gps_bus.rx = (gpio_num_t)GPS_SERIAL_RX; + bruceConfigPins.gps_bus.tx = (gpio_num_t)GPS_SERIAL_TX; + bruceConfigPins.gpsBaudrate = 9600; + bruceConfigPins.rfTx = 8; + bruceConfigPins.rfRx = 9; +} + +/*************************************************************************************** +** Function name: getBattery() +** location: display.cpp +** Description: Delivers the battery value from 1-100 +***************************************************************************************/ +int getBattery() { return 0; } + +/*************************************************************************************** +** Function name: isCharging() +** Description: Default implementation that returns false +***************************************************************************************/ +bool isCharging() { return false; } + +/********************************************************************* +** Function: setBrightness +** location: settings.cpp +** set brightness value +**********************************************************************/ +void _setBrightness(uint8_t brightval) { + if (brightval == 0) { + analogWrite(TFT_BL, brightval); + } else { + int bl = MINBRIGHT + round(((255 - MINBRIGHT) * brightval / 100)); + analogWrite(TFT_BL, bl); + } +} + +/********************************************************************* +** Function: InputHandler +** Handles the variables PrevPress, NextPress, SelPress, AnyKeyPress and EscPress +**********************************************************************/ +void InputHandler(void) { + static unsigned long tm = 0; + if (millis() - tm < 200 && !LongPress) return; +#ifdef HAS_TOUCH + TouchPoint t; + checkPowerSaveTime(); + bool _IH_touched = tft.getTouch(&t.x, &t.y); + if (_IH_touched) { + NextPress = false; + PrevPress = false; + UpPress = false; + DownPress = false; + SelPress = false; + EscPress = false; + AnyKeyPress = false; + NextPagePress = false; + PrevPagePress = false; + touchPoint.pressed = false; + _IH_touched = false; + Serial.printf("\nRAW: Touch Pressed on x=%d, y=%d", t.x, t.y); + if (bruceConfigPins.rotation == 3) { + t.y = (tftHeight + 20) - t.y; + t.x = tftWidth - t.x; + } + if (bruceConfigPins.rotation == 0) { + uint16_t tmp = t.x; + t.x = map((tftHeight + 20) - t.y, 0, 320, 0, 240); + t.y = map(tmp, 0, 240, 0, 320); + } + if (bruceConfigPins.rotation == 2) { + uint16_t tmp = t.x; + t.x = map(t.y, 0, 320, 0, 240); + t.y = map(tftWidth - tmp, 0, 240, 0, 320); + } + + Serial.printf("\nROT: Touch Pressed on x=%d, y=%d, rot=%d\n", t.x, t.y, bruceConfigPins.rotation); + + if (!wakeUpScreen()) AnyKeyPress = true; + else return; + + // Touch point global variable + touchPoint.x = t.x; + touchPoint.y = t.y; + touchPoint.pressed = true; + touchHeatMap(touchPoint); + tm = millis(); + } + +#endif +#ifdef HAS_3_BUTTONS + bool upPressed = (digitalRead(UP_BTN) == LOW); + bool selPressed = (digitalRead(SEL_BTN) == LOW); + bool dwPressed = (digitalRead(DW_BTN) == LOW); + + bool anyPressed = upPressed || selPressed || dwPressed; + if (anyPressed) tm = millis(); + if (anyPressed && wakeUpScreen()) return; + + AnyKeyPress = anyPressed; + PrevPress = upPressed; + EscPress = upPressed && dwPressed; + NextPress = dwPressed; + SelPress = selPressed; +#endif +} + +/********************************************************************* +** Function: powerOff +** location: mykeyboard.cpp +** Turns off the device (or try to) +**********************************************************************/ +void powerOff() {} + +/********************************************************************* +** Function: checkReboot +** location: mykeyboard.cpp +** Btn logic to turnoff the device (name is odd btw) +**********************************************************************/ +void checkReboot() {} diff --git a/boards/nm-cyd-c5/nm-cyd-c5.ini b/boards/nm-cyd-c5/nm-cyd-c5.ini new file mode 100644 index 0000000000..7bdd0c80e1 --- /dev/null +++ b/boards/nm-cyd-c5/nm-cyd-c5.ini @@ -0,0 +1,58 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nm-cyd-c5] +board = esp32-c5-devkitc-1 +board_build.partitions = custom_8Mb.csv +build_src_filter =${env.build_src_filter} +<../boards/nm-cyd-c5> +build_flags = + ${env.build_flags} + -Iboards/nm-cyd-c5 + -DDEVICE_NAME='"ESP32-C5"' + -DNM_CYD_ESP32C5=1 + -DBOARD_HAS_PSRAM=1 + -DARDUINO_USB_CDC_ON_BOOT=1 + -DARDUINO_USB_MODE=1 + -DCORE_DEBUG_LEVEL=1 + -DHAS_TOUCH=1 + -DROTATION=3 + + -DGPS_SERIAL_TX=5 + -DGPS_SERIAL_RX=4 + ; grove pins + ; defaults from https://github.com/espressif/arduino-esp32/blob/master/variants/esp32s3/pins_arduino.h + -DGROVE_SDA=8 ; default RF TX pin + -DGROVE_SCL=9 ; default IR/RF RX pin + ;-DALLOW_ALL_GPIO_FOR_IR_RF=1 ; Set this option to make use of all GPIOs, from 1 to 44 to be chosen, except TFT and SD pins + + ; ir led pin + -DIR_TX_PINS='{{"Pin 9", 9}, {"Pin 8", 8}}' + -DIR_RX_PINS='{{"Pin 9", 9}, {"Pin 8", 8}}' + -DLED_ON=HIGH + -DLED_OFF=LOW + + ;Radio Frequency (one pin modules) pin setting + -DRF_TX_PINS='{{"Pin 9", 9}, {"Pin 8", 8}}' + -DRF_RX_PINS='{{"Pin 9", 9}, {"Pin 8", 8}}' + + ; text sizes + -DFP=1 + -DFM=2 + -DFG=3 + ; ui control buttons + ;-DSEL_BTN=1 + ;-DUP_BTN=2 ; also work as ESC + ;-DDW_BTN=3 ; also work as NEXT + -DBTN_ALIAS='"OK"' + + ;FM Radio + -DFM_SI4713=1 ;Uncomment to activate FM Radio using Adafruit Si4713 + + diff --git a/boards/nm-cyd-c5/pins_arduino.h b/boards/nm-cyd-c5/pins_arduino.h new file mode 100644 index 0000000000..53ffb73a81 --- /dev/null +++ b/boards/nm-cyd-c5/pins_arduino.h @@ -0,0 +1,146 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include "soc/soc_caps.h" +#include + +#define PIN_RGB_LED 27 +// BUILTIN_LED can be used in new Arduino API digitalWrite() like in Blink.ino +static const uint8_t LED_BUILTIN = SOC_GPIO_PIN_COUNT + PIN_RGB_LED; +#define BUILTIN_LED LED_BUILTIN // backward compatibility +#define LED_BUILTIN LED_BUILTIN // allow testing #ifdef LED_BUILTIN +// RGB_BUILTIN and RGB_BRIGHTNESS can be used in new Arduino API rgbLedWrite() +#define RGB_BUILTIN LED_BUILTIN +#define RGB_BRIGHTNESS 64 + +static const uint8_t TX = 11; +static const uint8_t RX = 12; + +static const uint8_t USB_DM = 13; +static const uint8_t USB_DP = 14; + +static const uint8_t SDA = 4; +static const uint8_t SCL = 5; + +static const uint8_t SS = 10; +static const uint8_t MOSI = 7; +static const uint8_t MISO = 2; +static const uint8_t SCK = 6; + +static const uint8_t A0 = 1; +static const uint8_t A1 = 2; +static const uint8_t A2 = 3; +static const uint8_t A3 = 4; +static const uint8_t A4 = 5; +static const uint8_t A5 = 6; + +// LP I2C Pins are fixed on ESP32-C5 +static const uint8_t LP_SDA = 4; +static const uint8_t LP_SCL = 5; +#define WIRE1_PIN_DEFINED +#define SDA1 LP_SDA +#define SCL1 LP_SCL + +// LP UART Pins are fixed on ESP32-C5 +static const uint8_t LP_RX = 12; +static const uint8_t LP_TX = 11; + +#define HAS_RGB_LED 1 +#define LED_ORDER GRB +#define LED_TYPE_IS_RGBW 1 +#define LED_COUNT 1 +#define LED_TYPE WS2812 +#define LED_COLOR_STEP 15 +#define RGB_LED 27 + +/* Communication Buses*/ +// UART +#define SERIAL_TX 11 +#define SERIAL_RX 12 +// I2C +#define GROVE_SDA 8 +#define GROVE_SCL 9 +// SPI +#define SPI_SCK_PIN 6 +#define SPI_MOSI_PIN 7 +#define SPI_MISO_PIN 2 +#define SPI_SS_PIN 9 + +/* TFT definitions */ +#define HAS_SCREEN 1 +#define MINBRIGHT (uint8_t)1 +#define USER_SETUP_LOADED 1 + +/* --------------------- */ +// Setup for ST7789 240x320 + +#define ST7789_DRIVER 1 +#define TFT_WIDTH 240 +#define TFT_HEIGHT 320 + +/* --------------------- */ +// Setup for ILI9341 320x240 (no touch) + +// #define ILI9341_DRIVER 1 +// #define TFT_HEIGHT 320 +// #define TFT_WIDTH 240 + +/* --------------------- */ +// Common TFT definitions +#define TFT_BACKLIGHT_ON 1 +#define TFT_BL 25 +#define TFT_RST -1 +#define TFT_DC 24 +#define TFT_MISO 2 // set to share SPI with other devices +#define TFT_MOSI 7 +#define TFT_SCLK 6 +#define TFT_CS 23 +#define TOUCH_CS 1 +#define SMOOTH_FONT 1 +#define SPI_FREQUENCY 20000000 +#define SPI_READ_FREQUENCY 20000000 +#define SPI_TOUCH_FREQUENCY 2500000 + +/* Peripheral settings */ +// Bad USB with CH9329 +#define BAD_RX 4 +#define BAD_TX 5 +// GPS Bus +#define GPS_SERIAL_RX 4 +#define GPS_SERIAL_TX 5 + +#define USE_TFT_eSPI_TOUCH 1 +#define HAS_TOUCH 1 +#define TOUCH_CS 1 +#define BTN_ACT LOW +#define DEEPSLEEP_WAKEUP_PIN 0 + +// InfraRed +#define RXLED 9 +#define TXLED 8 +#define LED_ON HIGH +#define LED_OFF LOW +// SDCard +#define SDCARD_CS 10 +#define SDCARD_SCK SPI_SCK_PIN +#define SDCARD_MISO SPI_MISO_PIN +#define SDCARD_MOSI SPI_MOSI_PIN +// CC1101 +#define CC1101_GDO0_PIN 8 +#define CC1101_SS_PIN 9 +#define CC1101_MOSI_PIN SPI_MOSI_PIN +#define CC1101_SCK_PIN SPI_SCK_PIN +#define CC1101_MISO_PIN SPI_MISO_PIN +// NRF24 +#define NRF24_CE_PIN 8 +#define NRF24_SS_PIN 9 +#define NRF24_MOSI_PIN SPI_MOSI_PIN +#define NRF24_SCK_PIN SPI_SCK_PIN +#define NRF24_MISO_PIN SPI_MISO_PIN +// Ethernet +#define W5500_INT_PIN 8 +#define W5500_SS_PIN 9 +#define W5500_MOSI_PIN SPI_MOSI_PIN +#define W5500_SCK_PIN SPI_SCK_PIN +#define W5500_MISO_PIN SPI_MISO_PIN +#endif /* Pins_Arduino_h */ diff --git a/boards/pinouts/pins_arduino.h b/boards/pinouts/pins_arduino.h index 8cc716273c..d4b236c5d4 100644 --- a/boards/pinouts/pins_arduino.h +++ b/boards/pinouts/pins_arduino.h @@ -42,8 +42,12 @@ #include "../marauder-mini/pins_arduino.h" #elif LILYGO_T_HMI #include "../lilygo-t-hmi/pins_arduino.h" +#elif ELECROW +#include "../elecrow/pins_arduino.h" #elif ESP32C5_DEVKITC_1_TFT #include "../ESP32-C5-tft/pins_arduino.h" #elif ESP32C5_DEVKITC_1 #include "../ESP32-C5/pins_arduino.h" +#elif NM_CYD_ESP32C5 +#include "../nm-cyd-c5/pins_arduino.h" #endif diff --git a/docker/run_all_envs.sh b/docker/run_all_envs.sh index 1a7f9dc3a1..27f6a573d8 100644 --- a/docker/run_all_envs.sh +++ b/docker/run_all_envs.sh @@ -42,6 +42,13 @@ DEFAULT_ENVS=( lilygo-t-display-ttgo lilygo-t-hmi lilygo-t-lora-pager + elecrow-24B + elecrow-28B + elecrow-35B + elecrow-35Bv2_2 + LAUNCHER_elecrow-24B + LAUNCHER_elecrow-28B + LAUNCHER_elecrow-35B smoochiee-board Phantom_S024R LAUNCHER_Phantom_S024R @@ -94,7 +101,7 @@ for ((i = 0; i < ${#ENVS[@]}; i += JOBS)); do done done -if (( ${#failed[@]} > 0 )); then +if ((${#failed[@]} > 0)); then echo "Build failures: ${failed[*]}" >&2 exit 1 fi diff --git a/embedded_resources/web_interface/index.css b/embedded_resources/web_interface/index.css index 380fbc9c43..853014a5d1 100644 --- a/embedded_resources/web_interface/index.css +++ b/embedded_resources/web_interface/index.css @@ -410,8 +410,17 @@ svg > path { overflow-wrap: normal; overflow: auto; } +.dialog.upload { + width: 100%; + max-width: 420px; + max-height: calc(100vh - 20px); + display: flex; + flex-direction: column; +} .dialog.upload .dialog-body { padding: 10px; + overflow-y: auto; + max-height: calc(100vh - 60px); } .dialog.upload .upload-loading { width: 350px; diff --git a/flto_prep.py b/flto_prep.py new file mode 100644 index 0000000000..f8f898957f --- /dev/null +++ b/flto_prep.py @@ -0,0 +1,10 @@ +Import("env") + +# The Arduino ESP32 framework injects -fno-lto into LINKFLAGS to prevent LTO +# at link time. Remove it so GCC can perform whole-program LTO optimization +# across all LTO IR objects (user code + framework Arduino source). +# Prebuilt ESP-IDF archives (libfreertos.a etc.) are regular objects and +# participate in LTO linking transparently. +flags = env.get("LINKFLAGS", []) +if "-fno-lto" in flags: + env.Replace(LINKFLAGS=[f for f in flags if f != "-fno-lto"]) diff --git a/include/SerialDevice.h b/include/SerialDevice.h index 0735abd14e..12f1ae24e5 100644 --- a/include/SerialDevice.h +++ b/include/SerialDevice.h @@ -13,6 +13,7 @@ class SerialDevice { virtual size_t print(int n, int format = DEC) = 0; virtual size_t print(const String &s) = 0; virtual void vprintf(const char *fmt, va_list args) = 0; + virtual int read() = 0; virtual size_t write(uint8_t *str, size_t size) = 0; void printf(const char *fmt, ...) { va_list args; diff --git a/include/VectorDisplay.h b/include/VectorDisplay.h index 4a5eee472f..d8d6ee4eb2 100644 --- a/include/VectorDisplay.h +++ b/include/VectorDisplay.h @@ -500,15 +500,15 @@ class VectorDisplayClass : public Print { void text(int x, int y, const char *str, int n) { args.xyText.x = x; args.xyText.y = y; - if (n > VECTOR_DISPLAY_MAX_STRING) n = VECTOR_DISPLAY_MAX_STRING; + if (n > VECTOR_DISPLAY_MAX_STRING - 1) n = VECTOR_DISPLAY_MAX_STRING - 1; strncpy(args.xyText.text, str, n); + args.xyText.text[n] = 0; // Explicit null termination before loop if (fixCP437) { for (int i = 0; i < n; i++) { if ((uint8_t)args.xyText.text[i] >= 176) args.xyText.text[i]++; } } - args.xyText.text[n] = 0; sendCommand('T', &args, 4 + strlen(args.xyText.text) + 1); } @@ -520,15 +520,15 @@ class VectorDisplayClass : public Print { void addButton(uint8_t command, const char *str) { args.charText.c = command; - strncpy(args.charText.text, str, VECTOR_DISPLAY_MAX_STRING); - args.charText.text[VECTOR_DISPLAY_MAX_STRING] = 0; + strncpy(args.charText.text, str, VECTOR_DISPLAY_MAX_STRING - 1); + args.charText.text[VECTOR_DISPLAY_MAX_STRING - 1] = 0; sendCommand('U', &args, 1 + strlen(args.charText.text) + 1); } void addButton(uint8_t command, String str) { addButton(command, str.c_str()); } void toast(const char *str, unsigned n) { - if (VECTOR_DISPLAY_MAX_STRING < n) n = VECTOR_DISPLAY_MAX_STRING; + if (VECTOR_DISPLAY_MAX_STRING - 1 < n) n = VECTOR_DISPLAY_MAX_STRING - 1; strncpy(args.text, str, n); args.text[n] = 0; sendCommand('M', &args, n + 1); diff --git a/include/globals.h b/include/globals.h index 1362520197..348ee78e2b 100644 --- a/include/globals.h +++ b/include/globals.h @@ -104,6 +104,7 @@ struct Option { String label; std::function operation; bool selected = false; + bool enabled = true; bool (*hover)(void *hoverPointer, bool shouldRender); void *hoverPointer; bool hovered; // return to the remote (webui or app) if it is hovered on the loopoptions @@ -112,9 +113,9 @@ struct Option { String lbl, const std::function &op, bool sel = false, bool (*hov)(void *hoverPointer, bool shouldRender) = nullptr, // hover lambda returns true if it already handled rendering - void *ptr = nullptr, bool hvrd = false + void *ptr = nullptr, bool hvrd = false, bool en = true ) - : label(lbl), operation(op), selected(sel), hover(hov), hoverPointer(ptr), hovered(hvrd) {} + : label(lbl), operation(op), selected(sel), enabled(en), hover(hov), hoverPointer(ptr), hovered(hvrd) {} }; struct keyStroke { // DO NOT CHANGE IT!!!!! diff --git a/patch.py b/patch.py index 1dac1ede92..f8538e5dbe 100644 --- a/patch.py +++ b/patch.py @@ -104,6 +104,7 @@ def minify_js(js): minify_req = requests.post( 'https://www.toptal.com/developers/javascript-minifier/api/raw', {'input': js.read().decode('utf-8')}, + timeout=10 ) return js if minify_req is False else minify_req.text.encode('utf-8') @@ -112,6 +113,7 @@ def minify_html(html): minify_req = requests.post( 'https://www.toptal.com/developers/html-minifier/api/raw', {'input': html.read().decode('utf-8')}, + timeout=10 ) return html if minify_req is False else minify_req.text.encode('utf-8') diff --git a/platformio.ini b/platformio.ini index 0ae3c1bb9d..38e77a82d3 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,9 +10,9 @@ [platformio] default_envs = - ;m5stack-cardputer + m5stack-cardputer ;m5stack-sticks3 - m5stack-cplus2 + ;m5stack-cplus2 ;m5stack-cplus1_1 ;LAUNCHER_m5stack-cplus1_1 ;m5stack-core2 @@ -47,7 +47,7 @@ default_envs = ;lilygo-t-hmi ;lilygo-t-lora-pager ;smoochiee-board - ;xk404 + ;xk404 ;reaper ;Phantom_S024R ;LAUNCHER_Phantom_S024R @@ -64,8 +64,14 @@ default_envs = ;LAUNCHER_WaveSentry-R1 ;WaveSentry-R1 ;esp32-c5-tft - ;esp32-c5 - ;ES3C28P + ;esp32-c5 + ;ES3C28P + ;nm-cyd-c5 + ;elecrow-24B + ;elecrow-28B + ;elecrow-35B + ;elecrow-35Bv2_2 + ;uncomment to not use global dirs to avoid possible conflicts ;platforms_dir = .pio/platforms @@ -81,13 +87,14 @@ extra_configs = [env] platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.36/platform-espressif32.zip ; Arduino 3.3.6 ;https://github.com/pioarduino/platform-espressif32/releases/download/55.03.34/platform-espressif32.zip ; Arduino 3.3.4 - ;https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip ; Last Version + ;https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip ; Last Version platform_packages = framework-arduinoespressif32-libs @ https://github.com/bmorcelli/esp32-arduino-lib-builder/releases/download/idf-release_v5.5/bruce_esp32-arduino-libs-20260123-153546.zip ; Arduino 3.3.6 - ;framework-arduinoespressif32-libs @ https://github.com/bmorcelli/esp32-arduino-lib-builder/releases/download/idf-release_v5.5/bruce_esp32-arduino-libs-20251205-131242.zip ; Arduino 3.3.4 - ;framework-arduinoespressif32-libs @ https://github.com/bmorcelli/esp32-arduino-lib-builder/releases/download/idf-release_v5.5/esp32-arduino-libs-20250919-170356.zip ; Arduino 3.3.1 + ;framework-arduinoespressif32-libs @ https://github.com/bmorcelli/esp32-arduino-lib-builder/releases/download/idf-release_v5.5/bruce_esp32-arduino-libs-20251205-131242.zip ; Arduino 3.3.4 + ;framework-arduinoespressif32-libs @ https://github.com/bmorcelli/esp32-arduino-lib-builder/releases/download/idf-release_v5.5/esp32-arduino-libs-20250919-170356.zip ; Arduino 3.3.1 monitor_filters = esp32_exception_decoder, send_on_enter, colorize +monitor_speed = 115200 framework = arduino board_build.variants_dir = boards board_build.filesystem = littlefs @@ -123,6 +130,9 @@ build_flags = -DEEPROMSIZE=128 -DLH=8 -DLW=6 + -flto + -ffunction-sections + -fdata-sections -Os -Wl,--print-memory-usage -Wl,--gc-sections @@ -151,6 +161,7 @@ extra_scripts = pre:pre_build_current_year.py pre:gen_mqjs_headers.py pre:patch_library_conflicts.py + flto_prep.py post:build.py lib_deps = @@ -179,7 +190,7 @@ lib_deps = earlephilhower/ESP8266SAM@^1.1.0 mikalhart/TinyGPSPlus tinyu-zhao/FFT@^0.0.1 - h2zero/NimBLE-Arduino@^2.3.9 + h2zero/NimBLE-Arduino@2.5 nrf24/RF24 @ 1.4.11 Adafruit Si4713 Library@1.2.3 Bodmer/JPEGDecoder @@ -196,10 +207,6 @@ lib_deps = fastled/FastLED @^3.10.3 jgromes/RadioLib @ ^7.4.0 -monitor_speed = 115200 - - - [env_light] extends = env build_flags = @@ -249,7 +256,7 @@ lib_deps = ;earlephilhower/ESP8266SAM@^1.1.0 mikalhart/TinyGPSPlus@1.1.0 tinyu-zhao/FFT@0.0.1 - h2zero/NimBLE-Arduino@2.3.7 + h2zero/NimBLE-Arduino@2.5 nrf24/RF24 @ 1.4.11 ;Adafruit Si4713 Library@1.2.3 Bodmer/JPEGDecoder @@ -287,7 +294,6 @@ build_flags = -DSEND_PANASONIC=true -DDECODE_PANASONIC=true -DSEND_RAW=true - -include Arduino.h lib_ignore = FastLED diff --git a/src/core/USBSerial/USBSerial.h b/src/core/USBSerial/USBSerial.h index 9b127a01a6..81083aa33c 100644 --- a/src/core/USBSerial/USBSerial.h +++ b/src/core/USBSerial/USBSerial.h @@ -18,6 +18,7 @@ class USBSerial : public SerialDevice { void flush() override { out->flush(); } int available() override { return out->available(); } size_t write(uint8_t *str, size_t size) override { return out->write(str, size); } + int read() override { return out->read(); } void setSerialOutput(Stream *in) { out = in; } Stream *getSerialOutput() { return out; } USBSerial(Stream *in = &Serial) { out = in; } diff --git a/src/core/config.cpp b/src/core/config.cpp index a275e583d4..40453d10f4 100644 --- a/src/core/config.cpp +++ b/src/core/config.cpp @@ -62,6 +62,7 @@ JsonDocument BruceConfig::toJson() const { setting["startupApp"] = startupApp; setting["startupAppJSInterpreterFile"] = startupAppJSInterpreterFile; setting["wigleBasicToken"] = wigleBasicToken; + setting["wdgwarsApiKey"] = wdgwarsApiKey; setting["devMode"] = devMode; setting["colorInverted"] = colorInverted; @@ -353,6 +354,12 @@ void BruceConfig::fromFile(bool checkFS) { count++; log_e("Fail"); } + if (!setting["wdgwarsApiKey"].isNull()) { + wdgwarsApiKey = setting["wdgwarsApiKey"].as(); + } else { + count++; + log_e("Fail"); + } if (!setting["devMode"].isNull()) { devMode = setting["devMode"].as(); } else { @@ -723,6 +730,11 @@ void BruceConfig::setWigleBasicToken(String value) { saveFile(); } +void BruceConfig::setWdgwarsApiKey(String value) { + wdgwarsApiKey = value; + saveFile(); +} + void BruceConfig::setDevMode(int value) { devMode = value; validateDevModeValue(); diff --git a/src/core/config.h b/src/core/config.h index 1aeea72ceb..b853ed47bc 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -36,7 +36,7 @@ class BruceConfig : public BruceTheme { const char *filepath = "/bruce.conf"; // Settings - int dimmerSet = 10; + int dimmerSet = 60; int bright = 100; bool automaticTimeUpdateViaNTP = true; float tmz = 0; @@ -82,6 +82,7 @@ class BruceConfig : public BruceTheme { String startupApp = ""; String startupAppJSInterpreterFile = ""; String wigleBasicToken = ""; + String wdgwarsApiKey = "your 64-char hex key from wdgwars.pl/profile"; int devMode = 0; int colorInverted = 1; int badUSBBLEKeyboardLayout = 0; @@ -175,6 +176,7 @@ class BruceConfig : public BruceTheme { void setStartupApp(String value); void setStartupAppJSInterpreterFile(String value); void setWigleBasicToken(String value); + void setWdgwarsApiKey(String value); void setDevMode(int value); void validateDevModeValue(); void setColorInverted(int value); diff --git a/src/core/configPins.cpp b/src/core/configPins.cpp index af01396521..b7fc66d57d 100644 --- a/src/core/configPins.cpp +++ b/src/core/configPins.cpp @@ -7,7 +7,17 @@ String getMacAddress() { esp_read_mac(mac, ESP_MAC_WIFI_STA); char macStr[18]; - sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + snprintf( + macStr, + sizeof(macStr), + "%02X:%02X:%02X:%02X:%02X:%02X", + mac[0], + mac[1], + mac[2], + mac[3], + mac[4], + mac[5] + ); return String(macStr); } @@ -136,6 +146,17 @@ void BruceConfigPins::fromJson(JsonObject obj) { count++; log_e("Fail"); } + if (!root["PN532_Pins"].isNull()) { + SPIPins def = PN532_bus; + PN532_bus.fromJson(root["PN532_Pins"].as()); + if (PN532_bus.sck == GPIO_NUM_NC && def.sck != GPIO_NUM_NC) { + PN532_bus = def; + count++; + } + } else { + // Backward compatibility: keep existing/default PN532 pins when the + // key is absent in older configuration files. + } if (!root["SDCard_Pins"].isNull()) { SPIPins def = SDCARD_bus; @@ -220,6 +241,9 @@ void BruceConfigPins::toJson(JsonObject obj) const { JsonObject _NRF = root["NRF24_Pins"].to(); NRF24_bus.toJson(_NRF); + JsonObject _PN532 = root["PN532_Pins"].to(); + PN532_bus.toJson(_PN532); + JsonObject _SD = root["SDCard_Pins"].to(); SDCARD_bus.toJson(_SD); @@ -346,6 +370,7 @@ void BruceConfigPins::validateConfig() { #endif validateSpiPins(CC1101_bus); validateSpiPins(NRF24_bus); + validateSpiPins(PN532_bus); validateSpiPins(SDCARD_bus); validateI2CPins(i2c_bus); validateUARTPins(uart_bus); @@ -375,6 +400,12 @@ void BruceConfigPins::setNrf24Pins(SPIPins value) { saveFile(); } +void BruceConfigPins::setPn532Pins(SPIPins value) { + PN532_bus = value; + validateSpiPins(PN532_bus); + saveFile(); +} + void BruceConfigPins::setSDCardPins(SPIPins value) { SDCARD_bus = value; validateSpiPins(SDCARD_bus); diff --git a/src/core/configPins.h b/src/core/configPins.h index ed4c31678b..d7ebd4b1e5 100644 --- a/src/core/configPins.h +++ b/src/core/configPins.h @@ -135,6 +135,18 @@ class BruceConfigPins { SPIPins NRF24_bus; #endif +#ifdef PN532_SCK_PIN + SPIPins PN532_bus = { + (gpio_num_t)PN532_SCK_PIN, + (gpio_num_t)PN532_MISO_PIN, + (gpio_num_t)PN532_MOSI_PIN, + (gpio_num_t)PN532_SS_PIN, + (gpio_num_t)PN532_CE_PIN + }; +#else + SPIPins PN532_bus; +#endif + #ifdef SDCARD_SCK SPIPins SDCARD_bus = { (gpio_num_t)SDCARD_SCK, (gpio_num_t)SDCARD_MISO, (gpio_num_t)SDCARD_MOSI, (gpio_num_t)SDCARD_CS @@ -222,6 +234,7 @@ class BruceConfigPins { void setCC1101Pins(SPIPins value); void setNrf24Pins(SPIPins value); + void setPn532Pins(SPIPins value); void setSDCardPins(SPIPins value); #if !defined(LITE_VERSION) void setLoRaPins(SPIPins value); diff --git a/src/core/connect/esp_connection.cpp b/src/core/connect/esp_connection.cpp index 558bdc4831..646fb433f6 100644 --- a/src/core/connect/esp_connection.cpp +++ b/src/core/connect/esp_connection.cpp @@ -170,7 +170,9 @@ void EspConnection::printMessage(Message message) { String EspConnection::macToString(const uint8_t *mac) { char macStr[18]; - sprintf(macStr, "%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + snprintf( + macStr, sizeof(macStr), "%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] + ); return macStr; } diff --git a/src/core/display.cpp b/src/core/display.cpp index 341234ee95..aebbf901a2 100644 --- a/src/core/display.cpp +++ b/src/core/display.cpp @@ -468,6 +468,33 @@ void padprintln(double n, int digits, int16_t padx) { int loopOptions( std::vector