Compare commits
177 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a343e58cc | |||
| 61277e74b8 | |||
| efd3c6041c | |||
| 647678ff82 | |||
| 8115ca4fd9 | |||
| db6d3b4acb | |||
| 37420db000 | |||
| b067978c16 | |||
| 09f8031bff | |||
| 1450ca319d | |||
| c139300a58 | |||
| d0d05c67ca | |||
| f660550f86 | |||
| e9384e0c11 | |||
| 9c5a427a34 | |||
| d8346998ce | |||
| 3a59540365 | |||
| d25603166a | |||
| 17b4fc6a47 | |||
| 45a8379426 | |||
| 1e4234d895 | |||
| 2cb413c3d1 | |||
| 5777a1381b | |||
| 15de4e20b8 | |||
| 3802679de4 | |||
| a05a6afaaf | |||
| efd9662cfc | |||
| 00347cbd29 | |||
| b214a3358e | |||
| c7621b5e4c | |||
| 6dc4f698c9 | |||
| f97ca26b01 | |||
| 98bbea3e9c | |||
| f6cdabf3c0 | |||
| dcf28d0868 | |||
| 9cc58099b4 | |||
| 1216862aec | |||
| 7ad0a3cb04 | |||
| bab3eb19bc | |||
| a4d15b2a1e | |||
| 41ad569154 | |||
| faab6d825f | |||
| a2af95b92d | |||
| 53b711584f | |||
| ce8ac61d42 | |||
| d5c94c7a8a | |||
| 7027da00b8 | |||
| 095c8146c3 | |||
| 62c613477a | |||
| d83b98e99b | |||
| ade86c99b4 | |||
| 980b115f1d | |||
| 84049658db | |||
| 068600f98c | |||
| fe7fdd8583 | |||
| f26266ba76 | |||
| 35a918c82b | |||
| 63866fb371 | |||
| 457c21ffd8 | |||
| 65335578a4 | |||
| c0ed8f0a44 | |||
| a9b69010d8 | |||
| 1627b9fa85 | |||
| 1deaf4c426 | |||
| 0f8380e8fe | |||
| 5cc5b50694 | |||
| 5dfc6d70da | |||
| 50007ea9ed | |||
| e9f72490fc | |||
| 8c8ccd8783 | |||
| ee5a5a7181 | |||
| fbaff8cbac | |||
| d875ade8cb | |||
| 15f4fbfdc6 | |||
| 982fce9207 | |||
| 00b62a2831 | |||
| ab4cf79a47 | |||
| d06197a6aa | |||
| efd3dc43ed | |||
| 6de0f442fb | |||
| 29e4350517 | |||
| f9acf04dcb | |||
| a091923353 | |||
| 1593eb80ce | |||
| 869a56125f | |||
| 6116521556 | |||
| 3dfc27e93e | |||
| e4ecec64c9 | |||
| ce96474d84 | |||
| 2691dbb014 | |||
| 74eb830870 | |||
| 870924229a | |||
| b2647f46bb | |||
| d1c1a3a369 | |||
| a5090ec194 | |||
| f67cb241b7 | |||
| b2d4dc5ecb | |||
| a7c5d6a2ee | |||
| 08029a84dd | |||
| eb4e9f9649 | |||
| 3f1bfee3f5 | |||
| d72852a6e2 | |||
| d0ca3b16f8 | |||
| 81ece6f2e7 | |||
| 49a46f6236 | |||
| 358954f8be | |||
| 59ab11d498 | |||
| ebd2c7c6f9 | |||
| 7f33364bf4 | |||
| 0ebc022946 | |||
| f85d0239ff | |||
| 21936f7e9e | |||
| 19521791c5 | |||
| ef410086d9 | |||
| 2d535fec2a | |||
| 778e003d4d | |||
| 85a6ad3bbe | |||
| 13d7e84ef3 | |||
| 83a82be901 | |||
| b85ef7a2e7 | |||
| de46401d85 | |||
| bd2786b122 | |||
| 6d1d08944b | |||
| 70d36131f6 | |||
| b14887d5fb | |||
| 44b366b557 | |||
| ee88a563dc | |||
| 09cdf07b7c | |||
| d29e47f0eb | |||
| 933bc5fb97 | |||
| 6e8fbae62b | |||
| 0563e42dc9 | |||
| 5055fa7822 | |||
| ad2cad3bf1 | |||
| 6e77d5027f | |||
| 55bfb9fe3b | |||
| 2e86d4774b | |||
| b7f39f883d | |||
| 14e459e50f | |||
| 2345ba6d13 | |||
| a7a3b17ff6 | |||
| fd1e31dec4 | |||
| c5fc8790bb | |||
| e1bfdd7c91 | |||
| 5b375c21bb | |||
| c74006f8b6 | |||
| 8ccba15c25 | |||
| c1f55429b6 | |||
| 88b3bfbe3e | |||
| 6337458992 | |||
| 68e34ca740 | |||
| 5ec96f60f1 | |||
| c0f4738abe | |||
| 2e61aea93c | |||
| cff0605b0a | |||
| c87200a80d | |||
| 7856827ecf | |||
| 6c67845645 | |||
| 1bb1260ea0 | |||
| fa54eaa58a | |||
| f9e1f737fd | |||
| 686f7cce83 | |||
| c2edbad0fb | |||
| d86dc40472 | |||
| 3be251d8fb | |||
| bb7e79886f | |||
| 9fb8d45b2e | |||
| b13502170e | |||
| aa85f7d19d | |||
| dc20ed4874 | |||
| 12a9839420 | |||
| 97b8007aca | |||
| c3bcf93698 | |||
| 2bbd44a8b5 | |||
| 72230129bb | |||
| 3ea02d912f | |||
| 3ca0f8cf97 |
+4
-1
@@ -5,6 +5,7 @@ AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: BlockIndent
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignOperands: DontAlign
|
||||
AlignTrailingComments: false
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
@@ -37,12 +38,14 @@ BreakInheritanceList: BeforeColon
|
||||
ColumnLimit: 0
|
||||
CompactNamespaces: false
|
||||
ContinuationIndentWidth: 4
|
||||
EmptyLineBeforeAccessModifier: Always
|
||||
EmptyLineAfterAccessModifier: Always
|
||||
IndentCaseLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 4
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MaxEmptyLinesToKeep: 2
|
||||
NamespaceIndentation: All
|
||||
NamespaceIndentation: None
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PointerAlignment: Left
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [ByteWelder]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
polar: # Replace with a single Polar username
|
||||
buy_me_a_coffee: bytewelder
|
||||
thanks_dev: # Replace with a single thanks.dev username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: 'Bug: '
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Details (please complete the following information):**
|
||||
- ESP type: [e.g. ESP32-S3]
|
||||
- Device: [e.g. LilyGo T-Deck]
|
||||
- Tactility version: [e.g. 0.2.0 or main branch]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
Add your oops.tactility.one URL if you had a crash (scanned from QR).
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Question
|
||||
about: Ask a question
|
||||
title: ''
|
||||
labels: question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
### Checklist
|
||||
|
||||
- [ ] I read [contribution guidelines](https://github.com/ByteWelder/Tactility/blob/main/CONTRIBUTING.md)
|
||||
- [ ] Code adheres to the [coding style](https://github.com/ByteWelder/Tactility/blob/main/CODING_STYLE.md)
|
||||
|
||||
### Description
|
||||
|
||||
(describe what your changes are)
|
||||
@@ -18,9 +18,9 @@ runs:
|
||||
shell: bash
|
||||
run: cp sdkconfig.board.${{ inputs.board_id }} sdkconfig
|
||||
- name: 'Build'
|
||||
uses: espressif/esp-idf-ci-action@main
|
||||
uses: espressif/esp-idf-ci-action@v1
|
||||
with:
|
||||
esp_idf_version: v5.3.2
|
||||
esp_idf_version: v5.5
|
||||
target: ${{ inputs.arch }}
|
||||
path: './'
|
||||
- name: 'Release'
|
||||
@@ -29,12 +29,12 @@ runs:
|
||||
- name: 'Upload Artifact: Release'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tactility-${{ inputs.board_id }}
|
||||
name: Tactility-${{ inputs.board_id }}
|
||||
path: release/Tactility-${{ inputs.board_id }}
|
||||
retention-days: 30
|
||||
- name: 'Upload Artifact: Release symbols'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tactility-${{ inputs.board_id }}-symbols
|
||||
name: Tactility-${{ inputs.board_id }}-symbols
|
||||
path: release/Tactility-${{ inputs.board_id }}-symbols
|
||||
retention-days: 30
|
||||
|
||||
@@ -18,14 +18,18 @@ runs:
|
||||
shell: bash
|
||||
run: cp sdkconfig.board.${{ inputs.board_id }} sdkconfig
|
||||
- name: 'Build'
|
||||
uses: espressif/esp-idf-ci-action@main
|
||||
uses: espressif/esp-idf-ci-action@v1
|
||||
with:
|
||||
esp_idf_version: v5.3.2
|
||||
# NOTE: Update with ESP-IDF!
|
||||
esp_idf_version: v5.5
|
||||
target: ${{ inputs.arch }}
|
||||
path: './'
|
||||
- name: 'Release'
|
||||
shell: bash
|
||||
run: Buildscripts/release-sdk.sh release/TactilitySDK
|
||||
env:
|
||||
# NOTE: Update with ESP-IDF!
|
||||
ESP_IDF_VERSION: '5.5'
|
||||
run: Buildscripts/release-sdk.sh release/TactilitySDK
|
||||
- name: 'Upload Artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
|
||||
@@ -23,6 +23,7 @@ runs:
|
||||
shell: bash
|
||||
# See Libraries/SDL/docs/README-linux.md
|
||||
run: >
|
||||
sudo apt-get update &&
|
||||
sudo apt-get install build-essential git make
|
||||
pkg-config cmake ninja-build gnome-desktop-testing libasound2-dev libpulse-dev
|
||||
libaudio-dev libjack-dev libsndio-dev libx11-dev libxext-dev
|
||||
@@ -35,14 +36,16 @@ runs:
|
||||
WLR_LIBINPUT_NO_DEVICES: 1
|
||||
WAYLAND_DISPLAY: wayland-1
|
||||
GTK_USE_PORTAL: 0
|
||||
- name: "Configure Project"
|
||||
uses: threeal/cmake-action@v1.3.0
|
||||
- name: Setup cmake
|
||||
uses: jwlawson/actions-setup-cmake@v2
|
||||
with:
|
||||
cmake-version: '3.31.x'
|
||||
- name: "Prepare Project"
|
||||
shell: bash
|
||||
run: cmake -S ./ -B buildsim
|
||||
- name: "Build Tests"
|
||||
shell: bash
|
||||
run: cmake --build buildsim --target AppSim
|
||||
run: cmake --build buildsim --target FirmwareSim
|
||||
- name: 'Release'
|
||||
shell: bash
|
||||
run: Buildscripts/release-simulator.sh buildsim release/Simulator-${{ inputs.os_name }}-${{ inputs.platform_name }}
|
||||
|
||||
@@ -1,42 +1,54 @@
|
||||
name: Build Firmware
|
||||
on: [push]
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
types: [ opened, synchronize, reopened ]
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
yellow-board:
|
||||
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: yellow-board
|
||||
arch: esp32
|
||||
lilygo-tdeck:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: "Build"
|
||||
uses: ./.github/actions/build-firmware
|
||||
with:
|
||||
board_id: lilygo-tdeck
|
||||
arch: esp32s3
|
||||
m5stack-core2:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: "Build"
|
||||
uses: ./.github/actions/build-firmware
|
||||
with:
|
||||
board_id: m5stack-core2
|
||||
arch: esp32
|
||||
m5stack-cores3:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: "Build"
|
||||
uses: ./.github/actions/build-firmware
|
||||
with:
|
||||
board_id: m5stack-cores3
|
||||
arch: esp32s3
|
||||
board_id: ${{ matrix.board.id }}
|
||||
arch: ${{ matrix.board.arch }}
|
||||
|
||||
@@ -1,24 +1,26 @@
|
||||
name: Build SDK
|
||||
on: [push]
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
types: [ opened, synchronize, reopened ]
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
esp32:
|
||||
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: yellow-board
|
||||
arch: esp32
|
||||
esp32s3:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: "Build"
|
||||
uses: ./.github/actions/build-sdk
|
||||
with:
|
||||
board_id: lilygo-tdeck
|
||||
arch: esp32s3
|
||||
board_id: ${{ matrix.board.id }}
|
||||
arch: ${{ matrix.board.arch }}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
# Disabled because of issue: https://github.com/libsdl-org/setup-sdl/issues/23
|
||||
name: Build Simulator
|
||||
on: [push]
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
types: [ opened, synchronize, reopened ]
|
||||
jobs:
|
||||
Build-Simulator-Linux:
|
||||
runs-on: ubuntu-latest
|
||||
Linux:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: "Build"
|
||||
@@ -12,7 +17,7 @@ jobs:
|
||||
os_name: linux
|
||||
platform_name: amd64
|
||||
publish: true
|
||||
Build-Simulator-macOS:
|
||||
macOS:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
name: Tests
|
||||
on: [push]
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
jobs:
|
||||
Run:
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "Checkout repo"
|
||||
@@ -14,5 +19,7 @@ jobs:
|
||||
run: cmake -S ./ -B build
|
||||
- name: "Build Tests"
|
||||
run: cmake --build build --target build-tests
|
||||
- name: "Run Tests"
|
||||
- name: "Run TactilityCore Tests"
|
||||
run: build/Tests/TactilityCore/TactilityCoreTests --exit
|
||||
- name: "Run TactilityHeadless Tests"
|
||||
run: build/Tests/Tactility/TactilityTests --exit
|
||||
|
||||
@@ -7,6 +7,7 @@ build-sim/
|
||||
cmake-build-*/
|
||||
CMakeCache.txt
|
||||
*.cbp
|
||||
CMakeFiles
|
||||
|
||||
release/
|
||||
|
||||
@@ -16,3 +17,7 @@ sdkconfig.old
|
||||
managed_components/
|
||||
dependencies.lock
|
||||
|
||||
.vscode/
|
||||
.gitpod.yml
|
||||
|
||||
sdkconfig.board.*.dev
|
||||
@@ -10,3 +10,9 @@
|
||||
[submodule "Libraries/SDL"]
|
||||
path = Libraries/SDL
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
[submodule "Libraries/minitar/minitar"]
|
||||
path = Libraries/minitar/minitar
|
||||
url = https://github.com/ByteWelder/minitar.git
|
||||
[submodule "Libraries/cJSON/cJSON"]
|
||||
path = Libraries/cJSON/cJSON
|
||||
url = https://github.com/DaveGamble/cJSON.git
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
if (DEFINED ENV{ESP_IDF_VERSION})
|
||||
set(BOARD_COMPONENTS Tactility TactilityC)
|
||||
|
||||
if("${IDF_TARGET}" STREQUAL "esp32")
|
||||
list(APPEND BOARD_COMPONENTS
|
||||
YellowBoard
|
||||
M5stackCore2
|
||||
)
|
||||
endif()
|
||||
|
||||
if("${IDF_TARGET}" STREQUAL "esp32s3")
|
||||
list(APPEND BOARD_COMPONENTS
|
||||
LilygoTdeck
|
||||
M5stackCoreS3
|
||||
)
|
||||
endif()
|
||||
|
||||
idf_component_register(
|
||||
SRC_DIRS "Source"
|
||||
"Source/HelloWorld"
|
||||
REQUIRES ${BOARD_COMPONENTS}
|
||||
)
|
||||
else()
|
||||
|
||||
file(GLOB_RECURSE SOURCES "Source/*.c*")
|
||||
add_executable(AppSim ${SOURCES})
|
||||
target_link_libraries(AppSim
|
||||
PRIVATE Tactility
|
||||
PRIVATE TactilityCore
|
||||
PRIVATE TactilityHeadless
|
||||
PRIVATE Simulator
|
||||
PRIVATE SDL2::SDL2-static SDL2-static
|
||||
)
|
||||
|
||||
add_definitions(-D_Nullable=)
|
||||
add_definitions(-D_Nonnull=)
|
||||
endif()
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
# Kconfig file for Tactility example app
|
||||
menu "Tactility App"
|
||||
choice
|
||||
prompt "Board"
|
||||
default TT_BOARD_CUSTOM
|
||||
|
||||
config TT_BOARD_CUSTOM
|
||||
bool "Custom"
|
||||
config TT_BOARD_YELLOW_BOARD_24_CAP
|
||||
bool "Yellow Board (2.4\" capacitive)"
|
||||
config TT_BOARD_LILYGO_TDECK
|
||||
bool "LilyGo T-Deck"
|
||||
config TT_BOARD_M5STACK_CORE2
|
||||
bool "M5Stack Core2"
|
||||
config TT_BOARD_M5STACK_CORES3
|
||||
bool "M5Stack CoreS3"
|
||||
help
|
||||
Select a board/hardware configuration.
|
||||
Use TT_BOARD_CUSTOM if you will manually configure the board in your project.
|
||||
endchoice
|
||||
|
||||
config TT_SPLASH_DURATION
|
||||
int "Splash Duration (ms)"
|
||||
default 1500
|
||||
range 0 3000
|
||||
help
|
||||
The minimum time to show the splash screen in milliseconds.
|
||||
When set to 0, startup will continue to desktop as soon as boot operations are finished.
|
||||
endmenu
|
||||
@@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "sdkconfig.h"
|
||||
|
||||
// Supported hardware:
|
||||
#if defined(CONFIG_TT_BOARD_LILYGO_TDECK)
|
||||
#include "LilygoTdeck.h"
|
||||
#define TT_BOARD_HARDWARE &lilygo_tdeck
|
||||
#elif defined(CONFIG_TT_BOARD_YELLOW_BOARD_24_CAP)
|
||||
#include "YellowBoard.h"
|
||||
#define TT_BOARD_HARDWARE &yellow_board_24inch_cap
|
||||
#elif defined(CONFIG_TT_BOARD_M5STACK_CORE2)
|
||||
#include "M5stackCore2.h"
|
||||
#define TT_BOARD_HARDWARE &m5stack_core2
|
||||
#elif defined(CONFIG_TT_BOARD_M5STACK_CORES3)
|
||||
#include "M5stackCoreS3.h"
|
||||
#define TT_BOARD_HARDWARE &m5stack_cores3
|
||||
#else
|
||||
#define TT_BOARD_HARDWARE NULL
|
||||
#error Replace TT_BOARD_HARDWARE in main.c with your own. Or copy one of the ./sdkconfig.board.* files into ./sdkconfig.
|
||||
#endif
|
||||
|
||||
#else // else simulator
|
||||
|
||||
#include "Simulator.h"
|
||||
|
||||
extern tt::hal::Configuration hardware;
|
||||
#define TT_BOARD_HARDWARE &hardware
|
||||
|
||||
#endif // ESP_PLATFORM
|
||||
@@ -1,17 +0,0 @@
|
||||
#include "lvgl.h"
|
||||
#include "lvgl/Toolbar.h"
|
||||
|
||||
static void onShow(tt::app::AppContext& context, lv_obj_t* parent) {
|
||||
lv_obj_t* toolbar = tt::lvgl::toolbar_create(parent, context);
|
||||
lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0);
|
||||
|
||||
lv_obj_t* label = lv_label_create(parent);
|
||||
lv_label_set_text(label, "Hello, world!");
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||
}
|
||||
|
||||
extern const tt::app::AppManifest hello_world_app = {
|
||||
.id = "HelloWorld",
|
||||
.name = "Hello World",
|
||||
.onShow = onShow,
|
||||
};
|
||||
@@ -1,11 +0,0 @@
|
||||
dependencies:
|
||||
espressif/esp_lcd_ili9341: "2.0.0"
|
||||
espressif/esp_lcd_touch_cst816s: "1.0.3"
|
||||
espressif/esp_lcd_touch_gt911: "1.1.1~2"
|
||||
espressif/esp_lcd_touch_ft5x06: "1.0.6~1"
|
||||
espressif/esp_lcd_touch: "1.1.2"
|
||||
espressif/esp_tinyusb:
|
||||
version: "1.5.0"
|
||||
rules:
|
||||
- if: "target == esp32s3"
|
||||
idf: '5.3.2'
|
||||
@@ -1,5 +0,0 @@
|
||||
idf_component_register(
|
||||
SRC_DIRS "Source" "Source/hal"
|
||||
INCLUDE_DIRS "Source"
|
||||
REQUIRES Tactility esp_lvgl_port esp_lcd esp_lcd_touch_gt911 driver esp_adc
|
||||
)
|
||||
@@ -1,50 +0,0 @@
|
||||
#include "TactilityCore.h"
|
||||
#include "hal/TdeckDisplayConstants.h"
|
||||
#include <driver/spi_common.h>
|
||||
#include <soc/gpio_num.h>
|
||||
|
||||
#define TAG "tdeck"
|
||||
|
||||
// SPI
|
||||
#define TDECK_SPI_HOST SPI2_HOST
|
||||
#define TDECK_SPI_PIN_SCLK GPIO_NUM_40
|
||||
#define TDECK_SPI_PIN_MOSI GPIO_NUM_41
|
||||
#define TDECK_SPI_PIN_MISO GPIO_NUM_38
|
||||
#define TDECK_SPI_TRANSFER_SIZE_LIMIT (TDECK_LCD_HORIZONTAL_RESOLUTION * TDECK_LCD_SPI_TRANSFER_HEIGHT * (TDECK_LCD_BITS_PER_PIXEL / 8))
|
||||
|
||||
#define TDECK_LCD_BACKLIGHT_LEDC_TIMER LEDC_TIMER_0
|
||||
#define TDECK_LCD_BACKLIGHT_LEDC_MODE LEDC_LOW_SPEED_MODE
|
||||
#define TDECK_LCD_BACKLIGHT_LEDC_CHANNEL LEDC_CHANNEL_0
|
||||
#define TDECK_LCD_BACKLIGHT_LEDC_DUTY_RES LEDC_TIMER_8_BIT
|
||||
#define TDECK_LCD_BACKLIGHT_LEDC_FREQUENCY (4000)
|
||||
|
||||
static bool init_spi() {
|
||||
TT_LOG_I(TAG, LOG_MESSAGE_SPI_INIT_START_FMT, TDECK_SPI_HOST);
|
||||
|
||||
spi_bus_config_t bus_config = {
|
||||
.mosi_io_num = TDECK_SPI_PIN_MOSI,
|
||||
.miso_io_num = TDECK_SPI_PIN_MISO,
|
||||
.sclk_io_num = TDECK_SPI_PIN_SCLK,
|
||||
.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 = 0,
|
||||
.data5_io_num = 0,
|
||||
.data6_io_num = 0,
|
||||
.data7_io_num = 0,
|
||||
.max_transfer_sz = TDECK_SPI_TRANSFER_SIZE_LIMIT,
|
||||
.flags = 0,
|
||||
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
|
||||
.intr_flags = 0
|
||||
};
|
||||
|
||||
if (spi_bus_initialize(TDECK_SPI_HOST, &bus_config, SPI_DMA_CH_AUTO) != ESP_OK) {
|
||||
TT_LOG_E(TAG, LOG_MESSAGE_SPI_INIT_FAILED_FMT, TDECK_SPI_HOST);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tdeck_init_hardware() {
|
||||
return init_spi();
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
#include "hal/Configuration.h"
|
||||
#include "hal/TdeckDisplay.h"
|
||||
#include "hal/TdeckKeyboard.h"
|
||||
#include "hal/TdeckPower.h"
|
||||
#include "hal/TdeckSdCard.h"
|
||||
|
||||
bool tdeck_init_power();
|
||||
bool tdeck_init_hardware();
|
||||
bool tdeck_init_lvgl();
|
||||
|
||||
extern const tt::hal::Configuration lilygo_tdeck = {
|
||||
.initBoot = tdeck_init_power,
|
||||
.initHardware = tdeck_init_hardware,
|
||||
.initLvgl = tdeck_init_lvgl,
|
||||
.createDisplay = createDisplay,
|
||||
.createKeyboard = createKeyboard,
|
||||
.sdcard = createTdeckSdCard(),
|
||||
.power = tdeck_get_power,
|
||||
.i2c = {
|
||||
tt::hal::i2c::Configuration {
|
||||
.name = "Internal",
|
||||
.port = I2C_NUM_0,
|
||||
.initMode = tt::hal::i2c::InitByTactility,
|
||||
.canReinit = false,
|
||||
.hasMutableConfiguration = 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
|
||||
}
|
||||
},
|
||||
tt::hal::i2c::Configuration {
|
||||
.name = "External",
|
||||
.port = I2C_NUM_1,
|
||||
.initMode = tt::hal::i2c::InitByTactility,
|
||||
.canReinit = true,
|
||||
.hasMutableConfiguration = 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
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hal/Configuration.h>
|
||||
|
||||
extern const tt::hal::Configuration lilygo_tdeck;
|
||||
@@ -1,33 +0,0 @@
|
||||
#include "Log.h"
|
||||
#include "Thread.h"
|
||||
#include "lvgl/LvglSync.h"
|
||||
#include "esp_lvgl_port.h"
|
||||
#include "hal/TdeckDisplay.h"
|
||||
|
||||
#define TAG "tdeck_lvgl"
|
||||
|
||||
// LVGL
|
||||
// The minimum task stack seems to be about 3500, but that crashes the wifi app in some scenarios
|
||||
// At 8192, it sometimes crashes when wifi-auto enables and is busy connecting and then you open WifiManage
|
||||
#define TDECK_LVGL_TASK_STACK_DEPTH 9216
|
||||
|
||||
bool tdeck_init_lvgl() {
|
||||
static lv_disp_t* display = nullptr;
|
||||
const lvgl_port_cfg_t lvgl_cfg = {
|
||||
.task_priority = static_cast<UBaseType_t>(tt::THREAD_PRIORITY_RENDER),
|
||||
.task_stack = TDECK_LVGL_TASK_STACK_DEPTH,
|
||||
.task_affinity = -1, // core pinning
|
||||
.task_max_sleep_ms = 500,
|
||||
.timer_period_ms = 5
|
||||
};
|
||||
|
||||
TT_LOG_D(TAG, "LVGL port init");
|
||||
if (lvgl_port_init(&lvgl_cfg) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "LVGL port init failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
tt::lvgl::syncSet(&lvgl_port_lock, &lvgl_port_unlock);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
#include <driver/gpio.h>
|
||||
#include "TactilityCore.h"
|
||||
|
||||
#define TAG "tdeck"
|
||||
|
||||
// Power on
|
||||
#define TDECK_POWERON_GPIO GPIO_NUM_10
|
||||
|
||||
static bool tdeck_power_on() {
|
||||
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 tdeck_init_power() {
|
||||
ESP_LOGI(TAG, LOG_MESSAGE_POWER_ON_START);
|
||||
if (!tdeck_power_on()) {
|
||||
TT_LOG_E(TAG, LOG_MESSAGE_POWER_ON_FAILED);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
#include "TdeckDisplay.h"
|
||||
#include "TdeckDisplayConstants.h"
|
||||
#include "TdeckTouch.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <TactilityCore.h>
|
||||
#include <esp_lcd_panel_commands.h>
|
||||
|
||||
#include "driver/ledc.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include "esp_lcd_panel_vendor.h"
|
||||
#include "esp_lvgl_port.h"
|
||||
|
||||
#define TAG "tdeck_display"
|
||||
|
||||
static bool isBacklightInitialized = false;
|
||||
|
||||
static bool initBacklight() {
|
||||
TT_LOG_I(TAG, "Init backlight");
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = TDECK_LCD_BACKLIGHT_LEDC_MODE,
|
||||
.duty_resolution = TDECK_LCD_BACKLIGHT_LEDC_DUTY_RES,
|
||||
.timer_num = TDECK_LCD_BACKLIGHT_LEDC_TIMER,
|
||||
.freq_hz = TDECK_LCD_BACKLIGHT_LEDC_FREQUENCY,
|
||||
.clk_cfg = LEDC_AUTO_CLK,
|
||||
.deconfigure = false
|
||||
};
|
||||
|
||||
if (ledc_timer_config(&ledc_timer) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Backlight led timer config failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool setBacklight(uint8_t duty) {
|
||||
ledc_channel_config_t ledc_channel = {
|
||||
.gpio_num = TDECK_LCD_PIN_BACKLIGHT,
|
||||
.speed_mode = TDECK_LCD_BACKLIGHT_LEDC_MODE,
|
||||
.channel = TDECK_LCD_BACKLIGHT_LEDC_CHANNEL,
|
||||
.intr_type = LEDC_INTR_DISABLE,
|
||||
.timer_sel = TDECK_LCD_BACKLIGHT_LEDC_TIMER,
|
||||
.duty = duty,
|
||||
.hpoint = 0,
|
||||
.flags = {
|
||||
.output_invert = 0
|
||||
}
|
||||
};
|
||||
|
||||
// Setting the config in the timer init and then calling ledc_set_duty() doesn't work when
|
||||
// the app is running. For an unknown reason we have to call this config method every time:
|
||||
return ledc_channel_config(&ledc_channel) == ESP_OK;
|
||||
}
|
||||
|
||||
bool TdeckDisplay::start() {
|
||||
TT_LOG_I(TAG, "Starting");
|
||||
|
||||
const esp_lcd_panel_io_spi_config_t panel_io_config = {
|
||||
.cs_gpio_num = TDECK_LCD_PIN_CS,
|
||||
.dc_gpio_num = TDECK_LCD_PIN_DC,
|
||||
.spi_mode = 0,
|
||||
.pclk_hz = TDECK_LCD_SPI_FREQUENCY,
|
||||
.trans_queue_depth = 10,
|
||||
.on_color_trans_done = nullptr,
|
||||
.user_ctx = nullptr,
|
||||
.lcd_cmd_bits = 8,
|
||||
.lcd_param_bits = 8,
|
||||
.flags = {
|
||||
.dc_high_on_cmd = 0,
|
||||
.dc_low_on_data = 0,
|
||||
.dc_low_on_param = 0,
|
||||
.octal_mode = 0,
|
||||
.quad_mode = 0,
|
||||
.sio_mode = 1,
|
||||
.lsb_first = 0,
|
||||
.cs_high_active = 0,
|
||||
}
|
||||
};
|
||||
|
||||
if (esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)TDECK_LCD_SPI_HOST, &panel_io_config, &ioHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to create panel IO");
|
||||
return false;
|
||||
}
|
||||
|
||||
const esp_lcd_panel_dev_config_t panel_config = {
|
||||
.reset_gpio_num = GPIO_NUM_NC,
|
||||
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
|
||||
.data_endian = LCD_RGB_DATA_ENDIAN_LITTLE,
|
||||
.bits_per_pixel = TDECK_LCD_BITS_PER_PIXEL,
|
||||
.flags = {
|
||||
.reset_active_high = 0
|
||||
},
|
||||
.vendor_config = nullptr
|
||||
};
|
||||
|
||||
if (esp_lcd_new_panel_st7789(ioHandle, &panel_config, &panelHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to create panel");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_reset(panelHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to reset panel");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_init(panelHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to init panel");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_invert_color(panelHandle, true) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to init panel");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_swap_xy(panelHandle, true) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to swap XY ");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_mirror(panelHandle, true, false) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to mirror panel");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_disp_on_off(panelHandle, true) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to turn display on");
|
||||
return false;
|
||||
}
|
||||
|
||||
const lvgl_port_display_cfg_t disp_cfg = {
|
||||
.io_handle = ioHandle,
|
||||
.panel_handle = panelHandle,
|
||||
.buffer_size = TDECK_LCD_HORIZONTAL_RESOLUTION * TDECK_LCD_DRAW_BUFFER_HEIGHT * (TDECK_LCD_BITS_PER_PIXEL / 8),
|
||||
.double_buffer = true, // Disable to free up SPIRAM
|
||||
.trans_size = 0,
|
||||
.hres = TDECK_LCD_HORIZONTAL_RESOLUTION,
|
||||
.vres = TDECK_LCD_VERTICAL_RESOLUTION,
|
||||
.monochrome = false,
|
||||
.rotation = {
|
||||
.swap_xy = true,
|
||||
.mirror_x = true,
|
||||
.mirror_y = false,
|
||||
},
|
||||
.flags = {
|
||||
.buff_dma = false,
|
||||
.buff_spiram = true,
|
||||
.sw_rotate = false,
|
||||
.swap_bytes = false
|
||||
},
|
||||
};
|
||||
|
||||
displayHandle = lvgl_port_add_disp(&disp_cfg);
|
||||
TT_LOG_I(TAG, "Finished");
|
||||
return displayHandle != nullptr;
|
||||
}
|
||||
|
||||
bool TdeckDisplay::stop() {
|
||||
tt_assert(displayHandle != nullptr);
|
||||
|
||||
lvgl_port_remove_disp(displayHandle);
|
||||
|
||||
if (esp_lcd_panel_del(panelHandle) != ESP_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_io_del(ioHandle) != ESP_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
displayHandle = nullptr;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void TdeckDisplay::setPowerOn(bool turnOn) {
|
||||
if (esp_lcd_panel_disp_on_off(panelHandle, turnOn) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to turn display on/off");
|
||||
} else {
|
||||
poweredOn = turnOn;
|
||||
}
|
||||
}
|
||||
|
||||
tt::hal::Touch* _Nullable TdeckDisplay::createTouch() {
|
||||
return static_cast<tt::hal::Touch*>(new TdeckTouch());
|
||||
}
|
||||
|
||||
void TdeckDisplay::setBacklightDuty(uint8_t backlightDuty) {
|
||||
if (!isBacklightInitialized) {
|
||||
tt_check(initBacklight());
|
||||
isBacklightInitialized = true;
|
||||
}
|
||||
|
||||
if (!setBacklight(backlightDuty)) {
|
||||
TT_LOG_E(TAG, "Failed to configure display backlight");
|
||||
}
|
||||
}
|
||||
|
||||
void TdeckDisplay::setGammaCurve(uint8_t index) {
|
||||
uint8_t gamma_curve;
|
||||
switch (index) {
|
||||
case 0:
|
||||
gamma_curve = 0x01;
|
||||
break;
|
||||
case 1:
|
||||
gamma_curve = 0x04;
|
||||
break;
|
||||
case 2:
|
||||
gamma_curve = 0x02;
|
||||
break;
|
||||
case 3:
|
||||
gamma_curve = 0x08;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
const uint8_t param[] = {
|
||||
gamma_curve
|
||||
};
|
||||
|
||||
if (esp_lcd_panel_io_tx_param(ioHandle , LCD_CMD_GAMSET, param, 1) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to set gamma");
|
||||
}
|
||||
}
|
||||
|
||||
tt::hal::Display* createDisplay() {
|
||||
return static_cast<tt::hal::Display*>(new TdeckDisplay());
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <esp_lcd_types.h>
|
||||
#include "lvgl.h"
|
||||
#include "hal/Display.h"
|
||||
|
||||
extern lv_disp_t* displayHandle;
|
||||
|
||||
class TdeckDisplay : public tt::hal::Display {
|
||||
|
||||
private:
|
||||
|
||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
||||
lv_display_t* displayHandle = nullptr;
|
||||
bool poweredOn = false;
|
||||
|
||||
public:
|
||||
|
||||
bool start() override;
|
||||
|
||||
bool stop() override;
|
||||
|
||||
void setPowerOn(bool turnOn) override;
|
||||
bool isPoweredOn() const override { return poweredOn; };
|
||||
bool supportsPowerControl() const override { return true; }
|
||||
|
||||
tt::hal::Touch* _Nullable createTouch() override;
|
||||
|
||||
void setBacklightDuty(uint8_t backlightDuty) override;
|
||||
bool supportsBacklightDuty() const override { return true; }
|
||||
|
||||
void setGammaCurve(uint8_t index) override;
|
||||
uint8_t getGammaCurveCount() const override { return 4; };
|
||||
|
||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
||||
|
||||
private:
|
||||
|
||||
static bool startBacklight();
|
||||
};
|
||||
|
||||
tt::hal::Display* createDisplay();
|
||||
@@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define TDECK_LCD_SPI_HOST SPI2_HOST
|
||||
#define TDECK_LCD_PIN_CS GPIO_NUM_12
|
||||
#define TDECK_LCD_PIN_DC GPIO_NUM_11 // RS
|
||||
#define TDECK_LCD_PIN_BACKLIGHT GPIO_NUM_42
|
||||
#define TDECK_LCD_SPI_FREQUENCY 80000000
|
||||
#define TDECK_LCD_HORIZONTAL_RESOLUTION 320
|
||||
#define TDECK_LCD_VERTICAL_RESOLUTION 240
|
||||
#define TDECK_LCD_BITS_PER_PIXEL 16
|
||||
#define TDECK_LCD_DRAW_BUFFER_HEIGHT (TDECK_LCD_VERTICAL_RESOLUTION / 10)
|
||||
#define TDECK_LCD_SPI_TRANSFER_HEIGHT (TDECK_LCD_VERTICAL_RESOLUTION / 10)
|
||||
|
||||
// Backlight (PWM)
|
||||
#define TDECK_LCD_BACKLIGHT_LEDC_TIMER LEDC_TIMER_0
|
||||
#define TDECK_LCD_BACKLIGHT_LEDC_MODE LEDC_LOW_SPEED_MODE
|
||||
#define TDECK_LCD_BACKLIGHT_LEDC_CHANNEL LEDC_CHANNEL_0
|
||||
#define TDECK_LCD_BACKLIGHT_LEDC_DUTY_RES LEDC_TIMER_8_BIT
|
||||
#define TDECK_LCD_BACKLIGHT_LEDC_FREQUENCY (4000)
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/Keyboard.h"
|
||||
#include <TactilityCore.h>
|
||||
#include "esp_lcd_panel_io_interface.h"
|
||||
#include "esp_lcd_touch.h"
|
||||
|
||||
class TdeckKeyboard : public tt::hal::Keyboard {
|
||||
private:
|
||||
lv_indev_t* _Nullable deviceHandle = nullptr;
|
||||
public:
|
||||
bool start(lv_display_t* display) override;
|
||||
bool stop() override;
|
||||
bool isAttached() const override;
|
||||
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
||||
};
|
||||
|
||||
tt::hal::Keyboard* createKeyboard();
|
||||
@@ -1,131 +0,0 @@
|
||||
#include "TdeckPower.h"
|
||||
|
||||
#include "Log.h"
|
||||
#include "CoreDefines.h"
|
||||
|
||||
#define TAG "power"
|
||||
|
||||
/**
|
||||
* 2.0 ratio, but +.11 added as display voltage sag compensation.
|
||||
*/
|
||||
#define ADC_MULTIPLIER 2.11
|
||||
|
||||
#define ADC_REF_VOLTAGE 3.3f
|
||||
#define BATTERY_VOLTAGE_MIN 3.2f
|
||||
#define BATTERY_VOLTAGE_MAX 4.2f
|
||||
|
||||
static adc_oneshot_unit_init_cfg_t adcConfig = {
|
||||
.unit_id = ADC_UNIT_1,
|
||||
.clk_src = ADC_RTC_CLK_SRC_DEFAULT,
|
||||
.ulp_mode = ADC_ULP_MODE_DISABLE,
|
||||
};
|
||||
|
||||
static adc_oneshot_chan_cfg_t adcChannelConfig = {
|
||||
.atten = ADC_ATTEN_DB_12,
|
||||
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
||||
};
|
||||
|
||||
static uint8_t estimateChargeLevelFromVoltage(uint32_t milliVolt) {
|
||||
float volts = TT_MIN((float)milliVolt / 1000.f, BATTERY_VOLTAGE_MAX);
|
||||
float voltage_percentage = (volts - BATTERY_VOLTAGE_MIN) / (BATTERY_VOLTAGE_MAX - BATTERY_VOLTAGE_MIN);
|
||||
float voltage_factor = TT_MIN(1.0f, voltage_percentage);
|
||||
auto charge_level = (uint8_t) (voltage_factor * 100.f);
|
||||
TT_LOG_V(TAG, "mV = %lu, scaled = %.2f, factor = %.2f, result = %d", milliVolt, volts, voltage_factor, charge_level);
|
||||
return charge_level;
|
||||
}
|
||||
|
||||
TdeckPower::TdeckPower() {
|
||||
if (adc_oneshot_new_unit(&adcConfig, &adcHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "ADC config failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (adc_oneshot_config_channel(adcHandle, ADC_CHANNEL_3, &adcChannelConfig) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "ADC channel config failed");
|
||||
|
||||
adc_oneshot_del_unit(adcHandle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TdeckPower::~TdeckPower() {
|
||||
if (adcHandle) {
|
||||
adc_oneshot_del_unit(adcHandle);
|
||||
}
|
||||
}
|
||||
|
||||
bool TdeckPower::supportsMetric(MetricType type) const {
|
||||
switch (type) {
|
||||
case BATTERY_VOLTAGE:
|
||||
case CHARGE_LEVEL:
|
||||
return true;
|
||||
case IS_CHARGING:
|
||||
case CURRENT:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false; // Safety guard for when new enum values are introduced
|
||||
}
|
||||
|
||||
bool TdeckPower::getMetric(Power::MetricType type, Power::MetricData& data) {
|
||||
switch (type) {
|
||||
case BATTERY_VOLTAGE:
|
||||
return readBatteryVoltageSampled(data.valueAsUint32);
|
||||
case CHARGE_LEVEL:
|
||||
if (readBatteryVoltageSampled(data.valueAsUint32)) {
|
||||
data.valueAsUint32 = estimateChargeLevelFromVoltage(data.valueAsUint32);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case IS_CHARGING:
|
||||
case CURRENT:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false; // Safety guard for when new enum values are introduced
|
||||
}
|
||||
|
||||
bool TdeckPower::readBatteryVoltageOnce(uint32_t& output) {
|
||||
int raw;
|
||||
if (adc_oneshot_read(adcHandle, ADC_CHANNEL_3, &raw) == ESP_OK) {
|
||||
output = ADC_MULTIPLIER * ((1000.f * ADC_REF_VOLTAGE) / 4096.f) * (float)raw;
|
||||
TT_LOG_V(TAG, "Raw = %d, voltage = %lu", raw, output);
|
||||
return true;
|
||||
} else {
|
||||
TT_LOG_E(TAG, "Read failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_VOLTAGE_SAMPLES 15
|
||||
|
||||
bool TdeckPower::readBatteryVoltageSampled(uint32_t& output) {
|
||||
size_t samples_read = 0;
|
||||
uint32_t sample_accumulator = 0;
|
||||
uint32_t sample_read_buffer;
|
||||
|
||||
for (size_t i = 0; i < MAX_VOLTAGE_SAMPLES; ++i) {
|
||||
if (readBatteryVoltageOnce(sample_read_buffer)) {
|
||||
sample_accumulator += sample_read_buffer;
|
||||
samples_read++;
|
||||
}
|
||||
}
|
||||
|
||||
if (samples_read > 0) {
|
||||
output = sample_accumulator / samples_read;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static std::shared_ptr<Power> power;
|
||||
|
||||
std::shared_ptr<Power> tdeck_get_power() {
|
||||
if (power == nullptr) {
|
||||
power = std::make_shared<TdeckPower>();
|
||||
}
|
||||
return power;
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/Power.h"
|
||||
#include <esp_adc/adc_oneshot.h>
|
||||
#include <memory>
|
||||
|
||||
using namespace tt::hal;
|
||||
|
||||
class TdeckPower : public Power {
|
||||
|
||||
adc_oneshot_unit_handle_t adcHandle = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
TdeckPower();
|
||||
~TdeckPower();
|
||||
|
||||
bool supportsMetric(MetricType type) const override;
|
||||
bool getMetric(Power::MetricType type, Power::MetricData& data) override;
|
||||
|
||||
private:
|
||||
|
||||
bool readBatteryVoltageSampled(uint32_t& output);
|
||||
bool readBatteryVoltageOnce(uint32_t& output);
|
||||
};
|
||||
|
||||
std::shared_ptr<Power> tdeck_get_power();
|
||||
@@ -1,34 +0,0 @@
|
||||
#include "TdeckSdCard.h"
|
||||
|
||||
#include "lvgl/LvglSync.h"
|
||||
#include "hal/SpiSdCard.h"
|
||||
|
||||
#include <esp_vfs_fat.h>
|
||||
#include <sdmmc_cmd.h>
|
||||
|
||||
#define TDECK_SDCARD_SPI_FREQUENCY 800000U
|
||||
#define TDECK_SDCARD_PIN_CS GPIO_NUM_39
|
||||
#define TDECK_LCD_PIN_CS GPIO_NUM_12
|
||||
#define TDECK_RADIO_PIN_CS GPIO_NUM_9
|
||||
|
||||
std::shared_ptr<SdCard> createTdeckSdCard() {
|
||||
auto* configuration = new tt::hal::SpiSdCard::Config(
|
||||
TDECK_SDCARD_SPI_FREQUENCY,
|
||||
TDECK_SDCARD_PIN_CS,
|
||||
GPIO_NUM_NC,
|
||||
GPIO_NUM_NC,
|
||||
GPIO_NUM_NC,
|
||||
SdCard::MountBehaviourAtBoot,
|
||||
tt::lvgl::getLvglSyncLockable(),
|
||||
{
|
||||
TDECK_RADIO_PIN_CS,
|
||||
TDECK_LCD_PIN_CS
|
||||
}
|
||||
);
|
||||
|
||||
auto* sdcard = (SdCard*) new SpiSdCard(
|
||||
std::unique_ptr<SpiSdCard::Config>(configuration)
|
||||
);
|
||||
|
||||
return std::shared_ptr<SdCard>(sdcard);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/SdCard.h"
|
||||
|
||||
using namespace tt::hal;
|
||||
|
||||
std::shared_ptr<SdCard> createTdeckSdCard();
|
||||
@@ -1,85 +0,0 @@
|
||||
#include "TdeckTouch.h"
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_lcd_touch_gt911.h"
|
||||
#include "Log.h"
|
||||
#include "esp_lvgl_port.h"
|
||||
|
||||
#define TAG "tdeck_touch"
|
||||
|
||||
// Touch (GT911)
|
||||
#define TDECK_TOUCH_I2C_BUS_HANDLE I2C_NUM_0
|
||||
#define TDECK_TOUCH_X_MAX 240
|
||||
#define TDECK_TOUCH_Y_MAX 320
|
||||
|
||||
bool TdeckTouch::start(lv_display_t* display) {
|
||||
const esp_lcd_panel_io_i2c_config_t io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG();
|
||||
|
||||
if (esp_lcd_new_panel_io_i2c(TDECK_TOUCH_I2C_BUS_HANDLE, &io_config, &ioHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "touch io i2c creation failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_lcd_touch_config_t config = {
|
||||
.x_max = TDECK_TOUCH_X_MAX,
|
||||
.y_max = TDECK_TOUCH_Y_MAX,
|
||||
.rst_gpio_num = GPIO_NUM_NC,
|
||||
.int_gpio_num = GPIO_NUM_NC, // There is no reset pin for touch on the T-Deck, leading to a bug in esp_lvgl_port firing multiple click events when tapping the screen
|
||||
.levels = {
|
||||
.reset = 0,
|
||||
.interrupt = 0,
|
||||
},
|
||||
.flags = {
|
||||
.swap_xy = 1,
|
||||
.mirror_x = 1,
|
||||
.mirror_y = 0,
|
||||
},
|
||||
.process_coordinates = nullptr,
|
||||
.interrupt_callback = nullptr,
|
||||
.user_data = nullptr,
|
||||
.driver_data = nullptr
|
||||
};
|
||||
|
||||
if (esp_lcd_touch_new_i2c_gt911(ioHandle, &config, &touchHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "GT199 driver init failed");
|
||||
cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
const lvgl_port_touch_cfg_t touch_cfg = {
|
||||
.disp = display,
|
||||
.handle = touchHandle,
|
||||
};
|
||||
|
||||
TT_LOG_I(TAG, "Adding touch to LVGL");
|
||||
deviceHandle = lvgl_port_add_touch(&touch_cfg);
|
||||
if (deviceHandle == nullptr) {
|
||||
TT_LOG_E(TAG, "Adding touch failed");
|
||||
cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TdeckTouch::stop() {
|
||||
cleanup();
|
||||
return true;
|
||||
}
|
||||
|
||||
void TdeckTouch::cleanup() {
|
||||
if (deviceHandle != nullptr) {
|
||||
lv_indev_delete(deviceHandle);
|
||||
deviceHandle = nullptr;
|
||||
}
|
||||
|
||||
if (touchHandle != nullptr) {
|
||||
esp_lcd_touch_del(touchHandle);
|
||||
touchHandle = nullptr;
|
||||
}
|
||||
|
||||
if (ioHandle != nullptr) {
|
||||
esp_lcd_panel_io_del(ioHandle);
|
||||
ioHandle = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/Touch.h"
|
||||
#include "TactilityCore.h"
|
||||
#include "esp_lcd_panel_io_interface.h"
|
||||
#include "esp_lcd_touch.h"
|
||||
|
||||
class TdeckTouch : public tt::hal::Touch {
|
||||
private:
|
||||
esp_lcd_panel_io_handle_t _Nullable ioHandle = nullptr;
|
||||
esp_lcd_touch_handle_t _Nullable touchHandle = nullptr;
|
||||
lv_indev_t* _Nullable deviceHandle = nullptr;
|
||||
void cleanup();
|
||||
public:
|
||||
bool start(lv_display_t* display) override;
|
||||
bool stop() override;
|
||||
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
idf_component_register(
|
||||
SRC_DIRS "Source" "Source/hal" "Source/ft6x36" "Source/axp192"
|
||||
INCLUDE_DIRS "Source"
|
||||
REQUIRES Tactility esp_lvgl_port esp_lcd esp_lcd_ili9341 driver vfs fatfs
|
||||
)
|
||||
@@ -1,74 +0,0 @@
|
||||
#include <driver/i2c.h>
|
||||
#include <driver/spi_master.h>
|
||||
#include <intr_types.h>
|
||||
#include "Log.h"
|
||||
#include "hal/Core2DisplayConstants.h"
|
||||
#include "axp192/axp192.h"
|
||||
#include "hal/i2c/I2c.h"
|
||||
#include "CoreDefines.h"
|
||||
|
||||
#define TAG "core2"
|
||||
|
||||
#define CORE2_SPI2_PIN_SCLK GPIO_NUM_18
|
||||
#define CORE2_SPI2_PIN_MOSI GPIO_NUM_23
|
||||
#define CORE2_SPI2_PIN_MISO GPIO_NUM_38
|
||||
|
||||
axp192_t axpDevice;
|
||||
|
||||
static int32_t axpI2cRead(TT_UNUSED void* handle, uint8_t address, uint8_t reg, uint8_t* buffer, uint16_t size) {
|
||||
return tt::hal::i2c::masterRead(I2C_NUM_0, address, reg, buffer, size, 50 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
static int32_t axpI2cWrite(TT_UNUSED void* handle, uint8_t address, uint8_t reg, const uint8_t* buffer, uint16_t size) {
|
||||
return tt::hal::i2c::masterWrite(I2C_NUM_0, address, reg, buffer, size, 50 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
static bool initSpi2() {
|
||||
TT_LOG_I(TAG, LOG_MESSAGE_SPI_INIT_START_FMT, SPI2_HOST);
|
||||
const spi_bus_config_t bus_config = {
|
||||
.mosi_io_num = CORE2_SPI2_PIN_MOSI,
|
||||
.miso_io_num = CORE2_SPI2_PIN_MISO,
|
||||
.sclk_io_num = CORE2_SPI2_PIN_SCLK,
|
||||
.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,
|
||||
.max_transfer_sz = CORE2_LCD_DRAW_BUFFER_SIZE,
|
||||
.flags = 0,
|
||||
.isr_cpu_id = INTR_CPU_ID_AUTO,
|
||||
.intr_flags = 0
|
||||
};
|
||||
|
||||
if (spi_bus_initialize(SPI2_HOST, &bus_config, SPI_DMA_CH_AUTO) != ESP_OK) {
|
||||
TT_LOG_E(TAG, LOG_MESSAGE_SPI_INIT_FAILED_FMT, SPI2_HOST);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initAxp() {
|
||||
axpDevice.read = axpI2cRead;
|
||||
axpDevice.write = axpI2cWrite;
|
||||
|
||||
axp192_ioctl(&axpDevice, AXP192_LDO2_SET_VOLTAGE, 3300); // LCD + SD
|
||||
axp192_ioctl(&axpDevice, AXP192_LDO3_SET_VOLTAGE, 0); // VIB_MOTOR STOP
|
||||
axp192_ioctl(&axpDevice, AXP192_DCDC3_SET_VOLTAGE, 3300);
|
||||
|
||||
axp192_ioctl(&axpDevice, AXP192_LDO2_ENABLE);
|
||||
axp192_ioctl(&axpDevice, AXP192_LDO3_DISABLE);
|
||||
axp192_ioctl(&axpDevice, AXP192_DCDC3_ENABLE);
|
||||
|
||||
axp192_write(&axpDevice, AXP192_PWM1_DUTY_CYCLE_2, 255); // PWM 255 (LED OFF)
|
||||
axp192_write(&axpDevice, AXP192_GPIO1_CONTROL, 0x02); // GPIO1 PWM
|
||||
// TODO: We could charge at 390mA according to the M5Unified code, but the AXP driver in M5Unified limits to 132mA, so it's unclear what the AXP supports.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initBoot() {
|
||||
TT_LOG_I(TAG, "initBoot");
|
||||
return initAxp() && initSpi2();
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
bool initBoot();
|
||||
@@ -1,31 +0,0 @@
|
||||
#include "Log.h"
|
||||
#include "Thread.h"
|
||||
#include "lvgl/LvglSync.h"
|
||||
#include "esp_lvgl_port.h"
|
||||
|
||||
#define TAG "core2"
|
||||
|
||||
// LVGL
|
||||
// The minimum task stack seems to be about 3500, but that crashes the wifi app in some scenarios
|
||||
// At 4000, it crashes when the fps renderer is available
|
||||
#define CORE2_LVGL_TASK_STACK_DEPTH 9216
|
||||
|
||||
bool initLvgl() {
|
||||
const lvgl_port_cfg_t lvgl_cfg = {
|
||||
.task_priority = static_cast<UBaseType_t>(tt::THREAD_PRIORITY_RENDER),
|
||||
.task_stack = CORE2_LVGL_TASK_STACK_DEPTH,
|
||||
.task_affinity = -1, // core pinning
|
||||
.task_max_sleep_ms = 500,
|
||||
.timer_period_ms = 5
|
||||
};
|
||||
|
||||
TT_LOG_D(TAG, "LVGL port init");
|
||||
if (lvgl_port_init(&lvgl_cfg) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "LVGL port init failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
tt::lvgl::syncSet(&lvgl_port_lock, &lvgl_port_unlock);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
bool initLvgl();
|
||||
@@ -1,52 +0,0 @@
|
||||
#include "M5stackCore2.h"
|
||||
#include "InitBoot.h"
|
||||
#include "InitLvgl.h"
|
||||
#include "hal/Core2Display.h"
|
||||
#include "hal/Core2SdCard.h"
|
||||
#include "hal/Core2Power.h"
|
||||
|
||||
extern const tt::hal::Configuration m5stack_core2 = {
|
||||
.initBoot = initBoot,
|
||||
.initLvgl = initLvgl,
|
||||
.createDisplay = createDisplay,
|
||||
.sdcard = createSdCard(),
|
||||
.power = createPower,
|
||||
.i2c = {
|
||||
tt::hal::i2c::Configuration {
|
||||
.name = "Internal",
|
||||
.port = I2C_NUM_0,
|
||||
.initMode = tt::hal::i2c::InitByTactility,
|
||||
.canReinit = false, // Might be set to try after trying out what it does AXP and screen
|
||||
.hasMutableConfiguration = 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
|
||||
}
|
||||
},
|
||||
tt::hal::i2c::Configuration {
|
||||
.name = "External", // (Grove)
|
||||
.port = I2C_NUM_1,
|
||||
.initMode = tt::hal::i2c::InitByTactility,
|
||||
.canReinit = true,
|
||||
.hasMutableConfiguration = 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
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/Configuration.h"
|
||||
|
||||
extern const tt::hal::Configuration m5stack_core2;
|
||||
@@ -1,164 +0,0 @@
|
||||
#include "Core2Display.h"
|
||||
#include "Core2DisplayConstants.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <TactilityCore.h>
|
||||
#include <esp_lcd_panel_commands.h>
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_lcd_ili9341.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include "esp_lvgl_port.h"
|
||||
#include "Core2Touch.h"
|
||||
|
||||
#define TAG "core2_display"
|
||||
|
||||
bool Core2Display::start() {
|
||||
TT_LOG_I(TAG, "Starting");
|
||||
|
||||
const esp_lcd_panel_io_spi_config_t panel_io_config = ILI9341_PANEL_IO_SPI_CONFIG(
|
||||
CORE2_LCD_PIN_CS,
|
||||
CORE2_LCD_PIN_DC,
|
||||
nullptr,
|
||||
nullptr
|
||||
);
|
||||
|
||||
if (esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)CORE2_LCD_SPI_HOST, &panel_io_config, &ioHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to create panel");
|
||||
return false;
|
||||
}
|
||||
|
||||
const esp_lcd_panel_dev_config_t panel_config = {
|
||||
.reset_gpio_num = GPIO_NUM_NC,
|
||||
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR,
|
||||
.data_endian = LCD_RGB_DATA_ENDIAN_LITTLE,
|
||||
.bits_per_pixel = CORE2_LCD_BITS_PER_PIXEL,
|
||||
.flags = {
|
||||
.reset_active_high = false
|
||||
},
|
||||
.vendor_config = nullptr
|
||||
};
|
||||
|
||||
if (esp_lcd_new_panel_ili9341(ioHandle, &panel_config, &panelHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to create ili9341");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_reset(panelHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to reset panel");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_init(panelHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to init panel");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_mirror(panelHandle, false, false) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to set panel to mirror");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_invert_color(panelHandle, true) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to set panel to invert");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_disp_on_off(panelHandle, true) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to turn display on");
|
||||
return false;
|
||||
}
|
||||
|
||||
const lvgl_port_display_cfg_t disp_cfg = {
|
||||
.io_handle = ioHandle,
|
||||
.panel_handle = panelHandle,
|
||||
.control_handle = nullptr,
|
||||
.buffer_size = CORE2_LCD_DRAW_BUFFER_SIZE,
|
||||
.double_buffer = true,
|
||||
.trans_size = 0,
|
||||
.hres = CORE2_LCD_HORIZONTAL_RESOLUTION,
|
||||
.vres = CORE2_LCD_VERTICAL_RESOLUTION,
|
||||
.monochrome = false,
|
||||
.rotation = {
|
||||
.swap_xy = false,
|
||||
.mirror_x = false,
|
||||
.mirror_y = false,
|
||||
},
|
||||
.color_format = LV_COLOR_FORMAT_RGB565,
|
||||
.flags = {
|
||||
.buff_dma = false,
|
||||
.buff_spiram = true,
|
||||
.sw_rotate = false,
|
||||
.swap_bytes = true,
|
||||
.full_refresh = false,
|
||||
.direct_mode = false
|
||||
}
|
||||
};
|
||||
|
||||
displayHandle = lvgl_port_add_disp(&disp_cfg);
|
||||
TT_LOG_I(TAG, "Finished");
|
||||
return displayHandle != nullptr;
|
||||
}
|
||||
|
||||
bool Core2Display::stop() {
|
||||
tt_assert(displayHandle != nullptr);
|
||||
|
||||
lvgl_port_remove_disp(displayHandle);
|
||||
|
||||
if (esp_lcd_panel_del(panelHandle) != ESP_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_io_del(ioHandle) != ESP_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
displayHandle = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note:
|
||||
* The datasheet implies this should work, but it doesn't:
|
||||
* https://www.digikey.com/htmldatasheets/production/1640716/0/0/1/ILI9341-Datasheet.pdf
|
||||
*
|
||||
* This repo claims it only has 1 curve:
|
||||
* https://github.com/brucemack/hello-ili9341
|
||||
*
|
||||
* I'm leaving it in as I'm not sure if it's just my hardware that's problematic.
|
||||
*/
|
||||
void Core2Display::setGammaCurve(uint8_t index) {
|
||||
uint8_t gamma_curve;
|
||||
switch (index) {
|
||||
case 0:
|
||||
gamma_curve = 0x01;
|
||||
break;
|
||||
case 1:
|
||||
gamma_curve = 0x04;
|
||||
break;
|
||||
case 2:
|
||||
gamma_curve = 0x02;
|
||||
break;
|
||||
case 3:
|
||||
gamma_curve = 0x08;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
const uint8_t param[] = {
|
||||
gamma_curve
|
||||
};
|
||||
|
||||
if (esp_lcd_panel_io_tx_param(ioHandle , LCD_CMD_GAMSET, param, 1) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to set gamma");
|
||||
}
|
||||
}
|
||||
|
||||
tt::hal::Touch* _Nullable Core2Display::createTouch() {
|
||||
return static_cast<tt::hal::Touch*>(new Core2Touch());
|
||||
}
|
||||
|
||||
tt::hal::Display* createDisplay() {
|
||||
return static_cast<tt::hal::Display*>(new Core2Display());
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "lvgl.h"
|
||||
#include "hal/Display.h"
|
||||
|
||||
#include <esp_lcd_types.h>
|
||||
|
||||
extern lv_disp_t* displayHandle;
|
||||
|
||||
class Core2Display : public tt::hal::Display {
|
||||
|
||||
private:
|
||||
|
||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
||||
lv_display_t* displayHandle = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
bool start() override;
|
||||
|
||||
bool stop() override;
|
||||
|
||||
tt::hal::Touch* _Nullable createTouch() override;
|
||||
|
||||
bool supportsBacklightDuty() const override { return false; }
|
||||
|
||||
void setGammaCurve(uint8_t index) override;
|
||||
uint8_t getGammaCurveCount() const override { return 4; };
|
||||
|
||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
||||
};
|
||||
|
||||
tt::hal::Display* createDisplay();
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// Display
|
||||
#define CORE2_LCD_SPI_HOST SPI2_HOST
|
||||
#define CORE2_LCD_PIN_CS GPIO_NUM_5
|
||||
#define CORE2_LCD_PIN_DC GPIO_NUM_15
|
||||
#define CORE2_LCD_HORIZONTAL_RESOLUTION 320
|
||||
#define CORE2_LCD_VERTICAL_RESOLUTION 240
|
||||
#define CORE2_LCD_BITS_PER_PIXEL 16
|
||||
#define CORE2_LCD_DRAW_BUFFER_HEIGHT (CORE2_LCD_VERTICAL_RESOLUTION / 10)
|
||||
#define CORE2_LCD_DRAW_BUFFER_SIZE (CORE2_LCD_HORIZONTAL_RESOLUTION * CORE2_LCD_DRAW_BUFFER_HEIGHT * (CORE2_LCD_BITS_PER_PIXEL / 8))
|
||||
@@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/Power.h"
|
||||
#include <memory>
|
||||
|
||||
using namespace tt::hal;
|
||||
|
||||
class Core2Power : public Power {
|
||||
|
||||
public:
|
||||
|
||||
Core2Power() = default;
|
||||
~Core2Power() override = default;
|
||||
|
||||
bool supportsMetric(MetricType type) const override;
|
||||
bool getMetric(Power::MetricType type, Power::MetricData& data) override;
|
||||
|
||||
bool supportsChargeControl() const override { return true; }
|
||||
bool isAllowedToCharge() const override;
|
||||
void setAllowedToCharge(bool canCharge) override;
|
||||
};
|
||||
|
||||
std::shared_ptr<Power> createPower();
|
||||
@@ -1,31 +0,0 @@
|
||||
#include "Core2SdCard.h"
|
||||
|
||||
#include "lvgl/LvglSync.h"
|
||||
#include "hal/SpiSdCard.h"
|
||||
|
||||
#include <esp_vfs_fat.h>
|
||||
|
||||
#define CORE2_SDCARD_SPI_FREQUENCY 800000U
|
||||
#define CORE2_SDCARD_PIN_CS GPIO_NUM_4
|
||||
#define CORE2_LCD_PIN_CS GPIO_NUM_5
|
||||
|
||||
std::shared_ptr<SdCard> createSdCard() {
|
||||
auto* configuration = new tt::hal::SpiSdCard::Config(
|
||||
CORE2_SDCARD_SPI_FREQUENCY,
|
||||
CORE2_SDCARD_PIN_CS,
|
||||
GPIO_NUM_NC,
|
||||
GPIO_NUM_NC,
|
||||
GPIO_NUM_NC,
|
||||
SdCard::MountBehaviourAtBoot,
|
||||
tt::lvgl::getLvglSyncLockable(),
|
||||
{
|
||||
CORE2_LCD_PIN_CS
|
||||
}
|
||||
);
|
||||
|
||||
auto* sdcard = (SdCard*) new SpiSdCard(
|
||||
std::unique_ptr<SpiSdCard::Config>(configuration)
|
||||
);
|
||||
|
||||
return std::shared_ptr<SdCard>(sdcard);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/SdCard.h"
|
||||
|
||||
using namespace tt::hal;
|
||||
|
||||
std::shared_ptr<SdCard> createSdCard();
|
||||
@@ -1,94 +0,0 @@
|
||||
#include "Core2Touch.h"
|
||||
#include <esp_lvgl_port.h>
|
||||
|
||||
#define TAG "core2_touch"
|
||||
|
||||
static void touchReadCallback(lv_indev_t* indev, lv_indev_data_t* data) {
|
||||
auto* touch = (Core2Touch*)lv_indev_get_driver_data(indev);
|
||||
touch->readLast(data);
|
||||
}
|
||||
|
||||
static int32_t threadCallback(void* context) {
|
||||
auto* touch = (Core2Touch*)context;
|
||||
touch->driverThreadMain();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Core2Touch::Core2Touch() :
|
||||
driverThread(tt::Thread("core2_touch", 4096, threadCallback, this))
|
||||
{ }
|
||||
|
||||
void Core2Touch::driverThreadMain() {
|
||||
TPoint point = { .x = 0, .y = 0 };
|
||||
TEvent event = TEvent::None;
|
||||
|
||||
while (!shouldInterruptDriverThread()) {
|
||||
driver.processTouch();
|
||||
driver.poll(&point, &event);
|
||||
|
||||
if (mutex.lock(100)) {
|
||||
switch (event) {
|
||||
case TEvent::TouchStart:
|
||||
case TEvent::TouchMove:
|
||||
case TEvent::DragStart:
|
||||
case TEvent::DragMove:
|
||||
case TEvent::DragEnd:
|
||||
lastState = LV_INDEV_STATE_PR;
|
||||
lastPoint.x = point.x;
|
||||
lastPoint.y = point.y;
|
||||
break;
|
||||
case TEvent::TouchEnd:
|
||||
lastState = LV_INDEV_STATE_REL;
|
||||
lastPoint.x = point.x;
|
||||
lastPoint.y = point.y;
|
||||
break;
|
||||
case TEvent::Tap:
|
||||
case TEvent::None:
|
||||
break;
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Core2Touch::shouldInterruptDriverThread() {
|
||||
bool interrupt = false;
|
||||
if (mutex.lock(50 / portTICK_PERIOD_MS)) {
|
||||
interrupt = interruptDriverThread;
|
||||
mutex.unlock();
|
||||
}
|
||||
return interrupt;
|
||||
}
|
||||
|
||||
bool Core2Touch::start(lv_display_t* display) {
|
||||
TT_LOG_I(TAG, "start");
|
||||
|
||||
driverThread.start();
|
||||
|
||||
uint16_t width = lv_display_get_horizontal_resolution(display);
|
||||
uint16_t height = lv_display_get_vertical_resolution(display);
|
||||
if (!driver.begin(FT6X36_DEFAULT_THRESHOLD, width, height)) {
|
||||
TT_LOG_E(TAG, "driver.begin() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
deviceHandle = lv_indev_create();
|
||||
lv_indev_set_type(deviceHandle, LV_INDEV_TYPE_POINTER);
|
||||
lv_indev_set_driver_data(deviceHandle, this);
|
||||
lv_indev_set_read_cb(deviceHandle, touchReadCallback);
|
||||
|
||||
TT_LOG_I(TAG, "start success");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Core2Touch::stop() {
|
||||
lv_indev_delete(deviceHandle);
|
||||
interruptDriverThread = true;
|
||||
driverThread.join();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Core2Touch::readLast(lv_indev_data_t* data) {
|
||||
data->point = lastPoint;
|
||||
data->state = lastState;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/Touch.h"
|
||||
#include "TactilityCore.h"
|
||||
#include "ft6x36/FT6X36.h"
|
||||
|
||||
class Core2Touch : public tt::hal::Touch {
|
||||
|
||||
private:
|
||||
|
||||
lv_indev_t* _Nullable deviceHandle = nullptr;
|
||||
FT6X36 driver = FT6X36(I2C_NUM_0, GPIO_NUM_39);
|
||||
tt::Thread driverThread;
|
||||
bool interruptDriverThread = false;
|
||||
tt::Mutex mutex;
|
||||
|
||||
lv_point_t lastPoint = { .x = 0, .y = 0 };
|
||||
lv_indev_state_t lastState = LV_INDEV_STATE_RELEASED;
|
||||
|
||||
bool shouldInterruptDriverThread();
|
||||
|
||||
public:
|
||||
|
||||
Core2Touch();
|
||||
|
||||
bool start(lv_display_t* display) override;
|
||||
bool stop() override;
|
||||
|
||||
void readLast(lv_indev_data_t* data);
|
||||
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
||||
void driverThreadMain();
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
idf_component_register(
|
||||
SRC_DIRS "Source" "Source/hal" "Source/Axp2101"
|
||||
INCLUDE_DIRS "Source"
|
||||
REQUIRES Tactility esp_lvgl_port esp_lcd esp_lcd_ili9341 esp_lcd_touch_ft5x06 driver vfs fatfs
|
||||
)
|
||||
@@ -1,74 +0,0 @@
|
||||
#include "Axp2101.h"
|
||||
#include "Log.h"
|
||||
|
||||
bool Axp2101::readRegister12(uint8_t reg, float& out) const {
|
||||
std::uint8_t data[2] = {0};
|
||||
if (tt::hal::i2c::masterRead(port, DEFAULT_ADDRESS, reg, data, 2, DEFAULT_TIMEOUT) == ESP_OK) {
|
||||
out = (data[0] & 0x0F) << 8 | data[1];
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Axp2101::readRegister14(uint8_t reg, float& out) const {
|
||||
std::uint8_t data[2] = {0};
|
||||
if (tt::hal::i2c::masterRead(port, DEFAULT_ADDRESS, reg, data, 2, DEFAULT_TIMEOUT) == ESP_OK) {
|
||||
out = (data[0] & 0x3F) << 8 | data[1];
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Axp2101::readRegister16(uint8_t reg, uint16_t& out) const {
|
||||
std::uint8_t data[2] = {0};
|
||||
if (tt::hal::i2c::masterRead(port, DEFAULT_ADDRESS, reg, data, 2, DEFAULT_TIMEOUT) == ESP_OK) {
|
||||
out = data[0] << 8 | data[1];
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Axp2101::readRegister8(uint8_t reg, uint8_t& result) const {
|
||||
return tt::hal::i2c::masterWriteRead(port, DEFAULT_ADDRESS, ®, 1, &result, 1, DEFAULT_TIMEOUT);
|
||||
}
|
||||
|
||||
bool Axp2101::writeRegister8(uint8_t reg, uint8_t value) const {
|
||||
return tt::hal::i2c::masterWrite(port, DEFAULT_ADDRESS, reg, &value, 1, DEFAULT_TIMEOUT);
|
||||
}
|
||||
|
||||
bool Axp2101::getBatteryVoltage(float& vbatMillis) const {
|
||||
return readRegister14(0x34, vbatMillis);
|
||||
}
|
||||
|
||||
bool Axp2101::getChargeStatus(ChargeStatus& status) const {
|
||||
uint8_t value;
|
||||
if (readRegister8(0x01, value)) {
|
||||
value = (value >> 5) & 0b11;
|
||||
status = (value == 1) ? CHARGE_STATUS_CHARGING : ((value == 2) ? CHARGE_STATUS_DISCHARGING : CHARGE_STATUS_STANDBY);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Axp2101::isChargingEnabled(bool& enabled) const {
|
||||
uint8_t value;
|
||||
if (readRegister8(0x18, value)) {
|
||||
enabled = value & 0b10;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Axp2101::setChargingEnabled(bool enabled) const {
|
||||
uint8_t value;
|
||||
if (readRegister8(0x18, value)) {
|
||||
return writeRegister8(0x18, (value & 0xFD) | (enabled << 1));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define AXP2101_ADDRESS 0x34
|
||||
#define AW9523_ADDRESS 0x58
|
||||
@@ -1,104 +0,0 @@
|
||||
#include <driver/i2c.h>
|
||||
#include <driver/spi_master.h>
|
||||
#include <intr_types.h>
|
||||
#include "Log.h"
|
||||
#include "hal/CoreS3DisplayConstants.h"
|
||||
#include "hal/i2c/I2c.h"
|
||||
#include "CoreS3Constants.h"
|
||||
|
||||
#define TAG "core2"
|
||||
|
||||
#define CORES3_SPI2_PIN_SCLK GPIO_NUM_36
|
||||
#define CORES3_SPI2_PIN_MOSI GPIO_NUM_37
|
||||
#define CORES3_SPI2_PIN_MISO GPIO_NUM_35
|
||||
|
||||
/**
|
||||
* For details see https://github.com/espressif/esp-bsp/blob/master/bsp/m5stack_core_s3/m5stack_core_s3.c
|
||||
*/
|
||||
static bool initSpi3() {
|
||||
TT_LOG_I(TAG, LOG_MESSAGE_SPI_INIT_START_FMT, SPI3_HOST);
|
||||
const spi_bus_config_t bus_config = {
|
||||
.mosi_io_num = CORES3_SPI2_PIN_MOSI,
|
||||
.miso_io_num = CORES3_SPI2_PIN_MISO,
|
||||
.sclk_io_num = CORES3_SPI2_PIN_SCLK,
|
||||
.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,
|
||||
.max_transfer_sz = CORES3_LCD_DRAW_BUFFER_SIZE,
|
||||
.flags = 0,
|
||||
.isr_cpu_id = INTR_CPU_ID_AUTO,
|
||||
.intr_flags = 0
|
||||
};
|
||||
|
||||
if (spi_bus_initialize(SPI3_HOST, &bus_config, SPI_DMA_CH_AUTO) != ESP_OK) {
|
||||
TT_LOG_E(TAG, LOG_MESSAGE_SPI_INIT_FAILED_FMT, SPI3_HOST);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* For details see https://github.com/espressif/esp-bsp/blob/master/bsp/m5stack_core_s3/m5stack_core_s3.c
|
||||
*/
|
||||
bool initGpioExpander() {
|
||||
TT_LOG_I(TAG, "Init AW9523 GPIO expander");
|
||||
uint8_t aw9523_P0 = 0b10;
|
||||
uint8_t aw9523_P1 = 0b10100000;
|
||||
|
||||
// Enable LCD
|
||||
aw9523_P1 |= (1 << 1);
|
||||
|
||||
// Enable touch
|
||||
aw9523_P0 |= (1);
|
||||
|
||||
// SD card
|
||||
aw9523_P0 |= (1 << 4);
|
||||
|
||||
if (!tt::hal::i2c::masterWrite(I2C_NUM_0, AW9523_ADDRESS, 0x02, &aw9523_P0, 1, 1000)) {
|
||||
TT_LOG_E(TAG, "Failed to enable LCD");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tt::hal::i2c::masterWrite(I2C_NUM_0, AW9523_ADDRESS, 0x03, &aw9523_P1, 1, 1000)) {
|
||||
TT_LOG_E(TAG, "Failed to enable touch");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initPowerControl() {
|
||||
TT_LOG_I(TAG, "Init power control");
|
||||
|
||||
uint8_t sdcard_3v3 = 0b00011100;
|
||||
// TODO: Refactor to use Axp2101 class with https://github.com/m5stack/M5Unified/blob/b8cfec7fed046242da7f7b8024a4e92004a51ff7/src/utility/AXP2101_Class.cpp#L62
|
||||
if (!tt::hal::i2c::masterWrite(I2C_NUM_0, AXP2101_ADDRESS, 0x95, &sdcard_3v3, 1, 1000)) {
|
||||
TT_LOG_E(TAG, "Failed to enable SD card");
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Refactor to use Axp2102 class with https://github.com/m5stack/M5Unified/blob/b8cfec7fed046242da7f7b8024a4e92004a51ff7/src/utility/AXP2101_Class.cpp#L42
|
||||
uint8_t axp_dld01_enable = 0xBF; // For backlight
|
||||
if (!tt::hal::i2c::masterWrite(I2C_NUM_0, AXP2101_ADDRESS, 0x90, &axp_dld01_enable, 1, 1000)) {
|
||||
TT_LOG_E(TAG, "Failed to enable display backlight");
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Refactor to use Axp2101 class with https://github.com/m5stack/M5Unified/blob/b8cfec7fed046242da7f7b8024a4e92004a51ff7/src/utility/AXP2101_Class.cpp#L62
|
||||
uint8_t axp_dld01_voltage = 0b00011000; // For backlight
|
||||
if (!tt::hal::i2c::masterWrite(I2C_NUM_0, AXP2101_ADDRESS, 0x99, &axp_dld01_voltage, 1, 1000)) {
|
||||
TT_LOG_E(TAG, "Failed to set display backlight voltage");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initBoot() {
|
||||
TT_LOG_I(TAG, "initBoot");
|
||||
return initPowerControl() && initGpioExpander() && initSpi3();
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
bool initBoot();
|
||||
@@ -1,31 +0,0 @@
|
||||
#include "Log.h"
|
||||
#include "Thread.h"
|
||||
#include "lvgl/LvglSync.h"
|
||||
#include "esp_lvgl_port.h"
|
||||
|
||||
#define TAG "core2"
|
||||
|
||||
// LVGL
|
||||
// The minimum task stack seems to be about 3500, but that crashes the wifi app in some scenarios
|
||||
// At 4000, it crashes when the fps renderer is available
|
||||
#define CORE2_LVGL_TASK_STACK_DEPTH 9216
|
||||
|
||||
bool initLvgl() {
|
||||
const lvgl_port_cfg_t lvgl_cfg = {
|
||||
.task_priority = static_cast<UBaseType_t>(tt::THREAD_PRIORITY_RENDER),
|
||||
.task_stack = CORE2_LVGL_TASK_STACK_DEPTH,
|
||||
.task_affinity = -1, // core pinning
|
||||
.task_max_sleep_ms = 500,
|
||||
.timer_period_ms = 5
|
||||
};
|
||||
|
||||
TT_LOG_D(TAG, "LVGL port init");
|
||||
if (lvgl_port_init(&lvgl_cfg) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "LVGL port init failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
tt::lvgl::syncSet(&lvgl_port_lock, &lvgl_port_unlock);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
bool initLvgl();
|
||||
@@ -1,52 +0,0 @@
|
||||
#include "M5stackCoreS3.h"
|
||||
#include "InitBoot.h"
|
||||
#include "InitLvgl.h"
|
||||
#include "hal/CoreS3Display.h"
|
||||
#include "hal/CoreS3SdCard.h"
|
||||
#include "hal/CoreS3Power.h"
|
||||
|
||||
const tt::hal::Configuration m5stack_cores3 = {
|
||||
.initBoot = initBoot,
|
||||
.initLvgl = initLvgl,
|
||||
.createDisplay = createDisplay,
|
||||
.sdcard = createSdCard(),
|
||||
.power = createPower,
|
||||
.i2c = {
|
||||
tt::hal::i2c::Configuration {
|
||||
.name = "Internal",
|
||||
.port = I2C_NUM_0,
|
||||
.initMode = tt::hal::i2c::InitByTactility,
|
||||
.canReinit = false,
|
||||
.hasMutableConfiguration = 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
|
||||
}
|
||||
},
|
||||
tt::hal::i2c::Configuration {
|
||||
.name = "External", // Grove
|
||||
.port = I2C_NUM_1,
|
||||
.initMode = tt::hal::i2c::InitByTactility,
|
||||
.canReinit = true,
|
||||
.hasMutableConfiguration = 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
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/Configuration.h"
|
||||
|
||||
extern const tt::hal::Configuration m5stack_cores3;
|
||||
@@ -1,35 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "lvgl.h"
|
||||
#include "hal/Display.h"
|
||||
|
||||
#include <esp_lcd_types.h>
|
||||
|
||||
extern lv_disp_t* displayHandle;
|
||||
|
||||
class CoreS3Display : public tt::hal::Display {
|
||||
|
||||
private:
|
||||
|
||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
||||
lv_display_t* displayHandle = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
bool start() override;
|
||||
|
||||
bool stop() override;
|
||||
|
||||
tt::hal::Touch* _Nullable createTouch() override;
|
||||
|
||||
void setBacklightDuty(uint8_t backlightDuty) override;
|
||||
bool supportsBacklightDuty() const override { return true; }
|
||||
|
||||
void setGammaCurve(uint8_t index) override;
|
||||
uint8_t getGammaCurveCount() const override { return 4; };
|
||||
|
||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
||||
};
|
||||
|
||||
tt::hal::Display* createDisplay();
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// Display
|
||||
#define CORES3_LCD_SPI_HOST SPI3_HOST
|
||||
#define CORES3_LCD_PIN_CS GPIO_NUM_3
|
||||
#define CORES3_LCD_PIN_DC GPIO_NUM_35
|
||||
#define CORES3_LCD_HORIZONTAL_RESOLUTION 320
|
||||
#define CORES3_LCD_VERTICAL_RESOLUTION 240
|
||||
#define CORES3_LCD_BITS_PER_PIXEL 16
|
||||
#define CORES3_LCD_DRAW_BUFFER_HEIGHT (CORES3_LCD_VERTICAL_RESOLUTION / 10)
|
||||
#define CORES3_LCD_DRAW_BUFFER_SIZE (CORES3_LCD_HORIZONTAL_RESOLUTION * CORES3_LCD_DRAW_BUFFER_HEIGHT * (CORES3_LCD_BITS_PER_PIXEL / 8))
|
||||
@@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/Power.h"
|
||||
#include "Axp2101/Axp2101.h"
|
||||
#include <memory>
|
||||
|
||||
using namespace tt::hal;
|
||||
|
||||
class CoreS3Power : public Power {
|
||||
|
||||
Axp2101 axpDevice = Axp2101(I2C_NUM_0);
|
||||
|
||||
public:
|
||||
|
||||
CoreS3Power() = default;
|
||||
~CoreS3Power() override = default;
|
||||
|
||||
bool supportsMetric(MetricType type) const override;
|
||||
bool getMetric(Power::MetricType type, Power::MetricData& data) override;
|
||||
|
||||
bool supportsChargeControl() const override { return true; }
|
||||
bool isAllowedToCharge() const override;
|
||||
void setAllowedToCharge(bool canCharge) override;
|
||||
};
|
||||
|
||||
std::shared_ptr<Power> createPower();
|
||||
@@ -1,32 +0,0 @@
|
||||
#include "CoreS3SdCard.h"
|
||||
|
||||
#include "lvgl/LvglSync.h"
|
||||
#include "hal/SpiSdCard.h"
|
||||
|
||||
#include <esp_vfs_fat.h>
|
||||
|
||||
#define CORES3_SDCARD_SPI_FREQUENCY 800000U
|
||||
#define CORES3_SDCARD_PIN_CS GPIO_NUM_4
|
||||
#define CORES3_LCD_PIN_CS GPIO_NUM_3
|
||||
|
||||
std::shared_ptr<SdCard> createSdCard() {
|
||||
auto* configuration = new tt::hal::SpiSdCard::Config(
|
||||
CORES3_SDCARD_SPI_FREQUENCY,
|
||||
CORES3_SDCARD_PIN_CS,
|
||||
GPIO_NUM_NC,
|
||||
GPIO_NUM_NC,
|
||||
GPIO_NUM_NC,
|
||||
SdCard::MountBehaviourAtBoot,
|
||||
tt::lvgl::getLvglSyncLockable(),
|
||||
{
|
||||
CORES3_LCD_PIN_CS
|
||||
},
|
||||
SPI3_HOST
|
||||
);
|
||||
|
||||
auto* sdcard = (SdCard*) new SpiSdCard(
|
||||
std::unique_ptr<SpiSdCard::Config>(configuration)
|
||||
);
|
||||
|
||||
return std::shared_ptr<SdCard>(sdcard);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/SdCard.h"
|
||||
|
||||
using namespace tt::hal;
|
||||
|
||||
std::shared_ptr<SdCard> createSdCard();
|
||||
@@ -1,83 +0,0 @@
|
||||
#include "CoreS3Touch.h"
|
||||
#include "Log.h"
|
||||
#include "driver/i2c.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_lcd_touch_ft5x06.h"
|
||||
#include "esp_lcd_touch.h"
|
||||
#include "esp_lvgl_port.h"
|
||||
|
||||
#define TAG "cores3_touch"
|
||||
|
||||
bool CoreS3Touch::start(lv_display_t* display) {
|
||||
TT_LOG_I(TAG, "Starting");
|
||||
|
||||
esp_lcd_panel_io_i2c_config_t touch_io_config = ESP_LCD_TOUCH_IO_I2C_FT5x06_CONFIG();
|
||||
|
||||
if (esp_lcd_new_panel_io_i2c(I2C_NUM_0, &touch_io_config, &ioHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Touch I2C IO init failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_lcd_touch_config_t config = {
|
||||
.x_max = 320,
|
||||
.y_max = 240,
|
||||
.rst_gpio_num = GPIO_NUM_NC,
|
||||
.int_gpio_num = GPIO_NUM_NC,
|
||||
.levels = {
|
||||
.reset = 0,
|
||||
.interrupt = 0,
|
||||
},
|
||||
.flags = {
|
||||
.swap_xy = 0,
|
||||
.mirror_x = 0,
|
||||
.mirror_y = 0,
|
||||
},
|
||||
.process_coordinates = nullptr,
|
||||
.interrupt_callback = nullptr,
|
||||
.user_data = nullptr,
|
||||
.driver_data = nullptr
|
||||
};
|
||||
|
||||
if (esp_lcd_touch_new_i2c_ft5x06(ioHandle, &config, &touchHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Driver init failed");
|
||||
cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
const lvgl_port_touch_cfg_t touch_cfg = {
|
||||
.disp = display,
|
||||
.handle = touchHandle,
|
||||
};
|
||||
|
||||
deviceHandle = lvgl_port_add_touch(&touch_cfg);
|
||||
if (deviceHandle == nullptr) {
|
||||
TT_LOG_E(TAG, "Adding touch failed");
|
||||
cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
TT_LOG_I(TAG, "Finished");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CoreS3Touch::stop() {
|
||||
cleanup();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CoreS3Touch::cleanup() {
|
||||
if (deviceHandle != nullptr) {
|
||||
lv_indev_delete(deviceHandle);
|
||||
deviceHandle = nullptr;
|
||||
}
|
||||
|
||||
if (touchHandle != nullptr) {
|
||||
esp_lcd_touch_del(touchHandle);
|
||||
touchHandle = nullptr;
|
||||
}
|
||||
|
||||
if (ioHandle != nullptr) {
|
||||
esp_lcd_panel_io_del(ioHandle);
|
||||
ioHandle = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/Touch.h"
|
||||
#include "TactilityCore.h"
|
||||
#include <esp_lcd_touch.h>
|
||||
|
||||
class CoreS3Touch : public tt::hal::Touch {
|
||||
private:
|
||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
||||
esp_lcd_touch_handle_t touchHandle = nullptr;
|
||||
lv_indev_t* _Nullable deviceHandle = nullptr;
|
||||
void cleanup();
|
||||
public:
|
||||
bool start(lv_display_t* display) override;
|
||||
bool stop() override;
|
||||
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
||||
};
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "SdlTouch.h"
|
||||
#include "hal/Display.h"
|
||||
|
||||
extern lv_disp_t* displayHandle;
|
||||
|
||||
class SdlDisplay : public tt::hal::Display {
|
||||
public:
|
||||
bool start() override {
|
||||
return displayHandle != nullptr;
|
||||
}
|
||||
|
||||
bool stop() override { tt_crash("Not supported"); }
|
||||
|
||||
tt::hal::Touch* _Nullable createTouch() override { return dynamic_cast<tt::hal::Touch*>(new SdlTouch()); }
|
||||
|
||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
||||
};
|
||||
|
||||
tt::hal::Display* createDisplay() {
|
||||
return static_cast<tt::hal::Display*>(new SdlDisplay());
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/Keyboard.h"
|
||||
|
||||
#include <TactilityCore.h>
|
||||
|
||||
class SdlKeyboard : public tt::hal::Keyboard {
|
||||
private:
|
||||
lv_indev_t* _Nullable handle = nullptr;
|
||||
|
||||
public:
|
||||
bool start(lv_display_t* display) override {
|
||||
handle = lv_sdl_keyboard_create();
|
||||
return handle != nullptr;
|
||||
}
|
||||
|
||||
bool stop() override { tt_crash("Not supported"); }
|
||||
|
||||
bool isAttached() const override { return true; }
|
||||
|
||||
lv_indev_t* _Nullable getLvglIndev() override { return handle; }
|
||||
};
|
||||
|
||||
tt::hal::Keyboard* createKeyboard() {
|
||||
return static_cast<tt::hal::Keyboard*>(new SdlKeyboard());
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/Touch.h"
|
||||
|
||||
#include <TactilityCore.h>
|
||||
|
||||
class SdlTouch : public tt::hal::Touch {
|
||||
private:
|
||||
lv_indev_t* _Nullable handle = nullptr;
|
||||
|
||||
public:
|
||||
bool start(lv_display_t* display) override {
|
||||
handle = lv_sdl_mouse_create();
|
||||
return handle != nullptr;
|
||||
}
|
||||
|
||||
bool stop() override { tt_crash("Not supported"); }
|
||||
|
||||
lv_indev_t* _Nullable getLvglIndev() override { return handle; }
|
||||
};
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/SdCard.h"
|
||||
|
||||
using namespace tt::hal;
|
||||
|
||||
class SimulatorSdCard : public SdCard {
|
||||
private:
|
||||
State state;
|
||||
public:
|
||||
SimulatorSdCard() : SdCard(MountBehaviourAtBoot), state(StateUnmounted) {}
|
||||
|
||||
bool mount(const char* mountPath) override {
|
||||
state = StateMounted;
|
||||
return true;
|
||||
}
|
||||
bool unmount() override {
|
||||
state = StateUnmounted;
|
||||
return true;
|
||||
}
|
||||
|
||||
State getState() const override {
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
idf_component_register(
|
||||
SRC_DIRS "Source" "Source/hal"
|
||||
INCLUDE_DIRS "Source"
|
||||
REQUIRES Tactility esp_lvgl_port esp_lcd_touch_cst816s esp_lcd_ili9341 driver vfs fatfs
|
||||
)
|
||||
@@ -1,84 +0,0 @@
|
||||
#include "YellowConfig.h"
|
||||
#include "TactilityCore.h"
|
||||
#include "hal/YellowTouchConstants.h"
|
||||
#include <driver/spi_common.h>
|
||||
|
||||
#define TAG "twodotfour_bootstrap"
|
||||
|
||||
static bool init_i2c() {
|
||||
TT_LOG_I(TAG, LOG_MESSAGE_I2C_INIT_START);
|
||||
|
||||
const i2c_config_t i2c_conf = {
|
||||
.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
|
||||
}
|
||||
};
|
||||
|
||||
if (i2c_param_config(TWODOTFOUR_TOUCH_I2C_PORT, &i2c_conf) != ESP_OK) {
|
||||
TT_LOG_E(TAG, LOG_MESSAGE_I2C_INIT_CONFIG_FAILED );
|
||||
return false;
|
||||
}
|
||||
|
||||
if (i2c_driver_install(TWODOTFOUR_TOUCH_I2C_PORT, i2c_conf.mode, 0, 0, 0) != ESP_OK) {
|
||||
TT_LOG_E(TAG, LOG_MESSAGE_I2C_INIT_DRIVER_INSTALL_FAILED);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool init_spi2() {
|
||||
TT_LOG_I(TAG, LOG_MESSAGE_SPI_INIT_START_FMT, SPI2_HOST);
|
||||
|
||||
const spi_bus_config_t bus_config = {
|
||||
.mosi_io_num = TWODOTFOUR_SPI2_PIN_MOSI,
|
||||
.miso_io_num = GPIO_NUM_NC,
|
||||
.sclk_io_num = TWODOTFOUR_SPI2_PIN_SCLK,
|
||||
.quadwp_io_num = GPIO_NUM_NC,
|
||||
.quadhd_io_num = GPIO_NUM_NC,
|
||||
.max_transfer_sz = TWODOTFOUR_SPI2_TRANSACTION_LIMIT
|
||||
};
|
||||
|
||||
if (spi_bus_initialize(SPI2_HOST, &bus_config, SPI_DMA_CH_AUTO) != ESP_OK) {
|
||||
TT_LOG_E(TAG, LOG_MESSAGE_SPI_INIT_FAILED_FMT, SPI2_HOST);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool init_spi3() {
|
||||
TT_LOG_I(TAG, LOG_MESSAGE_SPI_INIT_START_FMT, SPI3_HOST);
|
||||
|
||||
const spi_bus_config_t bus_config = {
|
||||
.mosi_io_num = TWODOTFOUR_SPI3_PIN_MOSI,
|
||||
.miso_io_num = TWODOTFOUR_SPI3_PIN_MISO,
|
||||
.sclk_io_num = TWODOTFOUR_SPI3_PIN_SCLK,
|
||||
.quadwp_io_num = GPIO_NUM_NC,
|
||||
.quadhd_io_num = GPIO_NUM_NC,
|
||||
.data4_io_num = 0,
|
||||
.data5_io_num = 0,
|
||||
.data6_io_num = 0,
|
||||
.data7_io_num = 0,
|
||||
.max_transfer_sz = TWODOTFOUR_SPI3_TRANSACTION_LIMIT,
|
||||
.flags = 0,
|
||||
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
|
||||
.intr_flags = 0
|
||||
};
|
||||
|
||||
if (spi_bus_initialize(SPI3_HOST, &bus_config, SPI_DMA_CH_AUTO) != ESP_OK) {
|
||||
TT_LOG_E(TAG, LOG_MESSAGE_SPI_INIT_FAILED_FMT, SPI3_HOST);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool twodotfour_boot() {
|
||||
return init_i2c() && init_spi2() && init_spi3();
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#include "esp_lvgl_port.h"
|
||||
#include "Log.h"
|
||||
#include "lvgl/LvglSync.h"
|
||||
#include "Thread.h"
|
||||
|
||||
#define TAG "twodotfour_lvgl"
|
||||
|
||||
bool twodotfour_lvgl_init() {
|
||||
const lvgl_port_cfg_t lvgl_cfg = {
|
||||
.task_priority = static_cast<UBaseType_t>(tt::THREAD_PRIORITY_RENDER),
|
||||
.task_stack = 8096,
|
||||
.task_affinity = -1, // core pinning
|
||||
.task_max_sleep_ms = 500,
|
||||
.timer_period_ms = 5
|
||||
};
|
||||
|
||||
if (lvgl_port_init(&lvgl_cfg) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "lvgl port init failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set syncing functions
|
||||
tt::lvgl::syncSet(&lvgl_port_lock, &lvgl_port_unlock);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
#include "YellowBoard.h"
|
||||
#include "hal/YellowDisplay.h"
|
||||
#include "hal/YellowSdCard.h"
|
||||
|
||||
bool twodotfour_lvgl_init();
|
||||
bool twodotfour_boot();
|
||||
|
||||
const tt::hal::Configuration yellow_board_24inch_cap = {
|
||||
.initBoot = &twodotfour_boot,
|
||||
.initLvgl = &twodotfour_lvgl_init,
|
||||
.createDisplay = createDisplay,
|
||||
.sdcard = createYellowSdCard(),
|
||||
.power = nullptr,
|
||||
.i2c = {
|
||||
tt::hal::i2c::Configuration {
|
||||
.name = "First",
|
||||
.port = I2C_NUM_0,
|
||||
.initMode = tt::hal::i2c::InitDisabled,
|
||||
.canReinit = true,
|
||||
.hasMutableConfiguration = 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
|
||||
}
|
||||
},
|
||||
tt::hal::i2c::Configuration {
|
||||
.name = "Second",
|
||||
.port = I2C_NUM_1,
|
||||
.initMode = tt::hal::i2c::InitDisabled,
|
||||
.canReinit = true,
|
||||
.hasMutableConfiguration = 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
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/Configuration.h"
|
||||
|
||||
// Capacitive touch version of the 2.4" yellow board
|
||||
extern const tt::hal::Configuration yellow_board_24inch_cap;
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "driver/spi_common.h"
|
||||
#include "driver/i2c.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "hal/YellowDisplayConstants.h"
|
||||
|
||||
// SPI 2 - display
|
||||
#define TWODOTFOUR_SPI2_PIN_SCLK GPIO_NUM_14
|
||||
#define TWODOTFOUR_SPI2_PIN_MOSI GPIO_NUM_13
|
||||
#define TWODOTFOUR_SPI2_TRANSACTION_LIMIT TWODOTFOUR_LCD_DRAW_BUFFER_SIZE
|
||||
|
||||
// SPI 3 - sdcard
|
||||
#define TWODOTFOUR_SPI3_PIN_SCLK GPIO_NUM_18
|
||||
#define TWODOTFOUR_SPI3_PIN_MOSI GPIO_NUM_23
|
||||
#define TWODOTFOUR_SPI3_PIN_MISO GPIO_NUM_19
|
||||
#define TWODOTFOUR_SPI3_TRANSACTION_LIMIT 8192 // TODO: Determine proper limit
|
||||
@@ -1,213 +0,0 @@
|
||||
#include "YellowDisplay.h"
|
||||
#include "YellowDisplayConstants.h"
|
||||
#include "YellowTouch.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <TactilityCore.h>
|
||||
#include <esp_lcd_panel_commands.h>
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/ledc.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_lcd_ili9341.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include "esp_lvgl_port.h"
|
||||
|
||||
#define TAG "yellow_display"
|
||||
|
||||
static bool isBacklightInitialized = false;
|
||||
|
||||
static bool initBacklight() {
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = TWODOTFOUR_LCD_BACKLIGHT_LEDC_MODE,
|
||||
.duty_resolution = TWODOTFOUR_LCD_BACKLIGHT_LEDC_DUTY_RES,
|
||||
.timer_num = TWODOTFOUR_LCD_BACKLIGHT_LEDC_TIMER,
|
||||
.freq_hz = TWODOTFOUR_LCD_BACKLIGHT_LEDC_FREQUENCY,
|
||||
.clk_cfg = LEDC_AUTO_CLK,
|
||||
.deconfigure = false
|
||||
};
|
||||
|
||||
if (ledc_timer_config(&ledc_timer) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Backlight led timer config failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool setBacklight(uint8_t duty) {
|
||||
ledc_channel_config_t ledc_channel = {
|
||||
.gpio_num = TWODOTFOUR_LCD_PIN_BACKLIGHT,
|
||||
.speed_mode = TWODOTFOUR_LCD_BACKLIGHT_LEDC_MODE,
|
||||
.channel = TWODOTFOUR_LCD_BACKLIGHT_LEDC_CHANNEL,
|
||||
.intr_type = LEDC_INTR_DISABLE,
|
||||
.timer_sel = TWODOTFOUR_LCD_BACKLIGHT_LEDC_TIMER,
|
||||
.duty = duty,
|
||||
.hpoint = 0,
|
||||
.flags = {
|
||||
.output_invert = false
|
||||
}
|
||||
};
|
||||
|
||||
if (ledc_channel_config(&ledc_channel) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Backlight init failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool YellowDisplay::start() {
|
||||
TT_LOG_I(TAG, "Starting");
|
||||
|
||||
const esp_lcd_panel_io_spi_config_t panel_io_config = ILI9341_PANEL_IO_SPI_CONFIG(
|
||||
TWODOTFOUR_LCD_PIN_CS,
|
||||
TWODOTFOUR_LCD_PIN_DC,
|
||||
nullptr,
|
||||
nullptr
|
||||
);
|
||||
|
||||
if (esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)TWODOTFOUR_LCD_SPI_HOST, &panel_io_config, &ioHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to create panel");
|
||||
return false;
|
||||
}
|
||||
|
||||
const esp_lcd_panel_dev_config_t panel_config = {
|
||||
.reset_gpio_num = GPIO_NUM_NC,
|
||||
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR,
|
||||
.data_endian = LCD_RGB_DATA_ENDIAN_LITTLE,
|
||||
.bits_per_pixel = TWODOTFOUR_LCD_BITS_PER_PIXEL,
|
||||
.flags = {
|
||||
.reset_active_high = false
|
||||
},
|
||||
.vendor_config = nullptr
|
||||
};
|
||||
|
||||
if (esp_lcd_new_panel_ili9341(ioHandle, &panel_config, &panelHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to create ili9341");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_reset(panelHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to reset panel");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_init(panelHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to init panel");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_mirror(panelHandle, true, false) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to set panel to mirror");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_disp_on_off(panelHandle, true) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to turn display on");
|
||||
return false;
|
||||
}
|
||||
|
||||
const lvgl_port_display_cfg_t disp_cfg = {
|
||||
.io_handle = ioHandle,
|
||||
.panel_handle = panelHandle,
|
||||
.control_handle = nullptr,
|
||||
.buffer_size = TWODOTFOUR_LCD_DRAW_BUFFER_SIZE,
|
||||
.double_buffer = false,
|
||||
.trans_size = 0,
|
||||
.hres = TWODOTFOUR_LCD_HORIZONTAL_RESOLUTION,
|
||||
.vres = TWODOTFOUR_LCD_VERTICAL_RESOLUTION,
|
||||
.monochrome = false,
|
||||
.rotation = {
|
||||
.swap_xy = false,
|
||||
.mirror_x = true,
|
||||
.mirror_y = false,
|
||||
},
|
||||
.color_format = LV_COLOR_FORMAT_RGB565,
|
||||
.flags = {
|
||||
.buff_dma = true,
|
||||
.buff_spiram = false,
|
||||
.sw_rotate = false,
|
||||
.swap_bytes = true,
|
||||
.full_refresh = false,
|
||||
.direct_mode = false
|
||||
}
|
||||
};
|
||||
|
||||
displayHandle = lvgl_port_add_disp(&disp_cfg);
|
||||
TT_LOG_I(TAG, "Finished");
|
||||
return displayHandle != nullptr;
|
||||
}
|
||||
|
||||
bool YellowDisplay::stop() {
|
||||
tt_assert(displayHandle != nullptr);
|
||||
|
||||
lvgl_port_remove_disp(displayHandle);
|
||||
|
||||
if (esp_lcd_panel_del(panelHandle) != ESP_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (esp_lcd_panel_io_del(ioHandle) != ESP_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
displayHandle = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
void YellowDisplay::setBacklightDuty(uint8_t backlightDuty) {
|
||||
if (!isBacklightInitialized) {
|
||||
tt_check(initBacklight());
|
||||
isBacklightInitialized = true;
|
||||
}
|
||||
|
||||
if (!setBacklight(backlightDuty)) {
|
||||
TT_LOG_E(TAG, "Failed to configure display backlight");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note:
|
||||
* The datasheet implies this should work, but it doesn't:
|
||||
* https://www.digikey.com/htmldatasheets/production/1640716/0/0/1/ILI9341-Datasheet.pdf
|
||||
*
|
||||
* This repo claims it only has 1 curve:
|
||||
* https://github.com/brucemack/hello-ili9341
|
||||
*
|
||||
* I'm leaving it in as I'm not sure if it's just my hardware that's problematic.
|
||||
*/
|
||||
void YellowDisplay::setGammaCurve(uint8_t index) {
|
||||
uint8_t gamma_curve;
|
||||
switch (index) {
|
||||
case 0:
|
||||
gamma_curve = 0x01;
|
||||
break;
|
||||
case 1:
|
||||
gamma_curve = 0x04;
|
||||
break;
|
||||
case 2:
|
||||
gamma_curve = 0x02;
|
||||
break;
|
||||
case 3:
|
||||
gamma_curve = 0x08;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
const uint8_t param[] = {
|
||||
gamma_curve
|
||||
};
|
||||
|
||||
if (esp_lcd_panel_io_tx_param(ioHandle , LCD_CMD_GAMSET, param, 1) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to set gamma");
|
||||
}
|
||||
}
|
||||
|
||||
tt::hal::Touch* _Nullable YellowDisplay::createTouch() {
|
||||
return static_cast<tt::hal::Touch*>(new YellowTouch());
|
||||
}
|
||||
|
||||
tt::hal::Display* createDisplay() {
|
||||
return static_cast<tt::hal::Display*>(new YellowDisplay());
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "lvgl.h"
|
||||
#include "hal/Display.h"
|
||||
#include "esp_lcd_panel_io.h"
|
||||
|
||||
extern lv_disp_t* displayHandle;
|
||||
|
||||
class YellowDisplay : public tt::hal::Display {
|
||||
|
||||
private:
|
||||
|
||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
||||
lv_display_t* displayHandle = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
bool start() override;
|
||||
|
||||
bool stop() override;
|
||||
|
||||
tt::hal::Touch* _Nullable createTouch() override;
|
||||
|
||||
void setBacklightDuty(uint8_t backlightDuty) override;
|
||||
bool supportsBacklightDuty() const override { return true; }
|
||||
|
||||
void setGammaCurve(uint8_t index) override;
|
||||
uint8_t getGammaCurveCount() const override { return 4; };
|
||||
|
||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
||||
};
|
||||
|
||||
tt::hal::Display* createDisplay();
|
||||
@@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// Display backlight (PWM)
|
||||
#define TWODOTFOUR_LCD_BACKLIGHT_LEDC_TIMER LEDC_TIMER_0
|
||||
#define TWODOTFOUR_LCD_BACKLIGHT_LEDC_MODE LEDC_LOW_SPEED_MODE
|
||||
#define TWODOTFOUR_LCD_BACKLIGHT_LEDC_CHANNEL LEDC_CHANNEL_0
|
||||
#define TWODOTFOUR_LCD_BACKLIGHT_LEDC_DUTY_RES LEDC_TIMER_8_BIT
|
||||
#define TWODOTFOUR_LCD_BACKLIGHT_LEDC_FREQUENCY (1000)
|
||||
|
||||
#define TWODOTFOUR_LCD_PIN_BACKLIGHT GPIO_NUM_27
|
||||
|
||||
// Display
|
||||
#define TWODOTFOUR_LCD_SPI_HOST SPI2_HOST
|
||||
#define TWODOTFOUR_LCD_HORIZONTAL_RESOLUTION 240
|
||||
#define TWODOTFOUR_LCD_VERTICAL_RESOLUTION 320
|
||||
#define TWODOTFOUR_LCD_BITS_PER_PIXEL 16
|
||||
#define TWODOTFOUR_LCD_DRAW_BUFFER_HEIGHT (TWODOTFOUR_LCD_VERTICAL_RESOLUTION / 10)
|
||||
#define TWODOTFOUR_LCD_DRAW_BUFFER_SIZE (TWODOTFOUR_LCD_HORIZONTAL_RESOLUTION * TWODOTFOUR_LCD_DRAW_BUFFER_HEIGHT * (TWODOTFOUR_LCD_BITS_PER_PIXEL / 8))
|
||||
#define TWODOTFOUR_LCD_PIN_CS GPIO_NUM_15
|
||||
#define TWODOTFOUR_LCD_PIN_DC GPIO_NUM_2
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#include "YellowSdCard.h"
|
||||
|
||||
#define TAG "twodotfour_sdcard"
|
||||
|
||||
#include "lvgl/LvglSync.h"
|
||||
#include "hal/SpiSdCard.h"
|
||||
|
||||
#define SDCARD_SPI_HOST SPI3_HOST
|
||||
#define SDCARD_PIN_CS GPIO_NUM_5
|
||||
#define SDCARD_SPI_FREQUENCY 800000U
|
||||
|
||||
std::shared_ptr<SdCard> createYellowSdCard() {
|
||||
auto* configuration = new tt::hal::SpiSdCard::Config(
|
||||
SDCARD_SPI_FREQUENCY,
|
||||
SDCARD_PIN_CS,
|
||||
GPIO_NUM_NC,
|
||||
GPIO_NUM_NC,
|
||||
GPIO_NUM_NC,
|
||||
SdCard::MountBehaviourAtBoot,
|
||||
nullptr,
|
||||
std::vector<gpio_num_t>(),
|
||||
SDCARD_SPI_HOST
|
||||
);
|
||||
|
||||
auto* sdcard = (SdCard*) new SpiSdCard(
|
||||
std::unique_ptr<SpiSdCard::Config>(configuration)
|
||||
);
|
||||
|
||||
return std::shared_ptr<SdCard>(sdcard);
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/SdCard.h"
|
||||
|
||||
using namespace tt::hal;
|
||||
|
||||
std::shared_ptr<SdCard> createYellowSdCard();
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
#include "YellowTouch.h"
|
||||
#include "YellowTouchConstants.h"
|
||||
#include "Log.h"
|
||||
#include "driver/i2c.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_lcd_touch_cst816s.h"
|
||||
#include "esp_lcd_touch.h"
|
||||
#include "esp_lvgl_port.h"
|
||||
|
||||
#define TAG "twodotfour_touch"
|
||||
|
||||
bool YellowTouch::start(lv_display_t* display) {
|
||||
TT_LOG_I(TAG, "Starting");
|
||||
const esp_lcd_panel_io_i2c_config_t touch_io_config = ESP_LCD_TOUCH_IO_I2C_CST816S_CONFIG();
|
||||
|
||||
if (esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)TWODOTFOUR_TOUCH_I2C_PORT, &touch_io_config, &ioHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Touch I2C IO init failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_lcd_touch_config_t config = {
|
||||
.x_max = 240,
|
||||
.y_max = 320,
|
||||
.rst_gpio_num = GPIO_NUM_NC, //GPIO_NUM_25,
|
||||
.int_gpio_num = GPIO_NUM_NC, //GPIO_NUM_21,
|
||||
.levels = {
|
||||
.reset = 0,
|
||||
.interrupt = 0,
|
||||
},
|
||||
.flags = {
|
||||
.swap_xy = 0,
|
||||
.mirror_x = 0,
|
||||
.mirror_y = 0,
|
||||
},
|
||||
.process_coordinates = nullptr,
|
||||
.interrupt_callback = nullptr,
|
||||
.user_data = nullptr,
|
||||
.driver_data = nullptr
|
||||
};
|
||||
|
||||
if (esp_lcd_touch_new_i2c_cst816s(ioHandle, &config, &touchHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Driver init failed");
|
||||
cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
const lvgl_port_touch_cfg_t touch_cfg = {
|
||||
.disp = display,
|
||||
.handle = touchHandle,
|
||||
};
|
||||
|
||||
deviceHandle = lvgl_port_add_touch(&touch_cfg);
|
||||
if (deviceHandle == nullptr) {
|
||||
TT_LOG_E(TAG, "Adding touch failed");
|
||||
cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
TT_LOG_I(TAG, "Finished");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool YellowTouch::stop() {
|
||||
cleanup();
|
||||
return true;
|
||||
}
|
||||
|
||||
void YellowTouch::cleanup() {
|
||||
if (deviceHandle != nullptr) {
|
||||
lv_indev_delete(deviceHandle);
|
||||
deviceHandle = nullptr;
|
||||
}
|
||||
|
||||
if (touchHandle != nullptr) {
|
||||
esp_lcd_touch_del(touchHandle);
|
||||
touchHandle = nullptr;
|
||||
}
|
||||
|
||||
if (ioHandle != nullptr) {
|
||||
esp_lcd_panel_io_del(ioHandle);
|
||||
ioHandle = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/Touch.h"
|
||||
#include "TactilityCore.h"
|
||||
#include <esp_lcd_touch.h>
|
||||
|
||||
class YellowTouch : public tt::hal::Touch {
|
||||
private:
|
||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
||||
esp_lcd_touch_handle_t touchHandle = nullptr;
|
||||
lv_indev_t* _Nullable deviceHandle = nullptr;
|
||||
void cleanup();
|
||||
public:
|
||||
bool start(lv_display_t* display) override;
|
||||
bool stop() override;
|
||||
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// Touch
|
||||
#define TWODOTFOUR_TOUCH_I2C_PORT I2C_NUM_0
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
|
||||
|
||||
idf_component_register(
|
||||
SRCS ${SOURCE_FILES}
|
||||
INCLUDE_DIRS "Source"
|
||||
REQUIRES Tactility esp_lvgl_port ILI934x CST816S PwmBacklight driver vfs fatfs
|
||||
)
|
||||
@@ -0,0 +1,116 @@
|
||||
#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
|
||||
},
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "Display.h"
|
||||
#include "Cst816Touch.h"
|
||||
|
||||
#include <Ili934xDisplay.h>
|
||||
#include <PwmBacklight.h>
|
||||
|
||||
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
|
||||
// Note: GPIO 25 for reset and GPIO 21 for interrupt?
|
||||
auto configuration = std::make_unique<Cst816sTouch::Configuration>(
|
||||
I2C_NUM_0,
|
||||
240,
|
||||
320
|
||||
);
|
||||
|
||||
return std::make_shared<Cst816sTouch>(std::move(configuration));
|
||||
}
|
||||
|
||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||
Ili934xDisplay::Configuration panel_configuration = {
|
||||
.horizontalResolution = LCD_HORIZONTAL_RESOLUTION,
|
||||
.verticalResolution = LCD_VERTICAL_RESOLUTION,
|
||||
.gapX = 0,
|
||||
.gapY = 0,
|
||||
.swapXY = false,
|
||||
.mirrorX = true,
|
||||
.mirrorY = false,
|
||||
.invertColor = false,
|
||||
.swapBytes = true,
|
||||
.bufferSize = LCD_BUFFER_SIZE,
|
||||
.touch = createTouch(),
|
||||
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
||||
.resetPin = GPIO_NUM_NC,
|
||||
.rgbElementOrder = LCD_RGB_ELEMENT_ORDER_BGR
|
||||
};
|
||||
|
||||
auto spi_configuration = std::make_shared<Ili934xDisplay::SpiConfiguration>(Ili934xDisplay::SpiConfiguration {
|
||||
.spiHostDevice = LCD_SPI_HOST,
|
||||
.csPin = LCD_PIN_CS,
|
||||
.dcPin = LCD_PIN_DC,
|
||||
.pixelClockFrequency = 40'000'000,
|
||||
.transactionQueueDepth = 10
|
||||
});
|
||||
|
||||
return std::make_shared<Ili934xDisplay>(panel_configuration, spi_configuration, true);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/hal/display/DisplayDevice.h>
|
||||
#include <driver/gpio.h>
|
||||
#include <driver/spi_common.h>
|
||||
#include <memory>
|
||||
|
||||
// Display
|
||||
constexpr auto LCD_PIN_BACKLIGHT = GPIO_NUM_27;
|
||||
constexpr auto LCD_SPI_HOST = SPI2_HOST;
|
||||
constexpr auto LCD_PIN_CS = GPIO_NUM_15;
|
||||
constexpr auto LCD_PIN_DC = GPIO_NUM_2;
|
||||
constexpr auto LCD_HORIZONTAL_RESOLUTION = 240;
|
||||
constexpr auto LCD_VERTICAL_RESOLUTION = 320;
|
||||
constexpr auto LCD_BUFFER_HEIGHT = LCD_VERTICAL_RESOLUTION / 10;
|
||||
constexpr auto LCD_BUFFER_SIZE = LCD_HORIZONTAL_RESOLUTION * LCD_BUFFER_HEIGHT;
|
||||
constexpr auto LCD_SPI_TRANSFER_SIZE_LIMIT = LCD_BUFFER_SIZE * LV_COLOR_DEPTH / 8;
|
||||
|
||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "SdCard.h"
|
||||
|
||||
#define TAG "twodotfour_sdcard"
|
||||
|
||||
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
||||
|
||||
constexpr auto SDCARD_SPI_HOST = SPI3_HOST;
|
||||
constexpr auto SDCARD_PIN_CS = GPIO_NUM_5;
|
||||
|
||||
using tt::hal::sdcard::SpiSdCardDevice;
|
||||
|
||||
std::shared_ptr<SdCardDevice> createSdCard() {
|
||||
auto configuration = std::make_unique<SpiSdCardDevice::Config>(
|
||||
SDCARD_PIN_CS,
|
||||
GPIO_NUM_NC,
|
||||
GPIO_NUM_NC,
|
||||
GPIO_NUM_NC,
|
||||
SdCardDevice::MountBehaviour::AtBoot,
|
||||
std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive),
|
||||
std::vector<gpio_num_t>(),
|
||||
SDCARD_SPI_HOST
|
||||
);
|
||||
|
||||
return std::make_shared<SpiSdCardDevice>(
|
||||
std::move(configuration)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tactility/hal/sdcard/SdCardDevice.h"
|
||||
|
||||
using tt::hal::sdcard::SdCardDevice;
|
||||
|
||||
std::shared_ptr<SdCardDevice> createSdCard();
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
|
||||
|
||||
idf_component_register(
|
||||
SRCS ${SOURCE_FILES}
|
||||
INCLUDE_DIRS "Source"
|
||||
REQUIRES Tactility esp_lvgl_port ILI934x XPT2046SoftSPI PwmBacklight driver vfs fatfs
|
||||
)
|
||||
@@ -0,0 +1,129 @@
|
||||
#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,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
#include "Display.h"
|
||||
#include "Xpt2046SoftSpi.h"
|
||||
#include <Ili934xDisplay.h>
|
||||
#include <PwmBacklight.h>
|
||||
|
||||
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
|
||||
auto configuration = std::make_unique<Xpt2046SoftSpi::Configuration>(
|
||||
TOUCH_MOSI_PIN,
|
||||
TOUCH_MISO_PIN,
|
||||
TOUCH_SCK_PIN,
|
||||
TOUCH_CS_PIN,
|
||||
LCD_HORIZONTAL_RESOLUTION,
|
||||
LCD_VERTICAL_RESOLUTION,
|
||||
false, // swapXY
|
||||
true, // mirrorX
|
||||
false // mirrorY
|
||||
);
|
||||
|
||||
return std::make_shared<Xpt2046SoftSpi>(std::move(configuration));
|
||||
}
|
||||
|
||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||
Ili934xDisplay::Configuration panel_configuration = {
|
||||
.horizontalResolution = LCD_HORIZONTAL_RESOLUTION,
|
||||
.verticalResolution = LCD_VERTICAL_RESOLUTION,
|
||||
.gapX = 0,
|
||||
.gapY = 0,
|
||||
.swapXY = false,
|
||||
.mirrorX = true,
|
||||
.mirrorY = false,
|
||||
.invertColor = false,
|
||||
.swapBytes = true,
|
||||
.bufferSize = LCD_BUFFER_SIZE,
|
||||
.touch = createTouch(),
|
||||
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
||||
.resetPin = GPIO_NUM_NC,
|
||||
.rgbElementOrder = LCD_RGB_ELEMENT_ORDER_BGR
|
||||
};
|
||||
|
||||
auto spi_configuration = std::make_shared<Ili934xDisplay::SpiConfiguration>(Ili934xDisplay::SpiConfiguration {
|
||||
.spiHostDevice = LCD_SPI_HOST,
|
||||
.csPin = LCD_PIN_CS,
|
||||
.dcPin = LCD_PIN_DC,
|
||||
.pixelClockFrequency = 40'000'000,
|
||||
.transactionQueueDepth = 10
|
||||
});
|
||||
|
||||
return std::make_shared<Ili934xDisplay>(panel_configuration, spi_configuration, true);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/hal/display/DisplayDevice.h>
|
||||
#include <driver/gpio.h>
|
||||
#include <driver/spi_common.h>
|
||||
#include <memory>
|
||||
|
||||
// Display
|
||||
constexpr auto LCD_SPI_HOST = SPI2_HOST;
|
||||
constexpr auto LCD_PIN_CS = GPIO_NUM_15;
|
||||
constexpr auto LCD_PIN_DC = GPIO_NUM_2;
|
||||
constexpr auto LCD_HORIZONTAL_RESOLUTION = 240;
|
||||
constexpr auto LCD_VERTICAL_RESOLUTION = 320;
|
||||
constexpr auto LCD_BUFFER_HEIGHT = LCD_VERTICAL_RESOLUTION / 10;
|
||||
constexpr auto LCD_BUFFER_SIZE = LCD_HORIZONTAL_RESOLUTION * LCD_BUFFER_HEIGHT;
|
||||
constexpr auto LCD_SPI_TRANSFER_SIZE_LIMIT = LCD_BUFFER_SIZE * LV_COLOR_DEPTH / 8;
|
||||
|
||||
// Display backlight (PWM)
|
||||
constexpr auto LCD_PIN_BACKLIGHT = GPIO_NUM_21;
|
||||
|
||||
// Touch (Software SPI)
|
||||
constexpr auto TOUCH_MISO_PIN = GPIO_NUM_39;
|
||||
constexpr auto TOUCH_MOSI_PIN = GPIO_NUM_32;
|
||||
constexpr auto TOUCH_SCK_PIN = GPIO_NUM_25;
|
||||
constexpr auto TOUCH_CS_PIN = GPIO_NUM_33;
|
||||
constexpr auto TOUCH_IRQ_PIN = GPIO_NUM_36;
|
||||
|
||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "SdCard.h"
|
||||
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
|
||||
using tt::hal::sdcard::SpiSdCardDevice;
|
||||
|
||||
std::shared_ptr<SdCardDevice> createSdCard() {
|
||||
auto config = std::make_unique<SpiSdCardDevice::Config>(
|
||||
GPIO_NUM_5,
|
||||
GPIO_NUM_NC,
|
||||
GPIO_NUM_NC,
|
||||
GPIO_NUM_NC,
|
||||
SdCardDevice::MountBehaviour::AtBoot,
|
||||
std::make_shared<tt::Mutex>(tt::Mutex::Type::Recursive),
|
||||
std::vector<gpio_num_t>(),
|
||||
SPI3_HOST
|
||||
);
|
||||
|
||||
return std::make_shared<SpiSdCardDevice>(std::move(config));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tactility/hal/sdcard/SdCardDevice.h"
|
||||
|
||||
using tt::hal::sdcard::SdCardDevice;
|
||||
|
||||
std::shared_ptr<SdCardDevice> createSdCard();
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
|
||||
|
||||
idf_component_register(
|
||||
SRCS ${SOURCE_FILES}
|
||||
INCLUDE_DIRS "Source"
|
||||
REQUIRES Tactility esp_lvgl_port ST7789 XPT2046SoftSPI PwmBacklight driver vfs fatfs
|
||||
)
|
||||
@@ -0,0 +1,129 @@
|
||||
#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,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
#include "Display.h"
|
||||
#include "Xpt2046SoftSpi.h"
|
||||
#include <St7789Display.h>
|
||||
#include <PwmBacklight.h>
|
||||
|
||||
constexpr auto* TAG = "CYD";
|
||||
|
||||
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
|
||||
auto configuration = std::make_unique<Xpt2046SoftSpi::Configuration>(
|
||||
TOUCH_MOSI_PIN,
|
||||
TOUCH_MISO_PIN,
|
||||
TOUCH_SCK_PIN,
|
||||
TOUCH_CS_PIN,
|
||||
LCD_HORIZONTAL_RESOLUTION,
|
||||
LCD_VERTICAL_RESOLUTION,
|
||||
false, // swapXY
|
||||
true, // mirrorX
|
||||
false // mirrorY
|
||||
);
|
||||
|
||||
return std::make_shared<Xpt2046SoftSpi>(std::move(configuration));
|
||||
}
|
||||
|
||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||
St7789Display::Configuration panel_configuration = {
|
||||
.horizontalResolution = LCD_HORIZONTAL_RESOLUTION,
|
||||
.verticalResolution = LCD_VERTICAL_RESOLUTION,
|
||||
.gapX = 0,
|
||||
.gapY = 0,
|
||||
.swapXY = false,
|
||||
.mirrorX = false,
|
||||
.mirrorY = false,
|
||||
.invertColor = false,
|
||||
.bufferSize = LCD_BUFFER_SIZE,
|
||||
.touch = createTouch(),
|
||||
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
||||
.resetPin = GPIO_NUM_NC
|
||||
};
|
||||
|
||||
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
||||
.spiHostDevice = LCD_SPI_HOST,
|
||||
.csPin = LCD_PIN_CS,
|
||||
.dcPin = LCD_PIN_DC,
|
||||
.pixelClockFrequency = 62'500'000,
|
||||
.transactionQueueDepth = 10
|
||||
});
|
||||
|
||||
return std::make_shared<St7789Display>(panel_configuration, spi_configuration);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user