Compare commits

...

120 Commits

Author SHA1 Message Date
Hermes Reyna Bot 047c7c87d7 Export LVGL canvas symbols for side-loaded GameBoy app 2026-07-17 18:10:52 -04:00
Adolfo Reyna 94b5cdbfc4 feat(es3c28p): add audio playback and mic support, and fix chmod stub bug
Build Simulator / Linux (push) Has been cancelled
Build Simulator / macOS (push) Has been cancelled
Build Firmware / BuildSdk (map[arch:esp32 id:generic-esp32]) (push) Has been cancelled
Build Firmware / BuildSdk (map[arch:esp32c6 id:generic-esp32c6]) (push) Has been cancelled
Build Firmware / BuildSdk (map[arch:esp32p4 id:generic-esp32p4]) (push) Has been cancelled
Build Firmware / BuildSdk (map[arch:esp32s3 id:generic-esp32s3]) (push) Has been cancelled
Tests / TactilityTests (push) Has been cancelled
Tests / DevicetreeTests (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-2432s024c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-2432s024r]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-2432s028r]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-2432s028rv3]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-2432s032c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-3248s035c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-e32r28t]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-e32r32p]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:elecrow-crowpanel-basic-28]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:elecrow-crowpanel-basic-35]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:guition-jc2432w328c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:lilygo-tdisplay]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:m5stack-core2]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:m5stack-stickc-plus2]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:m5stack-stickc-plus]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32p4 id:guition-jc1060p470ciwy]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32p4 id:m5stack-tab5]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:btt-panda-touch]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:cyd-4848s040c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:cyd-8048s043c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:elecrow-crowpanel-advance-28]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:elecrow-crowpanel-advance-35]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:elecrow-crowpanel-advance-50]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:elecrow-crowpanel-basic-50]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:guition-jc3248w535c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:guition-jc8048w550c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:heltec-wifi-lora-32-v3]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:lilygo-tdeck]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:lilygo-tdisplay-s3]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:lilygo-tdongle-s3]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:lilygo-thmi]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:lilygo-tlora-pager]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:m5stack-cardputer-adv]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:m5stack-cardputer]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:m5stack-cores3]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:m5stack-papers3]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:m5stack-stackchan]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:m5stack-sticks3]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:unphone]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:waveshare-esp32-s3-geek]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:waveshare-s3-lcd-13]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:waveshare-s3-touch-lcd-128]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:waveshare-s3-touch-lcd-147]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:waveshare-s3-touch-lcd-43]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:wireless-tag-wt32-sc01-plus]) (push) Has been cancelled
Build Firmware / BundleArtifacts (push) Has been cancelled
Build Firmware / PublishFirmwareSnapshot (push) Has been cancelled
Build Firmware / PublishFirmwareStable (push) Has been cancelled
Build Firmware / PublishSdk (push) Has been cancelled
2026-06-23 12:34:32 -04:00
Adolfo Reyna 5c535490ea Fix compatibility issues for ESP-IDF v5.3.2 and add es3c28p target support
Build Simulator / Linux (push) Has been cancelled
Build Simulator / macOS (push) Has been cancelled
Build Firmware / BuildSdk (map[arch:esp32 id:generic-esp32]) (push) Has been cancelled
Build Firmware / BuildSdk (map[arch:esp32c6 id:generic-esp32c6]) (push) Has been cancelled
Build Firmware / BuildSdk (map[arch:esp32p4 id:generic-esp32p4]) (push) Has been cancelled
Build Firmware / BuildSdk (map[arch:esp32s3 id:generic-esp32s3]) (push) Has been cancelled
Tests / TactilityTests (push) Has been cancelled
Tests / DevicetreeTests (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-2432s024c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-2432s024r]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-2432s028r]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-2432s028rv3]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-2432s032c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-3248s035c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-e32r28t]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:cyd-e32r32p]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:elecrow-crowpanel-basic-28]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:elecrow-crowpanel-basic-35]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:guition-jc2432w328c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:lilygo-tdisplay]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:m5stack-core2]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:m5stack-stickc-plus2]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32 id:m5stack-stickc-plus]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32p4 id:guition-jc1060p470ciwy]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32p4 id:m5stack-tab5]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:btt-panda-touch]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:cyd-4848s040c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:cyd-8048s043c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:elecrow-crowpanel-advance-28]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:elecrow-crowpanel-advance-35]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:elecrow-crowpanel-advance-50]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:elecrow-crowpanel-basic-50]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:guition-jc3248w535c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:guition-jc8048w550c]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:heltec-wifi-lora-32-v3]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:lilygo-tdeck]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:lilygo-tdisplay-s3]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:lilygo-tdongle-s3]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:lilygo-thmi]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:lilygo-tlora-pager]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:m5stack-cardputer-adv]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:m5stack-cardputer]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:m5stack-cores3]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:m5stack-papers3]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:m5stack-stackchan]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:m5stack-sticks3]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:unphone]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:waveshare-esp32-s3-geek]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:waveshare-s3-lcd-13]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:waveshare-s3-touch-lcd-128]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:waveshare-s3-touch-lcd-147]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:waveshare-s3-touch-lcd-43]) (push) Has been cancelled
Build Firmware / BuildFirmware (map[arch:esp32s3 id:wireless-tag-wt32-sc01-plus]) (push) Has been cancelled
Build Firmware / BundleArtifacts (push) Has been cancelled
Build Firmware / PublishFirmwareSnapshot (push) Has been cancelled
Build Firmware / PublishFirmwareStable (push) Has been cancelled
Build Firmware / PublishSdk (push) Has been cancelled
2026-06-23 11:59:47 -04:00
Ken Van Hoeylandt e50659a3fb Fix for Gt911Touch. (#538) 2026-06-22 08:18:55 +02:00
Ken Van Hoeylandt aeccc15ab6 Fix for Gt911Touch when using new I2C driver. (#536)
Committing this straight to main branch to avoid wasting pipelines.
2026-06-21 22:20:07 +02:00
Shadowtrance 594b8bd27e Smart tab5keyboard (#533) 2026-06-19 22:14:07 +02:00
Ken Van Hoeylandt e8b9a1f2a9 Fixes and improvements (#534) 2026-06-19 20:46:56 +02:00
Ken Van Hoeylandt a35c88c8fd Grove driver, I2C migrations, bugfixes and docs (#532) 2026-06-19 00:52:31 +02:00
Ken Van Hoeylandt 8dabda2b5b Implement new I2C driver (#531) 2026-06-12 18:46:22 +02:00
Shadowtrance 8dd9bee8d0 M5Stack Tab5 TinyUSB MSC support implemented (#530) 2026-06-10 22:39:36 +02:00
Ken Van Hoeylandt 543390a977 Fix for CoreS3 touch (#529)
The FT6 driver does a hardware ID check, which fails on the CoreS3 but
not on Stackchan for some reason. FT5 works on Stackchan, so we'll use
that for all devices, just like M5GFX does.
2026-06-10 00:24:18 +02:00
Shadowtrance 62266dff58 Tab5 Keyboard (#528) 2026-06-09 23:19:56 +02:00
Shadowtrance 3dcc95f6f3 USB host support (#527) 2026-06-03 23:10:37 +02:00
Shadowtrance a59fbf4ed5 Tab5 features, StackChan, fixes, drivers.... (#526) 2026-05-28 23:31:25 +02:00
Shadowtrance 5c78d55b04 Bluetooth (#518)
* Bluetooth LE addition

* fixes

* use the psram!

helps a little on S3 (t-deck)

* custom device name

* Update symbols.c

* Feedback + fixes

Fixes external app start/stop server (child devices)
Fixes BtManage causing a full system hang upon disabling bt when a device is connected to the host.

* updoot

* more updoot

* move back!

* Revert "move back!"

This reverts commit d3694365c634acc5db62ac59771c496cb971a727.

* fix some of the things

* Addressing feedback? hmm

* Fixes

Bug 1 — Reconnect loop / Reconnect not working fixed
Bug 2 — Name-only advertising overwrites HID advertising
Bug 3 — BleHidDeviceCtx leak on re-enable
Enhancement — HID device auto-start on radio re-enable

* stuff...

* update for consistency with others

* fix crashes

and some bonus symbols

* a few symbols, i2c speed, cdn message

100kHz i2c speed seems to be more compatible with m5stack modules...and probably in general.
cdn message no longer applies

* Hide BT Settings when bt not enabled

* Addressing things and device fixes

* Missed one!

* stuff
2026-05-22 22:49:37 +02:00
Pirata 895e6bc50d Add merged binaries to release assets (#524) 2026-05-21 22:53:52 +02:00
Ken Van Hoeylandt 4170b86137 Various fixes and improvements (#515)
* Optional internal pull-ups for SD/MMC pins in DTS
  * Selectable on‑chip LDO channel for SD/MMC power (can be disabled)
  * Added several sensor/driver modules to generic ESP32 device configurations so that they become part of the SDKs
  * SD card mount now prints card information for clearer diagnostics
  * Fix for bug DTS boolean parsing. Improved tests to catch these issues.
  * Expanded SDK integration test to include new modules and headers
  * Modularized packaging to generate per‑module build files and include driver assets
2026-04-28 17:26:03 +02:00
NellowTCS be2cdc0b90 Implement device: CYD-2432S024R (#521) 2026-04-13 20:59:15 +02:00
NellowTCS 10ba4f58e2 Add calibration methods and app (#520) 2026-04-13 20:58:27 +02:00
NellowTCS 4dd2762b79 Implemented device CYD-3248S035C (#522) 2026-04-13 20:32:33 +02:00
Shadowtrance e64f4ff16b M5Stack StickS3 - New Tab5 - driver modules (#516)
Font size set to 18 for 800x480 displays
Fix web server dashboard not rendering when sdcard isn't present

Added new driver modules
-  BM8563 RTC
- RX8130CE RTC
- MPU6886 IMU
- QMI8658 IMU
- M5PM1 Power Management Chip

Applied the above modules to applicable devicetrees.

Added new device: M5Stack StickS3

Added new M5Stack Tab5 St7123 variant.

ButtonControl changed to use interupts and xQueue, added AppClose action.

And some bonus symbols of course, the apps are hungry for symbols.
2026-03-20 10:07:57 +01:00
Shadowtrance e560cc7df2 Styling fixes for paper displays (#514) 2026-03-14 17:40:29 +01:00
Ken Van Hoeylandt aa7530e515 New kernel drivers, filesystem API, and more (#513)
* **New Features**
  * BMI270 6-axis IMU driver added; new unified filesystem abstraction for mounted filesystems.
  * Public Wi‑Fi API surface (no implementation yet)
  * SDMMC driver added (kernel drive$)
  * expanded GPIO interrupt/callback support
* **Improvements**
  * M5Stack Tab5: revamped GPIO/power initialization and IMU integration.
  * LVGL updates including device fontSize configuration.
  * Updated all code related to SD card device/fs handling
  * Rename LilyGO T-HMI S3 to LilyGO T-HMI
* **Bug Fixes**
  * Simplified and consolidated SD card handling and mount discovery.
2026-03-07 16:13:39 +01:00
Shadowtrance 2de35b2d2d M5Stack PaperS3 improvements and other bug fixes (#512) 2026-03-06 21:45:56 +01:00
Rivair Sabino dos Santos 9fc0aa51d7 Implement battery support for LilyGO T-HMI S3 (#511) 2026-03-05 23:21:10 +01:00
Rivair Sabino dos Santos 2426c387eb Add initial support for LilyGO T-HMI S3 with device configuration and… (#509) 2026-03-03 22:38:42 +01:00
Shadowtrance 33caf09856 Files App - Copy, Cut, Paste Actions (#510) 2026-02-26 20:11:05 +01:00
Ken Van Hoeylandt d2048e01b6 Tab5 power expander driver and devicetree parsing improvements (#507)
* **New Features**
  * PI4IOE5V6408 I2C I/O expander driver with public GPIO APIs
  * CLI tool to list devicetree dependencies

* **Device Tree Updates**
  * M5Stack Tab5 configured with two I2C IO expanders; PI4IOE5V6408 binding added

* **Build / Tooling**
  * Devicetree code generation integrated into build; generated artifacts and dynamic dependency resolution exposed

* **Refactor**
  * Kernel/run APIs updated to accept a null‑terminated devicetree modules array; many module symbols renamed

* **Documentation**
  * Added README and Apache‑2.0 license for new driver module
2026-02-17 22:59:30 +01:00
Shadowtrance f0f764baff Mbedtls symbols and more (#508) 2026-02-17 19:00:08 +01:00
Ken Van Hoeylandt d860ba1f34 Tab5 audio, I2C improvements, UiDensity moved to lvgl-module and cleanup (#506)
- UiDensity moved to lvgl-module
- Deleted tt_hal and tt_hal_gpio (breaks apps, but will fix those right after merging)
- Added I2C 8 bit register operations
- Added device.properties to simulator
- Improved Tab5 hardware init, implement audio
- Add README.md to kernel
2026-02-15 19:45:12 +01:00
Ken Van Hoeylandt 3a24d058c9 Rename icons, fix T-Lora Pager config and more (#502)
* **New Features**
  * Added NFC chip-select to SD card hardware configuration.

* **Refactor**
  * Consolidated and renamed icon resources; apps and status-bar now reference unified icon headers and new icon constants.
  * Renamed LVGL lock API (timed → lvgl_try_lock) and updated callers.

* **Documentation**
  * Updated module README and license files; added Apache-2.0 license document.
2026-02-15 13:32:52 +01:00
Shadowtrance 72b55b221e Update device.properties to fix Waveshare GEEK PSRAM issue (#504) 2026-02-15 12:39:15 +01:00
Ken Van Hoeylandt 9a11e6f47b Implement UI scaling and more (#501)
**New Features**
 * Runtime font accessors and new symbol fonts for text, launcher, statusbar, and shared icons.
 * Added font height base setting to device.properties
 * Text fonts now have 3 sizes: small, default, large

**Improvements**
 * Renamed `UiScale` to `UiDensity`
 * Statusbar, toolbar and many UI components now compute heights and spacing from fonts/density.
 * SSD1306 initialization sequence refined for more stable startup.
 * Multiple image assets replaced by symbol-font rendering.
 * Many layout improvements related to density, font scaling and icon scaling
 * Updated folder name capitalization for newer style
2026-02-15 01:41:47 +01:00
Ken Van Hoeylandt 72c9b2b113 Add custom icon fonts to lvgl-module (#499)
* **New Features**
  * Added Material Design symbol fonts and LVGL font aliases for launcher, status bar, and shared UI icons.

* **Style**
  * Migrated app icons across the UI to the new symbol font system.
  * Updated launcher button sizing, font styling, recoloring and icon text color for consistency.
  * Default text/icon font macros set for consistent sizing across the UI.

* **Documentation**
  * Updated third‑party notices to include Material Design Icons links.
2026-02-13 20:27:08 +01:00
Shadowtrance 4ab29ae466 Guition 535 and 550 i2s config (#500) 2026-02-13 20:11:51 +01:00
Ken Van Hoeylandt 8ff990d635 Boot apps refactored (#498)
- Specify launcher via menuconfig
- Specify auto-start app via menuconfig
- Implement more rigid boot.properties fallbacks
- Devices with tiny screen now auto-start ApWebServer
- ApWebServer UI fixes
2026-02-12 00:10:04 +01:00
Shadowtrance 49632d15c9 AP Web Server App (#497)
Auto starts the web server in AP mode with generated SSID and Password.
For small devices.... or any i guess.
Hidden by default.
May need adjustments to suit even smaller screens than the waveshare GEEK.
And a few symbols for good measure. :)
2026-02-11 20:37:22 +01:00
Ken Van Hoeylandt 26c17986c6 GPIO refactored (#495)
* **Refactor**
  * GPIO subsystem moved to a descriptor-based model for per-pin ownership and runtime pin management; many platform drivers now acquire/release descriptors.
  * Device trees and drivers now use GPIO phandle-style pin specifications across all boards and all drivers.

* **Behavior**
  * Device list now encodes per-device status (ok/disabled); boot will skip disabled devices accordingly.

* **Deprecation**
  * Legacy GPIO HAL marked deprecated and replaced with descriptor-based interfaces.

* **Chores**
  * Bindings and platform configs updated to the new GPIO pin-spec format.
2026-02-11 20:34:54 +01:00
Ken Van Hoeylandt dff93cb655 Add lv_arc.h symbols (#496) 2026-02-10 12:35:40 +01:00
Ken Van Hoeylandt 25c3f19e5d Merge develop into main (#494)
* Updated runtime gating to enable LilyGO T-Deck specific apps and services
  * New device compatibility and model-detection APIs
  * Added a buffer-overflow error code and message
  * Updated GitHub Actions checkout to v4
  * Adjusted an LVGL-related library version
  * Device config now emits a T-Deck workaround flag when applicable
  * Removed internal developer comments and minor cleanups
2026-02-09 22:12:03 +01:00
Ken Van Hoeylandt 93efadd5e3 Devicetree DTS and YAML format improvements (#492)
* **DevicetreeCompiler**
  * Binding properties now support default values.
  * Compiler returns meaningful exit codes and reports errors more clearly.
  * Stronger validation of device configurations with unified error handling.
  * Added integration tests and a dedicated Devicetree test workflow.

* **Changes**
  * Platform binding schemas updated: some fields made required, others gained explicit defaults.
  * Many device-tree files simplified by removing unused/placeholder pin and transfer-size entries.

* **Documentation**
  * Removed several outdated TODO items.
2026-02-09 17:38:06 +01:00
Ken Van Hoeylandt d27404964a SPI device migration (#490)
- Implement SPI devices in dts files for all devices
- Removed `tt::hal::spi` HAL and its configurations
- Fix for devicetree generator "boolean" support
- Remove unused custom locks in all `DisplayDevice` implementations
- Fixed some bugs with devices
- Updated XPT2046 driver
- Fix for `WifiEsp` deadlock
- Export a lot of new `math.h` symbols with `tt_init.cpp`
- Created `SpiDeviceLock` in `TactilityCore` as a wrapper for kernel SPI locking
- Improved `TactilityKernel` SPI driver.
2026-02-08 22:14:18 +01:00
Ken Van Hoeylandt 74127a5f6c Add kernel drivers for SPI and UART and make locking APIs more consistent (#489)
- Add kernel support for SPI driver
- Add kernel support for UART driver
- Implemented ESP32 UART kernel driver
- Update existing UART-related code in Tactility to use new kernel driver
- Remove UART from tt::hal::Configuration
- Remove tt_hal_uart functionality but keep functions for now
- Update devicetrees for UART changes
- Kernel mutex and recursive mutex: improved locking API design
- Other kernel improvements
- Added device_exists_of_type() and device_find_by_name()
2026-02-07 21:28:11 +01:00
Rivair Sabino dos Santos 7e24105d0c Implement pagination for file entries in View class (#486)
* Implement pagination for file entries in View class

* Add resolveDirentFromListIndex method and refactor entry handling in View class

* Fix current_start_index calculation in View::update to prevent out-of-bounds access
2026-02-07 12:15:55 +01:00
Ken Van Hoeylandt 2aa41cb562 Revert LVGL from 9.4.0 to 9.3.0 (#488)
Because of stability issues on T-Deck
2026-02-07 08:26:21 +01:00
Ken Van Hoeylandt 0042ce6d32 Fix SDK (#487)
* **New Features**
  * Added a full SDK integration test suite with a minimal sample app and automated multi-platform build/run flows.
  * Added a new CLI build tool to orchestrate SDK download, build, packaging, and device install/run.

* **Documentation**
  * Added typography design token suggestion to ideas.

* **Chores**
  * Updated CI to run SDK integration prep and test steps.
  * Adjusted build artifact paths, license mappings, and repository ignore rules (including .tactility).
2026-02-06 22:50:13 +01:00
Ken Van Hoeylandt 79e43b093a Kernel improvements (#485)
* **New Features**
  * Added public accessors for querying module/device start and ready state.

* **Refactor**
  * Internal state moved to opaque internal objects; module/device/driver initializers now explicitly initialize internal pointers.
  * Lifecycle handling updated to construct/destruct internal state and use accessors.

* **Tests**
  * Tests updated to use public accessors and explicit construct/destruct lifecycle calls.

* **Chores**
  * Test build/include paths and small metadata updated.
2026-02-06 16:32:30 +01:00
Ken Van Hoeylandt 1757af859c Update LVGL, esp_lvgl_port and esp_lcd_touch (#484)
- LVGL: 9.3.0 -> 9.4.0
- esp_lvgl_port:  2.5.0 -> 2.7.0
- eps_lcd_touch: 1.1.2 -> 1.2.1
2026-02-06 00:35:41 +01:00
Ken Van Hoeylandt 626d0d9776 Devicetree DTS alias support (#483)
* **New Features**
  * Phandle support for device-to-device property references.
  * Recognition of #define-style declarations in device trees.
  * Device nodes may include optional aliases alongside node names.

* **Improvements**
  * Flatter, consistent device hierarchy processing for generation.
  * Error and log messages now reference node names for clearer diagnostics.

* **Other**
  * Added a static ESP32-based device tree and minor DTS comment updates.
2026-02-05 23:10:11 +01:00
Fuji Pebri ecc0a9c076 Added support for 1-line bus width SDMMC device mode (#482) 2026-02-05 22:46:55 +01:00
Ken Van Hoeylandt 4fe4faf422 Devicetree updates (#481)
* **New Features**
  * Added I2S audio support (i2s0) for LilyGO TLora Pager, M5Stack Cardputer (standard & Adv), M5Stack Core2, M5Stack CoreS3, and Guition JC1060P; moved i2s0 entry in LilyGO TDeck.

* **Chores**
  * Device-tree grammar now separately recognizes and ignores line (//) and block (/* */) comments.
  * Added reference docs to severa DTS files

* **Documentation**
  * Reworked ideas/roadmap
2026-02-05 19:31:47 +01:00
Ken Van Hoeylandt a1c835e073 I2S driver implementation (#480)
* **New Features**
  * ESP32 I2S controller support: runtime-configurable digital audio I/O with read/write/set/get operations and multiple formats.

* **Board Support**
  * LilyGO T-Deck device tree entry added to enable I2S peripheral pin configuration.

* **Documentation**
  * New/updated bindings and descriptors for I2S, I2C, GPIO, and root nodes.

* **Other**
  * Added GPIO "no pin" sentinel and exposed I2S controller API symbols.
2026-02-04 23:40:16 +01:00
Ken Van Hoeylandt 9a672a30ff Kernel and TactilitySDK improvements (#479)
* **New Features**
  * Expanded public device and driver APIs (accessors, sync, lifecycle, binding) and a module construct+start helper.
  * Added kernel symbol registry and new exported symbols (lvgl, C++ nothrow, I2S APIs, additional math funcs).

* **Refactor**
  * Renamed device traversal APIs for consistency (device_for_each*).
  * Moved inline helpers to explicit public declarations.

* **Chores**
  * Replaced several shell release scripts with Python-based SDK release tooling.
* **Style**
  * Header naming consistency fixes.
2026-02-03 23:24:37 +01:00
Ken Van Hoeylandt 9cc96fd32b M5Stack PaperS3 implementation (#478)
Selectively imported code from @juicecultus [fork](https://github.com/juicecultus/Tactility) with some changes/additions from me.
2026-02-03 21:22:40 +01:00
Ken Van Hoeylandt a935410f82 Kernel and buildscript improvements (#477)
* **New Features**
  * Centralized module management with global symbol resolution
  * Level-aware logging with colored prefixes and millisecond timestamps

* **Breaking Changes**
  * ModuleParent hierarchy and getModuleParent() removed
  * Logging API and adapter model replaced; LogLevel-driven log_generic signature changed

* **Improvements**
  * Unified, simplified module registration across build targets
  * Tests updated to reflect new module lifecycle and global symbol resolution
2026-02-03 08:35:29 +01:00
Ken Van Hoeylandt 1a61eac8e0 Export more symbols (#476)
* **Export more symbols:**
  * Expanded standard library support with additional math functions (trigonometric, exponential, and rounding operations), string comparison, directory operations, and locale configuration
  * Added C++ static initialization guard utilities to enhance object initialization support
2026-02-02 08:18:51 +01:00
Ken Van Hoeylandt 1f9e7f82fd Implement support for module symbols (#475)
* **New Features**
  - Adds module symbol support and per-module symbol tables, including LVGL symbol exports moved into a dedicated table.
* **API**
  - Adds symbol-resolution APIs and an accessor to enable dynamic lookup between modules.
* **Bug Fixes / Chores**
  - Explicitly initializes module symbol pointers across device and platform modules to avoid uninitialized state.
* **Tests**
  - Updates tests to account for symbol pointer initialization.
2026-02-02 07:50:43 +01:00
Ken Van Hoeylandt 9f721e6655 Refactor LVGL code into kernel module (#472)
* **New Features**
  * Added a standalone LVGL module and enabled LVGL support in the simulator for richer local UI testing.

* **Refactor**
  * HAL and LVGL split into distinct modules; startup and device attach/detach flows reorganized for clearer lifecycle management.
  * Public APIs tightened with clearer nullability/documentation.

* **Bug Fixes**
  * More consistent LVGL start/stop and device attach/detach behavior for improved stability.
2026-02-01 22:57:45 +01:00
Ken Van Hoeylandt 3fe1dc0312 Create hal-device module, fix GPIO, fix tests, fix TactilityC (#471)
* **New Features**
  * Added a HAL device module providing device enumeration, type queries and a HAL↔kernel bridge.

* **Improvements**
  * Integrated HAL module into startup; standardized module names, includes and lifecycle logging; safer file append behavior; broader build support.

* **API Changes**
  * Driver lifecycle now uses explicit add/remove semantics; C and HAL device type/lookup APIs clarified.

* **Chores**
  * Added module README and Apache‑2.0 license; updated build configuration to include the new module.

* **Fixes**
  * Updated tests and object file handling to behave correctly.
2026-02-01 01:05:16 +01:00
Ken Van Hoeylandt 5993ceb232 Rename device modules (#470)
Standardised device module identifiers across all supported devices to use consistent naming conventions with lowercase alphanumeric and hyphen-separated formats.
2026-01-31 13:11:36 +01:00
Ken Van Hoeylandt 399dca5e14 Partial reimplementation of TactilityC GPIO (#469)
* **New Features**
  * Added a GPIO hardware abstraction layer for reading pin levels from applications.
  * Applications can now query the number of available GPIO pins so they can adapt to different devices.
* **Chores**
  * Integrations updated so GPIO capabilities are discoverable and exported to running applications.
2026-01-31 12:34:45 +01:00
Ken Van Hoeylandt c9185740d7 Kernel improvements (#468)
* **New Features**
  * Plugin-style modules for platforms and devices with start/stop lifecycle and a runtime-consumable device tree array.

* **Refactor**
  * Consolidated initialization into a kernel/module startup flow.
  * Generated devicetree artifacts moved to the build Generated directory.

* **Changes**
  * Removed legacy no-op registration hooks and I2C lock/unlock wrappers.
  * Driver ownership and private state moved to explicit module/owner model.
  * Added ERROR_NOT_ALLOWED error code.
2026-01-31 09:18:02 +01:00
Shadowtrance d62314f41f Guition JC3248W535C (#467)
* Guition JC3248W535C

Files app fix
alert dialog and selection dialog fixes
symbol export

* Update Axs15231bDisplay.cpp

* Update Axs15231bDisplay.cpp
2026-01-31 00:01:12 +01:00
Ken Van Hoeylandt 87ca888bb4 Create DTS files for all devices and implement I2C changes (#466)
Devictree changes:
- Create DTS files for all remaining devices
- Update corresponding `devicetree.yaml`
- Remove `i2c` configuration from corresponding `tt::hal::Configuration`

Apps & HAL:
- Removed I2C Settings (we'll make a new one later after I rework that part of the HAL)
- Delete TactilityC GPIO and I2C functionality
- Delete Related SystemEvent types
- Refactor `tt::hal::i2c` to only use `struct Device*` wrapping

Scripting:
- Fix DevicetreeCompiler boolean parsing
- Create `build-all.py`
2026-01-29 22:01:19 +01:00
Ken Van Hoeylandt 71f8369377 TactilityKernel improvements (#464)
* **New Features**
  * Thread API with lifecycle, priority, affinity and state monitoring
  * Timer subsystem: one-shot/periodic timers, reset, pending callbacks, expiry queries
  * Expanded I²C: register-level ops, bulk writes, presence checks, ESP32 integration and new config properties
  * GPIO controller: pin level and options APIs
  * Error utilities: new error code, error-to-string, timeout helper and common macros
  * Device construction helpers (construct+start)

* **Tests**
  * New unit tests for thread and timer behavior

* **Documentation**
  * Expanded coding style guide (files/folders, C conventions)
2026-01-28 23:58:11 +01:00
Shadowtrance f6ddb14ec1 Dashboard auto refresh toggle (#465)
asset sync now works (AssetVersion)...could probably do with some improvements.
disable auth username and password if not enabled.
2026-01-28 21:15:36 +01:00
Ken Van Hoeylandt d551e467b8 Moved and renamed files for consistent C code style (#463)
* **Documentation**
  * Added new C coding style guide detailing naming conventions for files, directories, macros, constants, variables, functions, and type definitions with illustrative examples.
  * Updated C++ coding style documentation with clarifications on C naming conventions and header directory organization patterns.

* **Refactor**
  * Updated header include paths throughout the codebase to use lowercase naming conventions consistently.
2026-01-27 20:17:33 +01:00
Shadowtrance c05d46a28c Screensavers (#462)
Adds screensavers in addition to the backlight idle off. 
More info in screensavers.md

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added a screensaver system with multiple styles (Bouncing Balls, Mystify, Matrix Rain) and a common screensaver interface; auto-starts after inactivity, dismisses on interaction, and supports auto-off/backlight behavior.
  * New Display setting and UI dropdown to choose and persist the screensaver.

* **Documentation**
  * Added comprehensive screensaver docs covering usage, extension, and configuration.

* **Chores**
  * Registered the display-idle service.

* **Bug Fixes**
  * Updated LVGL API calls to match renamed functions.

<sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-27 17:21:16 +01:00
Ken Van Hoeylandt e6abd496f9 Various improvements (#461)
* **New Features**
  * Time and delay utilities added (ticks, ms, µs); SD card now uses an expansion-header CS pin; HTTP downloads warn when run on the GUI task and yield to avoid blocking.

* **Bug Fixes / Reliability**
  * Many hard-crash paths converted to guarded checks to reduce abrupt termination and improve stability.

* **Tests**
  * Unit tests added to validate time and delay accuracy.

* **Chores**
  * License header and build/macro updates.
2026-01-27 08:04:21 +01:00
Ken Van Hoeylandt 619b5aa53b M5Stack Tab5 support (#449)
* **New Features**
  * Added support for M5Stack Tab5: integrated display (ILI9881C MIPI-DSI), touch, and SD card.

* **User Interface**
  * Changed toolbar label from "External Apps" to "Installed Apps."

* **Improvements**
  * Clarified boot log messages ("Init boot"/"Init boot failed") for better diagnostics.
  * Firmware build matrix and configuration updated to include the M5Stack Tab5 target.
2026-01-27 00:18:53 +01:00
Shadowtrance 10381b10cd Chat app update, EspNow v2 & GPS Info (#460) 2026-01-26 17:32:57 +01:00
Ken Van Hoeylandt dfe2c865d1 TactilityKernel improvements and more (#459) 2026-01-25 23:54:33 +01:00
Ken Van Hoeylandt 96eccbdc8d Add tests and update licenses (#458)
Replace LGPL from past commit with Apache License 2.0 for the newly created projects:
- in Platforms/*
- TactilityKernel

Add license headers to source code in:
- in Platforms/*
- TactilityKernel
- TactilityFreeRtos

Updated LICENSE.md
2026-01-24 21:33:44 +01:00
Ken Van Hoeylandt 2839ea4c35 Update domain name and related URLs (#457) 2026-01-24 18:18:55 +01:00
Ken Van Hoeylandt 51b9547e99 Revert last change (#456) 2026-01-24 16:38:59 +01:00
Ken Van Hoeylandt d3797abf4e Update GitHub group references (#455)
ByteWelder -> TactilityProject
2026-01-24 16:34:04 +01:00
Ken Van Hoeylandt 4b6ed871a9 Implemented TactilityKernel and DevicetreeCompiler, updated licenses & copyrights (#452)
**New features**

- Created a devicetree DTS and YAML parser in Python
- Created new modules:
  - TactilityKernel (LGPL v3.0 license)
  - Platforms/PlatformEsp32 (LGPL v3.0 license) 
  - Platforms/PlatformPosix (LGPL v3.0 license)
  - Tests/TactilityKernelTests

Most boards have a placeholder DTS file, while T-Lora Pager has a few devices attached.

**Licenses**

Clarified licenses and copyrights better.

- Add explanation about the intent behind them.
- Added explanation about licenses for past and future subprojects
- Added more details explanations with regards to the logo usage
- Copied licenses to subprojects to make it more explicit
2026-01-24 15:47:11 +01:00
Shadowtrance 0d16eb606f ESP-NOW chat & P4 fixes (#454)
* Espnow chat fix

Fixes chat app not appearing and coexistence with wifi STA mode.
Wifi OFF and obviously not connected, espnow starts.
Wifi ON and connected, espnow starts.
Wifi ON and NOT connected, espnow starts.

* Fix P4 build
2026-01-24 12:42:49 +01:00
Shadowtrance b8214fd378 Trackball Pointer Mode & driver rewrite (#453) 2026-01-23 17:30:13 +01:00
Shadowtrance 01ffe420eb Webserver addition and TactilityC symbols (#451) 2026-01-21 21:47:59 +01:00
Ken Van Hoeylandt c98cb2bf10 Add Guition JC1060P470CIWY and update other Guition device IDs (#447)
This commit contains @josemalm32 's  implementation for the Guition JC1060P470CIWY  (see https://github.com/ByteWelder/Tactility/issues/427)

I've added these changes:
- Updated the branch for the new logging method
- Updated the branch for the PR that I mentioned in the above linked issue
- Replaced the manually pasted in esp_lcd_jd9165 driver with the one from the component registry
- Updated Spanish to English
- Updated all drivers' mutexes/locks
- Fixed the display color format
- Fixed bug in power deinit
- Renamed I2C bus in config
- Added device to continuous integration
- Renamed several Guition devices from CYD to Guition
- Fix for `EspLcdDisplayV2` init for when features are not supported
- Pin esp_wifi_remote to version 1.2.3
- Fix in `WifiManage` logging
- Fix for `WifiEsp.cpp`'s check for wifi presence
- Fix for `WifiEsp`'s scan list logging
- Fix for `gcc_soft_float_symbols` in TactiltyC
2026-01-07 22:41:45 +01:00
Ken Van Hoeylandt f620255c41 New logging and more (#446)
- `TT_LOG_*` macros are replaced by `Logger` via `#include<Tactility/Logger.h>`
- Changed default timezone to Europe/Amsterdam
- Fix for logic bug in unPhone hardware
- Fix for init/deinit in DRV2605 driver
- Other fixes
- Removed optimization that broke unPhone (disabled the moving of heap-related functions to flash)
2026-01-06 22:35:39 +01:00
Ken Van Hoeylandt 719f7bcece Fixes and improvements (#445)
- Remove unnecessary CS work-around for Cardputers
- Don't compile WifiMock when not necessary
- Fix for running apps on devices without SPIRAM
- Disable backlight dimming by default
2026-01-04 14:27:10 +01:00
Ken Van Hoeylandt 2ca8ae62fb Various fixes (#444)
- Add missing symbols for TactilitySDK
- Disable display idle logic when there's no LVGL display
2026-01-04 01:50:33 +01:00
Ken Van Hoeylandt fa544f9b3c Add missing timer methods to TactilityC (#443) 2026-01-03 22:34:51 +01:00
Ken Van Hoeylandt 812c2901db TactilitySDK updates (#442)
- Removed custom `TickType`
- Removed TactilityC functionality that is now covered by TactilityFreeRtos
2026-01-03 22:00:31 +01:00
Ken Van Hoeylandt 524b197105 Add TactilityFreeRtos to TactilitySDK (#441)
- TactlitySDK updates fro TactilityFreeRtos
- Enable auto-uploading of SDKs to the CDN when merging code
2026-01-03 16:28:07 +01:00
Ken Van Hoeylandt 7283920def Create TactilityFreertos subproject (#440) 2026-01-03 00:19:40 +01:00
Shadowtrance a4dc633063 Feature additions (#434)
Lots of things "ported" over from the "enhanced" fork. With some adjustments here and there.

KeyboardBacklight driver (for T-Deck only currently)
Trackball driver (for T-Deck only currently)
Keyboard backlight sleep/wake (for T-Deck only currently...also requires keyboard firmware update)
Display sleep/wake
Files - create file/folder
Keyboard settings (for T-Deck only currently)
Time & Date settings tweaks
Locale settings tweaks
Systeminfo additions
Espnow wifi coexist

initI2cDevices - moved to T-deck init.cpp / initBoot
KeyboardInitService - removed,  moved to T-deck init.cpp / initBoot
Adjusted TIMER_UPDATE_INTERVAL to 2 seconds.
Added lock to ActionCreateFolder

Maybe missed some things in the list.

Display wake could do with some kind of block on wake first touch to prevent UI elements being hit when waking device with touch. Same with encoder/trackball/keyboard press i guess.

The original code was written by @cscott0108 at https://github.com/cscott0108/tactility-enhanced-t-deck
2026-01-02 12:14:55 +01:00
Shadowtrance feaeb11e49 Added TactilityC symbols and DPI updates(#438)
+ btt-panda-touch size correction and dpi update
+ wt32-sc01-plus dpi update
2025-12-29 18:16:08 +01:00
Ken Van Hoeylandt 3fc2ff8bc6 Split off RecursiveMutex from Mutex (#437)
* Split off RecursiveMutex from Mutex

* Fix

* Code quality
2025-12-28 12:30:54 +01:00
Ken Van Hoeylandt f48654d3dc Various fixes and improvements (#435)
- Fix for `sdkconfig` generation: the keys that contained the MCU type in its name weren't properly upper-cased.
- Moved WiFi configuration property files to the user data path of the app instead of a fixed location.
- Moved more properties from `device.py` to `sdkconfig/default.properties`
- Fix for `device.cmake` device id parsing: separate basic property parsing from device id validation
- Created internal `tt::service::wifi::findServiceContext()`
- Changed Wi-Fi service id to lowercase (will change it for other services later)
2025-12-25 15:41:39 +01:00
Ken Van Hoeylandt 261796068e Fix for simulator SDL settings (#433) 2025-12-22 22:35:59 +01:00
Ken Van Hoeylandt 134e0b34b6 Fix for simulator build and improve ESP-IDF build (#432) 2025-12-22 21:16:51 +01:00
Shadowtrance 6c4a9975a4 Added TactilityC symbols (#429) 2025-12-18 09:45:53 +01:00
Ken Van Hoeylandt 776e3cd4c0 Fix Wi-Fi provisioning from /data (#428)
- Import from `/data/settings` instead of `/data`
- Removed unnecessary functions
- Header syntax cleanup
2025-12-17 14:38:29 +01:00
Ken Van Hoeylandt 76686e5c90 Fix for sdkconfig generation with device.py (#426) 2025-12-06 15:22:53 +01:00
Ken Van Hoeylandt cbaa32c27e Add LVGL lv_obj_ functions (#425) 2025-12-06 12:02:41 +01:00
NellowTCS 65d3d55cc4 Various fixes and improvements (#424)
- Read WiFi provisioning from /data
- Fix for finding apps at /data
- Expose more LVGL functions with TactilityC
2025-12-05 13:18:23 +01:00
Shadowtrance 62124541e9 WT32 SC01 Plus (#416) 2025-11-28 17:40:24 +01:00
NellowTCS 8de88dd3fd Software Rotation for ST7789 i8080 Driver (#422) 2025-11-27 22:40:33 +01:00
Ken Van Hoeylandt c6cc4034df Fix for CDN publishing script (#423) 2025-11-25 20:42:43 +01:00
Ken Van Hoeylandt b565d56029 Implement support for ESP32 C6 and P4 SOCs (#421)
- Implement generic ESP32 devices
- Updated GitHub Actions to first build the SDKs. These are now based on the generic device implementations and the build act as a filter before compiling the dozens of other devices. It should save on resources when boards fail to compile.
- Adapted code to C6 and P4 differences, heavily borrowed from from https://github.com/ByteWelder/Tactility/pull/394 written by @marciogranzotto, with some changes of my own
- Updated `device.py` to make the `[display]` section optional
2025-11-24 19:28:07 +01:00
Ken Van Hoeylandt fec8033fd7 Fixes for minitar related to app install (#420) 2025-11-24 00:22:12 +01:00
Ken Van Hoeylandt 6ab6ae5686 Merge develop into main (#419)
- Apply IRAM optimization to all platforms instead of only ESP32
- Implement performance optimizations
- Created `tt::hal::uart::open(uart_port_t)`
2025-11-23 00:11:08 +01:00
Ken Van Hoeylandt eba1f8955a Merge develop into main (#418)
- WiFi code cleanup
- When WifiConnect opens and SSID is filled in, automatically focus on the password field
- When no touch screen is present, toolbar close buttons should be automatically selected
- When `device.py` selects a device, print it on screen
2025-11-14 23:29:20 +01:00
Ken Van Hoeylandt a4f4784ed9 Add low memory warning (#417) 2025-11-14 15:43:00 +01:00
Ken Van Hoeylandt dddca1ea76 Generate commit hash and timestamp for CDN (#415) 2025-11-14 00:23:25 +01:00
Ken Van Hoeylandt c1ff024657 Rename Boards/ to Devices/ (#414) 2025-11-13 23:50:43 +01:00
Shadowtrance c7c9618f48 Waveshare GEEK (#413) 2025-11-13 22:32:02 +01:00
Ken Van Hoeylandt 0df6b78bd6 CDN script fixes (#412) 2025-11-12 23:28:16 +01:00
Ken Van Hoeylandt 7918451699 Replace sdkconfig with device.properties (#411) 2025-11-12 22:36:08 +01:00
NellowTCS 8335611796 Board Support: Heltec v3 (#407) 2025-11-05 09:04:40 +01:00
Shadowtrance 0d8c0a37cc LilyGo T-Display (#406)
+ expose lvglSwapBytes setting for the St7789Display driver.
+ updated all relevant boards accordingly.
2025-11-02 16:56:03 +01:00
NellowTCS ab2aa2c4d4 Access to the "/data" partition via USB Mass Storage (#405) 2025-11-02 16:26:35 +01:00
Ken Van Hoeylandt e2ec39304c Fixes for enums in TactilityC (#404) 2025-11-01 09:38:32 +01:00
Ken Van Hoeylandt 569cce38fa Implement automatic CDN publishing (#403) 2025-10-31 23:39:41 +01:00
Ken Van Hoeylandt 9ae3e48600 Create bundle-firmware action for release branch (#401) 2025-10-30 22:46:52 +01:00
Shadowtrance 388c2cfe4b BigTreeTech Panda Touch / K Touch (#402) 2025-10-30 22:09:09 +01:00
NellowTCS adea6678a5 New board: T-Display S3 (no touch) (#398) 2025-10-29 20:12:46 +01:00
1697 changed files with 74907 additions and 32941 deletions
+1 -1
View File
@@ -30,4 +30,4 @@ If applicable, add screenshots to help explain your problem.
**Additional context** **Additional context**
Add any other context about the problem here. Add any other context about the problem here.
Add your oops.tactility.one URL if you had a crash (scanned from QR). Add your oops.tactilityproject.org URL if you had a crash (scanned from QR).
@@ -1,7 +1,7 @@
### Checklist ### Checklist
- [ ] I read [contribution guidelines](https://github.com/ByteWelder/Tactility/blob/main/CONTRIBUTING.md) - [ ] I read [contribution guidelines](https://github.com/TactilityProject/Tactility/blob/main/CONTRIBUTING.md)
- [ ] Code adheres to the [coding style](https://github.com/ByteWelder/Tactility/blob/main/CODING_STYLE.md) - [ ] Code adheres to the [coding style](https://github.com/TactilityProject/Tactility/blob/main/CODING_STYLE.md)
### Description ### Description
+15 -2
View File
@@ -16,16 +16,23 @@ runs:
submodules: recursive submodules: recursive
- name: 'Board select' - name: 'Board select'
shell: bash shell: bash
run: cp sdkconfig.board.${{ inputs.board_id }} sdkconfig run: python device.py ${{ inputs.board_id }}
- name: 'Build' - name: 'Build'
uses: espressif/esp-idf-ci-action@v1 uses: espressif/esp-idf-ci-action@v1
with: with:
esp_idf_version: v5.5 esp_idf_version: v5.5.2
target: ${{ inputs.arch }} target: ${{ inputs.arch }}
path: './' path: './'
- name: 'Release' - name: 'Release'
shell: bash shell: bash
run: Buildscripts/release.sh ${{ inputs.board_id }} run: Buildscripts/release.sh ${{ inputs.board_id }}
- name: 'Merge binary'
shell: bash
run: |
python -m pip install esptool
cd release/Tactility-${{ inputs.board_id }}
bash ./merge.sh ${{ inputs.arch }}
mv Binaries/merged_binary.bin ../Tactility-${{ inputs.board_id }}.bin
- name: 'Upload Artifact: Release' - name: 'Upload Artifact: Release'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
@@ -38,3 +45,9 @@ runs:
name: Tactility-${{ inputs.board_id }}-symbols name: Tactility-${{ inputs.board_id }}-symbols
path: release/Tactility-${{ inputs.board_id }}-symbols path: release/Tactility-${{ inputs.board_id }}-symbols
retention-days: 30 retention-days: 30
- name: 'Upload Artifact: Merged binary'
uses: actions/upload-artifact@v4
with:
name: Tactility-${{ inputs.board_id }}.bin
path: release/Tactility-${{ inputs.board_id }}.bin
retention-days: 30
+18 -4
View File
@@ -16,20 +16,34 @@ runs:
submodules: recursive submodules: recursive
- name: 'Board select' - name: 'Board select'
shell: bash shell: bash
run: cp sdkconfig.board.${{ inputs.board_id }} sdkconfig run: python device.py ${{ inputs.board_id }}
- name: 'Build' - name: 'Build'
uses: espressif/esp-idf-ci-action@v1 uses: espressif/esp-idf-ci-action@v1
with: with:
# NOTE: Update with ESP-IDF! # NOTE: Update with ESP-IDF!
esp_idf_version: v5.5 esp_idf_version: v5.5.2
target: ${{ inputs.arch }} target: ${{ inputs.arch }}
path: './' path: './'
- name: 'Release' - name: 'Release'
shell: bash shell: bash
env: env:
# NOTE: Update with ESP-IDF! # NOTE: Update with ESP-IDF!
ESP_IDF_VERSION: '5.5' ESP_IDF_VERSION: '5.5.2'
run: Buildscripts/release-sdk.sh release/TactilitySDK run: python Buildscripts/release-sdk.py release/TactilitySDK
- name: 'Test Integration Prep'
shell: bash
# The manifest.properties of our integration test uses version 0.0.0 to indicate that it is not using a normal SDK
# This way, it only works with our custom build. That means we have to create a copy of the SDK with the correct folder structure:
run: |
TACTILITY_SDK_NAME="0.0.0-${{ inputs.arch }}"
mkdir -p test_sdk/$TACTILITY_SDK_NAME
cp -r release/TactilitySDK test_sdk/$TACTILITY_SDK_NAME
- name: 'Test Integration'
uses: espressif/esp-idf-ci-action@v1
with:
esp_idf_version: v5.5.2
target: ${{ inputs.arch }}
command: export TACTILITY_SDK_PATH=../../test_sdk && cd Tests/SdkIntegration && python tactility.py build ${{ inputs.arch }} --local-sdk
- name: 'Upload Artifact' - name: 'Upload Artifact'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
+1 -1
View File
@@ -15,7 +15,7 @@ runs:
using: "composite" using: "composite"
steps: steps:
- name: "Checkout repo" - name: "Checkout repo"
uses: actions/checkout@v2 uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Install Linux Dependencies for SDL - name: Install Linux Dependencies for SDL
@@ -0,0 +1,15 @@
name: Bundle All
runs:
using: 'composite'
steps:
- name: 'Download artifacts'
uses: actions/download-artifact@v4
with:
path: artifacts
- name: 'Upload Artifact'
uses: actions/upload-artifact@v4
with:
name: 'all-artifacts'
path: artifacts/
retention-days: 3
@@ -0,0 +1,24 @@
name: Publish Firmware
inputs:
cdn_version:
description: The version that determines the path on the CDN
required: true
runs:
using: 'composite'
steps:
- name: 'Download all-artifacts'
uses: actions/download-artifact@v4
with:
name: 'all-artifacts'
path: artifacts
- name: 'Install boto3'
shell: bash
run: pip install boto3
- name: 'Generate files'
shell: bash
run: version=`cat version.txt` && python Buildscripts/CDN/generate-firmware-files.py artifacts artifacts-cdn $version
- name: 'Upload files'
shell: bash
run: python Buildscripts/CDN/upload-firmware-files.py artifacts-cdn ${{ inputs.cdn_version }} ${{ env.CDN_ID }} ${{ env.CDN_TOKEN_NAME }} ${{ env.CDN_TOKEN_VALUE }}
+19
View File
@@ -0,0 +1,19 @@
name: Publish SDK
runs:
using: 'composite'
steps:
- name: 'Download all-artifacts'
uses: actions/download-artifact@v4
with:
name: 'all-artifacts'
path: artifacts
- name: 'Install boto3'
shell: bash
run: pip install boto3
- name: 'Generate files'
shell: bash
run: version=`cat version.txt` && python Buildscripts/CDN/generate-sdk-files.py artifacts artifacts-cdn $version
- name: 'Upload files'
shell: bash
run: version=`cat version.txt` && python Buildscripts/CDN/upload-sdk-files.py artifacts-cdn $version ${{ env.CDN_ID }} ${{ env.CDN_TOKEN_NAME }} ${{ env.CDN_TOKEN_VALUE }}
-54
View File
@@ -1,54 +0,0 @@
name: Build Firmware
on:
push:
branches:
- main
pull_request:
types: [ opened, synchronize, reopened ]
permissions: read-all
jobs:
build:
strategy:
matrix:
board: [
{ id: cyd-2432s024c, arch: esp32 },
{ id: cyd-2432s028r, arch: esp32 },
{ id: cyd-2432s028rv3, arch: esp32 },
{ id: cyd-e32r28t, arch: esp32 },
{ id: cyd-e32r32p, arch: esp32 },
{ id: cyd-2432s032c, arch: esp32 },
{ id: cyd-jc2432w328c, arch: esp32 },
{ id: cyd-8048s043c, arch: esp32s3 },
{ id: cyd-jc8048w550c, arch: esp32s3 },
{ id: cyd-4848s040c, arch: esp32s3 },
{ id: elecrow-crowpanel-advance-28, arch: esp32s3 },
{ id: elecrow-crowpanel-advance-35, arch: esp32s3 },
{ id: elecrow-crowpanel-advance-50, arch: esp32s3 },
{ id: elecrow-crowpanel-basic-28, arch: esp32 },
{ id: elecrow-crowpanel-basic-35, arch: esp32 },
{ id: elecrow-crowpanel-basic-50, arch: esp32s3 },
{ id: lilygo-tdeck, arch: esp32s3 },
{ id: lilygo-tdongle-s3, arch: esp32s3 },
{ id: lilygo-tlora-pager, arch: esp32s3 },
{ id: m5stack-cardputer, arch: esp32s3 },
{ id: m5stack-cardputer-adv, arch: esp32s3 },
{ id: m5stack-core2, arch: esp32 },
{ id: m5stack-cores3, arch: esp32s3 },
{ id: m5stack-stickc-plus, arch: esp32 },
{ id: m5stack-stickc-plus2, arch: esp32 },
{ id: unphone, arch: esp32s3 },
{ id: waveshare-s3-touch-lcd-43, arch: esp32s3 },
{ id: waveshare-s3-touch-lcd-147, arch: esp32s3 },
{ id: waveshare-s3-touch-lcd-128, arch: esp32s3 },
{ id: waveshare-s3-lcd-13, arch: esp32s3 }
]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: "Build"
uses: ./.github/actions/build-firmware
with:
board_id: ${{ matrix.board.id }}
arch: ${{ matrix.board.arch }}
-26
View File
@@ -1,26 +0,0 @@
name: Build SDK
on:
push:
branches:
- main
pull_request:
types: [ opened, synchronize, reopened ]
permissions: read-all
jobs:
build:
strategy:
matrix:
board: [
{ id: cyd-2432s028r, arch: esp32 },
{ id: lilygo-tdeck, arch: esp32s3 },
]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: "Build"
uses: ./.github/actions/build-sdk
with:
board_id: ${{ matrix.board.id }}
arch: ${{ matrix.board.arch }}
+139
View File
@@ -0,0 +1,139 @@
name: Build Firmware
on:
push:
branches:
- main
tags:
- v*
pull_request:
types: [ opened, synchronize, reopened ]
permissions: read-all
jobs:
BuildSdk:
strategy:
matrix:
board: [
{ id: generic-esp32, arch: esp32 },
{ id: generic-esp32c6, arch: esp32c6 },
{ id: generic-esp32p4, arch: esp32p4 },
{ id: generic-esp32s3, arch: esp32s3 },
]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: "Build SDK"
uses: ./.github/actions/build-sdk
with:
board_id: ${{ matrix.board.id }}
arch: ${{ matrix.board.arch }}
BuildFirmware:
strategy:
matrix:
board: [
{ id: btt-panda-touch, arch: esp32s3 },
{ id: cyd-2432s024c, arch: esp32 },
{ id: cyd-2432s024r, arch: esp32 },
{ id: cyd-2432s028r, arch: esp32 },
{ id: cyd-2432s028rv3, arch: esp32 },
{ id: cyd-e32r28t, arch: esp32 },
{ id: cyd-e32r32p, arch: esp32 },
{ id: cyd-2432s032c, arch: esp32 },
{ id: cyd-3248s035c, arch: esp32 },
{ id: cyd-8048s043c, arch: esp32s3 },
{ id: cyd-4848s040c, arch: esp32s3 },
{ id: elecrow-crowpanel-advance-28, arch: esp32s3 },
{ id: elecrow-crowpanel-advance-35, arch: esp32s3 },
{ id: elecrow-crowpanel-advance-50, arch: esp32s3 },
{ id: elecrow-crowpanel-basic-28, arch: esp32 },
{ id: elecrow-crowpanel-basic-35, arch: esp32 },
{ id: elecrow-crowpanel-basic-50, arch: esp32s3 },
{ id: guition-jc1060p470ciwy, arch: esp32p4 },
{ id: guition-jc2432w328c, arch: esp32 },
{ id: guition-jc3248w535c, arch: esp32s3 },
{ id: guition-jc8048w550c, arch: esp32s3 },
{ id: heltec-wifi-lora-32-v3, arch: esp32s3 },
{ id: lilygo-tdeck, arch: esp32s3 },
{ id: lilygo-thmi, arch: esp32s3 },
{ id: lilygo-tdongle-s3, arch: esp32s3 },
{ id: lilygo-tdisplay-s3, arch: esp32s3 },
{ id: lilygo-tlora-pager, arch: esp32s3 },
{ id: lilygo-tdisplay, arch: esp32 },
{ id: m5stack-cardputer, arch: esp32s3 },
{ id: m5stack-cardputer-adv, arch: esp32s3 },
{ id: m5stack-core2, arch: esp32 },
{ id: m5stack-cores3, arch: esp32s3 },
{ id: m5stack-papers3, arch: esp32s3 },
{ id: m5stack-stackchan, arch: esp32s3 },
{ id: m5stack-stickc-plus, arch: esp32 },
{ id: m5stack-stickc-plus2, arch: esp32 },
{ id: m5stack-sticks3, arch: esp32s3 },
{ id: m5stack-tab5, arch: esp32p4 },
{ id: unphone, arch: esp32s3 },
{ id: waveshare-esp32-s3-geek, arch: esp32s3 },
{ id: waveshare-s3-lcd-13, arch: esp32s3 },
{ id: waveshare-s3-touch-lcd-128, arch: esp32s3 },
{ id: waveshare-s3-touch-lcd-147, arch: esp32s3 },
{ id: waveshare-s3-touch-lcd-43, arch: esp32s3 },
{ id: wireless-tag-wt32-sc01-plus, arch: esp32s3 }
]
runs-on: ubuntu-latest
needs: [ BuildSdk ]
steps:
- uses: actions/checkout@v4
- name: "Build Firmware"
uses: ./.github/actions/build-firmware
with:
board_id: ${{ matrix.board.id }}
arch: ${{ matrix.board.arch }}
BundleArtifacts:
runs-on: ubuntu-latest
needs: [ BuildFirmware ]
if: |
(github.event_name == 'push' && github.ref == 'refs/heads/main') ||
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v'))
steps:
- uses: actions/checkout@v4
- name: "Bundle Artifacts"
uses: ./.github/actions/bundle-artifacts
PublishFirmwareSnapshot:
runs-on: ubuntu-latest
needs: [ BundleArtifacts ]
if: (github.event_name == 'push' && github.ref == 'refs/heads/main')
steps:
- uses: actions/checkout@v4
- name: "Publish Firmware Snapshot"
env:
CDN_ID: ${{ secrets.CDN_ID }}
CDN_TOKEN_NAME: ${{ secrets.CDN_TOKEN_NAME }}
CDN_TOKEN_VALUE: ${{ secrets.CDN_TOKEN_VALUE }}
uses: ./.github/actions/publish-firmware
with:
cdn_version: snapshot
PublishFirmwareStable:
runs-on: ubuntu-latest
needs: [ BundleArtifacts ]
if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v'))
steps:
- uses: actions/checkout@v4
- name: "Publish Firmware Stable"
env:
CDN_ID: ${{ secrets.CDN_ID }}
CDN_TOKEN_NAME: ${{ secrets.CDN_TOKEN_NAME }}
CDN_TOKEN_VALUE: ${{ secrets.CDN_TOKEN_VALUE }}
uses: ./.github/actions/publish-firmware
with:
cdn_version: stable
PublishSdk:
runs-on: ubuntu-latest
needs: [ BundleArtifacts ]
if: (github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')))
steps:
- uses: actions/checkout@v4
- name: "Publish SDKs"
env:
CDN_ID: ${{ secrets.CDN_ID }}
CDN_TOKEN_NAME: ${{ secrets.CDN_TOKEN_NAME }}
CDN_TOKEN_VALUE: ${{ secrets.CDN_TOKEN_VALUE }}
uses: ./.github/actions/publish-sdk
+23 -5
View File
@@ -4,13 +4,13 @@ on:
branches: branches:
- main - main
pull_request: pull_request:
types: [opened, synchronize, reopened] types: [ opened, synchronize, reopened ]
jobs: jobs:
run: TactilityTests:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: "Checkout repo" - name: "Checkout repo"
uses: actions/checkout@v2 uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: "Configure Project" - name: "Configure Project"
@@ -20,6 +20,24 @@ jobs:
- name: "Build Tests" - name: "Build Tests"
run: cmake --build build --target build-tests run: cmake --build build --target build-tests
- name: "Run TactilityCore Tests" - name: "Run TactilityCore Tests"
run: build/Tests/TactilityCore/TactilityCoreTests --exit run: build/Tests/TactilityCore/TactilityCoreTests
- name: "Run TactilityFreeRtos Tests"
run: build/Tests/TactilityFreeRtos/TactilityFreeRtosTests
- name: "Run TactilityHeadless Tests" - name: "Run TactilityHeadless Tests"
run: build/Tests/Tactility/TactilityTests --exit run: build/Tests/Tactility/TactilityTests
- name: "Run TactilityKernel Tests"
run: build/Tests/TactilityKernel/TactilityKernelTests
DevicetreeTests:
runs-on: ubuntu-latest
steps:
- name: "Checkout repo"
uses: actions/checkout@v4
with:
submodules: recursive
- name: "Install Python Dependencies"
shell: bash
run: pip install lark==1.3.1 pyyaml==6.0.3
- name: "Run Devicetree Tests"
shell: bash
working-directory: Buildscripts/DevicetreeCompiler/tests
run: python test_integration.py
+7 -2
View File
@@ -3,8 +3,7 @@
build/ build/
buildsim/ buildsim/
build-sim/ cmake-*/
cmake-build-*/
CMakeCache.txt CMakeCache.txt
*.cbp *.cbp
CMakeFiles CMakeFiles
@@ -18,6 +17,12 @@ managed_components/
dependencies.lock dependencies.lock
.vscode/ .vscode/
*.code-workspace
.gitpod.yml .gitpod.yml
sdkconfig.board.*.dev sdkconfig.board.*.dev
.tactility/
.caveman.json
.ai/mcp
@@ -1,116 +0,0 @@
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#include <PwmBacklight.h>
static bool initBoot() {
// Set the RGB LED Pins to output and turn them off
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT)); // Red
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_16, GPIO_MODE_OUTPUT)); // Green
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_17, GPIO_MODE_OUTPUT)); // Blue
// 0 on, 1 off
ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_4, 1)); // Red
ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_16, 1)); // Green
ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_17, 1)); // Blue
return driver::pwmbacklight::init(LCD_PIN_BACKLIGHT);
}
static tt::hal::DeviceVector createDevices() {
return {
createDisplay(),
createSdCard()
};
}
extern const tt::hal::Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
tt::hal::i2c::Configuration {
.name = "First",
.port = I2C_NUM_0,
.initMode = tt::hal::i2c::InitMode::ByTactility,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_33,
.scl_io_num = GPIO_NUM_32,
.sda_pullup_en = false,
.scl_pullup_en = false,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
tt::hal::i2c::Configuration {
.name = "Second",
.port = I2C_NUM_1,
.initMode = tt::hal::i2c::InitMode::Disabled,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_NC,
.scl_io_num = GPIO_NUM_NC,
.sda_pullup_en = false,
.scl_pullup_en = false,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
tt::hal::spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_13,
.miso_io_num = GPIO_NUM_NC,
.sclk_io_num = GPIO_NUM_14,
.quadwp_io_num = GPIO_NUM_NC, // Quad SPI LCD driver is not yet supported
.quadhd_io_num = GPIO_NUM_NC, // Quad SPI LCD driver is not yet supported
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = tt::hal::spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
},
tt::hal::spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_23,
.miso_io_num = GPIO_NUM_19,
.sclk_io_num = GPIO_NUM_18,
.quadwp_io_num = GPIO_NUM_NC, // Quad SPI LCD driver is not yet supported
.quadhd_io_num = GPIO_NUM_NC, // Quad SPI LCD driver is not yet supported
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 8192,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = tt::hal::spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr
},
}
};
@@ -1,129 +0,0 @@
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#include <PwmBacklight.h>
using namespace tt::hal;
static bool initBoot() {
// Set the RGB LED Pins to output and turn them off
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT)); // Red
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_16, GPIO_MODE_OUTPUT)); // Green
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_17, GPIO_MODE_OUTPUT)); // Blue
// 0 on, 1 off
ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_4, 1)); // Red
ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_16, 1)); // Green
ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_17, 1)); // Blue
return driver::pwmbacklight::init(LCD_PIN_BACKLIGHT);
}
static DeviceVector createDevices() {
return {
createDisplay(),
createSdCard()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
i2c::Configuration {
.name = "CN1",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_27,
.scl_io_num = GPIO_NUM_22,
.sda_pullup_en = false,
.scl_pullup_en = false,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
// Display
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_13,
.miso_io_num = GPIO_NUM_12,
.sclk_io_num = GPIO_NUM_14,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock()
},
// SDCard
spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_23,
.miso_io_num = GPIO_NUM_19,
.sclk_io_num = GPIO_NUM_18,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 0,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
},
},
.uart {
uart::Configuration {
.name = "P1",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_1,
.txPin = GPIO_NUM_3,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
@@ -1,129 +0,0 @@
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#include <PwmBacklight.h>
using namespace tt::hal;
static bool initBoot() {
// Set the RGB LED Pins to output and turn them off
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT)); // Red
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_16, GPIO_MODE_OUTPUT)); // Green
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_17, GPIO_MODE_OUTPUT)); // Blue
// 0 on, 1 off
ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_4, 1)); // Red
ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_16, 1)); // Green
ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_17, 1)); // Blue
return driver::pwmbacklight::init(LCD_PIN_BACKLIGHT);
}
static DeviceVector createDevices() {
return {
createDisplay(),
createSdCard()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
i2c::Configuration {
.name = "CN1",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_27,
.scl_io_num = GPIO_NUM_22,
.sda_pullup_en = false,
.scl_pullup_en = false,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
// Display
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_13,
.miso_io_num = GPIO_NUM_12,
.sclk_io_num = GPIO_NUM_14,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock()
},
// SDCard
spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_23,
.miso_io_num = GPIO_NUM_19,
.sclk_io_num = GPIO_NUM_18,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 0,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
},
},
.uart {
uart::Configuration {
.name = "P1",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_1,
.txPin = GPIO_NUM_3,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
@@ -1,117 +0,0 @@
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/kernel/SystemEvents.h>
#include <Tactility/lvgl/LvglSync.h>
#include <PwmBacklight.h>
bool initBoot() {
if (!driver::pwmbacklight::init(LCD_PIN_BACKLIGHT)) {
return false;
}
// Set the RGB LED Pins to output and turn them off
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT)); // Red
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_16, GPIO_MODE_OUTPUT)); // Green
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_17, GPIO_MODE_OUTPUT)); // Blue
// 0 on, 1 off
ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_4, 1)); // Red
ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_16, 1)); // Green
ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_17, 1)); // Blue
// This display has a weird glitch with gamma during boot, which results in uneven dark gray colours.
// Setting gamma curve index to 0 doesn't work at boot for an unknown reason, so we set the curve index to 1:
tt::kernel::subscribeSystemEvent(tt::kernel::SystemEvent::BootSplash, [](auto) {
auto display = tt::hal::findFirstDevice<tt::hal::display::DisplayDevice>(tt::hal::Device::Type::Display);
assert(display != nullptr);
tt::lvgl::lock(portMAX_DELAY);
display->setGammaCurve(1U);
tt::lvgl::unlock();
});
return true;
}
static tt::hal::DeviceVector createDevices() {
return {
createDisplay(),
createSdCard()
};
}
extern const tt::hal::Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
tt::hal::i2c::Configuration {
.name = "Internal",
.port = I2C_NUM_0,
.initMode = tt::hal::i2c::InitMode::ByTactility,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_33,
.scl_io_num = GPIO_NUM_32,
.sda_pullup_en = false,
.scl_pullup_en = false,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
// Display
tt::hal::spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_13,
.miso_io_num = GPIO_NUM_NC,
.sclk_io_num = GPIO_NUM_14,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = tt::hal::spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
},
// SD card
tt::hal::spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_23,
.miso_io_num = GPIO_NUM_19,
.sclk_io_num = GPIO_NUM_18,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 0,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = tt::hal::spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr
},
}
};
@@ -1,89 +0,0 @@
#include "devices/St7701Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/kernel/SystemEvents.h>
#include <Tactility/lvgl/LvglSync.h>
#include <PwmBacklight.h>
using namespace tt::hal;
static bool initBoot() {
return driver::pwmbacklight::init(GPIO_NUM_38, 1000);
}
static DeviceVector createDevices() {
return {
std::make_shared<St7701Display>(),
createSdCard()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
//Touch
i2c::Configuration {
.name = "Internal",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_19,
.scl_io_num = GPIO_NUM_45,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
//H1 header,
i2c::Configuration {
.name = "External",
.port = I2C_NUM_1,
.initMode = i2c::InitMode::Disabled,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_NC,
.scl_io_num = GPIO_NUM_NC,
.sda_pullup_en = false,
.scl_pullup_en = false,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
// SD Card & display init
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_47,
.miso_io_num = GPIO_NUM_41,
.sclk_io_num = GPIO_NUM_48,
.quadwp_io_num = -1,
.quadhd_io_num = GPIO_NUM_42,
.data4_io_num = -1,
.data5_io_num = -1,
.data6_io_num = -1,
.data7_io_num = -1,
.data_io_default_level = false,
.max_transfer_sz = 1024 * 128,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock()
}
}
};
@@ -1,114 +0,0 @@
#include "PwmBacklight.h"
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
using namespace tt::hal;
static bool initBoot() {
// Display backlight
return driver::pwmbacklight::init(GPIO_NUM_2, 200);
}
static DeviceVector createDevices() {
return {
createDisplay(),
createSdCard()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
// Touch
i2c::Configuration {
.name = "Internal",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_19,
.scl_io_num = GPIO_NUM_20,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
// P4 header, JST SH 1.0, GND / 3.3V / IO17 / IO18
i2c::Configuration {
.name = "External",
.port = I2C_NUM_1,
.initMode = i2c::InitMode::Disabled,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_17,
.scl_io_num = GPIO_NUM_18,
.sda_pullup_en = false,
.scl_pullup_en = false,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
// SD Card
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_11,
.miso_io_num = GPIO_NUM_13,
.sclk_io_num = GPIO_NUM_12,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 8192,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr
}
},
.uart {
// P4 header, JST SH 1.0, GND / 3.3V / IO17 / IO18
uart::Configuration {
.name = "UART1",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_17,
.txPin = GPIO_NUM_18,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 9600,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
@@ -1,72 +0,0 @@
#include "devices/SdCard.h"
#include "devices/Display.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#include <PwmBacklight.h>
static bool initBoot() {
return driver::pwmbacklight::init(LCD_BACKLIGHT_PIN);
}
static tt::hal::DeviceVector createDevices() {
return {
createDisplay(),
createSdCard()
};
}
extern const tt::hal::Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {},
.spi = {
tt::hal::spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_13,
.miso_io_num = GPIO_NUM_12,
.sclk_io_num = GPIO_NUM_14,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = tt::hal::spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock()
},
tt::hal::spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_23,
.miso_io_num = GPIO_NUM_19,
.sclk_io_num = GPIO_NUM_18,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 0,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = tt::hal::spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock()
},
}
};
@@ -1,96 +0,0 @@
#include "devices/SdCard.h"
#include "devices/Display.h"
#include "devices/Power.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#include <PwmBacklight.h>
using namespace tt::hal;
static bool initBoot() {
return driver::pwmbacklight::init(DISPLAY_BACKLIGHT_PIN);
}
static tt::hal::DeviceVector createDevices() {
return {
createPower(),
createDisplay(),
createSdCard()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
tt::hal::i2c::Configuration {
.name = "External",
.port = I2C_NUM_0,
.initMode = tt::hal::i2c::InitMode::ByTactility,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_32,
.scl_io_num = GPIO_NUM_25,
.sda_pullup_en = false,
.scl_pullup_en = false,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
},
// Display
.spi = {
tt::hal::spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_13,
.miso_io_num = GPIO_NUM_12,
.sclk_io_num = GPIO_NUM_14,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = DISPLAY_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = tt::hal::spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock()
},
// SD Card
tt::hal::spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_23,
.miso_io_num = GPIO_NUM_19,
.sclk_io_num = GPIO_NUM_18,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 8192,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = tt::hal::spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr
},
}
};
@@ -1,148 +0,0 @@
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <PwmBacklight.h>
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
using namespace tt::hal;
static bool initBoot() {
//Set the RGB Led Pins to output and turn them off
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT)); //Red
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_16, GPIO_MODE_OUTPUT)); //Green
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_17, GPIO_MODE_OUTPUT)); //Blue
//0 on, 1 off... yep it's backwards.
ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_4, 1)); //Red
ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_16, 1)); //Green
ESP_ERROR_CHECK(gpio_set_level(GPIO_NUM_17, 1)); //Blue
return driver::pwmbacklight::init(LCD_PIN_BACKLIGHT);
}
static DeviceVector createDevices() {
return {
createDisplay(),
createSdCard()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
//Touch
i2c::Configuration {
.name = "Internal",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_33,
.scl_io_num = GPIO_NUM_32,
.sda_pullup_en = false,
.scl_pullup_en = false,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
//CN1 header, JST SH 1.25, GND / IO22 / IO21 / 3.3V
i2c::Configuration {
.name = "External",
.port = I2C_NUM_1,
.initMode = i2c::InitMode::Disabled,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_21,
.scl_io_num = GPIO_NUM_22,
.sda_pullup_en = false,
.scl_pullup_en = false,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
//Display
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_13,
.miso_io_num = GPIO_NUM_NC,
.sclk_io_num = GPIO_NUM_14,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock()
},
//SD Card
spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_23,
.miso_io_num = GPIO_NUM_19,
.sclk_io_num = GPIO_NUM_18,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 8192,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr
}
},
.uart {
//CN1 header, JST SH 1.25, GND / IO22 / IO21 / 3.3V
uart::Configuration {
.name = "UART1",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_21,
.txPin = GPIO_NUM_22,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 9600,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
@@ -1,114 +0,0 @@
#include "PwmBacklight.h"
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
using namespace tt::hal;
static bool initBoot() {
return driver::pwmbacklight::init(GPIO_NUM_2);
}
static DeviceVector createDevices() {
return {
createDisplay(),
createSdCard()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
//Touch
i2c::Configuration {
.name = "Internal",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_19,
.scl_io_num = GPIO_NUM_20,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
//P4 header, JST SH 1.25, GND / 3.3V / IO17 / IO18 or
//P5 header, JST SH 1.0, GND / 3.3V / IO17 / IO18
i2c::Configuration {
.name = "External",
.port = I2C_NUM_1,
.initMode = i2c::InitMode::Disabled,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_17,
.scl_io_num = GPIO_NUM_18,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
//SD Card
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_11,
.miso_io_num = GPIO_NUM_13,
.sclk_io_num = GPIO_NUM_12,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 8192,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr
}
},
.uart {
//P4 header, JST SH 1.0, GND / 3.3V / IO17 / IO18
uart::Configuration {
.name = "UART1",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_17,
.txPin = GPIO_NUM_18,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 9600,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
@@ -1,145 +0,0 @@
#include "PwmBacklight.h"
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
using namespace tt::hal;
static bool initBoot() {
return driver::pwmbacklight::init(GPIO_NUM_38);
}
static DeviceVector createDevices() {
return {
createDisplay(),
createSdCard()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
// There is only 1 (internal for touch, and also serves as "I2C-OUT" port)
// Note: You could repurpose 1 or more UART interfaces as I2C interfaces
i2c::Configuration {
.name = "Main",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_15,
.scl_io_num = GPIO_NUM_16,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
// Display
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_DISABLED,
.config = {
.mosi_io_num = GPIO_NUM_39,
.miso_io_num = GPIO_NUM_NC,
.sclk_io_num = GPIO_NUM_42,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
},
// SD card
spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_6,
.miso_io_num = GPIO_NUM_4,
.sclk_io_num = GPIO_NUM_5,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 32768,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr // No custom lock needed
}
},
.uart {
// "UART0-IN"
uart::Configuration {
.name = "UART0",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_44,
.txPin = GPIO_NUM_43,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
},
// "UART1-OUT"
uart::Configuration {
.name = "UART1",
.port = UART_NUM_2,
.rxPin = GPIO_NUM_18,
.txPin = GPIO_NUM_17,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
@@ -1,147 +0,0 @@
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#include <PwmBacklight.h>
#define CROWPANEL_SPI_TRANSFER_SIZE_LIMIT (CROWPANEL_LCD_HORIZONTAL_RESOLUTION * CROWPANEL_LCD_SPI_TRANSFER_HEIGHT * (LV_COLOR_DEPTH / 8))
using namespace tt::hal;
static bool initBoot() {
return driver::pwmbacklight::init(GPIO_NUM_38);
}
static DeviceVector createDevices() {
return {
createDisplay(),
createSdCard()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
// There is only 1 (internal for touch, and also serves as "I2C-OUT" port)
// Note: You could repurpose 1 or more UART interfaces as I2C interfaces
i2c::Configuration {
.name = "Main",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_15,
.scl_io_num = GPIO_NUM_16,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
// Display
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_DISABLED,
.config = {
.mosi_io_num = GPIO_NUM_39,
.miso_io_num = GPIO_NUM_NC,
.sclk_io_num = GPIO_NUM_42,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = CROWPANEL_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
},
// SD card
spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_6,
.miso_io_num = GPIO_NUM_4,
.sclk_io_num = GPIO_NUM_5,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 32768,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr // No custom lock needed
}
},
.uart {
// "UART0-IN"
uart::Configuration {
.name = "UART0",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_44,
.txPin = GPIO_NUM_43,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
},
// "UART1-OUT"
uart::Configuration {
.name = "UART1",
.port = UART_NUM_2,
.rxPin = GPIO_NUM_18,
.txPin = GPIO_NUM_17,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
@@ -1,131 +0,0 @@
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
#include <TCA9534.h>
using namespace tt::hal;
static bool initBoot() {
TCA9534_IO_EXP io_expander = {
.I2C_ADDR = 0x18,
.i2c_master_port = I2C_NUM_0,
.interrupt_pin = GPIO_NUM_NC,
.interrupt_task = nullptr
};
// Enable LCD backlight
set_tca9534_io_pin_direction(&io_expander, TCA9534_IO1, TCA9534_OUTPUT);
set_tca9534_io_pin_output_state(&io_expander, TCA9534_IO1, 255);
return true;
}
static DeviceVector createDevices() {
return {
createDisplay(),
createSdCard()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
// There is only 1 (internal for touch, and also serves as "I2C-OUT" port)
// Note: You could repurpose 1 or more UART interfaces as I2C interfaces
i2c::Configuration {
.name = "Main",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_15,
.scl_io_num = GPIO_NUM_16,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
// SD card
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_6,
.miso_io_num = GPIO_NUM_4,
.sclk_io_num = GPIO_NUM_5,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 8192,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr // No custom lock needed
}
},
.uart {
// "UART0-OUT"
uart::Configuration {
.name = "UART0",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_44,
.txPin = GPIO_NUM_43,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
},
// "UART1-OUT"
uart::Configuration {
.name = "UART1",
.port = UART_NUM_2,
.rxPin = GPIO_NUM_19,
.txPin = GPIO_NUM_20,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
@@ -1,123 +0,0 @@
#include "PwmBacklight.h"
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Xpt2046Power.h>
using namespace tt::hal;
static bool initBoot() {
return driver::pwmbacklight::init(GPIO_NUM_27);
}
static DeviceVector createDevices() {
return {
std::make_shared<Xpt2046Power>(),
createDisplay(),
createSdCard(),
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
// There is only 1 (internal for touch, and also serves as "I2C-OUT" port)
// Note: You could repurpose 1 or more UART interfaces as I2C interfaces
i2c::Configuration {
.name = "Main",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_22,
.scl_io_num = GPIO_NUM_21,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
// Display
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_DISABLED,
.config = {
.mosi_io_num = GPIO_NUM_13,
.miso_io_num = GPIO_NUM_12,
.sclk_io_num = GPIO_NUM_14,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
},
// SD card
spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_23,
.miso_io_num = GPIO_NUM_19,
.sclk_io_num = GPIO_NUM_18,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 32768,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr // No custom lock needed
}
},
.uart {
// "UART1"
uart::Configuration {
.name = "UART1",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_16,
.txPin = GPIO_NUM_17,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
@@ -1,125 +0,0 @@
#include "PwmBacklight.h"
#include "Tactility/lvgl/LvglSync.h"
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
#include <Xpt2046Power.h>
constexpr auto CROWPANEL_SPI_TRANSFER_SIZE_LIMIT = (CROWPANEL_LCD_HORIZONTAL_RESOLUTION * CROWPANEL_LCD_SPI_TRANSFER_HEIGHT * (LV_COLOR_DEPTH / 8));
using namespace tt::hal;
static bool initBoot() {
return driver::pwmbacklight::init(GPIO_NUM_27);
}
static DeviceVector createDevices() {
return {
std::make_shared<Xpt2046Power>(),
createDisplay(),
createSdCard(),
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
// There is only 1 (internal for touch, and also serves as "I2C-OUT" port)
// Note: You could repurpose 1 or more UART interfaces as I2C interfaces
i2c::Configuration {
.name = "Main",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_22,
.scl_io_num = GPIO_NUM_21,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
// Display
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_DISABLED,
.config = {
.mosi_io_num = GPIO_NUM_13,
.miso_io_num = GPIO_NUM_33,
.sclk_io_num = GPIO_NUM_14,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = CROWPANEL_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
},
// SD card
spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_23,
.miso_io_num = GPIO_NUM_19,
.sclk_io_num = GPIO_NUM_18,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 32768,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr // No custom lock needed
}
},
.uart {
// "UART1"
uart::Configuration {
.name = "UART1",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_3,
.txPin = GPIO_NUM_1,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
@@ -1,97 +0,0 @@
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
#include <PwmBacklight.h>
using namespace tt::hal;
static bool initBoot() {
// Note: I tried 100 Hz to 100 kHz and couldn't get the flickering to stop
return driver::pwmbacklight::init(GPIO_NUM_2);
}
static DeviceVector createDevices() {
return {
createDisplay(),
createSdCard(),
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
// There is only 1 (internal for touch, and also serves as "I2C-OUT" port)
// Note: You could repurpose 1 or more UART interfaces as I2C interfaces
i2c::Configuration {
.name = "Main",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_19,
.scl_io_num = GPIO_NUM_20,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
// SD card
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_11,
.miso_io_num = GPIO_NUM_13,
.sclk_io_num = GPIO_NUM_12,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 8192,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr
}
},
.uart {
// "UART1"
uart::Configuration {
.name = "UART1",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_44,
.txPin = GPIO_NUM_43,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
@@ -1,111 +0,0 @@
#include "devices/Display.h"
#include "devices/Power.h"
#include "devices/Sdcard.h"
#include "devices/TdeckKeyboard.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
bool initBoot();
using namespace tt::hal;
static std::vector<std::shared_ptr<Device>> createDevices() {
return {
createPower(),
createDisplay(),
std::make_shared<TdeckKeyboard>(),
createSdCard()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
i2c::Configuration {
.name = "Internal",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_18,
.scl_io_num = GPIO_NUM_8,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
i2c::Configuration {
.name = "External",
.port = I2C_NUM_1,
.initMode = i2c::InitMode::Disabled,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_43,
.scl_io_num = GPIO_NUM_44,
.sda_pullup_en = false,
.scl_pullup_en = false,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_41,
.miso_io_num = GPIO_NUM_38,
.sclk_io_num = GPIO_NUM_40,
.quadwp_io_num = GPIO_NUM_NC, // Quad SPI LCD driver is not yet supported
.quadhd_io_num = GPIO_NUM_NC, // Quad SPI LCD driver is not yet supported
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
}
},
.uart {
uart::Configuration {
.name = "Grove",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_44,
.txPin = GPIO_NUM_43,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 38400,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
-63
View File
@@ -1,63 +0,0 @@
#include "PwmBacklight.h"
#include "Tactility/kernel/SystemEvents.h"
#include "Tactility/service/gps/GpsService.h"
#include <Tactility/TactilityCore.h>
#include <Tactility/hal/gps/GpsConfiguration.h>
#define TAG "tdeck"
// Power on
#define TDECK_POWERON_GPIO GPIO_NUM_10
static bool powerOn() {
gpio_config_t device_power_signal_config = {
.pin_bit_mask = BIT64(TDECK_POWERON_GPIO),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE,
};
if (gpio_config(&device_power_signal_config) != ESP_OK) {
return false;
}
if (gpio_set_level(TDECK_POWERON_GPIO, 1) != ESP_OK) {
return false;
}
return true;
}
bool initBoot() {
ESP_LOGI(TAG, LOG_MESSAGE_POWER_ON_START);
if (!powerOn()) {
TT_LOG_E(TAG, LOG_MESSAGE_POWER_ON_FAILED);
return false;
}
/* 32 Khz and higher gives an issue where the screen starts dimming again above 80% brightness
* when moving the brightness slider rapidly from a lower setting to 100%.
* This is not a slider bug (data was debug-traced) */
if (!driver::pwmbacklight::init(GPIO_NUM_42, 30000)) {
TT_LOG_E(TAG, "Backlight init failed");
return false;
}
tt::kernel::subscribeSystemEvent(tt::kernel::SystemEvent::BootSplash, [](tt::kernel::SystemEvent event) {
auto gps_service = tt::service::gps::findGpsService();
if (gps_service != nullptr) {
std::vector<tt::hal::gps::GpsConfiguration> gps_configurations;
gps_service->getGpsConfigurations(gps_configurations);
if (gps_configurations.empty()) {
if (gps_service->addGpsConfiguration(tt::hal::gps::GpsConfiguration {.uartName = "Grove", .baudRate = 38400, .model = tt::hal::gps::GpsModel::UBLOX10})) {
TT_LOG_I(TAG, "Configured internal GPS");
} else {
TT_LOG_E(TAG, "Failed to configure internal GPS");
}
}
}
});
return true;
}
@@ -1,62 +0,0 @@
#include "TdeckKeyboard.h"
#include <Tactility/hal/i2c/I2c.h>
#include <driver/i2c.h>
constexpr auto* TAG = "TdeckKeyboard";
constexpr auto TDECK_KEYBOARD_I2C_BUS_HANDLE = I2C_NUM_0;
constexpr auto TDECK_KEYBOARD_SLAVE_ADDRESS = 0x55;
static bool keyboard_i2c_read(uint8_t* output) {
return tt::hal::i2c::masterRead(TDECK_KEYBOARD_I2C_BUS_HANDLE, TDECK_KEYBOARD_SLAVE_ADDRESS, output, 1, 100 / portTICK_PERIOD_MS);
}
/**
* The callback simulates press and release events, because the T-Deck
* keyboard only publishes press events on I2C.
* LVGL currently works without those extra release events, but they
* are implemented for correctness and future compatibility.
*
* @param indev_drv
* @param data
*/
static void keyboard_read_callback(TT_UNUSED lv_indev_t* indev, lv_indev_data_t* data) {
static uint8_t last_buffer = 0x00;
uint8_t read_buffer = 0x00;
// Defaults
data->key = 0;
data->state = LV_INDEV_STATE_RELEASED;
if (keyboard_i2c_read(&read_buffer)) {
if (read_buffer == 0 && read_buffer != last_buffer) {
TT_LOG_D(TAG, "Released %d", last_buffer);
data->key = last_buffer;
data->state = LV_INDEV_STATE_RELEASED;
} else if (read_buffer != 0) {
TT_LOG_D(TAG, "Pressed %d", read_buffer);
data->key = read_buffer;
data->state = LV_INDEV_STATE_PRESSED;
}
}
last_buffer = read_buffer;
}
bool TdeckKeyboard::startLvgl(lv_display_t* display) {
deviceHandle = lv_indev_create();
lv_indev_set_type(deviceHandle, LV_INDEV_TYPE_KEYPAD);
lv_indev_set_read_cb(deviceHandle, &keyboard_read_callback);
lv_indev_set_display(deviceHandle, display);
lv_indev_set_user_data(deviceHandle, this);
return true;
}
bool TdeckKeyboard::stopLvgl() {
lv_indev_delete(deviceHandle);
deviceHandle = nullptr;
return true;
}
bool TdeckKeyboard::isAttached() const {
return tt::hal::i2c::masterHasDeviceAtAddress(TDECK_KEYBOARD_I2C_BUS_HANDLE, TDECK_KEYBOARD_SLAVE_ADDRESS, 100);
}
@@ -1,92 +0,0 @@
#include "devices/Display.h"
#include "devices/Sdcard.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#define TDECK_SPI_TRANSFER_SIZE_LIMIT (80 * 160 * (LV_COLOR_DEPTH / 8))
bool initBoot();
using namespace tt::hal;
static std::vector<std::shared_ptr<Device>> createDevices() {
return {
createDisplay(),
createSdCard()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.uiScale = UiScale::Smallest,
.createDevices = createDevices,
.i2c = {
i2c::Configuration {
.name = "STEMMA QT",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_44,
.scl_io_num = GPIO_NUM_43,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_3,
.miso_io_num = GPIO_NUM_NC,
.sclk_io_num = GPIO_NUM_5,
.quadwp_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = TDECK_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
},
},
.uart {
uart::Configuration {
.name = "STEMMA QT",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_44,
.txPin = GPIO_NUM_43,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 38400,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
@@ -1,22 +0,0 @@
#include "Sdcard.h"
#include <Tactility/hal/sdcard/SdmmcDevice.h>
#include <Tactility/lvgl/LvglSync.h>
using tt::hal::sdcard::SdmmcDevice;
std::shared_ptr<SdCardDevice> createSdCard() {
auto configuration = std::make_unique<SdmmcDevice::Config>(
GPIO_NUM_12,
GPIO_NUM_16,
GPIO_NUM_14,
GPIO_NUM_17,
GPIO_NUM_21,
GPIO_NUM_18,
SdCardDevice::MountBehaviour::AtBoot
);
return std::make_shared<SdmmcDevice>(
std::move(configuration)
);
}
@@ -1,106 +0,0 @@
#include "devices/Display.h"
#include "devices/SdCard.h"
#include "devices/TpagerEncoder.h"
#include "devices/TpagerKeyboard.h"
#include "devices/TpagerPower.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Bq25896.h>
#include <Drv2605.h>
#define TPAGER_SPI_TRANSFER_SIZE_LIMIT (480 * 222 * (LV_COLOR_DEPTH / 8))
bool tpagerInit();
using namespace tt::hal;
static DeviceVector createDevices() {
auto bq27220 = std::make_shared<Bq27220>(I2C_NUM_0);
auto power = std::make_shared<TpagerPower>(bq27220);
auto tca8418 = std::make_shared<Tca8418>(I2C_NUM_0);
auto keyboard = std::make_shared<TpagerKeyboard>(tca8418);
return std::vector<std::shared_ptr<Device>> {
tca8418,
std::make_shared<Bq25896>(I2C_NUM_0),
bq27220,
std::make_shared<Drv2605>(I2C_NUM_0),
power,
createTpagerSdCard(),
createDisplay(),
keyboard,
std::make_shared<TpagerEncoder>()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = tpagerInit,
.createDevices = createDevices,
.i2c = {
i2c::Configuration {
.name = "Internal",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_3,
.scl_io_num = GPIO_NUM_2,
.sda_pullup_en = false,
.scl_pullup_en = false,
.master = {
.clk_speed = 100'000
},
.clk_flags = 0
}
}
},
.spi {spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_34,
.miso_io_num = GPIO_NUM_33,
.sclk_io_num = GPIO_NUM_35,
.quadwp_io_num = GPIO_NUM_NC, // Quad SPI LCD driver is not yet supported
.quadhd_io_num = GPIO_NUM_NC, // Quad SPI LCD driver is not yet supported
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = TPAGER_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
}},
.uart {uart::Configuration {
.name = "Internal",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_4,
.txPin = GPIO_NUM_12,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 38400,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}}
};
@@ -1,145 +0,0 @@
#include "devices/Display.h"
#include "devices/SdCard.h"
#include "devices/CardputerKeyboard.h"
#include "devices/CardputerPower.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#include <PwmBacklight.h>
#include <Tca8418.h>
using namespace tt::hal;
bool initBoot() {
return driver::pwmbacklight::init(LCD_PIN_BACKLIGHT, 512);
}
static DeviceVector createDevices() {
auto tca8418 = std::make_shared<Tca8418>(I2C_NUM_0);
return {
createSdCard(),
createDisplay(),
tca8418,
std::make_shared<CardputerKeyboard>(tca8418),
std::make_shared<CardputerPower>()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.uiScale = UiScale::Smallest,
.createDevices = createDevices,
.i2c {
i2c::Configuration {
.name = "Main",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_8,
.scl_io_num = GPIO_NUM_9,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
i2c::Configuration {
.name = "Port A", // Grove
.port = I2C_NUM_1,
.initMode = i2c::InitMode::Disabled,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_2,
.scl_io_num = GPIO_NUM_1,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
},
.spi {
// Display
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_35,
.miso_io_num = GPIO_NUM_NC,
.sclk_io_num = GPIO_NUM_36,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock()
},
// SDCard
spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_14,
.miso_io_num = GPIO_NUM_39,
.sclk_io_num = GPIO_NUM_40,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 0,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr
},
},
.uart {
uart::Configuration {
.name = "Port A",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_2,
.txPin = GPIO_NUM_1,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
@@ -1,126 +0,0 @@
#include "devices/Display.h"
#include "devices/SdCard.h"
#include "devices/CardputerEncoder.h"
#include "devices/CardputerKeyboard.h"
#include "devices/CardputerPower.h"
#include <PwmBacklight.h>
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
using namespace tt::hal;
bool initBoot() {
return driver::pwmbacklight::init(LCD_PIN_BACKLIGHT, 512);
}
static DeviceVector createDevices() {
return {
createSdCard(),
createDisplay(),
std::make_shared<CardputerKeyboard>(),
std::make_shared<CardputerEncoder>(),
std::make_shared<CardputerPower>()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.uiScale = UiScale::Smallest,
.createDevices = createDevices,
.i2c {
i2c::Configuration {
.name = "Port A", // Grove
.port = I2C_NUM_0,
.initMode = i2c::InitMode::Disabled,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_2,
.scl_io_num = GPIO_NUM_1,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
},
.spi {
// Display
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_35,
.miso_io_num = GPIO_NUM_NC,
.sclk_io_num = GPIO_NUM_36,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock()
},
// SDCard
spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_14,
.miso_io_num = GPIO_NUM_39,
.sclk_io_num = GPIO_NUM_40,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 0,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr
},
},
.uart {
uart::Configuration {
.name = "Port A",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_2,
.txPin = GPIO_NUM_1,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
-9
View File
@@ -1,9 +0,0 @@
# M5Stack Core2
This board implementation concerns the original Core2 hardware and **not** the v1.1 variant.
Reference implementations:
- [ESP-BSP](https://github.com/espressif/esp-bsp/tree/master/bsp/m5stack_core_2)
Docs:
- [M5Stack.com](https://docs.m5stack.com/en/core/Core2)
@@ -1,111 +0,0 @@
#include "devices/Display.h"
#include "devices/SdCard.h"
#include "devices/Power.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
using namespace tt::hal;
bool initBoot() {
return initAxp();
}
static DeviceVector createDevices() {
return {
getAxp192(),
createSdCard(),
createDisplay()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
i2c::Configuration {
.name = "Internal",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_21,
.scl_io_num = GPIO_NUM_22,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
i2c::Configuration {
.name = "Port A", // Grove
.port = I2C_NUM_1,
.initMode = i2c::InitMode::ByTactility,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_32,
.scl_io_num = GPIO_NUM_33,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_23,
.miso_io_num = GPIO_NUM_38,
.sclk_io_num = GPIO_NUM_18,
.quadwp_io_num = GPIO_NUM_NC, // Quad SPI LCD driver is not yet supported
.quadhd_io_num = GPIO_NUM_NC, // Quad SPI LCD driver is not yet supported
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
}
},
.uart {
uart::Configuration {
.name = "Port A", // Grove
.port = UART_NUM_1,
.rxPin = GPIO_NUM_32,
.txPin = GPIO_NUM_33,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
},
}
};
-7
View File
@@ -1,7 +0,0 @@
# M5Stack CoreS3
Reference implementations:
- [ESP-BSP](https://github.com/espressif/esp-bsp/tree/master/bsp/m5stack_core_s3)
Docs:
- [M5Stack.com](https://docs.m5stack.com/en/core/CoreS3)
@@ -1,191 +0,0 @@
#include "InitBoot.h"
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/hal/uart/Uart.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Axp2101Power.h>
using namespace tt::hal;
static DeviceVector createDevices() {
return {
axp2101,
aw9523,
std::make_shared<Axp2101Power>(axp2101),
createSdCard(),
createDisplay()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
i2c::Configuration {
.name = "Internal",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_12,
.scl_io_num = GPIO_NUM_11,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
i2c::Configuration {
.name = "Port A", // Grove
.port = I2C_NUM_1,
.initMode = i2c::InitMode::Disabled,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_2,
.scl_io_num = GPIO_NUM_1,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
i2c::Configuration {
.name = "Port B", // Grove
.port = I2C_NUM_1,
.initMode = i2c::InitMode::Disabled,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_9,
.scl_io_num = GPIO_NUM_8,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
i2c::Configuration {
.name = "Port C", // Grove
.port = I2C_NUM_1,
.initMode = i2c::InitMode::Disabled,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_18,
.scl_io_num = GPIO_NUM_17,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_37,
.miso_io_num = GPIO_NUM_35,
.sclk_io_num = GPIO_NUM_36,
.data2_io_num = GPIO_NUM_NC,
.data3_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
}
},
.uart {
uart::Configuration {
.name = "Port A",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_2,
.txPin = GPIO_NUM_1,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
},
uart::Configuration {
.name = "Port B",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_9,
.txPin = GPIO_NUM_8,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
},
uart::Configuration {
.name = "Port C",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_18,
.txPin = GPIO_NUM_17,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
-5
View File
@@ -1,5 +0,0 @@
# M5Stack StickC Plus
Docs:
- [M5Stack.com](https://docs.m5stack.com/en/core/m5stickc_plus)
@@ -1,117 +0,0 @@
#include "devices/Display.h"
#include "devices/Power.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#include <ButtonControl.h>
using namespace tt::hal;
bool initBoot() {
// CH552 applies 4 V to GPIO 0, which reduces Wi-Fi sensitivity
// Setting output to high adds a bias of 3.3 V and suppresses over-voltage:
gpio::configure(0, gpio::Mode::Output, false, false);
gpio::setLevel(0, true);
return initAxp();
}
static DeviceVector createDevices() {
return {
getAxp192(),
ButtonControl::createTwoButtonControl(37, 39),
createDisplay()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.uiScale = UiScale::Smallest,
.createDevices = createDevices,
.i2c = {
i2c::Configuration {
.name = "Internal",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_21,
.scl_io_num = GPIO_NUM_22,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
i2c::Configuration {
.name = "Grove",
.port = I2C_NUM_1,
.initMode = i2c::InitMode::ByTactility,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_32,
.scl_io_num = GPIO_NUM_33,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_15,
.miso_io_num = GPIO_NUM_NC,
.sclk_io_num = GPIO_NUM_13,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
}
},
.uart {
uart::Configuration {
.name = "Grove",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_32,
.txPin = GPIO_NUM_33,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
},
}
};
-5
View File
@@ -1,5 +0,0 @@
# M5Stack StickC Plus2
Docs:
- [M5Stack.com](https://docs.m5stack.com/en/core/M5StickC%20PLUS2)
@@ -1,119 +0,0 @@
#include "devices/Display.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#include <ButtonControl.h>
#include <PwmBacklight.h>
using namespace tt::hal;
bool initBoot() {
// CH552 applies 4 V to GPIO 0, which reduces Wi-Fi sensitivity
// Setting output to high adds a bias of 3.3 V and suppresses over-voltage:
gpio::configure(0, gpio::Mode::Output, false, false);
gpio::setLevel(0, true);
// "Hold power" pin: must be set to high to keep the device powered on:
gpio::configure(4, gpio::Mode::Output, false, false);
gpio::setLevel(4, true);
return driver::pwmbacklight::init(GPIO_NUM_27, 512);
}
static DeviceVector createDevices() {
return {
ButtonControl::createTwoButtonControl(37, 39),
createDisplay()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.uiScale = UiScale::Smallest,
.createDevices = createDevices,
.i2c = {
i2c::Configuration {
.name = "Internal",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_21,
.scl_io_num = GPIO_NUM_22,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
i2c::Configuration {
.name = "Grove",
.port = I2C_NUM_1,
.initMode = i2c::InitMode::ByTactility,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_32,
.scl_io_num = GPIO_NUM_33,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_15,
.miso_io_num = GPIO_NUM_NC,
.sclk_io_num = GPIO_NUM_13,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
}
},
.uart {
uart::Configuration {
.name = "Grove",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_32,
.txPin = GPIO_NUM_33,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
},
}
};
-107
View File
@@ -1,107 +0,0 @@
#include "LvglTask.h"
#include <Tactility/Log.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Tactility/Mutex.h>
#include <Tactility/Thread.h>
#include <lvgl.h>
#define TAG "lvgl_task"
// Mutex for LVGL drawing
static tt::Mutex lvgl_mutex(tt::Mutex::Type::Recursive);
static tt::Mutex task_mutex(tt::Mutex::Type::Recursive);
static uint32_t task_max_sleep_ms = 10;
// Mutex for LVGL task state (to modify task_running state)
static bool task_running = false;
lv_disp_t* displayHandle = nullptr;
static void lvgl_task(void* arg);
static bool task_lock(TickType_t timeout) {
return task_mutex.lock(timeout);
}
static void task_unlock() {
task_mutex.unlock();
}
static void task_set_running(bool running) {
assert(task_lock(configTICK_RATE_HZ / 100));
task_running = running;
task_unlock();
}
bool lvgl_task_is_running() {
assert(task_lock(configTICK_RATE_HZ / 100));
bool result = task_running;
task_unlock();
return result;
}
static bool lvgl_lock(uint32_t timeoutMillis) {
return lvgl_mutex.lock(pdMS_TO_TICKS(timeoutMillis));
}
static void lvgl_unlock() {
lvgl_mutex.unlock();
}
void lvgl_task_interrupt() {
tt_check(task_lock(portMAX_DELAY));
task_set_running(false); // interrupt task with boolean as flag
task_unlock();
}
void lvgl_task_start() {
TT_LOG_I(TAG, "lvgl task starting");
tt::lvgl::syncSet(&lvgl_lock, &lvgl_unlock);
// Create the main app loop, like ESP-IDF
BaseType_t task_result = xTaskCreate(
lvgl_task,
"lvgl",
8192,
nullptr,
static_cast<UBaseType_t>(tt::Thread::Priority::High), // Should be higher than main app task
nullptr
);
assert(task_result == pdTRUE);
}
static void lvgl_task(TT_UNUSED void* arg) {
TT_LOG_I(TAG, "lvgl task started");
/** Ideally. the display handle would be created during Simulator.start(),
* but somehow that doesn't work. Waiting here from a ThreadFlag when that happens
* also doesn't work. It seems that it must be called from this task. */
displayHandle = lv_sdl_window_create(320, 240);
lv_sdl_window_set_title(displayHandle, "Tactility");
uint32_t task_delay_ms = task_max_sleep_ms;
task_set_running(true);
while (lvgl_task_is_running()) {
if (lvgl_lock(10)) {
task_delay_ms = lv_timer_handler();
lvgl_unlock();
}
if ((task_delay_ms > task_max_sleep_ms) || (1 == task_delay_ms)) {
task_delay_ms = task_max_sleep_ms;
} else if (task_delay_ms < 1) {
task_delay_ms = 1;
}
vTaskDelay(pdMS_TO_TICKS(task_delay_ms));
}
lv_disp_remove(displayHandle);
displayHandle = nullptr;
vTaskDelete(nullptr);
}
-5
View File
@@ -1,5 +0,0 @@
#pragma once
void lvgl_task_start();
bool lvgl_task_is_running();
void lvgl_task_interrupt();
-62
View File
@@ -1,62 +0,0 @@
#include "Main.h"
#include <Tactility/TactilityCore.h>
#include <Tactility/Thread.h>
#include "FreeRTOS.h"
#include "task.h"
#define TAG "freertos"
namespace simulator {
MainFunction mainFunction = nullptr;
void setMain(MainFunction newMainFunction) {
mainFunction = newMainFunction;
}
static void freertosMainTask(TT_UNUSED void* parameter) {
TT_LOG_I(TAG, "starting app_main()");
assert(simulator::mainFunction);
mainFunction();
TT_LOG_I(TAG, "returned from app_main()");
vTaskDelete(nullptr);
}
void freertosMain() {
BaseType_t task_result = xTaskCreate(
freertosMainTask,
"main",
8192,
nullptr,
static_cast<UBaseType_t>(tt::Thread::Priority::Normal),
nullptr
);
assert(task_result == pdTRUE);
// Blocks forever
vTaskStartScheduler();
}
} // namespace
/**
* Assert implementation as defined in the FreeRTOSConfig.h
* It allows you to set breakpoints and debug asserts.
*/
void vAssertCalled(unsigned long line, const char* const file) {
static portBASE_TYPE xPrinted = pdFALSE;
volatile uint32_t set_to_nonzero_in_debugger_to_continue = 0;
TT_LOG_E(TAG, "assert triggered at %s:%d", file, line);
taskENTER_CRITICAL();
{
// Step out by attaching a debugger and setting set_to_nonzero_in_debugger_to_continue
while (set_to_nonzero_in_debugger_to_continue == 0) {
// NO-OP
}
}
taskEXIT_CRITICAL();
}
-89
View File
@@ -1,89 +0,0 @@
#include "LvglTask.h"
#include "hal/SdlDisplay.h"
#include "hal/SdlKeyboard.h"
#include "hal/SimulatorPower.h"
#include "hal/SimulatorSdCard.h"
#include <src/lv_init.h> // LVGL
#include <Tactility/hal/Configuration.h>
#define TAG "hardware"
using namespace tt::hal;
static bool initBoot() {
lv_init();
lvgl_task_start();
return true;
}
TT_UNUSED static void deinitPower() {
lvgl_task_interrupt();
while (lvgl_task_is_running()) {
tt::kernel::delayMillis(10);
}
#if LV_ENABLE_GC || !LV_MEM_CUSTOM
lv_deinit();
#endif
}
static std::vector<std::shared_ptr<Device>> createDevices() {
return {
std::make_shared<SdlDisplay>(),
std::make_shared<SdlKeyboard>(),
std::make_shared<SimulatorPower>(),
std::make_shared<SimulatorSdCard>()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
i2c::Configuration {
.name = "Internal",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = 1,
.scl_io_num = 2,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
i2c::Configuration {
.name = "External",
.port = I2C_NUM_1,
.initMode = i2c::InitMode::ByTactility,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = 3,
.scl_io_num = 2,
.sda_pullup_en = false,
.scl_pullup_en = false,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.uart = {
uart::Configuration {
.name = "/dev/ttyUSB0",
.baudRate = 115200
},
uart::Configuration {
.name = "/dev/ttyACM0",
.baudRate = 115200
}
}
};
-28
View File
@@ -1,28 +0,0 @@
#pragma once
#include "SdlTouch.h"
#include <Tactility/hal/display/DisplayDevice.h>
/** Hack: variable comes from LvglTask.cpp */
extern lv_disp_t* displayHandle;
class SdlDisplay final : public tt::hal::display::DisplayDevice {
public:
std::string getName() const override { return "SDL Display"; }
std::string getDescription() const override { return ""; }
bool start() override { return true; }
bool stop() override { tt_crash("Not supported"); }
bool supportsLvgl() const override { return true; }
bool startLvgl() override { return displayHandle != nullptr; }
bool stopLvgl() override { tt_crash("Not supported"); }
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable getTouchDevice() override { return std::make_shared<SdlTouch>(); }
bool supportsDisplayDriver() const override { return false; }
std::shared_ptr<tt::hal::display::DisplayDriver> _Nullable getDisplayDriver() override { return nullptr; }
};
-85
View File
@@ -1,85 +0,0 @@
#include "UnPhoneFeatures.h"
#include "devices/Hx8357Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Xpt2046Power.h>
#define UNPHONE_SPI_TRANSFER_SIZE_LIMIT (UNPHONE_LCD_HORIZONTAL_RESOLUTION * UNPHONE_LCD_SPI_TRANSFER_HEIGHT * LV_COLOR_DEPTH / 8)
bool initBoot();
static tt::hal::DeviceVector createDevices() {
return {
std::make_shared<Xpt2046Power>(),
createDisplay(),
createSdCard()
};
}
extern const tt::hal::Configuration hardwareConfiguration = {
.initBoot = initBoot,
.createDevices = createDevices,
.i2c = {
tt::hal::i2c::Configuration {
.name = "Internal",
.port = I2C_NUM_0,
.initMode = tt::hal::i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_3,
.scl_io_num = GPIO_NUM_4,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
},
tt::hal::i2c::Configuration {
.name = "Unused",
.port = I2C_NUM_1,
.initMode = tt::hal::i2c::InitMode::Disabled,
.isMutable = true,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_NC,
.scl_io_num = GPIO_NUM_NC,
.sda_pullup_en = false,
.scl_pullup_en = false,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
tt::hal::spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_40,
.miso_io_num = GPIO_NUM_41,
.sclk_io_num = GPIO_NUM_39,
.quadwp_io_num = -1, // Quad SPI LCD driver is not yet supported
.quadhd_io_num = -1, // Quad SPI LCD driver is not yet supported
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = UNPHONE_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = tt::hal::spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
}
}
};
@@ -1,95 +0,0 @@
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#include <PwmBacklight.h>
using namespace tt::hal;
static DeviceVector createDevices() {
return {
createDisplay(),
createSdCard()
};
}
static bool initBoot() {
return driver::pwmbacklight::init(GPIO_NUM_20, 256);
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.uiScale = UiScale::Smallest,
.createDevices = createDevices,
.i2c = {
//IMU
i2c::Configuration {
.name = "Main",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_47,
.scl_io_num = GPIO_NUM_48,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
// Display
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_DISABLED,
.config = {
.mosi_io_num = GPIO_NUM_41,
.miso_io_num = GPIO_NUM_NC,
.sclk_io_num = GPIO_NUM_40,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = LCD_SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
},
// SD card
spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_18,
.miso_io_num = GPIO_NUM_16,
.sclk_io_num = GPIO_NUM_21,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 32768,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr // No custom lock needed
}
}
};
@@ -1,98 +0,0 @@
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#include <PwmBacklight.h>
using namespace tt::hal;
constexpr auto* TAG = "Waveshare";
static DeviceVector createDevices() {
return {
createDisplay(),
createSdCard()
};
}
static bool initBoot() {
return driver::pwmbacklight::init(GPIO_NUM_2, 256);
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.uiScale = UiScale::Smallest,
.createDevices = createDevices,
.i2c = {
i2c::Configuration {
.name = "Main",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_6,
.scl_io_num = GPIO_NUM_7,
.sda_pullup_en = false,
.scl_pullup_en = false,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
// Display
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_DISABLED,
.config = {
.mosi_io_num = GPIO_NUM_11,
.miso_io_num = GPIO_NUM_12,
.sclk_io_num = GPIO_NUM_10,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = ((240 * (240 / 10)) * LV_COLOR_DEPTH / 8),
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
},
// SD card available via external sd card module and uses VSYS (5V) / GND / IO15 / IO16 / IO17 / IO18 pins.
// Common micro sd card module you'd find on aliexpress with voltage regulator onboard. Others may work.
// JST SH 1.0 Header, GND / VSYS (5V) / RESET / BOOT / GND / 3.3V / IO15 / IO16 / IO17 / IO18 / IO21 / IO33
spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_16,
.miso_io_num = GPIO_NUM_15,
.sclk_io_num = GPIO_NUM_17,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 32768,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr // No custom lock needed
}
}
};
@@ -1,92 +0,0 @@
#include "devices/Display.h"
#include "devices/Sdcard.h"
#include <Tactility/hal/Configuration.h>
#include <Tactility/lvgl/LvglSync.h>
#define SPI_TRANSFER_SIZE_LIMIT (172 * 320 * (LV_COLOR_DEPTH / 8))
bool initBoot();
using namespace tt::hal;
static std::vector<std::shared_ptr<Device>> createDevices() {
return {
createDisplay(),
createSdCard()
};
}
extern const Configuration hardwareConfiguration = {
.initBoot = initBoot,
.uiScale = UiScale::Smallest,
.createDevices = createDevices,
.i2c = {
i2c::Configuration {
.name = "Internal",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_42,
.scl_io_num = GPIO_NUM_41,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_39,
.miso_io_num = GPIO_NUM_NC,
.sclk_io_num = GPIO_NUM_38,
.quadwp_io_num = GPIO_NUM_NC, // Quad SPI LCD driver is not yet supported
.quadhd_io_num = GPIO_NUM_NC, // Quad SPI LCD driver is not yet supported
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
},
spi::Configuration {
.device = SPI3_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_15,
.miso_io_num = GPIO_NUM_17,
.sclk_io_num = GPIO_NUM_16,
.data2_io_num = GPIO_NUM_NC,
.data3_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = SPI_TRANSFER_SIZE_LIMIT,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr
}
},
.uart {}
};
@@ -1,90 +0,0 @@
#include "devices/Display.h"
#include "devices/SdCard.h"
#include <Tactility/hal/Configuration.h>
using namespace tt::hal;
static DeviceVector createDevices() {
return {
createDisplay(),
createSdCard()
};
}
extern const Configuration hardwareConfiguration = {
.createDevices = createDevices,
.i2c = {
// There is only 1 (internal for touch, and also serves as "I2C-OUT" port)
// Note: You could repurpose 1 or more UART interfaces as I2C interfaces
i2c::Configuration {
.name = "Main",
.port = I2C_NUM_0,
.initMode = i2c::InitMode::ByTactility,
.isMutable = false,
.config = (i2c_config_t) {
.mode = I2C_MODE_MASTER,
.sda_io_num = GPIO_NUM_8,
.scl_io_num = GPIO_NUM_9,
.sda_pullup_en = true,
.scl_pullup_en = true,
.master = {
.clk_speed = 400000
},
.clk_flags = 0
}
}
},
.spi {
// SD card
spi::Configuration {
.device = SPI2_HOST,
.dma = SPI_DMA_CH_AUTO,
.config = {
.mosi_io_num = GPIO_NUM_11,
.miso_io_num = GPIO_NUM_13,
.sclk_io_num = GPIO_NUM_12,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.data_io_default_level = false,
.max_transfer_sz = 8192,
.flags = 0,
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
.intr_flags = 0
},
.initMode = spi::InitMode::ByTactility,
.isMutable = false,
.lock = nullptr
}
},
.uart {
// "UART1"
uart::Configuration {
.name = "UART1",
.port = UART_NUM_1,
.rxPin = GPIO_NUM_44,
.txPin = GPIO_NUM_43,
.rtsPin = GPIO_NUM_NC,
.ctsPin = GPIO_NUM_NC,
.rxBufferSize = 1024,
.txBufferSize = 1024,
.config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
}
}
}
}
};
+230
View File
@@ -0,0 +1,230 @@
import subprocess
from datetime import datetime, UTC
import os
import sys
import configparser
from dataclasses import dataclass, asdict
import json
import shutil
from configparser import RawConfigParser
VERBOSE = False
DEVICES_FOLDER = "Devices"
@dataclass
class IndexEntry:
id: str
name: str
vendor: str
incubating: bool
warningMessage: str
infoMessage: str
@dataclass
class Manifest:
name: str
version: str
new_install_prompt_erase: str
funding_url: str
builds: list
@dataclass
class ManifestBuild:
chipFamily: str
parts: list
@dataclass
class ManifestBuildPart:
path: str
offset: int
@dataclass
class DeviceIndex:
version: str
created: str
gitCommit: str
devices: list
shell_color_red = "\033[91m"
shell_color_orange = "\033[93m"
shell_color_reset = "\033[m"
def print_warning(message):
print(f"{shell_color_orange}WARNING: {message}{shell_color_reset}")
def print_error(message):
print(f"{shell_color_red}ERROR: {message}{shell_color_reset}")
def print_help():
print("Usage: python generate-firmware-files.py [inPath] [outPath] [version]")
print(" inPath path with the extracted release files")
print(" outPath path where the CDN files will become available")
print(" version technical version name (e.g. 1.2.0)")
print("Options:")
print(" --verbose Show extra console output")
def exit_with_error(message):
print_error(message)
sys.exit(1)
def read_properties_file(path):
config = configparser.RawConfigParser()
# Don't convert keys to lowercase
config.optionxform = str
config.read(path)
return config
def get_property_or_none(properties: RawConfigParser, group: str, key: str):
if group not in properties.sections():
return None
if key not in properties[group].keys():
return None
return properties[group][key]
def get_boolean_property_or_false(properties: RawConfigParser, group: str, key: str):
if group not in properties.sections():
return False
if key not in properties[group].keys():
return False
return properties[group][key] == "true"
def get_property_or_exit(properties: RawConfigParser, group: str, key: str):
if group not in properties.sections():
exit_with_error(f"Device properties does not contain group: {group}")
if key not in properties[group].keys():
exit_with_error(f"Device properties does not contain key: {key}")
return properties[group][key]
def read_device_properties(device_id):
mapping_file_path = os.path.join(DEVICES_FOLDER, device_id, "device.properties")
if not os.path.isfile(mapping_file_path):
exit_with_error(f"Mapping file not found: {mapping_file_path}")
return read_properties_file(mapping_file_path)
def to_manifest_chip_name(name):
if name == "esp32":
return "ESP32"
elif name == "esp32s2":
return "ESP32-S2"
elif name == "esp32s3":
return "ESP32-S3"
elif name == "esp32c2":
return "ESP32-C2"
elif name == "esp32c3":
return "ESP32-C3"
elif name == "esp32c5":
return "ESP32-C5"
elif name == "esp32c6":
return "ESP32-C6"
elif name == "esp32c61":
return "ESP32-C61"
elif name == "esp32h2":
return "ESP32-H2"
elif name == "esp32h4":
return "ESP32-H4"
elif name == "esp32p4":
return "ESP32-P4"
else:
exit_with_error(f"to_manifest_chip_name() doesn't support {name} yet")
return ""
def process_device(in_path: str, out_path: str, device_directory: str, device_id: str, device_properties: RawConfigParser, version: str):
in_device_path = os.path.join(in_path, device_directory)
in_device_binaries_path = os.path.join(in_device_path, "Binaries")
if not os.path.isdir(in_device_binaries_path):
exit_with_error(f"Could not find directory {in_device_binaries_path}")
flasher_args_path = os.path.join(in_device_binaries_path, "flasher_args.json")
if not os.path.isfile(flasher_args_path):
exit_with_error(f"Could not find flasher arguments path {flasher_args_path}")
with open(flasher_args_path) as json_data:
flasher_args = json.load(json_data)
flash_files = flasher_args["flash_files"]
device_vendor = get_property_or_exit(device_properties, "general", "vendor")
device_name = get_property_or_exit(device_properties, "general", "name")
manifest = Manifest(
name=f"Tactility for {device_vendor} {device_name}",
version=version,
new_install_prompt_erase="true",
funding_url="https://github.com/sponsors/ByteWelder",
builds=[
ManifestBuild(
chipFamily=to_manifest_chip_name(flasher_args["extra_esptool_args"]["chip"]),
parts=[]
)
]
)
for offset in flash_files:
flash_file_entry = flash_files[offset]
flash_file_entry_name = os.path.basename(flash_file_entry)
in_flash_file_path = os.path.join(in_device_binaries_path, flash_file_entry)
out_flash_file_name = f"{device_id}-{flash_file_entry_name}"
out_flash_file_path = os.path.join(out_path, out_flash_file_name)
if VERBOSE:
print(f"Copying {in_flash_file_path} -> {out_flash_file_path}")
shutil.copy(in_flash_file_path, out_flash_file_path)
manifest.builds[0].parts.append(
ManifestBuildPart(
path=out_flash_file_name,
offset=int(offset, 16)
)
)
json_manifest_path = os.path.join(out_path, f"{device_id}.json")
with open(json_manifest_path, 'w') as json_manifest_file:
json.dump(asdict(manifest), json_manifest_file, indent=2)
def get_git_commit_hash():
return subprocess.check_output(['git', 'rev-parse', 'HEAD']).decode('ascii').strip()
def main(in_path: str, out_path: str, version: str):
if not os.path.exists(in_path):
exit_with_error(f"Input path not found: {in_path}")
if os.path.exists(out_path):
shutil.rmtree(out_path)
os.mkdir(out_path)
artifact_directories = os.listdir(in_path)
device_index = DeviceIndex(
version=version,
created=datetime.now(UTC).strftime('%Y-%m-%dT%H:%M:%S'),
gitCommit=get_git_commit_hash(),
devices=[]
)
for artifact_directory in artifact_directories:
if artifact_directory.endswith("-symbols") or artifact_directory.endswith(".bin") or artifact_directory.startswith("TactilitySDK-"):
continue
device_id = artifact_directory.removeprefix("Tactility-")
if not device_id:
exit_with_error(f"Cannot derive device id from directory: {artifact_directory}")
device_properties = read_device_properties(device_id)
process_device(in_path, out_path, artifact_directory, device_id, device_properties, version)
warning_message = get_property_or_none(device_properties, "cdn", "warningMessage")
info_message = get_property_or_none(device_properties, "cdn", "infoMessage")
incubating = get_boolean_property_or_false(device_properties, "general", "incubating")
device_names = get_property_or_exit(device_properties, "general", "name").split(',')
for device_name in device_names:
device_index.devices.append(asdict(IndexEntry(
id=device_id,
name=device_name.strip(),
vendor=get_property_or_exit(device_properties, "general", "vendor"),
incubating=incubating,
warningMessage=warning_message,
infoMessage=info_message
)))
index_file_path = os.path.join(out_path, "index.json")
with open(index_file_path, "w") as index_file:
json.dump(asdict(device_index), index_file, indent=2)
if __name__ == "__main__":
print("Tactility CDN File Generator")
if "--help" in sys.argv:
print_help()
sys.exit()
# Argument validation
if len(sys.argv) < 4:
print_help()
sys.exit(1)
if "--verbose" in sys.argv:
VERBOSE = True
sys.argv.remove("--verbose")
main(in_path=sys.argv[1], out_path=sys.argv[2], version=sys.argv[3])
+86
View File
@@ -0,0 +1,86 @@
import subprocess
from datetime import datetime, UTC
import os
import sys
from dataclasses import dataclass, asdict
import json
import shutil
VERBOSE = False
@dataclass
class SdkIndex:
version: str
created: str
gitCommit: str
platforms: dict
shell_color_red = "\033[91m"
shell_color_orange = "\033[93m"
shell_color_reset = "\033[m"
def print_warning(message):
print(f"{shell_color_orange}WARNING: {message}{shell_color_reset}")
def print_error(message):
print(f"{shell_color_red}ERROR: {message}{shell_color_reset}")
def exit_with_error(message):
print_error(message)
sys.exit(1)
def print_help():
print("Usage: python generate-sdk-files.py [inPath] [outPath] [version]")
print(" inPath path with the extracted release files")
print(" outPath path where the CDN files will become available")
print(" version technical version name (e.g. 1.2.0)")
print("Options:")
print(" --verbose Show extra console output")
def get_git_commit_hash():
return subprocess.check_output(['git', 'rev-parse', 'HEAD']).decode('ascii').strip()
def main(in_path: str, out_path: str, version: str):
if not os.path.exists(in_path):
exit_with_error(f"Input path not found: {in_path}")
if os.path.exists(out_path):
shutil.rmtree(out_path)
os.mkdir(out_path)
artifact_directories = os.listdir(in_path)
sdk_index = SdkIndex(
version=version,
created=datetime.now(UTC).strftime('%Y-%m-%dT%H:%M:%S'),
gitCommit=get_git_commit_hash(),
platforms={}
)
for artifact_directory in artifact_directories:
if VERBOSE:
print(f"Processing {in_path}/{artifact_directory}")
if not artifact_directory.startswith("TactilitySDK-"):
continue
sdk_platform = artifact_directory.removeprefix("TactilitySDK-")
if not sdk_platform:
exit_with_error(f"Cannot derive platform from directory name: {artifact_directory}")
sdk_index.platforms[sdk_platform] = f"{artifact_directory}.zip"
if VERBOSE:
print(f"Archiving {in_path}/{artifact_directory} to {out_path}/{artifact_directory}.zip")
shutil.make_archive(os.path.join(out_path, artifact_directory), 'zip', os.path.join(in_path, artifact_directory))
index_file_path = os.path.join(out_path, "index.json")
if VERBOSE:
print(f"Generating {index_file_path}")
with open(index_file_path, "w") as index_file:
json.dump(asdict(sdk_index), index_file, indent=2)
if __name__ == "__main__":
print("Tactility CDN SDK File Generator")
if "--help" in sys.argv:
print_help()
sys.exit()
# Argument validation
if len(sys.argv) < 4:
print_help()
sys.exit(1)
if "--verbose" in sys.argv:
VERBOSE = True
sys.argv.remove("--verbose")
main(in_path=sys.argv[1], out_path=sys.argv[2], version=sys.argv[3])
+65
View File
@@ -0,0 +1,65 @@
import os
import sys
import boto3
SHELL_COLOR_RED = "\033[91m"
SHELL_COLOR_ORANGE = "\033[93m"
SHELL_COLOR_RESET = "\033[m"
def print_warning(message):
print(f"{SHELL_COLOR_ORANGE}WARNING: {message}{SHELL_COLOR_RESET}")
def print_error(message):
print(f"{SHELL_COLOR_RED}ERROR: {message}{SHELL_COLOR_RESET}")
def print_help():
print("Usage: python upload-firmware-files.py [path] [version] [cloudflareAccountId] [cloudflareTokenName] [cloudflareTokenValue]")
print("")
print("Options:")
print(" --index-only Upload only index.json")
def exit_with_error(message):
print_error(message)
sys.exit(1)
def main(path: str, version: str, cloudflare_account_id, cloudflare_token_name: str, cloudflare_token_value: str, index_only: bool):
if not os.path.exists(path):
exit_with_error(f"Path not found: {path}")
s3 = boto3.client(
service_name="s3",
endpoint_url=f"https://{cloudflare_account_id}.r2.cloudflarestorage.com",
aws_access_key_id=cloudflare_token_name,
aws_secret_access_key=cloudflare_token_value,
region_name="auto"
)
files_to_upload = os.listdir(path)
counter = 1
total = len(files_to_upload)
for file_name in files_to_upload:
if not index_only or file_name == 'index.json':
object_path = f"firmware/{version}/{file_name}"
print(f"[{counter}/{total}] Uploading {file_name} to {object_path}")
file_path = os.path.join(path, file_name)
try:
s3.upload_file(file_path, "tactility", object_path)
except Exception as e:
exit_with_error(f"Failed to upload {file_name}: {str(e)}")
counter += 1
if __name__ == "__main__":
print("Tactility CDN Firmware Uploader")
if "--help" in sys.argv:
print_help()
sys.exit()
# Argument validation
if len(sys.argv) < 6:
print_help()
sys.exit(1)
main(
path=sys.argv[1],
version=sys.argv[2],
cloudflare_account_id=sys.argv[3],
cloudflare_token_name=sys.argv[4],
cloudflare_token_value=sys.argv[5],
index_only="--index-only" in sys.argv
)
+65
View File
@@ -0,0 +1,65 @@
import os
import sys
import boto3
SHELL_COLOR_RED = "\033[91m"
SHELL_COLOR_ORANGE = "\033[93m"
SHELL_COLOR_RESET = "\033[m"
def print_warning(message):
print(f"{SHELL_COLOR_ORANGE}WARNING: {message}{SHELL_COLOR_RESET}")
def print_error(message):
print(f"{SHELL_COLOR_RED}ERROR: {message}{SHELL_COLOR_RESET}")
def print_help():
print("Usage: python upload-sdk-files.py [path] [version] [cloudflareAccountId] [cloudflareTokenName] [cloudflareTokenValue]")
print("")
print("Options:")
print(" --index-only Upload only index.json")
def exit_with_error(message):
print_error(message)
sys.exit(1)
def main(path: str, version: str, cloudflare_account_id, cloudflare_token_name: str, cloudflare_token_value: str, index_only: bool):
if not os.path.exists(path):
exit_with_error(f"Path not found: {path}")
s3 = boto3.client(
service_name="s3",
endpoint_url=f"https://{cloudflare_account_id}.r2.cloudflarestorage.com",
aws_access_key_id=cloudflare_token_name,
aws_secret_access_key=cloudflare_token_value,
region_name="auto"
)
files_to_upload = os.listdir(path)
counter = 1
total = len(files_to_upload)
for file_name in files_to_upload:
if not index_only or file_name == 'index.json':
object_path = f"sdk/{version}/{file_name}"
print(f"[{counter}/{total}] Uploading {file_name} to {object_path}")
file_path = os.path.join(path, file_name)
try:
s3.upload_file(file_path, "tactility", object_path)
except Exception as e:
exit_with_error(f"Failed to upload {file_name}: {str(e)}")
counter += 1
if __name__ == "__main__":
print("Tactility CDN SDK Uploader")
if "--help" in sys.argv:
print_help()
sys.exit()
# Argument validation
if len(sys.argv) < 6:
print_help()
sys.exit(1)
main(
path=sys.argv[1],
version=sys.argv[2],
cloudflare_account_id=sys.argv[3],
cloudflare_token_name=sys.argv[4],
cloudflare_token_value=sys.argv[5],
index_only="--index-only" in sys.argv
)
-9
View File
@@ -1,9 +0,0 @@
idf_component_register(
INCLUDE_DIRS "Libraries/TactilityC/Include" "Libraries/lvgl/Include"
)
add_prebuilt_library(TactilityC Libraries/TactilityC/Binary/libTactilityC.a)
add_prebuilt_library(lvgl Libraries/lvgl/Binary/liblvgl.a)
target_link_libraries(${COMPONENT_LIB} INTERFACE TactilityC)
target_link_libraries(${COMPONENT_LIB} INTERFACE lvgl)
-17
View File
@@ -1,17 +0,0 @@
function(tactility_project)
endfunction()
function(_tactility_project)
endfunction()
macro(tactility_project project_name)
set(TACTILITY_SKIP_SPIFFS 1)
include("${TACTILITY_SDK_PATH}/Libraries/elf_loader/elf_loader.cmake")
project_elf($project_name)
file(READ ${TACTILITY_SDK_PATH}/idf-version.txt TACTILITY_SDK_IDF_VERSION)
if (NOT "$ENV{ESP_IDF_VERSION}" STREQUAL "${TACTILITY_SDK_IDF_VERSION}")
message(FATAL_ERROR "ESP-IDF version of Tactility SDK (${TACTILITY_SDK_IDF_VERSION}) does not match current ESP-IDF version ($ENV{ESP_IDF_VERSION})")
endif()
endmacro()
@@ -0,0 +1,4 @@
.venv/
.idea/
__pycache__/
build/
@@ -0,0 +1,29 @@
import sys
from source.printing import print_error
from source.main import main
def print_help():
print("Usage: python compile.py [in_file] [out_path] [arguments]\n")
print(f"\t[in_path] the path where the root devicetree.yaml file is")
print(f"\t[out_path] output folder for C file output")
print("")
print("Optional arguments:\n")
print("\t--help prints this help text")
print("\t--verbose output debug info")
if __name__ == "__main__":
if "--help" in sys.argv:
print_help()
sys.exit()
args = [a for a in sys.argv[1:] if not a.startswith("--")]
if len(args) < 2:
print_error("Missing argument")
print_help()
sys.exit()
is_verbose = "--verbose" in sys.argv
devicetree_yaml_config = args[0]
output_path = args[1]
result = main(devicetree_yaml_config, output_path, is_verbose)
sys.exit(result)
@@ -0,0 +1,35 @@
import sys
import os
from source.printing import print_error
from source.config import parse_config
def print_help():
print("Usage: python dependencies.py [path]\n")
print("\t[in_file] the path where the root devicetree.yaml file is")
if __name__ == "__main__":
if "--help" in sys.argv:
print_help()
sys.exit()
args = [a for a in sys.argv[1:] if not a.startswith("--")]
if len(args) < 1:
print_error("Missing argument")
print_help()
sys.exit(1)
yaml_directory = args[0]
if not os.path.exists(yaml_directory):
print_error(f"Path not found: {yaml_directory}")
sys.exit(1)
config = parse_config(yaml_directory, os.getcwd())
# Device module is added first because it's started first:
# It creates the root device, so it must exist before its children.
device_dependency = os.path.basename(os.path.normpath(yaml_directory))
print(device_dependency)
for dependency in config.dependencies:
dependency_name = os.path.basename(os.path.normpath(dependency))
print(dependency_name)
@@ -0,0 +1,20 @@
import os
from .exception import DevicetreeException
def find_bindings(directory_path: str) -> list[str]:
yaml_files = []
for root, dirs, files in os.walk(directory_path):
for file in files:
if file.endswith(".yaml"):
full_path = os.path.join(root, file)
yaml_files.append(os.path.abspath(full_path))
return yaml_files
def find_all_bindings(directory_paths: list[str]) -> list[str]:
yaml_files = []
for directory_path in directory_paths:
new_paths = find_bindings(directory_path)
if len(new_paths) == 0:
raise DevicetreeException(f"No bindings found in {directory_path}")
yaml_files += new_paths
return yaml_files
@@ -0,0 +1,58 @@
import yaml
import os
from .models import Binding, BindingProperty
def parse_binding(file_path: str, binding_dirs: list[str]) -> Binding:
with open(file_path, 'r') as f:
data = yaml.safe_load(f)
description = data.get('description', '')
bus = data.get('bus', None)
properties_dict = {}
# Handle inclusions
includes = data.get('include', [])
all_includes = list(includes) # Copy for iteration
for include_file in includes:
include_path = None
for binding_dir in binding_dirs:
potential_path = os.path.join(binding_dir, include_file)
if os.path.exists(potential_path):
include_path = potential_path
break
if not include_path:
print(f"Warning: Could not find include file {include_file}")
continue
parent_binding = parse_binding(include_path, binding_dirs)
if not description and parent_binding.description:
description = parent_binding.description
if not bus and parent_binding.bus:
bus = parent_binding.bus
for prop in parent_binding.properties:
properties_dict[prop.name] = prop
for include in parent_binding.includes:
all_includes.append(include)
# Parse local properties
compatible = data.get('compatible', None)
properties_raw = data.get('properties', {})
for name, details in properties_raw.items():
prop = BindingProperty(
name=name,
type=details.get('type', 'unknown'),
required=details.get('required', False),
description=details.get('description', '').strip(),
default=details.get('default', None),
)
properties_dict[name] = prop
filename = os.path.basename(file_path)
return Binding(
filename=filename,
compatible=compatible,
description=description.strip(),
properties=list(properties_dict.values()),
includes=all_includes,
bus=bus
)
@@ -0,0 +1,50 @@
from dataclasses import dataclass, field
import yaml
import os
@dataclass
class DeviceTreeConfig:
dependencies: list[str] = field(default_factory=list)
bindings: list[str] = field(default_factory=list)
dts: str = ""
def parse_config(file_path: str, project_root: str) -> DeviceTreeConfig:
"""
Parses devicetree.yaml and recursively finds dependencies.
Returns a list of DeviceTreeConfig objects in post-order (dependencies first).
"""
config = DeviceTreeConfig([], [], "")
visited = set()
def _parse_recursive(current_path: str, is_root: bool):
abs_path = os.path.abspath(current_path)
if abs_path in visited:
return
visited.add(abs_path)
# Try to see if it's a directory and contains devicetree.yaml
if os.path.isdir(abs_path):
abs_path = os.path.join(abs_path, "devicetree.yaml")
with open(abs_path, 'r') as f:
data = yaml.safe_load(f) or {}
# Handle dependencies before adding current config (post-order)
deps = data.get("dependencies", [])
for dep in deps:
# Dependencies are relative to project_root
dep_path = os.path.join(project_root, dep)
_parse_recursive(dep_path, False)
if is_root:
config.dependencies += deps
dts_path = data.get("dts", "")
config.dts = os.path.join(current_path, dts_path)
bindings = data.get("bindings", "")
if bindings:
bindings_resolved = os.path.join(current_path, bindings)
config.bindings.append(bindings_resolved)
_parse_recursive(file_path, True)
return config
@@ -0,0 +1,2 @@
class DevicetreeException(Exception):
pass
@@ -0,0 +1,9 @@
def read_file(path: str):
with open(path, "r") as file:
result = file.read()
return result
def write_file(path: str, content: str):
with open(path, "w") as file:
result = file.write(content)
return result
@@ -0,0 +1,314 @@
import os.path
from textwrap import dedent
from source.models import *
from .exception import DevicetreeException
def write_include(file, include: IncludeC, verbose: bool):
if verbose:
print("Processing include:")
print(f" {include.statement}")
file.write(include.statement)
file.write('\n')
def write_define(file, define: DefineC, verbose: bool):
if verbose:
print("Processing define:")
print(f" {define.statement}")
file.write(define.statement)
file.write('\n')
def get_device_node_name_safe(device: Device):
if device.node_name == "/":
return "root"
else:
return device.node_name.replace("-", "_")
def get_device_type_name(device: Device, bindings: list[Binding]):
device_binding = find_device_binding(device, bindings)
if device_binding is None:
raise DevicetreeException(f"Binding not found for {device.node_name}")
if device_binding.compatible is None:
raise DevicetreeException(f"Couldn't find compatible binding for {device.node_name}")
compatible_safe = device_binding.compatible.split(",")[-1]
return compatible_safe.replace("-", "_")
def find_device_property(device: Device, name: str) -> DeviceProperty:
for property in device.properties:
if property.name == name:
return property
return None
def find_device_binding(device: Device, bindings: list[Binding]) -> Binding:
compatible_property = find_device_property(device, "compatible")
if compatible_property is None:
raise DevicetreeException(f"property 'compatible' not found in device {device.node_name}")
for binding in bindings:
if binding.compatible == compatible_property.value:
return binding
return None
def find_binding(compatible: str, bindings: list[Binding]) -> Binding:
for binding in bindings:
if binding.compatible == compatible:
return binding
return None
def find_phandle(devices: list[Device], phandle: str):
for device in devices:
if device.node_name == phandle or device.node_alias == phandle:
return f"&{get_device_node_name_safe(device)}"
raise DevicetreeException(f"phandle '{phandle}' not found in devicetree")
def property_to_string(property: DeviceProperty, devices: list[Device]) -> str:
type = property.type
if type == "value" or type == "int":
return property.value
elif type == "boolean" or type == "bool":
if property.value is None or not property.value:
return "false"
else:
return "true"
elif type == "text":
return f"\"{property.value}\""
elif type == "values":
value_list = list()
for item in property.value:
if isinstance(item, PropertyValue):
value_list.append(property_to_string(DeviceProperty(name="", type=item.type, value=item.value), devices))
else:
value_list.append(str(item))
return "{ " + ",".join(value_list) + " }"
elif type == "phandle":
return find_phandle(devices, property.value)
elif type == "phandle-array":
value_list = list()
if isinstance(property.value, list):
for item in property.value:
if isinstance(item, PropertyValue):
value_list.append(property_to_string(DeviceProperty(name="", type=item.type, value=item.value), devices))
else:
value_list.append(str(item))
return "{ " + ",".join(value_list) + " }"
elif isinstance(property.value, str):
# If it's a string, assume it's a #define and show it as-is
return property.value
else:
raise Exception(f"Unsupported phandle-array type for {property.value}")
else:
raise DevicetreeException(f"property_to_string() has an unsupported type: {type}")
def resolve_parameters_from_bindings(device: Device, bindings: list[Binding], devices: list[Device]) -> list:
compatible_property = find_device_property(device, "compatible")
if compatible_property is None:
raise DevicetreeException(f"Cannot find 'compatible' property for {device.node_name}")
device_binding = find_binding(compatible_property.value, bindings)
if device_binding is None:
raise DevicetreeException(f"Binding not found for {device.node_name} and compatible '{compatible_property.value}'")
# Filter out system properties
binding_properties = []
binding_property_names = set()
for property in device_binding.properties:
if property.name != "compatible":
binding_properties.append(property)
binding_property_names.add(property.name)
# Check for invalid properties in device
for device_property in device.properties:
if device_property.name in ["compatible"]:
continue
if device_property.name not in binding_property_names:
raise DevicetreeException(f"Device '{device.node_name}' has invalid property '{device_property.name}'")
# Allocate total expected configuration arguments
result = [0] * len(binding_properties)
for index, binding_property in enumerate(binding_properties):
device_property = find_device_property(device, binding_property.name)
# No property specified in DTS, use binding defaults
if device_property is None:
if binding_property.default is not None:
temp_prop = DeviceProperty(
name=binding_property.name,
type=binding_property.type,
value=binding_property.default
)
result[index] = property_to_string(temp_prop, devices)
elif binding_property.required:
raise DevicetreeException(f"device {device.node_name} doesn't have property '{binding_property.name}'")
elif binding_property.type == "bool" or binding_property.type == "boolean":
if binding_property.default == "true" or binding_property.default == None:
result[index] = "true"
else: # Explicit or implied false
result[index] = "false"
else:
raise DevicetreeException(f"Device {device.node_name} doesn't have property '{binding_property.name}' and no default value is set")
else:
result[index] = property_to_string(device_property, devices)
return result
def write_config(file, device: Device, bindings: list[Binding], devices: list[Device], type_name: str):
node_name = get_device_node_name_safe(device)
config_type = f"{type_name}_config_dt"
config_variable_name = f"{node_name}_config"
file.write(f"static const {config_type} {config_variable_name}" " = {\n")
config_params = resolve_parameters_from_bindings(device, bindings, devices)
# Indent all params
for index, config_param in enumerate(config_params):
config_params[index] = f"\t{config_param}"
# Join with command and newline
if len(config_params) > 0:
config_params_joined = ",\n".join(config_params)
file.write(f"{config_params_joined}\n")
file.write("};\n\n")
def write_device_structs(file, device: Device, parent_device: Device, bindings: list[Binding], devices: list[Device], verbose: bool):
if verbose:
print(f"Writing device struct for '{device.node_name}'")
# Assemble some pre-requisites
type_name = get_device_type_name(device, bindings)
compatible_property = find_device_property(device, "compatible")
if compatible_property is None:
raise DevicetreeException(f"Cannot find 'compatible' property for {device.node_name}")
node_name = get_device_node_name_safe(device)
config_variable_name = f"{node_name}_config"
if parent_device is not None:
parent_node_name = get_device_node_name_safe(parent_device)
parent_value = f"&{parent_node_name}"
else:
parent_value = "NULL"
# Write config struct
write_config(file, device, bindings, devices, type_name)
# Write device struct
file.write(f"static struct Device {node_name}" " = {\n")
file.write(f"\t.name = \"{device.node_name}\",\n") # Use original name
file.write(f"\t.config = &{config_variable_name},\n")
file.write(f"\t.parent = {parent_value},\n")
file.write("\t.internal = NULL\n")
file.write("};\n\n")
# Child devices
for child_device in device.devices:
write_device_structs(file, child_device, device, bindings, devices, verbose)
def get_device_status_variable(device: Device):
if device.status == "okay" or device.status is None:
return "DTS_DEVICE_STATUS_OKAY"
elif device.status == "disabled":
return "DTS_DEVICE_STATUS_DISABLED"
else:
raise DevicetreeException(f"Unsupported device status '{device.status}'")
def write_device_list_entry(file, device: Device, bindings: list[Binding], verbose: bool):
if verbose:
print(f"Processing device init code for '{device.node_name}'")
# Assemble some pre-requisites
compatible_property = find_device_property(device, "compatible")
if compatible_property is None:
raise DevicetreeException(f"Cannot find 'compatible' property for {device.node_name}")
# Type & instance names
node_name = get_device_node_name_safe(device)
device_variable = node_name
status = get_device_status_variable(device)
# Write device struct
file.write("\t{ " f"&{device_variable}, \"{compatible_property.value}\", {status}" " },\n")
# Write children
for child_device in device.devices:
write_device_list_entry(file, child_device, bindings, verbose)
# Walk the tree and gather all devices
def gather_devices(device: Device, output: list[Device]):
output.append(device)
for child_device in device.devices:
gather_devices(child_device, output)
def generate_devicetree_c(filename: str, items: list[object], bindings: list[Binding], config, verbose: bool):
# Create a cache for looking up device names and aliases easily
# We still want to traverse it as a tree during code generation because of parent-setting
devices = list()
for item in items:
if type(item) is Device:
gather_devices(item, devices)
with open(filename, "w") as file:
file.write(dedent('''\
// Default headers
#include <tactility/device.h>
#include <tactility/dts.h>
#include <tactility/module.h>
// DTS headers
'''))
# Write all headers first
for item in items:
if type(item) is IncludeC:
write_include(file, item, verbose)
elif type(item) is DefineC:
write_define(file, item, verbose)
file.write("\n")
# Then write all devices
for item in items:
if type(item) is Device:
write_device_structs(file, item, None, bindings, devices, verbose)
file.write("struct DtsDevice dts_devices[] = {\n")
for item in items:
if type(item) is Device:
write_device_list_entry(file, item, bindings, verbose)
file.write("\tDTS_DEVICE_TERMINATOR\n")
file.write("};\n")
# Gather module symbols
module_symbol_names = []
# Device's own module goes first (started before its dependency modules)
if config.dts:
device_dir = os.path.dirname(os.path.normpath(config.dts))
device_name = os.path.basename(device_dir)
if device_name:
device_module_name = device_name.replace('-', '_')
if not device_module_name.endswith("_module"):
device_module_name += "_module"
module_symbol_names.append(device_module_name)
for dependency in config.dependencies:
dependency_name = os.path.basename(os.path.normpath(dependency))
module_symbol_name = f"{dependency_name.replace('-', '_')}"
if not module_symbol_name.endswith("_module"):
module_symbol_name += "_module"
module_symbol_names.append(module_symbol_name)
file.write("\n")
# Forward declaration of symbol variables
for symbol in module_symbol_names:
file.write(f"extern struct Module {symbol};\n")
file.write("\n")
# Create array of symbol variables
file.write("struct Module* dts_modules[] = {\n")
for symbol in module_symbol_names:
file.write(f"\t&{symbol},\n")
file.write("\tNULL\n")
file.write("};\n")
def generate_devicetree_h(filename: str):
with open(filename, "w") as file:
file.write(dedent('''\
#pragma once
#include <tactility/error.h>
#include <tactility/dts.h>
#ifdef __cplusplus
extern "C" {
#endif
// Array of device tree modules terminated with DTS_MODULE_TERMINATOR
extern struct DtsDevice dts_devices[];
// Array of module symbols terminated with NULL
extern struct Module* dts_modules[];
#ifdef __cplusplus
}
#endif
'''))
def generate(output_path: str, items: list[object], bindings: list[Binding], config, verbose: bool):
if not os.path.exists(output_path):
os.makedirs(output_path)
devicetree_c_filename = os.path.join(output_path, "devicetree.c")
generate_devicetree_c(devicetree_c_filename, items, bindings, config, verbose)
devicetree_h_filename = os.path.join(output_path, "devicetree.h")
generate_devicetree_h(devicetree_h_filename)
@@ -0,0 +1,50 @@
%import common.DIGIT -> DIGIT
%import common.LETTER -> LETTER
%import common.HEXDIGIT -> HEXDIGIT
%import common.SIGNED_INT -> SIGNED_INT
%import common.WS -> WS
%import common.SIGNED_NUMBER -> SIGNED_NUMBER
%import common.ESCAPED_STRING -> ESCAPED_STRING
%ignore WS
// Comment
SINGLE_LINE_COMMENT: /\/\/[^\n]*/
MULTI_LINE_COMMENT: /\/\*([^*]|\*+[^*\/])*\*+\//
%ignore SINGLE_LINE_COMMENT
%ignore MULTI_LINE_COMMENT
// Boolean
BOOLEAN: "true" | "false"
// Main
INCLUDE_C: /#include <[\w\/.\-]+>/
DEFINE_C: /#define[^\n]+/
PROPERTY_NAME: /#?[a-zA-Z0-9_\-,]+/
QUOTE: "\""
QUOTED_TEXT: QUOTE /[^"]+/ QUOTE
quoted_text_array: QUOTED_TEXT ("," " "* QUOTED_TEXT)+
HEX_NUMBER: "0x" HEXDIGIT+
NUMBER: SIGNED_NUMBER | HEX_NUMBER
PHANDLE: /&[0-9a-zA-Z_\-]+/
C_VARIABLE: /[0-9a-zA-Z_]+/
VALUE: NUMBER | PHANDLE | C_VARIABLE
value: VALUE
values: VALUE+
array: NUMBER+
property_value: quoted_text_array | QUOTED_TEXT | "<" value ">" | "<" values ">" | "[" array "]" | PHANDLE
device_property: PROPERTY_NAME ["=" property_value] ";"
NODE_ALIAS: /[a-zA-Z0-9_\-\/@]+/
NODE_NAME: /[a-zA-Z0-9_\-\/@]+/
device: (NODE_ALIAS ":")? NODE_NAME "{" (device | device_property)* "};"
dts_version: /[0-9a-zA-Z\-]+/
start: "/" dts_version "/;" (INCLUDE_C | DEFINE_C)* device+
@@ -0,0 +1,53 @@
import os
from pprint import pprint
from lark import Lark
from source.files import *
from source.transformer import *
from source.generator import *
from source.binding_files import find_all_bindings
from source.binding_parser import parse_binding
from source.config import *
from source.exception import DevicetreeException
def main(config_path: str, output_path: str, verbose: bool) -> int:
print(f"Generating devicetree code\n config: {config_path}\n output: {output_path}")
if not os.path.isdir(config_path):
print(f"Directory not found: {config_path}")
return 1
config = parse_config(config_path, os.getcwd())
if verbose:
pprint(config)
try:
project_dir = os.path.dirname(os.path.realpath(__file__))
grammar_path = os.path.join(project_dir, "grammar.lark")
lark_data = read_file(grammar_path)
dts_data = read_file(config.dts)
lark = Lark(lark_data)
parsed = lark.parse(dts_data)
if verbose:
print(parsed.pretty())
transformed = DtsTransformer().transform(parsed)
if verbose:
pprint(transformed)
binding_files = find_all_bindings(config.bindings)
if verbose:
print("Bindings found:")
for binding_file in binding_files:
print(f" {binding_file}")
if verbose:
print("Parsing bindings")
bindings = []
for binding_file in binding_files:
bindings.append(parse_binding(binding_file, config.bindings))
if verbose:
for binding in bindings:
pprint(binding)
generate(output_path, transformed, bindings, config, verbose)
return 0
except DevicetreeException as caught:
print("\033[31mError: ", caught, "\033[0m")
return 1
@@ -0,0 +1,49 @@
from dataclasses import dataclass
@dataclass
class DtsVersion:
version: str
@dataclass
class Device:
node_name: str
node_alias: str
status: str
properties: list
devices: list
@dataclass
class DeviceProperty:
name: str
type: str
value: object
@dataclass
class PropertyValue:
type: str
value: object
@dataclass
class IncludeC:
statement: str
@dataclass
class DefineC:
statement: str
@dataclass
class BindingProperty:
name: str
type: str
required: bool
description: str
default: object = None
@dataclass
class Binding:
filename: str
compatible: list[str]
description: str
properties: list[BindingProperty]
includes: list[str]
bus: str = None
@@ -0,0 +1,20 @@
import sys
if sys.platform == "win32":
SHELL_COLOR_RED = ""
SHELL_COLOR_ORANGE = ""
SHELL_COLOR_RESET = ""
else:
SHELL_COLOR_RED = "\033[91m"
SHELL_COLOR_ORANGE = "\033[93m"
SHELL_COLOR_RESET = "\033[m"
def print_warning(message):
print(f"{SHELL_COLOR_ORANGE}WARNING: {message}{SHELL_COLOR_RESET}")
def print_error(message):
print(f"{SHELL_COLOR_RED}ERROR: {message}{SHELL_COLOR_RESET}")
def exit_with_error(message):
print_error(message)
sys.exit(1)
@@ -0,0 +1,90 @@
from typing import List
from lark import Transformer
from lark import Token
from source.models import *
from dataclasses import dataclass
from .exception import DevicetreeException
def flatten_token_array(tokens: List[Token], name: str):
result_list = list()
for token in tokens:
result_list.append(token.value)
return Token(name, result_list)
@dataclass
class NodeNameAndAlias:
name: str
alias: str
class DtsTransformer(Transformer):
# Flatten the start node into a list
def start(self, tokens):
return tokens
def dts_version(self, tokens: List[Token]):
version = tokens[0].value
if version != "dts-v1":
raise DevicetreeException(f"Unsupported DTS version: {version}")
return DtsVersion(version)
def device(self, tokens: list):
node_name = None
node_alias = None
status = None
properties = list()
child_devices = list()
for index, item in enumerate(tokens):
if type(item) is Token and item.type == 'NODE_NAME':
node_name = item.value
elif type(item) is Token and item.type == 'NODE_ALIAS':
node_alias = item.value
elif type(item) is DeviceProperty:
if item.name == "status":
status = item.value
else:
properties.append(item)
elif type(item) is Device:
child_devices.append(item)
return Device(node_name, node_alias, status, properties, child_devices)
def device_property(self, objects: List[object]):
name = objects[0]
# Boolean property has no value as the value is implied to be true
if (len(objects) == 1) or (objects[1] is None):
return DeviceProperty(name, "boolean", True)
if type(objects[1]) is not PropertyValue:
raise DevicetreeException(f"Object was not converted to PropertyValue: {objects[1]}")
return DeviceProperty(name, objects[1].type, objects[1].value)
def property_value(self, tokens: List):
token = tokens[0]
if type(token) is Token:
raise DevicetreeException(f"Failed to convert token to PropertyValue: {token}")
return token
def PHANDLE(self, token: Token):
return PropertyValue(type="phandle", value=token.value[1:])
def values(self, object):
return PropertyValue(type="values", value=object)
def value(self, object):
# PHANDLE is already converted to PropertyValue
if isinstance(object[0], PropertyValue):
return object[0]
return PropertyValue(type="value", value=object[0])
def array(self, object):
return PropertyValue(type="array", value=object)
def VALUE(self, token: Token):
if token.value.startswith("&"):
return PropertyValue(type="phandle", value=token.value[1:])
return token.value
def NUMBER(self, token: Token):
return token.value
def PROPERTY_NAME(self, token: Token):
return token.value
def QUOTED_TEXT(self, token: Token):
return PropertyValue("text", token.value[1:-1])
def quoted_text_array(self, tokens: List[Token]):
result_list = list()
for token in tokens:
result_list.append(token.value)
return PropertyValue("text_array", result_list)
def INCLUDE_C(self, token: Token):
return IncludeC(token.value)
def DEFINE_C(self, token: Token):
return DefineC(token.value)
@@ -0,0 +1,16 @@
description: Boolean test device binding
compatible: "test,bool-device"
properties:
binding-default-true-setting-implied:
type: boolean
default: true
binding-default-false-setting-implied:
type: boolean
default: false
binding-default-false-setting-direct:
type: boolean
default: false
binding-implied-true-setting-direct:
type: boolean
binding-implied-true-setting-implied:
type: boolean
@@ -0,0 +1,10 @@
description: Generic test device binding
compatible: "test,generic-device"
properties:
reg:
type: int
required: true
int-prop:
type: int
string-prop:
type: string
@@ -0,0 +1,5 @@
description: Test root binding
compatible: "test,root"
properties:
model:
type: string
@@ -0,0 +1,2 @@
dts: test.dts
bindings: bindings
@@ -0,0 +1,59 @@
// Default headers
#include <tactility/device.h>
#include <tactility/dts.h>
#include <tactility/module.h>
// DTS headers
#include <test_include.h>
static const root_config_dt root_config = {
"Test Model"
};
static struct Device root = {
.name = "/",
.config = &root_config,
.parent = NULL,
.internal = NULL
};
static const generic_device_config_dt test_device@0_config = {
0,
42,
"hello"
};
static struct Device test_device@0 = {
.name = "test-device@0",
.config = &test_device@0_config,
.parent = &root,
.internal = NULL
};
static const bool_device_config_dt bool_test_device_config = {
true,
false,
true,
true,
true
};
static struct Device bool_test_device = {
.name = "bool-test-device",
.config = &bool_test_device_config,
.parent = &root,
.internal = NULL
};
struct DtsDevice dts_devices[] = {
{ &root, "test,root", DTS_DEVICE_STATUS_OKAY },
{ &test_device@0, "test,generic-device", DTS_DEVICE_STATUS_OKAY },
{ &bool_test_device, "test,bool-device", DTS_DEVICE_STATUS_OKAY },
DTS_DEVICE_TERMINATOR
};
extern struct Module data_module;
struct Module* dts_modules[] = {
&data_module,
NULL
};
@@ -0,0 +1,17 @@
#pragma once
#include <tactility/error.h>
#include <tactility/dts.h>
#ifdef __cplusplus
extern "C" {
#endif
// Array of device tree modules terminated with DTS_MODULE_TERMINATOR
extern struct DtsDevice dts_devices[];
// Array of module symbols terminated with NULL
extern struct Module* dts_modules[];
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,22 @@
/dts-v1/;
#include <test_include.h>
/ {
compatible = "test,root";
model = "Test Model";
test_device1: test-device@0 {
compatible = "test,generic-device";
reg = <0>;
status = "okay";
int-prop = <42>;
string-prop = "hello";
};
bool-test-device {
compatible = "test,bool-device";
binding-default-false-setting-direct;
binding-implied-true-setting-direct;
};
};
@@ -0,0 +1,112 @@
import os
import subprocess
import shutil
import sys
import tempfile
# Path to the compile.py script
# We assume this script is in Buildscripts/DevicetreeCompiler/tests/
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, ".."))
COMPILE_SCRIPT = os.path.join(PROJECT_ROOT, "compile.py")
TEST_DATA_DIR = os.path.join(SCRIPT_DIR, "data")
def run_compiler(config_path, output_path):
result = subprocess.run(
[sys.executable, COMPILE_SCRIPT, config_path, output_path],
capture_output=True,
text=True,
cwd=PROJECT_ROOT,
timeout=60
)
return result
def test_compile_success():
print("Running test_compile_success...")
with tempfile.TemporaryDirectory() as output_dir:
result = run_compiler(TEST_DATA_DIR, output_dir)
if result.returncode != 0:
print(f"FAILED: Compilation failed: {result.stderr} {result.stdout}")
return False
for filename in ["devicetree.c", "devicetree.h"]:
generated_path = os.path.join(output_dir, filename)
expected_path = os.path.join(TEST_DATA_DIR, f"expected_{filename}")
if not os.path.exists(generated_path):
print(f"FAILED: {filename} not generated")
return False
if not os.path.exists(expected_path):
print(f"FAILED: {os.path.basename(expected_path)} not found in test data")
return False
diff_result = subprocess.run(["diff", "-u", expected_path, generated_path], capture_output=True, text=True)
if diff_result.returncode != 0:
print(f"FAILED: {filename} does not match expected_{filename}")
print(diff_result.stdout)
return False
print("PASSED")
return True
def test_compile_invalid_dts():
print("Running test_compile_invalid_dts...")
with tempfile.TemporaryDirectory() as tmp_dir:
bad_data_dir = os.path.join(tmp_dir, "bad_data")
os.makedirs(bad_data_dir)
output_dir = os.path.join(tmp_dir, "output")
os.makedirs(output_dir)
with open(os.path.join(bad_data_dir, "devicetree.yaml"), "w") as f:
f.write("dts: bad.dts\nbindings: bindings")
with open(os.path.join(bad_data_dir, "bad.dts"), "w") as f:
f.write("/dts-v1/;\n / { invalid syntax }")
os.makedirs(os.path.join(bad_data_dir, "bindings"))
result = run_compiler(bad_data_dir, output_dir)
if result.returncode == 0:
print("FAILED: Compilation should have failed but succeeded")
return False
print("PASSED")
return True
def test_compile_missing_config():
print("Running test_compile_missing_config...")
with tempfile.TemporaryDirectory() as output_dir:
result = run_compiler("/non/existent/path", output_dir)
if result.returncode == 0:
print("FAILED: Compilation should have failed for non-existent path")
return False
if "Directory not found" not in result.stdout:
print(f"FAILED: Expected 'Directory not found' error message, got: {result.stdout}")
return False
print("PASSED")
return True
if __name__ == "__main__":
tests = [
test_compile_success,
test_compile_invalid_dts,
test_compile_missing_config
]
failed = 0
for test in tests:
if not test():
failed += 1
if failed > 0:
print(f"\n{failed} tests failed")
sys.exit(1)
else:
print("\nAll tests passed")
sys.exit(0)
+26
View File
@@ -0,0 +1,26 @@
param(
# "--chip esp32s3" is irrelevant, just need to be added, fallback to "esp32s3"
[string]$chip = "esp32s3"
)
if ($null -eq (Get-Command "esptool" -ErrorAction SilentlyContinue))
{
Write-Host "Unable to find esptool in your path. Make sure you have Python installed and on your path. Then run `pip install esptool`."
exit 1
}
# Create merge command based on partitions
$json = Get-Content .\Binaries\flasher_args.json -Raw | ConvertFrom-Json
$jsonClean = $json.flash_files -replace '[\{\}\@\;]', ''
$jsonClean = $jsonClean -replace '[\=]', ' '
$mergeArgs = @('--chip', $chip, 'merge-bin', '--output', 'merged_binary.bin') + ($jsonClean -split '\s+' | Where-Object { $_ })
Push-Location Binaries
& esptool @mergeArgs
$exitCode = $LASTEXITCODE
Pop-Location
if ($exitCode -ne 0) {
exit $exitCode
}
+52
View File
@@ -0,0 +1,52 @@
#!/usr/bin/env bash
# Usage:
# merge.sh [chip]
#
# Arguments:
# chip - optional ESP32 SOC variant (e.g. esp32, esp32s3, esp32c6)
#
# Requirements:
# jq - run 'pip install jq'
# esptool.py - run 'pip install esptool'
#
# Documentation:
# https://docs.espressif.com/projects/esptool/en/latest/esp32/
#
# Source: https://stackoverflow.com/a/53798785
function is_bin_in_path {
builtin type -P "$1" &> /dev/null
}
function require_bin {
program=$1
if ! is_bin_in_path $program; then
exit 1
else
exit 0
fi
}
# Find either esptool (installed via system package manager) or esptool.py (installed via pip)
if ! is_bin_in_path esptool; then
if ! is_bin_in_path esptool.py; then
echo "\e[31m⚠️ esptool not found! Install it from your package manager or install python and run 'pip install esptool'\e[0m"
exit 1
else
esptoolPath=esptool.py
fi
else
esptoolPath=esptool
fi
chip=${1:-esp32s3}
# Take the flash_arg file contents and join each line in the file into a single line
flash_args="$(tr '\n' ' ' < Binaries/flash_args)"
read -r -a flash_args_array <<< "$flash_args"
(
cd Binaries || exit 1
"$esptoolPath" --chip "$chip" merge-bin --output merged_binary.bin "${flash_args_array[@]}"
) || exit 1
+24
View File
@@ -0,0 +1,24 @@
idf_component_register(
INCLUDE_DIRS
"Libraries/TactilityC/include"
"Libraries/TactilityKernel/include"
"Libraries/TactilityFreeRtos/include"
"Libraries/lvgl/include"
"Modules/lvgl-module/include"
"Drivers/bm8563-module/include"
"Drivers/bmi270-module/include"
"Drivers/mpu6886-module/include"
"Drivers/pi4ioe5v6408-module/include"
"Drivers/qmi8658-module/include"
"Drivers/rx8130ce-module/include"
REQUIRES esp_timer
)
# Regular and core features
add_prebuilt_library(TactilityC Libraries/TactilityC/binary/libTactilityC.a)
add_prebuilt_library(TactilityKernel Libraries/TactilityKernel/binary/libTactilityKernel.a)
add_prebuilt_library(lvgl Libraries/lvgl/binary/liblvgl.a)
target_link_libraries(${COMPONENT_LIB} INTERFACE TactilityC)
target_link_libraries(${COMPONENT_LIB} INTERFACE TactilityKernel)
target_link_libraries(${COMPONENT_LIB} INTERFACE lvgl)
@@ -0,0 +1,36 @@
function(tactility_project)
endfunction()
function(_tactility_project)
endfunction()
macro(tactility_project project_name)
set(TACTILITY_SKIP_SPIFFS 1)
include("${TACTILITY_SDK_PATH}/Libraries/elf_loader/elf_loader.cmake")
project_elf($project_name)
file(READ ${TACTILITY_SDK_PATH}/idf-version.txt TACTILITY_SDK_IDF_VERSION)
string(REGEX REPLACE "^([0-9]+\\.[0-9]+).*" "\\1" TACTILITY_SDK_IDF_MAJOR_MINOR "${TACTILITY_SDK_IDF_VERSION}")
string(REGEX REPLACE "^([0-9]+\\.[0-9]+).*" "\\1" CURRENT_IDF_MAJOR_MINOR "$ENV{ESP_IDF_VERSION}")
if (NOT "${CURRENT_IDF_MAJOR_MINOR}" STREQUAL "${TACTILITY_SDK_IDF_MAJOR_MINOR}")
message(FATAL_ERROR "ESP-IDF version of Tactility SDK (${TACTILITY_SDK_IDF_VERSION}) does not match current ESP-IDF version ($ENV{ESP_IDF_VERSION})")
endif()
set(EXTRA_COMPONENT_DIRS
"Libraries/TactilityFreeRtos"
"Modules"
"Drivers"
)
set(COMPONENTS
TactilityFreeRtos
bm8563-module
bmi270-module
mpu6886-module
pi4ioe5v6408-module
qmi8658-module
rx8130ce-module
)
endmacro()
Binary file not shown.
-27
View File
@@ -1,27 +0,0 @@
if (NOT WIN32)
string(ASCII 27 Esc)
set(ColorReset "${Esc}[m")
set(Cyan "${Esc}[36m")
else ()
set(ColorReset "")
set(Cyan "")
endif ()
function(INIT_TACTILITY_GLOBALS SDKCONFIG_FILE)
get_filename_component(SDKCONFIG_FILE_ABS ${SDKCONFIG_FILE} ABSOLUTE)
# Find the board identifier in the sdkconfig file
file(READ ${SDKCONFIG_FILE_ABS} sdkconfig_text)
string(REGEX MATCH "(CONFIG_TT_BOARD_ID\=\"[a-z0-9_\-]*\")" sdkconfig_board_id "${sdkconfig_text}")
if (sdkconfig_board_id STREQUAL "")
message(FATAL_ERROR "CONFIG_TT_BOARD_ID not found in sdkconfig:\nMake sure you copied one of the sdkconfig.board.* files into sdkconfig")
endif ()
string(LENGTH ${sdkconfig_board_id} sdkconfig_board_id_length)
set(id_length 0)
math(EXPR id_length "${sdkconfig_board_id_length} - 21")
string(SUBSTRING ${sdkconfig_board_id} 20 ${id_length} board_id)
message("Board name: ${Cyan}${board_id}${ColorReset}")
set(TACTILITY_BOARD_PROJECT ${board_id})
message("Board path: ${Cyan}Boards/${TACTILITY_BOARD_PROJECT}${ColorReset}\n")
set_property(GLOBAL PROPERTY TACTILITY_BOARD_PROJECT ${TACTILITY_BOARD_PROJECT})
set_property(GLOBAL PROPERTY TACTILITY_BOARD_ID ${board_id})
endfunction()
+38
View File
@@ -0,0 +1,38 @@
import os
import subprocess
import shutil
import time
def build(device: str) -> bool:
print(f"Building {device}...")
shutil.rmtree(os.path.join('Firmware', 'Generated'), ignore_errors=True)
result = subprocess.run(['python', 'device.py', device], capture_output=True, text=True)
if result.returncode != 0:
print(f"Failed to select device {device}")
return False
result = subprocess.run(['idf.py', f"-Bbuild-all-{device}", 'build'], capture_output=True, text=True)
if result.returncode != 0:
print(f"Build failed for {device}:")
print(result.stdout)
print(result.stderr)
return result.returncode == 0
def main():
start_time = time.time()
buildscripts_dir = 'Devices'
if not os.path.exists(buildscripts_dir):
print(f"Directory '{buildscripts_dir}' not found.")
return
for item in os.listdir(buildscripts_dir):
item_path = os.path.join(buildscripts_dir, item)
if os.path.isdir(item_path) and item != 'simulator':
if not build(item):
return
print("All builds succeeded.")
end_time = time.time()
print(f"Elapsed time: {end_time - start_time:.2f} seconds")
if __name__ == "__main__":
main()
+28
View File
@@ -0,0 +1,28 @@
if (NOT WIN32)
string(ASCII 27 Esc)
set(ColorReset "${Esc}[m")
set(Cyan "${Esc}[36m")
else ()
set(ColorReset "")
set(Cyan "")
endif ()
include("${CMAKE_CURRENT_LIST_DIR}/properties.cmake")
function(INIT_TACTILITY_GLOBALS SDKCONFIG_FILE)
GET_PROPERTY_FILE_CONTENT(${SDKCONFIG_FILE} sdkconfig_text)
# Get device id
GET_PROPERTY_VALUE(sdkconfig_text "CONFIG_TT_DEVICE_ID" device_id)
# Validate device id
if (NOT device_id MATCHES "^[a-z0-9\-]*$")
message(FATAL_ERROR "Device identifier ${device_id} contains invalid characters. Valid characters: a-z 0-9 \"-\"")
endif ()
# Output results
message("Device identifier: ${Cyan}${device_id}${ColorReset}")
set(TACTILITY_DEVICE_PROJECT ${device_id})
message("Device project path: ${Cyan}Devices/${TACTILITY_DEVICE_PROJECT}${ColorReset} ")
message("")
set_property(GLOBAL PROPERTY TACTILITY_DEVICE_PROJECT ${TACTILITY_DEVICE_PROJECT})
set_property(GLOBAL PROPERTY TACTILITY_DEVICE_ID ${device_id})
endfunction()
-4
View File
@@ -1,4 +0,0 @@
#!/bin/sh
config_idf_target=`cat sdkconfig | grep CONFIG_IDF_TARGET=`
echo ${config_idf_target:19:-1}
+6 -14
View File
@@ -8,20 +8,12 @@ else ()
set(TACTILITY_TARGET " @ Simulator") set(TACTILITY_TARGET " @ Simulator")
endif () endif ()
if (NOT WIN32) string(ASCII 27 Esc)
string(ASCII 27 Esc) set(ColorReset "${Esc}[m")
set(ColorReset "${Esc}[m") set(Cyan "${Esc}[36m")
set(Cyan "${Esc}[36m") set(Grey "${Esc}[37m")
set(Grey "${Esc}[37m") set(LightPurple "${Esc}[1;35m")
set(LightPurple "${Esc}[1;35m") set(White "${Esc}[1;37m")
set(White "${Esc}[1;37m")
else ()
set(ColorReset "")
set(Cyan "")
set(Grey "")
set(LightPurple "")
set(White "")
endif ()
# Some terminals (e.g. GitHub Actions) reset colour for every in a multiline message(), # Some terminals (e.g. GitHub Actions) reset colour for every in a multiline message(),
# so we add the colour to each line instead of assuming it would automatically be re-used. # so we add the colour to each line instead of assuming it would automatically be re-used.
+37
View File
@@ -0,0 +1,37 @@
if (COMMAND tactility_add_module)
return()
endif()
macro(tactility_get_module_name NAME OUT_NAME)
if (DEFINED ENV{ESP_IDF_VERSION})
set(${OUT_NAME} ${COMPONENT_LIB})
else ()
set(${OUT_NAME} ${NAME})
endif ()
endmacro()
macro(tactility_add_module NAME)
set(options)
set(oneValueArgs)
set(multiValueArgs SRCS INCLUDE_DIRS PRIV_INCLUDE_DIRS REQUIRES PRIV_REQUIRES)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (DEFINED ENV{ESP_IDF_VERSION})
idf_component_register(
SRCS ${ARG_SRCS}
INCLUDE_DIRS ${ARG_INCLUDE_DIRS}
PRIV_INCLUDE_DIRS ${ARG_PRIV_INCLUDE_DIRS}
REQUIRES ${ARG_REQUIRES}
PRIV_REQUIRES ${ARG_PRIV_REQUIRES}
)
else()
add_library(${NAME} OBJECT)
target_sources(${NAME} PRIVATE ${ARG_SRCS})
target_include_directories(${NAME}
PRIVATE ${ARG_PRIV_INCLUDE_DIRS}
PUBLIC ${ARG_INCLUDE_DIRS}
)
target_link_libraries(${NAME} PUBLIC ${ARG_REQUIRES})
target_link_libraries(${NAME} PRIVATE ${ARG_PRIV_REQUIRES})
endif()
endmacro()
+79
View File
@@ -0,0 +1,79 @@
function(GET_PROPERTY_VALUE PROPERTIES_CONTENT_VAR KEY_NAME RESULT_VAR)
# Search for the key and its value in the properties content
# Supports KEY=VALUE, KEY="VALUE", and optional spaces around =
# Use parentheses to capture the value
# We use ^ and $ with multiline if available, but string(REGEX) doesn't support them easily for lines.
# So we look for the key at the beginning of the string or after a newline.
if ("${${PROPERTIES_CONTENT_VAR}}" MATCHES "(^|\n)${KEY_NAME}[ \t]*=[ \t]*\"?([^\n\"]*)\"?")
set(${RESULT_VAR} "${CMAKE_MATCH_2}" PARENT_SCOPE)
else ()
message(FATAL_ERROR "Property '${KEY_NAME}' not found in the properties content.")
endif ()
endfunction()
function(GET_PROPERTY_FILE_CONTENT PROPERTY_FILE RESULT_VAR)
get_filename_component(PROPERTY_FILE_ABS ${PROPERTY_FILE} ABSOLUTE)
# Find the device identifier in the sdkconfig file
if (NOT EXISTS ${PROPERTY_FILE_ABS})
message(FATAL_ERROR "Property file not found: ${PROPERTY_FILE}\nMake sure you select a device by running \"python device.py [device-id]\"\n")
endif ()
file(READ ${PROPERTY_FILE_ABS} file_content)
set(${RESULT_VAR} "${file_content}" PARENT_SCOPE)
endfunction()
function(READ_PROPERTIES_TO_MAP PROPERTY_FILE RESULT_VAR)
get_filename_component(PROPERTY_FILE_ABS ${PROPERTY_FILE} ABSOLUTE)
if (NOT EXISTS ${PROPERTY_FILE_ABS})
message(FATAL_ERROR "Property file not found: ${PROPERTY_FILE}")
endif ()
file(STRINGS ${PROPERTY_FILE_ABS} lines)
set(current_section "")
set(map_content "")
foreach(line IN LISTS lines)
string(STRIP "${line}" line)
if (line STREQUAL "" OR line MATCHES "^#")
continue()
endif ()
if (line MATCHES "^\\[.*\\]$")
set(current_section "${line}")
elseif (line MATCHES "^([^=]+)=(.*)$")
set(key "${CMAKE_MATCH_1}")
set(value "${CMAKE_MATCH_2}")
string(STRIP "${key}" key)
string(STRIP "${value}" value)
# Remove optional quotes from value
if (value MATCHES "^\"(.*)\"$")
set(value "${CMAKE_MATCH_1}")
endif ()
list(APPEND map_content "${current_section}${key}" "${value}")
endif ()
endforeach()
set(${RESULT_VAR} "${map_content}" PARENT_SCOPE)
endfunction()
function(GET_VALUE_FROM_MAP MAP_VAR KEY_NAME RESULT_VAR)
list(FIND ${MAP_VAR} "${KEY_NAME}" key_index)
if (key_index EQUAL -1)
set(${RESULT_VAR} "" PARENT_SCOPE)
return()
endif ()
math(EXPR value_index "${key_index} + 1")
list(GET ${MAP_VAR} ${value_index} value)
set(${RESULT_VAR} "${value}" PARENT_SCOPE)
endfunction()
function(KEY_EXISTS_IN_MAP MAP_VAR KEY_NAME RESULT_VAR)
list(FIND ${MAP_VAR} "${KEY_NAME}" key_index)
if (key_index EQUAL -1)
set(${RESULT_VAR} FALSE PARENT_SCOPE)
else ()
set(${RESULT_VAR} TRUE PARENT_SCOPE)
endif ()
endfunction()
+58
View File
@@ -0,0 +1,58 @@
#!/usr/bin/env python3
import os
import shutil
import subprocess
import sys
def get_idf_target():
try:
with open("sdkconfig", "r") as f:
for line in f:
if line.startswith("CONFIG_IDF_TARGET="):
# CONFIG_IDF_TARGET="esp32s3" -> esp32s3
return line.split('=')[1].strip().strip('"')
except FileNotFoundError:
print("sdkconfig not found")
return None
return None
def main():
# 1. Get idf_target
idf_target = get_idf_target()
if not idf_target:
print("Could not determine IDF target from sdkconfig")
sys.exit(1)
# 2. Get version
try:
with open("version.txt", "r") as f:
version = f.read().strip()
except FileNotFoundError:
print("version.txt not found")
sys.exit(1)
# 3. Construct sdk_path
# release/TactilitySDK/${version}-${idf_target}/TactilitySDK
sdk_path = os.path.join("release", "TactilitySDK", f"{version}-{idf_target}", "TactilitySDK")
# 4. Cleanup sdk_path
if os.path.exists(sdk_path):
print(f"Cleaning up {sdk_path}")
shutil.rmtree(sdk_path)
os.makedirs(sdk_path, exist_ok=True)
# 5. Call release-sdk.py
# Note: Using sys.executable to ensure we use the same python interpreter
script_path = os.path.join("Buildscripts", "release-sdk.py")
print(f"Running {script_path} {sdk_path}")
result = subprocess.run([sys.executable, script_path, sdk_path])
if result.returncode != 0:
print(f"Error: {script_path} failed with return code {result.returncode}")
sys.exit(result.returncode)
if __name__ == "__main__":
main()
-14
View File
@@ -1,14 +0,0 @@
#!/bin/sh
#
# Description: Releases the current build files as an SDK in release/TactilitySDK-[platform]
# This deployment is used when compiling new SDK features for apps.
#
idf_target=`Buildscripts/get-idf-target.sh`
version=`cat version.txt`
sdk_path="release/TactilitySDK/${version}-${idf_target}/TactilitySDK"
mkdir -p ${sdk_path}
echo Cleaning up ${sdk_path}
rm -rf ${sdk_path}
./Buildscripts/release-sdk.sh ${sdk_path}
+163
View File
@@ -0,0 +1,163 @@
#!/usr/bin/env python3
import os
import shutil
import glob
import subprocess
import sys
from textwrap import dedent
def map_copy(mappings, target_base):
"""
Helper function to map input files/directories to output files/directories.
mappings: list of dicts with 'src' (glob pattern) and 'dst' (relative to target_base or absolute)
'src' can be a single file or a directory (if it ends with /).
"""
for mapping in mappings:
src_pattern = mapping['src']
dst_rel = mapping['dst']
dst_path = os.path.join(target_base, dst_rel)
# To preserve directory structure, we need to know where the wildcard starts
# or have a way to determine the "base" of the search.
# We'll split the pattern into a fixed base and a pattern part.
# Simple heuristic: find the first occurrence of '*' or '?'
wildcard_idx = -1
for i, char in enumerate(src_pattern):
if char in '*?':
wildcard_idx = i
break
if wildcard_idx != -1:
# Found a wildcard. The base is the directory containing it.
pattern_base = os.path.dirname(src_pattern[:wildcard_idx])
else:
# No wildcard. If it's a directory, we might want to preserve its name?
# For now, let's treat no-wildcard as no relative structure needed.
pattern_base = None
src_files = glob.glob(src_pattern, recursive=True)
if not src_files:
continue
for src in src_files:
if os.path.isdir(src):
continue
if pattern_base and src.startswith(pattern_base):
# Calculate relative path from the base of the glob pattern
rel_src = os.path.relpath(src, pattern_base)
# If dst_rel ends with /, it's a target directory
if dst_rel.endswith('/') or os.path.isdir(dst_path):
final_dst = os.path.join(dst_path, rel_src)
else:
# If dst_rel is a file, we can't really preserve structure
# unless we join it. But usually it's a dir if structure is preserved.
final_dst = dst_path
else:
final_dst = dst_path if not (dst_rel.endswith('/') or os.path.isdir(dst_path)) else os.path.join(dst_path, os.path.basename(src))
os.makedirs(os.path.dirname(final_dst), exist_ok=True)
shutil.copy2(src, final_dst)
def get_driver_mappings(driver_name):
return [
{'src': f'Drivers/{driver_name}/include/**', 'dst': f'Drivers/{driver_name}/include/'},
{'src': f'Drivers/{driver_name}/*.md', 'dst': f'Drivers/{driver_name}/'},
{'src': f'build/esp-idf/{driver_name}/lib{driver_name}.a', 'dst': f'Drivers/{driver_name}/binary/lib{driver_name}.a'},
]
def get_module_mappings(module_name):
return [
{'src': f'Modules/{module_name}/include/**', 'dst': f'Modules/{module_name}/include/'},
{'src': f'Modules/{module_name}/*.md', 'dst': f'Modules/{module_name}/'},
{'src': f'build/esp-idf/{module_name}/lib{module_name}.a', 'dst': f'Modules/{module_name}/binary/lib{module_name}.a'},
]
def create_module_cmakelists(module_name):
return dedent(f'''
cmake_minimum_required(VERSION 3.20)
idf_component_register(
INCLUDE_DIRS "include"
)
add_prebuilt_library({module_name} "binary/lib{module_name}.a")
'''.format(module_name=module_name))
def write_module_cmakelists(path, content):
with open(path, 'w') as f:
f.write(content)
def add_driver(target_path, driver_name):
mappings = get_driver_mappings(driver_name)
map_copy(mappings, target_path)
cmakelists_content = create_module_cmakelists(driver_name)
write_module_cmakelists(os.path.join(target_path, f"Drivers/{driver_name}/CMakeLists.txt"), cmakelists_content)
def add_module(target_path, module_name):
mappings = get_module_mappings(module_name)
map_copy(mappings, target_path)
cmakelists_content = create_module_cmakelists(module_name)
write_module_cmakelists(os.path.join(target_path, f"Modules/{module_name}/CMakeLists.txt"), cmakelists_content)
def main():
if len(sys.argv) < 2:
print("Usage: release-sdk.py [target_path]")
print("Example: release-sdk.py release/TactilitySDK")
sys.exit(1)
target_path = os.path.abspath(sys.argv[1])
os.makedirs(target_path, exist_ok=True)
# Mapping logic
mappings = [
{'src': 'version.txt', 'dst': ''},
# TactilityC
{'src': 'build/esp-idf/TactilityC/libTactilityC.a', 'dst': 'Libraries/TactilityC/binary/'},
{'src': 'TactilityC/Include/*', 'dst': 'Libraries/TactilityC/include/'},
{'src': 'TactilityC/CMakeLists.txt', 'dst': 'Libraries/TactilityC/'},
{'src': 'TactilityC/LICENSE*.*', 'dst': 'Libraries/TactilityC/'},
# TactilityFreeRtos
{'src': 'TactilityFreeRtos/Include/**', 'dst': 'Libraries/TactilityFreeRtos/include/'},
{'src': 'TactilityFreeRtos/CMakeLists.txt', 'dst': 'Libraries/TactilityFreeRtos/'},
{'src': 'TactilityFreeRtos/LICENSE*.*', 'dst': 'Libraries/TactilityFreeRtos/'},
# TactilityKernel
{'src': 'build/esp-idf/TactilityKernel/libTactilityKernel.a', 'dst': 'Libraries/TactilityKernel/binary/'},
{'src': 'TactilityKernel/include/**', 'dst': 'Libraries/TactilityKernel/include/'},
{'src': 'TactilityKernel/CMakeLists.txt', 'dst': 'Libraries/TactilityKernel/'},
{'src': 'TactilityKernel/*.md', 'dst': 'Libraries/TactilityKernel/'},
# lvgl (basics)
{'src': 'build/esp-idf/lvgl__lvgl/liblvgl__lvgl.a', 'dst': 'Libraries/lvgl/binary/liblvgl.a'},
{'src': 'Libraries/lvgl/lvgl.h', 'dst': 'Libraries/lvgl/include/'},
{'src': 'Libraries/lvgl/lv_version.h', 'dst': 'Libraries/lvgl/include/'},
{'src': 'Libraries/lvgl/LICENCE*.*', 'dst': 'Libraries/lvgl/'},
{'src': 'Libraries/lvgl/src/lv_conf_kconfig.h', 'dst': 'Libraries/lvgl/include/lv_conf.h'},
{'src': 'Libraries/lvgl/src/**/*.h', 'dst': 'Libraries/lvgl/include/src/'},
# elf_loader
{'src': 'Libraries/elf_loader/elf_loader.cmake', 'dst': 'Libraries/elf_loader/'},
{'src': 'Libraries/elf_loader/license.txt', 'dst': 'Libraries/elf_loader/'},
# Final scripts
{'src': 'Buildscripts/TactilitySDK/TactilitySDK.cmake', 'dst': ''},
{'src': 'Buildscripts/TactilitySDK/CMakeLists.txt', 'dst': ''},
]
map_copy(mappings, target_path)
# Modules
add_module(target_path, "lvgl-module")
# Drivers
add_driver(target_path, "bm8563-module")
add_driver(target_path, "bmi270-module")
add_driver(target_path, "mpu6886-module")
add_driver(target_path, "pi4ioe5v6408-module")
add_driver(target_path, "qmi8658-module")
add_driver(target_path, "rx8130ce-module")
# Output ESP-IDF SDK version to file
esp_idf_version = os.environ.get("ESP_IDF_VERSION", "")
with open(os.path.join(target_path, "idf-version.txt"), "a") as f:
f.write(esp_idf_version)
if __name__ == "__main__":
main()
-49
View File
@@ -1,49 +0,0 @@
#!/bin/sh
#
# Usage: release-sdk.sh [target_path]
# Example: release.sh release/TactilitySDK
# Description: Releases the current build files as an SDK in the specified folder.
#
target_path=$1
mkdir -p $target_path
build_dir=`pwd`
library_path=$target_path/Libraries
cp version.txt $target_path
# TactilityC
tactility_library_path=$library_path/TactilityC
mkdir -p $tactility_library_path/Binary
cp build/esp-idf/TactilityC/libTactilityC.a $tactility_library_path/Binary/
mkdir -p $tactility_library_path/Include
find_target_dir=$build_dir/$tactility_library_path/Include/
cp TactilityC/Include/* $find_target_dir
cp Documentation/license-tactilitysdk.md $build_dir/$tactility_library_path/LICENSE.md
# lvgl
lvgl_library_path=$library_path/lvgl
mkdir -p $lvgl_library_path/Binary
mkdir -p $lvgl_library_path/Include
cp build/esp-idf/lvgl/liblvgl.a $lvgl_library_path/Binary/
find_target_dir=$build_dir/$lvgl_library_path/Include/
cd Libraries/lvgl
find src/ -name '*.h' | cpio -pdm $find_target_dir
cd -
cp Libraries/lvgl/lvgl.h $find_target_dir
cp Libraries/lvgl/lv_version.h $find_target_dir
cp Libraries/lvgl/LICENCE.txt $lvgl_library_path/LICENSE.txt
cp Libraries/lvgl/src/lv_conf_kconfig.h $lvgl_library_path/Include/lv_conf.h
# elf_loader
elf_loader_library_path=$library_path/elf_loader
mkdir -p $elf_loader_library_path
cp Libraries/elf_loader/elf_loader.cmake $elf_loader_library_path/
cp Libraries/elf_loader/license.txt $elf_loader_library_path/
cp Buildscripts/CMake/TactilitySDK.cmake $target_path/
cp Buildscripts/CMake/CMakeLists.txt $target_path/
printf '%s' "$ESP_IDF_VERSION" >> $target_path/idf-version.txt

Some files were not shown because too many files have changed in this diff Show More