Compare commits

..

117 commits

Author SHA1 Message Date
Li Bo
7da906e535 Merge branch 'fix/4g_modem_web_config' into 'usb/add_usb_solutions'
fix(4g_modem): fix router web config function

See merge request ae_group/esp-iot-solution!598
2022-08-31 17:24:54 +08:00
Li Bo
6b757d65ec fix(4g_modem): fix router web config function 2022-08-31 17:24:54 +08:00
Li Bo
9582fc06e2 Merge branch 'feature/4g_module_support_web_config' into 'usb/add_usb_solutions'
feat(4g_module): support config using webpage

See merge request ae_group/esp-iot-solution!585
2022-05-10 17:31:25 +08:00
Li Junru
5b7618008e feat(4g_module): support config using webpage 2022-05-10 16:58:31 +08:00
Xu Chun Guang
8ea35502a9 Merge branch 'usb/add_webusb' into 'usb/add_usb_solutions'
Usb/add webusb

See merge request ae_group/esp-iot-solution!581
2022-04-07 14:15:46 +08:00
zhaokeke
c87add67af feat(usb): add dfu upload firmware support 2022-03-30 10:45:26 +08:00
zhaokeke
2e92f0e687 feat: add webusb fearure 2022-03-28 11:46:17 +08:00
Li Bo
14d9f9bbea Merge branch 'usb/add_tinyusb_dual_cdc_example' into 'usb/add_usb_solutions'
usb(cdc): add tinyusb dual cdc port example

See merge request ae_group/esp-iot-solution!579
2022-03-16 13:58:26 +08:00
Li Bo
f6d0d2d807 usb(cdc): add tinyusb dual cdc port example 2022-03-16 13:40:46 +08:00
Li Bo
3505a91fe2 Merge branch 'usb/rebase_on_idf_release_v4.4' into 'usb/add_usb_solutions'
usb: rebase on idf release/v4.4

See merge request rd/esp-iot-solution!570
2022-03-07 15:39:12 +08:00
Li Bo
0473e9b941 usb(uvc_stream/usbh_cdc): get fullspeed descriptor by default
resolve #146, resolve #152, resolve #156, resolve #157
2022-03-07 14:47:39 +08:00
Li Bo
2ba36c5152 usb_phy: using usb phy api 2022-02-22 14:42:03 +08:00
Li Bo
e2523e5e84 hcd: fix ctrl transfer size 2022-02-21 10:32:34 +08:00
Xu Chun Guang
7b333fa902 Merge branch 'usb/dfu_class' into 'usb/add_usb_solutions'
usb: add dfu class

See merge request rd/esp-iot-solution!564
2022-01-24 06:51:05 +00:00
Xu Chun Guang
2c2140a336 Merge branch 'feature/improve_usb_msc_upload_file_speed' into 'usb/add_usb_solutions'
feature: change wear levelling default sector size to 4096 in msc example

See merge request rd/esp-iot-solution!558
2022-01-21 07:59:33 +00:00
zhaokeke
8e93154db2 docs(USB): add USB DFU and ECM usage 2022-01-20 10:58:10 +08:00
zhaokeke
b7f2eea1ca usb: add dfu class 2022-01-18 11:13:22 +08:00
Xu Chun Guang
427667030d Merge branch 'usb/fix_ecm_error' into 'usb/add_usb_solutions'
Add USB ECM support

See merge request rd/esp-iot-solution!563
2022-01-17 12:21:42 +00:00
zhaokeke
16dc60d15d USB(ECM): Automatic switching network 2022-01-17 20:10:18 +08:00
Xu Chun Guang
c093d77d2a Merge branch 'bugfix/usb_dongle_for_esp32s3' into 'usb/add_usb_solutions'
bugfix(usb_dongle): usb communication exception for esp32s3 dual core

See merge request rd/esp-iot-solution!561
2022-01-17 09:38:30 +00:00
Tian Sen Wen
c211307bc9 bugfix(usb_dongle): usb communication exception for esp32s3 dual core 2022-01-17 17:18:42 +08:00
zhaokeke
6111f64d7a USB: fix ecm mode report probe error 2022-01-17 16:19:28 +08:00
Xu Chun Guang
5a488103b3 Merge branch 'usb/auto_recall_dhcp' into 'usb/add_usb_solutions'
feat: After the networt is switched, the network adapter automatically restarts

See merge request rd/esp-iot-solution!545
2022-01-17 04:14:47 +00:00
zhaokeke
0d65119c6b USB(RNDIS): Automatic switching network
After the RNDIS networt is switched, the network adapter automatically restarts.
This feature only works on Windows; Linux does not support it.
For details, please refer to https://iter01.com/600150.html
2022-01-17 11:51:39 +08:00
Wang Yu Xin
262acde05c feat: change wear levelling default sector size to 4096 2022-01-10 14:36:50 +08:00
Tian Sen Wen
3505e6bfe3 Merge branch 'docs/update_usb_dongle_readme' into 'usb/add_usb_solutions'
docs: update usb_dongle readme

See merge request rd/esp-iot-solution!555
2021-12-23 08:32:16 +00:00
Tian Sen Wen
74ca6c6caf docs: update usb_dongle readme 2021-12-23 16:08:38 +08:00
Li Bo
0e43d61398 Merge branch 'docs/uvc_add_english_readme' into 'usb/add_usb_solutions'
docs: uvc add english readme

See merge request rd/esp-iot-solution!553
2021-12-03 03:54:52 +00:00
Li Bo
3daed6f6cb docs: uvc add english readme 2021-12-03 03:54:51 +00:00
Li Bo
49c940ca7d Merge branch 'bugfix/fix_4g_module_network' into 'usb/add_usb_solutions'
bugfix(cdc_4g): fix network issues

See merge request rd/esp-iot-solution!552
2021-12-01 11:12:27 +00:00
Li Bo
7b82c1f4a3 bugfix(cdc_4g): fix network issues
1. fix set dns address issue
2. fix ip packet loss
3. fix wifi no password
2021-12-01 17:44:41 +08:00
Li Bo
450e8166de Merge branch 'usb/add_hid_device_example' into 'usb/add_usb_solutions'
examples(hid): add usb hid device example

See merge request rd/esp-iot-solution!551
2021-11-22 07:05:22 +00:00
Li Bo
e4148e84ca examples(hid): add usb hid device example 2021-11-22 14:26:47 +08:00
Li Bo
d036d0f79b Merge branch 'bugfix/fix_4g_module_sudden_disconnect' into 'usb/add_usb_solutions'
bugfix(usb_cdc_4g_module): handle usb sudden disconnect

See merge request rd/esp-iot-solution!549
2021-11-18 09:33:56 +00:00
Li Bo
294e7c796b bugfix(usb_cdc_4g_module): handle usb sudden disconnect 2021-11-18 16:35:15 +08:00
Li Bo
b26ede89a2 Merge branch 'feature/usb_cdc_support_hot_plug' into 'usb/add_usb_solutions'
feature(usbh_cdc): usb host cdc support hot plug

See merge request rd/esp-iot-solution!546
2021-11-18 03:45:46 +00:00
Li Bo
f75b5eb95a feature(usbh_cdc): usb host cdc support hot plug 2021-11-18 11:33:44 +08:00
Xu Chun Guang
86a45f1d65 Merge branch 'doc/usb_dongle_idf_commit_dependent' into 'usb/add_usb_solutions'
Doc/usb dongle idf commit dependent

See merge request rd/esp-iot-solution!548
2021-11-12 01:38:11 +00:00
Tian Sen Wen
1dfe02d3a3 doc(usb_dongle): add idf commit dependent 2021-11-10 16:39:37 +08:00
Li Bo
81f2ac2d7a Merge branch 'feature/usb_uvc_support_hot_plug' into 'usb/add_usb_solutions'
feature(uvc): usb host uvc support hot plug

See merge request rd/esp-iot-solution!547
2021-11-04 08:35:10 +00:00
Li Bo
7a3fb2c187 docs(uvc): add english version uvc component readme 2021-11-04 16:30:29 +08:00
Li Bo
bc12b4102e examples(uvc): using idf api to change usb phy 2021-11-04 15:20:11 +08:00
Li Bo
53dc96f9de feature(uvc): usb host uvc support hot plug 2021-10-28 20:50:27 +08:00
Li Bo
a6dad407bd Merge branch 'bugfix/uvc_streaming_stop' into 'usb/add_usb_solutions'
fix(host/uvc_stream): fix esp32s3 can't stop streaming

See merge request rd/esp-iot-solution!544
2021-09-29 13:29:43 +00:00
Li Bo
037380aaf6 fix(host/uvc_stream): fix esp32s3 can't stop streaming 2021-09-27 12:59:32 +08:00
Xu Chun Guang
ef92581eb6 Merge branch 'doc/update_usb_dongle_readme' into 'usb/add_usb_solutions'
doc: update usb_dongle readme

See merge request rd/esp-iot-solution!540
2021-09-09 06:20:48 +00:00
Li Bo
933f12f618 Merge branch 'usb/idf_usb_api_update' into 'usb/add_usb_solutions'
update: upstream idf usb api update

See merge request rd/esp-iot-solution!541
2021-09-06 12:42:36 +00:00
Li Bo
346dfe8f0f update: adapt upstream idf api to latest d5f58ab135
Breakchange: some usb related api renamed
2021-09-06 19:21:13 +08:00
Tian Sen Wen
208e240c8a doc: update usb_dongle readme 2021-09-01 16:21:40 +08:00
Xu Chun Guang
488f751d4b Merge branch 'feature/add_usb_ble_adapter' into 'usb/add_usb_solutions'
feat: add BLE adapter into USB_Dongle

See merge request rd/esp-iot-solution!533
2021-08-31 07:18:39 +00:00
Xu Long Zhuang
787e6c10d1 fix: get le acl buffer size frist 2021-08-31 14:06:28 +08:00
Li Bo
0d91ac2e89 Merge branch 'fix/usb_examples_add_default_iot_solution_path' into 'usb/add_usb_solutions'
fix(examples/usb): cmakelist add default iot_solution path

See merge request rd/esp-iot-solution!539
2021-08-30 11:26:19 +00:00
Li Bo
f8dc3f333c fix(examples/usb): cmakelist add default iot_solution path
fix #124, fix #126
2021-08-30 18:05:45 +08:00
Tian Sen Wen
a686eacd35 doc: supplement BLE adapter description 2021-08-30 11:39:34 +08:00
Tian Sen Wen
84582cc3db feat: add BLE adapter into USB_Dongle 2021-08-30 11:39:24 +08:00
Li Bo
0c94b50a29 Merge branch '4g_module/support_a7600c1' into 'usb/add_usb_solutions'
4g_module: support a7600c1

See merge request rd/esp-iot-solution!536
2021-08-19 07:53:39 +00:00
Li Bo
02be652859 4g_module: support a7600c1 2021-08-19 14:46:29 +08:00
Xu Long Zhuang
3174999337 feat: add BLE S3 adapter for linux system 2021-08-19 11:05:30 +08:00
Xu Chun Guang
a704157929 Merge branch 'feature/USB_Dongle_WiFi' into 'usb/add_usb_solutions'
feature(usb_dongle): add USB Dongle WiFi Solution

See merge request rd/esp-iot-solution!521
2021-08-19 02:57:13 +00:00
Tian Sen Wen
f35216cc9d feat(usb_rndis): add USB Dongle WiFi Solution 2021-08-19 10:01:37 +08:00
Li Bo
914d1d7344 Merge branch 'usb/cdc_4g_module_optimize' into 'usb/add_usb_solutions'
usb: cdc 4g module optimize

See merge request rd/esp-iot-solution!520
2021-08-17 12:56:18 +00:00
Li Bo
dd9eb1ef44 4g_module: support air724ug ec600n
fix #111, fix #116
2021-08-17 19:53:02 +08:00
Li Bo
9fc08ebf22 usbh_cdc: control line state can be configured
fix #121
2021-08-17 19:35:42 +08:00
Li Bo
5ea34d5c55 4g_module: printf current ringbuffer load 2021-08-17 15:59:40 +08:00
Li Bo
1e13bff142 4g_module: add sdkconfig.defaults for different target 2021-08-17 15:59:34 +08:00
Li Bo
542c1a1dd3 4g_module: using notify to handle usb event 2021-08-17 15:50:34 +08:00
Li Bo
c590714a19 usbh_cdc: usb cdc task can be configured 2021-08-17 15:50:34 +08:00
Li Bo
792cbacb39 Merge branch 'examples/modify_usb_example_dir_structure' into 'usb/add_usb_solutions'
examples: modify usb example dir structure

See merge request rd/esp-iot-solution!534
2021-08-16 04:45:00 +00:00
Li Bo
d653f66ab5 host(cdc): remove examples to usb host directory 2021-08-16 11:50:05 +08:00
Li Bo
811c8b8cc9 host(uvc): remove examples to usb host directory 2021-08-16 11:47:29 +08:00
Li Bo
2df6f18863 device(msc/cdc): remove examples to usb device directory 2021-08-16 11:09:50 +08:00
Li Bo
b5fabb2778 Merge branch 'usb/add_tinyusb_examples' into 'usb/add_usb_solutions'
usb: add tinyusb examples

See merge request rd/esp-iot-solution!526
2021-08-13 05:56:13 +00:00
Li Bo
38ac718a5a example(device/msc): add usb msc wireless disk 2021-08-13 13:18:13 +08:00
Li Bo
5d36355d0b examples(device/cdc): add usb_uart_bridge example 2021-08-13 13:18:05 +08:00
Li Bo
22336d984e Merge branch 'usb/add_tinyusb_additions' into 'usb/add_usb_solutions'
usb: add tinyusb additions

See merge request rd/esp-iot-solution!524
2021-08-12 08:50:23 +00:00
Li Bo
ee9d396085 Merge branch 'boards/add_esp32s3_usb_otg_board' into 'usb/add_usb_solutions'
boards: add esp32s3-usb-otg-ev board

See merge request rd/esp-iot-solution!523
2021-08-12 02:06:15 +00:00
Tian Sen Wen
fdd3d3ef37 Merge branch 'bugfix/EXTRA_COMPONENT_DIRS_for_FreeRTOS-Plus-CLI' into 'usb/add_usb_solutions'
fix: modify EXTRA_COMPONENT_DIRS for FreeRTOS-Plus-CLI

See merge request rd/esp-iot-solution!525
2021-08-11 12:06:56 +00:00
Li Bo
290ca8f1b5 boards: add board_common_wifi 2021-08-11 19:58:26 +08:00
Tian Sen Wen
645b69c57d fix: modify EXTRA_COMPONENT_DIRS for FreeRTOS-Plus-CLI 2021-08-11 19:12:58 +08:00
Li Bo
b99a30d93b boards: add free pin definitions 2021-08-11 17:28:28 +08:00
Li Bo
d6e371b33a config_descriptor: clean remote-wakeup bit as esp32sx currently not support 2021-08-11 15:04:46 +08:00
Li Bo
023172596c device(cdc): support dual interface 2021-08-11 15:04:46 +08:00
Li Bo
6ec820ac67 device(msc): eject after all logical disk disable 2021-08-11 15:04:46 +08:00
Li Bo
d2a03219b7 idf:update to 81448dc 2021-08-11 15:03:24 +08:00
Li Bo
f29697dc91 tinyusb: add msc and hid support 2021-08-11 15:01:33 +08:00
Li Bo
7aee86cbb5 tinyusb: idf update to 2c1cc50 2021-08-11 14:59:13 +08:00
Li Bo
5efcb5545a boards: add esp32s3-usb-otg-ev 2021-08-11 14:38:18 +08:00
Li Bo
31f5d3746a boards: unified common functions 2021-08-11 13:50:38 +08:00
Li Bo
e7b276ed06 Merge branch 'feature/FreeRTOS_CLI' into 'usb/add_usb_solutions'
Feature/FreeRTOS-CLI

See merge request rd/esp-iot-solution!519
2021-08-10 06:30:02 +00:00
Tian Sen Wen
fec57dd42c fix(FreeRTOS_CLI): Adapt to ESP-IDF platform 2021-08-10 14:19:35 +08:00
Tian Sen Wen
41789a1ecc feat: add FreeRTOS CLI component 2021-08-10 14:19:35 +08:00
Li Bo
72327d4242 feature(4g_module): support manually set dhcp dns 2021-08-04 14:47:34 +08:00
Li Bo
93bb98de86 fix(4g_module): fix ap dhcp dns problem 2021-08-04 10:51:36 +08:00
Li Bo
45506dc8f1 Merge branch 'usb/reconnect_after_4g_lost' into 'usb/add_usb_solutions'
usb/reconnect after 4g lost

See merge request rd/esp-iot-solution!518
2021-08-02 13:59:40 +00:00
Li Bo
1b33e0226e fix(4g_module):try re-dial if 4g lost 2021-08-02 21:19:54 +08:00
Li Bo
5e97e2d4b5 Merge branch 'usb/fix_4g_module_gpio' into 'usb/add_usb_solutions'
fix(4g_module): led/control gpio can be 0 if not use

See merge request rd/esp-iot-solution!517
2021-08-02 13:00:20 +00:00
Li Bo
f10e7d3a34 fix(4g_module): led/control gpio can be 0 if not use 2021-08-02 20:06:16 +08:00
Li Bo
e7f7cdac8e Merge branch 'usb/add_cdc_4g_module' into 'usb/add_usb_solutions'
examples(cdc_4g_module): support usb cdc mode 4g module

See merge request rd/esp-iot-solution!515
2021-07-26 10:52:31 +00:00
Li Bo
62e99f7fee examples(cdc_4g_module): add usb host driving 4g module 2021-07-26 18:34:50 +08:00
Li Bo
07a7c1da7e Merge branch 'usb/add_usb_cdc_driver' into 'usb/add_usb_solutions'
usb(cdc): add usb host cdc driver

See merge request rd/esp-iot-solution!514
2021-07-26 10:26:20 +00:00
Li Bo
afe63e2e5f Merge branch 'usb/add_usb_cdc_driver' into 'usb/add_usb_solutions'
usb(cdc): add usb host cdc driver

See merge request rd/esp-iot-solution!514
2021-07-26 10:26:17 +00:00
Li Bo
066757fb98 usb(cdc): add usb host cdc driver 2021-07-26 17:51:45 +08:00
Li Bo
15400ccc22 Merge branch 'usb/uvc_esp32s3_support' into 'usb/add_usb_solutions'
usb(uvc): add esp32s3 support

See merge request rd/esp-iot-solution!513
2021-07-20 04:01:42 +00:00
Li Bo
313c23ae87 usb(uvc): add esp32s3 support 2021-07-20 12:01:38 +08:00
Li Bo
cefcbf27e5 Merge branch 'usb/uvc_hcd_change_irp_to_urb' into 'usb/add_usb_solutions'
usb/uvc hcd change irp to urb

See merge request rd/esp-iot-solution!512
2021-06-29 10:05:48 +00:00
Li Bo
aeaf16c5ac IDF: update idf patch 2021-06-29 16:26:26 +08:00
Li Bo
6d4be32e9f hcd: change irp to urb 2021-06-18 16:24:38 +08:00
Li Bo
ef20483dcc examples(usb_camera_lcd_display): using camera real stream by default 2021-06-07 11:24:48 +08:00
Li Bo
f8d96c2443 usb: add latest esp-idf patch 2021-06-04 20:39:53 +08:00
Li Bo
6af80a8a43 readme: fix broken reference 2021-06-04 20:38:20 +08:00
Li Bo
43b99ab617 ci: sync usb_solutions to github 2021-06-04 19:56:00 +08:00
Li Bo
310c5a9c62 examples(uvc): update readme 2021-06-04 17:52:43 +08:00
Li Bo
e3a9a43d99 examples(uvc): add usb camera sdcard saving 2021-06-04 17:36:38 +08:00
Li Bo
be73c2f267 examples(uvc): add usb camera wifi http transfer 2021-06-04 17:36:04 +08:00
Li Bo
630da9f721 examples(uvc): add usb camera lcd display 2021-06-04 17:35:40 +08:00
Li Bo
6bd97c7fcb usb: add esp-idf usb temp patch 2021-06-04 17:34:40 +08:00
Li Bo
aa4d43c899 uvc_stream: add usb camera component 2021-06-04 17:24:35 +08:00
689 changed files with 140815 additions and 14992 deletions

View file

@ -1,20 +0,0 @@
name: Push components to Espressif Component Service
on:
push:
branches:
- master
jobs:
upload_components:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
with:
submodules: 'recursive'
- name: Upload components to component service
uses: espressif/github-actions/upload_components@master
with:
directories: "components/button;components/audio/pwm_audio"
namespace: "espressif"
api_token: ${{ secrets.IDF_COMPONENT_API_TOKEN }}

80
.gitignore vendored
View file

@ -1,19 +1,19 @@
build/
.settings
.config .config
*.o *.o
*.pyc *.pyc
*.d
*.old
*.cproject
# gtags # gtags
GTAGS GTAGS
GRTAGS GRTAGS
GPATH GPATH
# emacs # vscode setting
.dir-locals.el .vscode/
# emacs temp file suffixes
*~
.#*
\#*#
# eclipse setting # eclipse setting
.settings .settings
@ -21,16 +21,6 @@ GPATH
# MacOS directory files # MacOS directory files
.DS_Store .DS_Store
# Components Unit Test Apps files
components/**/build
components/**/sdkconfig
components/**/sdkconfig.old
# Example project files
examples/**/sdkconfig
examples/**/sdkconfig.old
examples/**/build
# Doc build artifacts # Doc build artifacts
docs/**/_build/ docs/**/_build/
docs/**/doxygen-warning-log.txt docs/**/doxygen-warning-log.txt
@ -39,10 +29,12 @@ docs/**/sphinx-warning-log-sanitized.txt
docs/**/xml/ docs/**/xml/
docs/**/xml_in/ docs/**/xml_in/
docs/**/man/ docs/**/man/
docs/doxygen_sqlite3.db
# Downloaded font files # Example project files
docs/_static/DejaVuSans.ttf examples/**/sdkconfig
docs/_static/NotoSansSC-Regular.otf examples/**/sdkconfig.old
examples/**/build
# Unit test app files # Unit test app files
tools/unit-test-app/sdkconfig tools/unit-test-app/sdkconfig
@ -50,52 +42,10 @@ tools/unit-test-app/sdkconfig.old
tools/unit-test-app/build tools/unit-test-app/build
tools/unit-test-app/builds tools/unit-test-app/builds
tools/unit-test-app/output tools/unit-test-app/output
tools/unit-test-app/test_configs
# Unit Test CMake compile log folder # ESP-IDF library
log_ut_cmake
# test application build files
tools/test_apps/**/build
tools/test_apps/**/sdkconfig
tools/test_apps/**/sdkconfig.old
# IDF monitor test
tools/test_idf_monitor/outputs
TEST_LOGS
# gcov coverage reports
*.gcda
*.gcno
coverage.info
coverage_report/
test_multi_heap_host
# VS Code Settings
.vscode/
# VIM files
*.swp
*.swo
# Clion IDE CMake build & config
.idea/
cmake-build-*/
# Results for the checking of the Python coding style and static analysis
.mypy_cache
flake8_output.txt
# ESP-IDF default build directory name
build build
# lock files for examples and components # Local ENV
.envrc
dependencies.lock dependencies.lock
# managed_components for examples
managed_components
# pytest log
pytest_embedded_log/

View file

@ -30,38 +30,28 @@ before_script:
artifacts: artifacts:
when: always when: always
paths: paths:
- $BUILD_PATH/*/*/*/build/*.bin - $BUILD_PATH/*/*/build/*.bin
- $BUILD_PATH/*/*/*/build/*/*.bin - $BUILD_PATH/*/*/build/*.elf
- $BUILD_PATH/*/*/*/build/*.json - $BUILD_PATH/*/*/build/*.map
- $BUILD_PATH/*.json - $BUILD_PATH/*/*/build/download.config
- $LOG_PATH/* - $BUILD_PATH/*/*/build/bootloader/*.bin
- $LOG_PATH
expire_in: 1 week expire_in: 1 week
variables: variables:
IDF_CI_BUILD: "1" IDF_CI_BUILD: "1"
LOG_PATH: "$CI_PROJECT_DIR/log_examples" LOG_PATH: "$CI_PROJECT_DIR/log_examples"
BUILD_PATH: "$CI_PROJECT_DIR/build_examples" BUILD_PATH: "$CI_PROJECT_DIR/build_examples"
SIZE_INFO_LOCATION: "$CI_PROJECT_DIR/log_examples/size_info.txt"
PEDANTIC_CFLAGS: ""
PEDANTIC_CXXFLAGS: ""
script: script:
# it's not possible to build 100% out-of-tree and have the "artifacts" # it's not possible to build 100% out-of-tree and have the "artifacts"
# mechanism work, but this is the next best thing # mechanism work, but this is the next best thing
- rm -rf ${BUILD_PATH} - rm -rf ${BUILD_PATH}
- mkdir ${BUILD_PATH}
- mkdir -p ${LOG_PATH}
# build some of examples # build some of examples
- python ${IOT_SOLUTION_PATH}/tools/ci/genarate_build_json.py - ${IOT_SOLUTION_PATH}/tools/ci/build_examples.sh "${CI_JOB_NAME}"
- ${IOT_SOLUTION_PATH}/tools/ci/build_examples.sh
build_examples_00_with_idf_v4.2: build_examples_00:
<<: *build_examples_template <<: *build_examples_template
image: espressif/idf:release-v4.2
build_examples_00_with_idf_v4.3:
<<: *build_examples_template
image: espressif/idf:release-v4.3
build_examples_00_with_idf_v4.4:
<<: *build_examples_template
image: espressif/idf:release-v4.4
build_docs: build_docs:
stage: build stage: build
@ -84,8 +74,6 @@ build_docs:
expire_in: 1 mos expire_in: 1 mos
script: script:
- source /opt/pyenv/activate && pyenv global 3.6.10 - source /opt/pyenv/activate && pyenv global 3.6.10
- pip install "setuptools<57.5.0"
- pip install "funcparserlib==0.3.6"
- /opt/pyenv/pyenv-1.2.16/versions/3.6.10/bin/python -m pip install --user -r docs/requirements.txt - /opt/pyenv/pyenv-1.2.16/versions/3.6.10/bin/python -m pip install --user -r docs/requirements.txt
- cd docs - cd docs
- ./check_lang_folder_sync.sh - ./check_lang_folder_sync.sh
@ -103,6 +91,7 @@ push_to_github:
only: only:
- master - master
- /^release\/v/ - /^release\/v/
- usb/add_usb_solutions
# when: on_success # when: on_success
image: $CI_DOCKER_REGISTRY/esp32-ci-env image: $CI_DOCKER_REGISTRY/esp32-ci-env
variables: variables:

6
.gitmodules vendored
View file

@ -4,9 +4,3 @@
[submodule "examples/hmi/lvgl_example/components/lv_examples/lv_examples"] [submodule "examples/hmi/lvgl_example/components/lv_examples/lv_examples"]
path = examples/hmi/lvgl_example/components/lv_examples/lv_examples path = examples/hmi/lvgl_example/components/lv_examples/lv_examples
url = https://github.com/lvgl/lv_examples.git url = https://github.com/lvgl/lv_examples.git
[submodule "examples/camera/camera_components/esp32-camera"]
path = examples/camera/camera_components/esp32-camera
url = https://github.com/espressif/esp32-camera
[submodule "examples/decompress/xz_compressed_ota/bootloader_components"]
path = examples/decompress/xz_compressed_ota/bootloader_components
url = https://github.com/espressif/esp-bootloader-plus.git

View file

@ -14,5 +14,4 @@ formats:
python: python:
version: 3.7 version: 3.7
install: install:
- requirements: docs/setuptools.requirements.txt
- requirements: docs/requirements.txt - requirements: docs/requirements.txt

View file

@ -21,5 +21,6 @@ list(APPEND EXTRA_COMPONENT_DIRS
"$ENV{IOT_SOLUTION_PATH}/components/sensors/pressure" "$ENV{IOT_SOLUTION_PATH}/components/sensors/pressure"
"$ENV{IOT_SOLUTION_PATH}/components/storage" "$ENV{IOT_SOLUTION_PATH}/components/storage"
"$ENV{IOT_SOLUTION_PATH}/components/storage/eeprom" "$ENV{IOT_SOLUTION_PATH}/components/storage/eeprom"
"$ENV{IOT_SOLUTION_PATH}/components/FreeRTOS-Plus-CLI"
) )

View file

@ -17,3 +17,4 @@ EXTRA_COMPONENT_DIRS += $(IOT_SOLUTION_PATH)/components/sensors/light_sensor
EXTRA_COMPONENT_DIRS += $(IOT_SOLUTION_PATH)/components/sensors/pressure EXTRA_COMPONENT_DIRS += $(IOT_SOLUTION_PATH)/components/sensors/pressure
EXTRA_COMPONENT_DIRS += $(IOT_SOLUTION_PATH)/components/storage EXTRA_COMPONENT_DIRS += $(IOT_SOLUTION_PATH)/components/storage
EXTRA_COMPONENT_DIRS += $(IOT_SOLUTION_PATH)/components/storage/eeprom EXTRA_COMPONENT_DIRS += $(IOT_SOLUTION_PATH)/components/storage/eeprom
EXTRA_COMPONENT_DIRS += $(IOT_SOLUTION_PATH)/components/FreeRTOS-Plus-CLI

View file

@ -0,0 +1,3 @@
idf_component_register(SRCS "FreeRTOS_CLI.c"
INCLUDE_DIRS include
PRIV_REQUIRES )

View file

@ -0,0 +1,359 @@
/*
* FreeRTOS+CLI V1.0.4
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/* Standard includes. */
#include <string.h>
#include <stdint.h>
/* FreeRTOS includes. */
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
/* Utils includes. */
#include "FreeRTOS_CLI.h"
/* If the application writer needs to place the buffer used by the CLI at a
fixed address then set configAPPLICATION_PROVIDES_cOutputBuffer to 1 in
FreeRTOSConfig.h, then declare an array with the following name and size in
one of the application files:
char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
*/
#ifndef configAPPLICATION_PROVIDES_cOutputBuffer
#define configAPPLICATION_PROVIDES_cOutputBuffer 0
#endif
PRIVILEGED_DATA portMUX_TYPE xCLIMux = portMUX_INITIALIZER_UNLOCKED;
typedef struct xCOMMAND_INPUT_LIST
{
const CLI_Command_Definition_t *pxCommandLineDefinition;
struct xCOMMAND_INPUT_LIST *pxNext;
} CLI_Definition_List_Item_t;
/*
* The callback function that is executed when "help" is entered. This is the
* only default command that is always present.
*/
static BaseType_t prvHelpCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
/*
* Return the number of parameters that follow the command name.
*/
static int8_t prvGetNumberOfParameters( const char *pcCommandString );
/* The definition of the "help" command. This command is always at the front
of the list of registered commands. */
static const CLI_Command_Definition_t xHelpCommand =
{
"help",
"help:\r\n Lists all the registered commands\r\n\r\n",
prvHelpCommand,
0
};
/* The definition of the list of commands. Commands that are registered are
added to this list. */
static CLI_Definition_List_Item_t xRegisteredCommands =
{
&xHelpCommand, /* The first command in the list is always the help command, defined in this file. */
NULL /* The next pointer is initialised to NULL, as there are no other registered commands yet. */
};
/* A buffer into which command outputs can be written is declared here, rather
than in the command console implementation, to allow multiple command consoles
to share the same buffer. For example, an application may allow access to the
command interpreter by UART and by Ethernet. Sharing a buffer is done purely
to save RAM. Note, however, that the command console itself is not re-entrant,
so only one command interpreter interface can be used at any one time. For that
reason, no attempt at providing mutual exclusion to the cOutputBuffer array is
attempted.
configAPPLICATION_PROVIDES_cOutputBuffer is provided to allow the application
writer to provide their own cOutputBuffer declaration in cases where the
buffer needs to be placed at a fixed address (rather than by the linker). */
#if( configAPPLICATION_PROVIDES_cOutputBuffer == 0 )
static char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
#else
extern char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
#endif
/*-----------------------------------------------------------*/
void FreeRTOS_CLICreatMux(void)
{
vPortCPUInitializeMutex( &xCLIMux );
}
/*-----------------------------------------------------------*/
BaseType_t FreeRTOS_CLIRegisterCommand( const CLI_Command_Definition_t * const pxCommandToRegister )
{
static CLI_Definition_List_Item_t *pxLastCommandInList = &xRegisteredCommands;
CLI_Definition_List_Item_t *pxNewListItem;
BaseType_t xReturn = pdFAIL;
/* Check the parameter is not NULL. */
configASSERT( pxCommandToRegister );
/* Create a new list item that will reference the command being registered. */
pxNewListItem = ( CLI_Definition_List_Item_t * ) pvPortMalloc( sizeof( CLI_Definition_List_Item_t ) );
configASSERT( pxNewListItem );
if( pxNewListItem != NULL )
{
taskENTER_CRITICAL( &xCLIMux );
{
/* Reference the command being registered from the newly created
list item. */
pxNewListItem->pxCommandLineDefinition = pxCommandToRegister;
/* The new list item will get added to the end of the list, so
pxNext has nowhere to point. */
pxNewListItem->pxNext = NULL;
/* Add the newly created list item to the end of the already existing
list. */
pxLastCommandInList->pxNext = pxNewListItem;
/* Set the end of list marker to the new list item. */
pxLastCommandInList = pxNewListItem;
}
taskEXIT_CRITICAL( &xCLIMux );
xReturn = pdPASS;
}
return xReturn;
}
/*-----------------------------------------------------------*/
BaseType_t FreeRTOS_CLIProcessCommand( const char * const pcCommandInput, char * pcWriteBuffer, size_t xWriteBufferLen )
{
static const CLI_Definition_List_Item_t *pxCommand = NULL;
BaseType_t xReturn = pdTRUE;
const char *pcRegisteredCommandString;
size_t xCommandStringLength;
/* Note: This function is not re-entrant. It must not be called from more
thank one task. */
if( pxCommand == NULL )
{
/* Search for the command string in the list of registered commands. */
for( pxCommand = &xRegisteredCommands; pxCommand != NULL; pxCommand = pxCommand->pxNext )
{
pcRegisteredCommandString = pxCommand->pxCommandLineDefinition->pcCommand;
xCommandStringLength = strlen( pcRegisteredCommandString );
/* To ensure the string lengths match exactly, so as not to pick up
a sub-string of a longer command, check the byte after the expected
end of the string is either the end of the string or a space before
a parameter. */
if( strncmp( pcCommandInput, pcRegisteredCommandString, xCommandStringLength ) == 0 )
{
if( ( pcCommandInput[ xCommandStringLength ] == ' ' ) || ( pcCommandInput[ xCommandStringLength ] == 0x00 ) )
{
/* The command has been found. Check it has the expected
number of parameters. If cExpectedNumberOfParameters is -1,
then there could be a variable number of parameters and no
check is made. */
if( pxCommand->pxCommandLineDefinition->cExpectedNumberOfParameters >= 0 )
{
if( prvGetNumberOfParameters( pcCommandInput ) != pxCommand->pxCommandLineDefinition->cExpectedNumberOfParameters )
{
xReturn = pdFALSE;
}
}
break;
}
}
}
}
if( ( pxCommand != NULL ) && ( xReturn == pdFALSE ) )
{
/* The command was found, but the number of parameters with the command
was incorrect. */
strncpy( pcWriteBuffer, "Incorrect command parameter(s). Enter \"help\" to view a list of available commands.\r\n", xWriteBufferLen );
pxCommand = NULL;
}
else if( pxCommand != NULL )
{
/* Call the callback function that is registered to this command. */
xReturn = pxCommand->pxCommandLineDefinition->pxCommandInterpreter( pcWriteBuffer, xWriteBufferLen, pcCommandInput );
/* If xReturn is pdFALSE, then no further strings will be returned
after this one, and pxCommand can be reset to NULL ready to search
for the next entered command. */
if( xReturn == pdFALSE )
{
pxCommand = NULL;
}
}
else
{
/* pxCommand was NULL, the command was not found. */
strncpy( pcWriteBuffer, "Command not recognised. Enter 'help' to view a list of available commands.\r\n", xWriteBufferLen );
xReturn = pdFALSE;
}
return xReturn;
}
/*-----------------------------------------------------------*/
char *FreeRTOS_CLIGetOutputBuffer( void )
{
return cOutputBuffer;
}
/*-----------------------------------------------------------*/
const char *FreeRTOS_CLIGetParameter( const char *pcCommandString, UBaseType_t uxWantedParameter, BaseType_t *pxParameterStringLength )
{
UBaseType_t uxParametersFound = 0;
const char *pcReturn = NULL;
*pxParameterStringLength = 0;
while( uxParametersFound < uxWantedParameter )
{
/* Index the character pointer past the current word. If this is the start
of the command string then the first word is the command itself. */
while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) != ' ' ) )
{
pcCommandString++;
}
/* Find the start of the next string. */
while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) == ' ' ) )
{
pcCommandString++;
}
/* Was a string found? */
if( *pcCommandString != 0x00 )
{
/* Is this the start of the required parameter? */
uxParametersFound++;
if( uxParametersFound == uxWantedParameter )
{
/* How long is the parameter? */
pcReturn = pcCommandString;
while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) != ' ' ) )
{
( *pxParameterStringLength )++;
pcCommandString++;
}
if( *pxParameterStringLength == 0 )
{
pcReturn = NULL;
}
break;
}
}
else
{
break;
}
}
return pcReturn;
}
/*-----------------------------------------------------------*/
static BaseType_t prvHelpCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
{
static const CLI_Definition_List_Item_t * pxCommand = NULL;
BaseType_t xReturn;
( void ) pcCommandString;
if( pxCommand == NULL )
{
/* Reset the pxCommand pointer back to the start of the list. */
pxCommand = &xRegisteredCommands;
}
/* Return the next command help string, before moving the pointer on to
the next command in the list. */
strncpy( pcWriteBuffer, pxCommand->pxCommandLineDefinition->pcHelpString, xWriteBufferLen );
pxCommand = pxCommand->pxNext;
if( pxCommand == NULL )
{
/* There are no more commands in the list, so there will be no more
strings to return after this one and pdFALSE should be returned. */
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
return xReturn;
}
/*-----------------------------------------------------------*/
static int8_t prvGetNumberOfParameters( const char *pcCommandString )
{
int8_t cParameters = 0;
BaseType_t xLastCharacterWasSpace = pdFALSE;
/* Count the number of space delimited words in pcCommandString. */
while( *pcCommandString != 0x00 )
{
if( ( *pcCommandString ) == ' ' )
{
if( xLastCharacterWasSpace != pdTRUE )
{
cParameters++;
xLastCharacterWasSpace = pdTRUE;
}
}
else
{
xLastCharacterWasSpace = pdFALSE;
}
pcCommandString++;
}
/* If the command string ended with spaces, then there will have been too
many parameters counted. */
if( xLastCharacterWasSpace == pdTRUE )
{
cParameters--;
}
/* The value returned is one less than the number of space delimited words,
as the first word should be the command itself. */
return cParameters;
}

View file

@ -0,0 +1,32 @@
Changes between V1.0.3 and V1.0.4 released
+ Update to use stdint and the FreeRTOS specific typedefs that were
introduced in FreeRTOS V8.0.0.
Changes between V1.0.2 and V1.0.3 released
+ Previously, and in line with good software engineering practice, the
FreeRTOS coding standard did not permit the use of char types that were
not explicitly qualified as either signed or unsigned. As a result char
pointers used to reference strings required casts, as did the use of any
standard string handling functions. The casts ensured compiler warnings
were not generated by compilers that defaulted unqualified char types to
be signed or compilers that defaulted unqualified char types to be
unsigned. As it has in later MISRA standards, this rule has now been
relaxed, and unqualified char types are now permitted, but only when:
1) The char is used to point to a human readable text string.
2) The char is used to hold a single ASCII character.
Changes between V1.0.1 and V1.0.2 released 14/10/2013
+ Changed double quotes (") to single quotes (') in the help string to
allow the strings to be used with JSON in FreeRTOS+Nabto.
Changes between V1.0.0 and V1.0.1 released 05/07/2012
+ Change the name of the structure used to map a function that implements
a CLI command to the string used to call the command from
xCommandLineInput to CLI_Command_Definition_t, as it was always intended
to be. A #define was added to map the old name to the new name for
reasons of backward compatibility.

View file

@ -0,0 +1,19 @@
FreeRTOS+CLI is released under the following MIT license.
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,5 @@
[InternetShortcut]
URL=http://www.freertos.org/cli
IDList=
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,2

View file

@ -0,0 +1,7 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
COMPONENT_ADD_INCLUDEDIRS := ./include
COMPONENT_SRCDIRS := .

View file

@ -0,0 +1,115 @@
/*
* FreeRTOS+CLI V1.0.4
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#ifndef COMMAND_INTERPRETER_H
#define COMMAND_INTERPRETER_H
#include "freertos/FreeRTOS.h"
/* The prototype to which callback functions used to process command line
commands must comply. pcWriteBuffer is a buffer into which the output from
executing the command can be written, xWriteBufferLen is the length, in bytes of
the pcWriteBuffer buffer, and pcCommandString is the entire string as input by
the user (from which parameters can be extracted).*/
typedef BaseType_t (*pdCOMMAND_LINE_CALLBACK)( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
/* The structure that defines command line commands. A command line command
should be defined by declaring a const structure of this type. */
typedef struct xCOMMAND_LINE_INPUT
{
const char * const pcCommand; /* The command that causes pxCommandInterpreter to be executed. For example "help". Must be all lower case. */
const char * const pcHelpString; /* String that describes how to use the command. Should start with the command itself, and end with "\r\n". For example "help: Returns a list of all the commands\r\n". */
const pdCOMMAND_LINE_CALLBACK pxCommandInterpreter; /* A pointer to the callback function that will return the output generated by the command. */
int8_t cExpectedNumberOfParameters; /* Commands expect a fixed number of parameters, which may be zero. */
} CLI_Command_Definition_t;
/* For backward compatibility. */
#define xCommandLineInput CLI_Command_Definition_t
#define configCOMMAND_INT_MAX_OUTPUT_SIZE 500
/*
* Create a Mux.
*
* Note: Must be called before FreeRTOS_CLIProcessCommand.
*/
void FreeRTOS_CLICreatMux(void);
/*
* Register the command passed in using the pxCommandToRegister parameter.
* Registering a command adds the command to the list of commands that are
* handled by the command interpreter. Once a command has been registered it
* can be executed from the command line.
*/
BaseType_t FreeRTOS_CLIRegisterCommand( const CLI_Command_Definition_t * const pxCommandToRegister );
/*
* Runs the command interpreter for the command string "pcCommandInput". Any
* output generated by running the command will be placed into pcWriteBuffer.
* xWriteBufferLen must indicate the size, in bytes, of the buffer pointed to
* by pcWriteBuffer.
*
* FreeRTOS_CLIProcessCommand should be called repeatedly until it returns pdFALSE.
*
* pcCmdIntProcessCommand is not reentrant. It must not be called from more
* than one task - or at least - by more than one task at a time.
*/
BaseType_t FreeRTOS_CLIProcessCommand( const char * const pcCommandInput, char * pcWriteBuffer, size_t xWriteBufferLen );
/*-----------------------------------------------------------*/
/*
* A buffer into which command outputs can be written is declared in the
* main command interpreter, rather than in the command console implementation,
* to allow application that provide access to the command console via multiple
* interfaces to share a buffer, and therefore save RAM. Note, however, that
* the command interpreter itself is not re-entrant, so only one command
* console interface can be used at any one time. For that reason, no attempt
* is made to provide any mutual exclusion mechanism on the output buffer.
*
* FreeRTOS_CLIGetOutputBuffer() returns the address of the output buffer.
*/
char *FreeRTOS_CLIGetOutputBuffer( void );
/*
* Return a pointer to the xParameterNumber'th word in pcCommandString.
*/
const char *FreeRTOS_CLIGetParameter( const char *pcCommandString, UBaseType_t uxWantedParameter, BaseType_t *pxParameterStringLength );
#endif /* COMMAND_INTERPRETER_H */

View file

@ -0,0 +1,4 @@
Contains source and header files that implement FreeRTOS+CLI. See
http://www.FreeRTOS.org/cli for documentation and license information.

View file

@ -1,3 +1,3 @@
idf_component_register(SRCS "dac_audio.c" idf_component_register(SRCS "dac_audio.c"
INCLUDE_DIRS "include" INCLUDE_DIRS "include"
REQUIRES driver) )

View file

@ -12,15 +12,17 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "sdkconfig.h"
#ifdef CONFIG_IDF_TARGET_ESP32
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "esp_log.h" #include "esp_log.h"
#include "driver/i2s.h" #include "driver/i2s.h"
#include "dac_audio.h" #include "dac_audio.h"
#include "sdkconfig.h"
/**
* @attention "I2S DAC only support ESP32"
*/
#ifdef CONFIG_IDF_TARGET_ESP32
static const char *TAG = "DAC audio"; static const char *TAG = "DAC audio";
#define DAC_AUDIO_CHECK(a, str, ret_val) \ #define DAC_AUDIO_CHECK(a, str, ret_val) \
@ -154,11 +156,7 @@ esp_err_t dac_audio_init(dac_audio_config_t *cfg)
i2s_config.mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN; i2s_config.mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN;
i2s_config.sample_rate = cfg->sample_rate; i2s_config.sample_rate = cfg->sample_rate;
i2s_config.bits_per_sample = cfg->bits_per_sample; i2s_config.bits_per_sample = cfg->bits_per_sample;
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0))
i2s_config.communication_format = I2S_COMM_FORMAT_I2S_MSB;
#else
i2s_config.communication_format = I2S_COMM_FORMAT_STAND_MSB; i2s_config.communication_format = I2S_COMM_FORMAT_STAND_MSB;
#endif
if (I2S_DAC_CHANNEL_RIGHT_EN == cfg->dac_mode) { if (I2S_DAC_CHANNEL_RIGHT_EN == cfg->dac_mode) {
i2s_config.channel_format = I2S_CHANNEL_FMT_ALL_RIGHT; i2s_config.channel_format = I2S_CHANNEL_FMT_ALL_RIGHT;
} else if (I2S_DAC_CHANNEL_LEFT_EN == cfg->dac_mode) { } else if (I2S_DAC_CHANNEL_LEFT_EN == cfg->dac_mode) {

View file

@ -1,3 +1,5 @@
idf_component_register(SRCS "pwm_audio.c"
INCLUDE_DIRS "include" set(pwm_audio_srcs "pwm_audio.c")
REQUIRES driver)
idf_component_register(SRCS "${pwm_audio_srcs}"
INCLUDE_DIRS "include")

View file

@ -1,13 +0,0 @@
# Component: Button
[documentation](https://docs.espressif.com/projects/espressif-esp-iot-solution/en/latest/audio/pwm_audio.html)
The PWM audio function uses the internal LEDC peripheral in ESP32 to generate PWM audio, which does not need an external audio Codec chip.
## Features
- Allows any GIPO with output capability as an audio output pin
- Supports 8-bit ~ 10-bit PWM resolution
- Supports stereo
- Supports 8 48 KHz sampling rate
[Here](https://github.com/espressif/esp-iot-solution/tree/master/examples/audio/wav_player) is a simple player example that uses PWM to output audio.

View file

@ -1,5 +0,0 @@
version: "1.0.0"
description: PWM audio output driver for ESP32 series Socs
url: https://github.com/espressif/esp-iot-solution/tree/master/components/audio/pwm_audio
dependencies:
idf: ">=4.0"

View file

@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -12,8 +12,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#define _SOC_TIMG_STRUCT_H_ // to exclude `timer_group_struct.h` file
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
@ -21,25 +19,18 @@
#include "freertos/task.h" #include "freertos/task.h"
#include "driver/ledc.h" #include "driver/ledc.h"
#include "esp_err.h" #include "esp_err.h"
#include "esp_timer.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
#include "driver/timer.h" #include "driver/timer.h"
#include "soc/timer_group_struct.h"
#include "soc/ledc_struct.h" #include "soc/ledc_struct.h"
#include "soc/ledc_reg.h" #include "soc/ledc_reg.h"
#include "pwm_audio.h" #include "pwm_audio.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3) #if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32)
#ifdef CONFIG_IDF_TARGET_ESP32
#include "reg_struct/esp32_timer_group_struct.h"
#elif defined CONFIG_IDF_TARGET_ESP32S2
#include "reg_struct/esp32s2_timer_group_struct.h"
#elif defined CONFIG_IDF_TARGET_ESP32S3
#include "reg_struct/esp32s3_timer_group_struct.h"
#elif defined CONFIG_IDF_TARGET_ESP32C3
#include "reg_struct/esp32c3_timer_group_struct.h"
#endif
static const char *TAG = "pwm_audio"; static const char *TAG = "pwm_audio";
#define PWM_AUDIO_CHECK(a, str, ret_val) \ #define PWM_AUDIO_CHECK(a, str, ret_val) \
@ -67,10 +58,6 @@ static const char *PWM_AUDIO_NOT_INITIALIZED = "PWM AUDIO Uninitialized";
#define CHANNEL_RIGHT_MASK (0x02) #define CHANNEL_RIGHT_MASK (0x02)
#define VOLUME_0DB (16) #define VOLUME_0DB (16)
#ifndef TIMER_BASE_CLK
#define TIMER_BASE_CLK 80000000
#endif
/** /**
* Debug Configuration * Debug Configuration
**/ **/
@ -90,7 +77,7 @@ typedef struct {
pwm_audio_config_t config; /**< pwm audio config struct */ pwm_audio_config_t config; /**< pwm audio config struct */
ledc_channel_config_t ledc_channel[PWM_AUDIO_CH_MAX]; /**< ledc channel config */ ledc_channel_config_t ledc_channel[PWM_AUDIO_CH_MAX]; /**< ledc channel config */
ledc_timer_config_t ledc_timer; /**< ledc timer config */ ledc_timer_config_t ledc_timer; /**< ledc timer config */
_timg_dev_t *timg_dev; /**< timer group register pointer */ timg_dev_t *timg_dev; /**< timer group register pointer */
ringbuf_handle_t *ringbuf; /**< audio ringbuffer pointer */ ringbuf_handle_t *ringbuf; /**< audio ringbuffer pointer */
uint32_t channel_mask; /**< channel gpio mask */ uint32_t channel_mask; /**< channel gpio mask */
uint32_t channel_set_num; /**< channel audio set number */ uint32_t channel_set_num; /**< channel audio set number */
@ -134,7 +121,7 @@ static esp_err_t rb_destroy(ringbuf_handle_t *rb)
rb = NULL; rb = NULL;
return ESP_OK; return ESP_OK;
} }
static ringbuf_handle_t *rb_create(uint32_t size) static ringbuf_handle_t* rb_create(uint32_t size)
{ {
if (size < (BUFFER_MIN_SIZE << 2)) { if (size < (BUFFER_MIN_SIZE << 2)) {
ESP_LOGE(TAG, "Invalid buffer size, Minimum = %d", (int32_t)(BUFFER_MIN_SIZE << 2)); ESP_LOGE(TAG, "Invalid buffer size, Minimum = %d", (int32_t)(BUFFER_MIN_SIZE << 2));
@ -262,6 +249,7 @@ static inline void ledc_set_right_duty_fast(uint32_t duty_val)
*g_ledc_right_conf1_val |= 0x80000000; *g_ledc_right_conf1_val |= 0x80000000;
} }
/* /*
* Timer group ISR handler * Timer group ISR handler
*/ */
@ -272,14 +260,31 @@ static void IRAM_ATTR timer_group_isr(void *para)
if (handle == NULL) { if (handle == NULL) {
return; return;
} }
#ifdef CONFIG_IDF_TARGET_ESP32S2
/* Clear the interrupt */ /* Clear the interrupt */
// uint32_t st = timer_ll_get_intr_status(handle->timg_dev); if ((handle->timg_dev)->int_st.val & BIT(handle->config.timer_num)) {
// if (st & (1UL << handle->config.timer_num)) { (handle->timg_dev)->int_clr.val |= (1UL << handle->config.timer_num);
timer_ll_clear_intr_status(handle->timg_dev, handle->config.timer_num); }
// }
/* After the alarm has been triggered /* After the alarm has been triggered
we need enable it again, so it is triggered the next time */ we need enable it again, so it is triggered the next time */
timer_ll_enable_alarm(handle->timg_dev, handle->config.timer_num, 1); handle->timg_dev->hw_timer[handle->config.timer_num].config.alarm_en = TIMER_ALARM_EN;
#endif /**< CONFIG_IDF_TARGET_ESP32S2 */
#ifdef CONFIG_IDF_TARGET_ESP32
/* Clear the interrupt */
if (handle->timg_dev->int_st_timers.val & BIT(handle->config.timer_num)) {
handle->timg_dev->int_clr_timers.val |= (1UL << handle->config.timer_num);
}
/* After the alarm has been triggered
we need enable it again, so it is triggered the next time */
handle->timg_dev->hw_timer[handle->config.timer_num].config.alarm_en = TIMER_ALARM_EN;
#endif /**< CONFIG_IDF_TARGET_ESP32 */
static uint8_t wave_h, wave_l; static uint8_t wave_h, wave_l;
static uint16_t value; static uint16_t value;
@ -436,9 +441,9 @@ esp_err_t pwm_audio_init(const pwm_audio_config_t *cfg)
/**< Get timer group register pointer */ /**< Get timer group register pointer */
if (cfg->tg_num == TIMER_GROUP_0) { if (cfg->tg_num == TIMER_GROUP_0) {
handle->timg_dev = TIMERG0; handle->timg_dev = &TIMERG0;
} else { } else {
handle->timg_dev = TIMERG1; handle->timg_dev = &TIMERG1;
} }
/** /**
@ -552,7 +557,7 @@ esp_err_t pwm_audio_set_param(int rate, ledc_timer_bit_t bits, int ch)
timer_set_counter_value(handle->config.tg_num, handle->config.timer_num, 0x00000000ULL); timer_set_counter_value(handle->config.tg_num, handle->config.timer_num, 0x00000000ULL);
/* Configure the alarm value and the interrupt on alarm. */ /* Configure the alarm value and the interrupt on alarm. */
uint32_t divider = timer_ll_get_clock_prescale(handle->timg_dev, handle->config.timer_num); uint32_t divider = handle->timg_dev->hw_timer[handle->config.timer_num].config.divider;
timer_set_alarm_value(handle->config.tg_num, handle->config.timer_num, (TIMER_BASE_CLK / divider) / handle->framerate); timer_set_alarm_value(handle->config.tg_num, handle->config.timer_num, (TIMER_BASE_CLK / divider) / handle->framerate);
// timer_enable_intr(handle->config.tg_num, handle->config.timer_num); // timer_enable_intr(handle->config.tg_num, handle->config.timer_num);
return res; return res;
@ -567,7 +572,7 @@ esp_err_t pwm_audio_set_sample_rate(int rate)
pwm_audio_data_t *handle = g_pwm_audio_handle; pwm_audio_data_t *handle = g_pwm_audio_handle;
handle->framerate = rate; handle->framerate = rate;
uint32_t divider = timer_ll_get_clock_prescale(handle->timg_dev, handle->config.timer_num); uint32_t divider = handle->timg_dev->hw_timer[handle->config.timer_num].config.divider;
res = timer_set_alarm_value(handle->config.tg_num, handle->config.timer_num, (TIMER_BASE_CLK / divider) / handle->framerate); res = timer_set_alarm_value(handle->config.tg_num, handle->config.timer_num, (TIMER_BASE_CLK / divider) / handle->framerate);
return res; return res;
} }
@ -746,9 +751,10 @@ esp_err_t pwm_audio_start(void)
/**< timer enable interrupt */ /**< timer enable interrupt */
portENTER_CRITICAL_SAFE(&timer_spinlock); portENTER_CRITICAL_SAFE(&timer_spinlock);
timer_ll_enable_intr(handle->timg_dev, handle->config.timer_num, 1); handle->timg_dev->int_ena.val |= BIT(handle->config.timer_num);
timer_ll_enable_counter(handle->timg_dev, handle->config.timer_num, 1); handle->timg_dev->hw_timer[handle->config.timer_num].config.enable = 1;
timer_ll_enable_alarm(handle->timg_dev, handle->config.timer_num, 1); /** Make sure the interrupt is enabled*/ handle->timg_dev->hw_timer[handle->config.timer_num].config.alarm_en = TIMER_ALARM_EN; /** Make sure the interrupt is enabled*/
handle->timg_dev->hw_timer[handle->config.timer_num].config.level_int_en = 1;
portEXIT_CRITICAL_SAFE(&timer_spinlock); portEXIT_CRITICAL_SAFE(&timer_spinlock);
res = timer_start(handle->config.tg_num, handle->config.timer_num); res = timer_start(handle->config.tg_num, handle->config.timer_num);
@ -764,8 +770,9 @@ esp_err_t pwm_audio_stop(void)
/**< just disable timer ,keep pwm output to reduce switching nosie */ /**< just disable timer ,keep pwm output to reduce switching nosie */
/**< timer disable interrupt */ /**< timer disable interrupt */
portENTER_CRITICAL_SAFE(&timer_spinlock); portENTER_CRITICAL_SAFE(&timer_spinlock);
timer_ll_enable_intr(handle->timg_dev, handle->config.timer_num, 0); handle->timg_dev->hw_timer[handle->config.timer_num].config.enable = 0;
timer_ll_enable_counter(handle->timg_dev, handle->config.timer_num, 0); handle->timg_dev->int_ena.val &= (~BIT(handle->config.timer_num));
handle->timg_dev->hw_timer[handle->config.timer_num].config.level_int_en = 0;
portEXIT_CRITICAL_SAFE(&timer_spinlock); portEXIT_CRITICAL_SAFE(&timer_spinlock);
// timer_pause(handle->config.tg_num, handle->config.timer_num); // timer_pause(handle->config.tg_num, handle->config.timer_num);

View file

@ -1,784 +0,0 @@
/**
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Group: Configuration and Control Register */
/** Type of txconfig register
* Timer x configuration register
*/
typedef union {
struct {
uint32_t reserved_0: 10;
/** tx_alarm_en : R/W; bitpos: [10]; default: 0;
* When set, the alarm is enabled. This bit is automatically cleared once an
*
* alarm occurs.
*/
uint32_t tx_alarm_en: 1;
/** tx_level_int_en : R/W; bitpos: [11]; default: 0;
* When set, an alarm will generate a level type interrupt.
*/
uint32_t tx_level_int_en: 1;
/** tx_edge_int_en : R/W; bitpos: [12]; default: 0;
* When set, an alarm will generate an edge type interrupt.
*/
uint32_t tx_edge_int_en: 1;
/** tx_divider : R/W; bitpos: [28:13]; default: 1;
* Timer x clock (Tx_clk) prescaler value.
*/
uint32_t tx_divider: 16;
/** tx_autoreload : R/W; bitpos: [29]; default: 1;
* When set, timer x auto-reload at alarm is enabled.
*/
uint32_t tx_autoreload: 1;
/** tx_increase : R/W; bitpos: [30]; default: 1;
* When set, the timer x time-base counter will increment every clock tick. When
*
* cleared, the timer x time-base counter will decrement.
*/
uint32_t tx_increase: 1;
/** tx_en : R/W; bitpos: [31]; default: 0;
* When set, the timer x time-base counter is enabled.
*/
uint32_t tx_en: 1;
};
uint32_t val;
} _timg_txconfig_reg_t;
/** Type of txlo register
* Timer x current value, low 32 bits
*/
typedef union {
struct {
/** tx_lo : RO; bitpos: [31:0]; default: 0;
* After writing to TIMG_TxUPDATE_REG, the low 32 bits of the time-base counter
*
* of timer x can be read here.
*/
uint32_t tx_lo: 32;
};
uint32_t val;
} _timg_txlo_reg_t;
/** Type of txhi register
* Timer x current value, high 32 bits
*/
typedef union {
struct {
/** tx_hi : RO; bitpos: [31:0]; default: 0;
* After writing to TIMG_TxUPDATE_REG, the high 32 bits of the time-base counter
*
* of timer x can be read here.
*/
uint32_t tx_hi: 32;
};
uint32_t val;
} _timg_txhi_reg_t;
/** Type of txupdate register
* Write to copy current timer value to TIMGn_Tx_(LO/HI)_REG
*/
typedef union {
struct {
uint32_t reserved_0: 31;
/** tx_update : R/W; bitpos: [31]; default: 0;
* After writing 0 or 1 to TIMG_TxUPDATE_REG, the counter value is latched.
*/
uint32_t tx_update: 1;
};
uint32_t val;
} _timg_txupdate_reg_t;
/** Type of txalarmlo register
* Timer x alarm value, low 32 bits
*/
typedef union {
struct {
/** tx_alarm_lo : R/W; bitpos: [31:0]; default: 0;
* Timer x alarm trigger time-base counter value, low 32 bits.
*/
uint32_t tx_alarm_lo: 32;
};
uint32_t val;
} _timg_txalarmlo_reg_t;
/** Type of txalarmhi register
* Timer x alarm value, high bits
*/
typedef union {
struct {
/** tx_alarm_hi : R/W; bitpos: [31:0]; default: 0;
*
*
* Timer x alarm trigger time-base counter value, high 32 bits.
*/
uint32_t tx_alarm_hi: 32;
};
uint32_t val;
} _timg_txalarmhi_reg_t;
/** Type of txloadlo register
* Timer x reload value, low 32 bits
*/
typedef union {
struct {
/** tx_load_lo : R/W; bitpos: [31:0]; default: 0;
*
*
* Low 32 bits of the value that a reload will load onto timer x time-base
*
* Counter.
*/
uint32_t tx_load_lo: 32;
};
uint32_t val;
} _timg_txloadlo_reg_t;
/** Type of txloadhi register
* Timer x reload value, high 32 bits
*/
typedef union {
struct {
/** tx_load_hi : R/W; bitpos: [31:0]; default: 0;
*
*
* High 32 bits of the value that a reload will load onto timer x time-base
*
* counter.
*/
uint32_t tx_load_hi: 32;
};
uint32_t val;
} _timg_txloadhi_reg_t;
/** Type of txload register
* Write to reload timer from TIMG_T0_(LOADLOLOADHI)_REG
*/
typedef union {
struct {
/** tx_load : WO; bitpos: [31:0]; default: 0;
*
*
* Write any value to trigger a timer x time-base counter reload.
*/
uint32_t tx_load: 32;
};
uint32_t val;
} _timg_txload_reg_t;
/** Group: Configuration and Control Register for WDT */
/** Type of wdtconfig0 register
* Watchdog timer configuration register
*/
typedef union {
struct {
uint32_t reserved_0: 14;
/** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1;
* When set, Flash boot protection is enabled.
*/
uint32_t wdt_flashboot_mod_en: 1;
/** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1;
* System reset signal length selection. 0: 100 ns, 1: 200 ns,
*
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/
uint32_t wdt_sys_reset_length: 3;
/** wdt_cpu_reset_length : R/W; bitpos: [20:18]; default: 1;
* CPU reset signal length selection. 0: 100 ns, 1: 200 ns,
*
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/
uint32_t wdt_cpu_reset_length: 3;
/** wdt_level_int_en : R/W; bitpos: [21]; default: 0;
* When set, a level type interrupt will occur at the timeout of a stage
*
* configured to generate an interrupt.
*/
uint32_t wdt_level_int_en: 1;
/** wdt_edge_int_en : R/W; bitpos: [22]; default: 0;
* When set, an edge type interrupt will occur at the timeout of a stage
*
* configured to generate an interrupt.
*/
uint32_t wdt_edge_int_en: 1;
/** wdt_stg3 : R/W; bitpos: [24:23]; default: 0;
* Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*
*/
uint32_t wdt_stg3: 2;
/** wdt_stg2 : R/W; bitpos: [26:25]; default: 0;
* Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*
*/
uint32_t wdt_stg2: 2;
/** wdt_stg1 : R/W; bitpos: [28:27]; default: 0;
* Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*
*/
uint32_t wdt_stg1: 2;
/** wdt_stg0 : R/W; bitpos: [30:29]; default: 0;
* Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*
*/
uint32_t wdt_stg0: 2;
/** wdt_en : R/W; bitpos: [31]; default: 0;
* When set, MWDT is enabled.
*/
uint32_t wdt_en: 1;
};
uint32_t val;
} _timg_wdtconfig0_reg_t;
/** Type of wdtconfig1 register
* Watchdog timer prescaler register
*/
typedef union {
struct {
uint32_t reserved_0: 16;
/** wdt_clk_prescaler : R/W; bitpos: [31:16]; default: 1;
* MWDT clock prescaler value. MWDT clock period = 12.5 ns *
*
* TIMG_WDT_CLK_PRESCALE.
*/
uint32_t wdt_clk_prescaler: 16;
};
uint32_t val;
} _timg_wdtconfig1_reg_t;
/** Type of wdtconfig2 register
* Watchdog timer stage 0 timeout value
*/
typedef union {
struct {
/** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000;
* Stage 0 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg0_hold: 32;
};
uint32_t val;
} _timg_wdtconfig2_reg_t;
/** Type of wdtconfig3 register
* Watchdog timer stage 1 timeout value
*/
typedef union {
struct {
/** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727;
* Stage 1 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg1_hold: 32;
};
uint32_t val;
} _timg_wdtconfig3_reg_t;
/** Type of wdtconfig4 register
* Watchdog timer stage 2 timeout value
*/
typedef union {
struct {
/** wdt_stg2_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 2 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg2_hold: 32;
};
uint32_t val;
} _timg_wdtconfig4_reg_t;
/** Type of wdtconfig5 register
* Watchdog timer stage 3 timeout value
*/
typedef union {
struct {
/** wdt_stg3_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 3 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg3_hold: 32;
};
uint32_t val;
} _timg_wdtconfig5_reg_t;
/** Type of wdtfeed register
* Write to feed the watchdog timer
*/
typedef union {
struct {
/** wdt_feed : WO; bitpos: [31:0]; default: 0;
* Write any value to feed the MWDT. (WO)
*/
uint32_t wdt_feed: 32;
};
uint32_t val;
} _timg_wdtfeed_reg_t;
/** Type of wdtwprotect register
* Watchdog write protect register
*/
typedef union {
struct {
/** wdt_wkey : R/W; bitpos: [31:0]; default: 1356348065;
* If the register contains a different value than its reset value, write
*
* protection is enabled.
*/
uint32_t wdt_wkey: 32;
};
uint32_t val;
} _timg_wdtwprotect_reg_t;
/** Group: Configuration and Control Register for RTC CALI */
/** Type of rtccalicfg register
* RTC calibration configuration register
*/
typedef union {
struct {
uint32_t reserved_0: 12;
/** rtc_cali_start_cycling : R/W; bitpos: [12]; default: 1;
* Reserved
*/
uint32_t rtc_cali_start_cycling: 1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1;
* 0:rtcslowclock. 1:clk_80m. 2:xtal_32k.
*/
uint32_t rtc_cali_clk_sel: 2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0;
* Reserved
*/
uint32_t rtc_cali_rdy: 1;
/** rtc_cali_max : R/W; bitpos: [30:16]; default: 1;
* Reserved
*/
uint32_t rtc_cali_max: 15;
/** rtc_cali_start : R/W; bitpos: [31]; default: 0;
* Reserved
*/
uint32_t rtc_cali_start: 1;
};
uint32_t val;
} _timg_rtccalicfg_reg_t;
/** Type of rtccalicfg1 register
* RTC calibration configuration1 register
*/
typedef union {
struct {
uint32_t reserved_0: 7;
/** rtc_cali_value : RO; bitpos: [31:7]; default: 0;
* Reserved
*/
uint32_t rtc_cali_value: 25;
};
uint32_t val;
} _timg_rtccalicfg1_reg_t;
/** Group: Configuration and Control Register for LACT */
/** Type of lactconfig register
* LACT configuration register
*/
typedef union {
struct {
uint32_t reserved_0: 7;
/** lact_rtc_only : R/W; bitpos: [7]; default: 0;
* Reserved
*/
uint32_t lact_rtc_only: 1;
/** lact_cpst_en : R/W; bitpos: [8]; default: 1;
* Reserved
*/
uint32_t lact_cpst_en: 1;
/** lact_lac_en : R/W; bitpos: [9]; default: 1;
* Reserved
*/
uint32_t lact_lac_en: 1;
/** lact_alarm_en : R/W; bitpos: [10]; default: 0;
* Reserved
*/
uint32_t lact_alarm_en: 1;
/** lact_level_int_en : R/W; bitpos: [11]; default: 0;
* Reserved
*/
uint32_t lact_level_int_en: 1;
/** lact_edge_int_en : R/W; bitpos: [12]; default: 0;
* Reserved
*/
uint32_t lact_edge_int_en: 1;
/** lact_divider : R/W; bitpos: [28:13]; default: 1;
* Reserved
*/
uint32_t lact_divider: 16;
/** lact_autoreload : R/W; bitpos: [29]; default: 1;
* Reserved
*/
uint32_t lact_autoreload: 1;
/** lact_increase : R/W; bitpos: [30]; default: 1;
* Reserved
*/
uint32_t lact_increase: 1;
/** lact_en : R/W; bitpos: [31]; default: 0;
* Reserved
*/
uint32_t lact_en: 1;
};
uint32_t val;
} _timg_lactconfig_reg_t;
/** Type of lactrtc register
* LACT RTC register
*/
typedef union {
struct {
uint32_t reserved_0: 6;
/** lact_rtc_step_len : R/W; bitpos: [31:6]; default: 0;
* Reserved
*/
uint32_t lact_rtc_step_len: 26;
};
uint32_t val;
} _timg_lactrtc_reg_t;
/** Type of lactlo register
* LACT low register
*/
typedef union {
struct {
/** lact_lo : RO; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_lo: 32;
};
uint32_t val;
} _timg_lactlo_reg_t;
/** Type of lacthi register
* LACT high register
*/
typedef union {
struct {
/** lact_hi : RO; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_hi: 32;
};
uint32_t val;
} _timg_lacthi_reg_t;
/** Type of lactupdate register
* LACT update register
*/
typedef union {
struct {
/** lact_update : WO; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_update: 32;
};
uint32_t val;
} _timg_lactupdate_reg_t;
/** Type of lactalarmlo register
* LACT alarm low register
*/
typedef union {
struct {
/** lact_alarm_lo : R/W; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_alarm_lo: 32;
};
uint32_t val;
} _timg_lactalarmlo_reg_t;
/** Type of lactalarmhi register
* LACT alarm high register
*/
typedef union {
struct {
/** lact_alarm_hi : R/W; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_alarm_hi: 32;
};
uint32_t val;
} _timg_lactalarmhi_reg_t;
/** Type of lactloadlo register
* LACT load low register
*/
typedef union {
struct {
/** lact_load_lo : R/W; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_load_lo: 32;
};
uint32_t val;
} _timg_lactloadlo_reg_t;
/** Type of lactloadhi register
* Timer LACT load high register
*/
typedef union {
struct {
/** lact_load_hi : R/W; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_load_hi: 32;
};
uint32_t val;
} _timg_lactloadhi_reg_t;
/** Type of lactload register
* Timer LACT load register
*/
typedef union {
struct {
/** lact_load : WO; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_load: 32;
};
uint32_t val;
} _timg_lactload_reg_t;
/** Group: Interrupt Register */
/** Type of int_ena_timers register
* Interrupt enable bits
*/
typedef union {
struct {
/** tx_int_ena : R/W; bitpos: [0]; default: 0;
* The interrupt enable bit for the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_ena: 1;
/** t1_int_ena : R/W; bitpos: [1]; default: 0;
* The interrupt enable bit for the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_ena: 1;
/** wdt_int_ena : R/W; bitpos: [2]; default: 0;
* The interrupt enable bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_ena: 1;
/** lact_int_ena : R/W; bitpos: [3]; default: 0;
* The interrupt enable bit for the TIMG_LACT_INT interrupt.
*/
uint32_t lact_int_ena: 1;
uint32_t reserved_4: 28;
};
uint32_t val;
} _timg_int_ena_timers_reg_t;
/** Type of int_raw_timers register
* Raw interrupt status
*/
typedef union {
struct {
/** t0_int_raw : RO; bitpos: [0]; default: 0;
* The raw interrupt status bit for the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_raw: 1;
/** t1_int_raw : RO; bitpos: [1]; default: 0;
* The raw interrupt status bit for the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_raw: 1;
/** wdt_int_raw : RO; bitpos: [2]; default: 0;
* The raw interrupt status bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_raw: 1;
/** lact_int_raw : RO; bitpos: [3]; default: 0;
* The raw interrupt status bit for the TIMG_LACT_INT interrupt.
*/
uint32_t lact_int_raw: 1;
uint32_t reserved_4: 28;
};
uint32_t val;
} _timg_int_raw_timers_reg_t;
/** Type of int_st_timers register
* Masked interrupt status
*/
typedef union {
struct {
/** t0_int_st : RO; bitpos: [0]; default: 0;
* The masked interrupt status bit for the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_st: 1;
/** t1_int_st : RO; bitpos: [1]; default: 0;
* The masked interrupt status bit for the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_st: 1;
/** wdt_int_st : RO; bitpos: [2]; default: 0;
* The masked interrupt status bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_st: 1;
/** lact_int_st : RO; bitpos: [3]; default: 0;
* The masked interrupt status bit for the TIMG_LACT_INT interrupt.
*/
uint32_t lact_int_st: 1;
uint32_t reserved_4: 28;
};
uint32_t val;
} _timg_int_st_timers_reg_t;
/** Type of int_clr_timers register
* Interrupt clear bits
*/
typedef union {
struct {
/** t0_int_clr : WO; bitpos: [0]; default: 0;
* Set this bit to clear the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_clr: 1;
/** t1_int_clr : WO; bitpos: [1]; default: 0;
* Set this bit to clear the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_clr: 1;
/** wdt_int_clr : WO; bitpos: [2]; default: 0;
* Set this bit to clear the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_clr: 1;
/** lact_int_clr : WO; bitpos: [3]; default: 0;
* Set this bit to clear the TIMG_LACT_INT interrupt.
*/
uint32_t lact_int_clr: 1;
uint32_t reserved_4: 28;
};
uint32_t val;
} _timg_int_clr_timers_reg_t;
/** Group: Version Register */
/** Type of timers_date register
* Version control register
*/
typedef union {
struct {
/** timers_date : R/W; bitpos: [27:0]; default: 26243681;
* Version control register.
*/
uint32_t timers_date: 28;
uint32_t reserved_28: 4;
};
uint32_t val;
} _timg_timers_date_reg_t;
/** Group: Configuration Register */
/** Type of regclk register
* Timer group clock gate register
*/
typedef union {
struct {
uint32_t reserved_0: 31;
/** clk_en : R/W; bitpos: [31]; default: 0;
* Register clock gate signal. 1: Registers can be read and written to by software. 0:
* Registers can not be read or written to by software.
*/
uint32_t clk_en: 1;
};
uint32_t val;
} _timg_regclk_reg_t;
typedef struct {
volatile _timg_txconfig_reg_t config;
volatile _timg_txlo_reg_t lo;
volatile _timg_txhi_reg_t hi;
volatile _timg_txupdate_reg_t update;
volatile _timg_txalarmlo_reg_t alarmlo;
volatile _timg_txalarmhi_reg_t alarmhi;
volatile _timg_txloadlo_reg_t loadlo;
volatile _timg_txloadhi_reg_t loadhi;
volatile _timg_txload_reg_t load;
} _timg_hwtimer_reg_t;
typedef struct _timg_dev_t {
volatile _timg_hwtimer_reg_t hw_timer[2];
volatile _timg_wdtconfig0_reg_t wdtconfig0;
volatile _timg_wdtconfig1_reg_t wdtconfig1;
volatile _timg_wdtconfig2_reg_t wdtconfig2;
volatile _timg_wdtconfig3_reg_t wdtconfig3;
volatile _timg_wdtconfig4_reg_t wdtconfig4;
volatile _timg_wdtconfig5_reg_t wdtconfig5;
volatile _timg_wdtfeed_reg_t wdtfeed;
volatile _timg_wdtwprotect_reg_t wdtwprotect;
volatile _timg_rtccalicfg_reg_t rtccalicfg;
volatile _timg_rtccalicfg1_reg_t rtccalicfg1;
volatile _timg_lactconfig_reg_t lactconfig;
volatile _timg_lactrtc_reg_t lactrtc;
volatile _timg_lactlo_reg_t lactlo;
volatile _timg_lacthi_reg_t lacthi;
volatile _timg_lactupdate_reg_t lactupdate;
volatile _timg_lactalarmlo_reg_t lactalarmlo;
volatile _timg_lactalarmhi_reg_t lactalarmhi;
volatile _timg_lactloadlo_reg_t lactloadlo;
volatile _timg_lactloadhi_reg_t lactloadhi;
volatile _timg_lactload_reg_t lactload;
volatile _timg_int_ena_timers_reg_t int_ena_timers;
volatile _timg_int_raw_timers_reg_t int_raw_timers;
volatile _timg_int_st_timers_reg_t int_st_timers;
volatile _timg_int_clr_timers_reg_t int_clr_timers;
uint32_t _reserved_0ac[20];
volatile _timg_timers_date_reg_t timers_date;
volatile _timg_regclk_reg_t regclk;
} _timg_dev_t;
#define TIMERG0_BASE 0x3ff5F000
#define TIMERG1_BASE 0x3ff60000
#define TIMERG0 ((_timg_dev_t*) TIMERG0_BASE)
#define TIMERG1 ((_timg_dev_t*) TIMERG1_BASE)
__attribute__((always_inline))
static inline void timer_ll_enable_alarm(_timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tx_alarm_en = en;
// use level type interrupt
hw->hw_timer[timer_num].config.tx_level_int_en = en;
}
__attribute__((always_inline))
static inline void timer_ll_enable_counter(_timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tx_en = en;
}
__attribute__((always_inline))
static inline void timer_ll_enable_intr(_timg_dev_t *hw, uint32_t timer_num, bool en)
{
if (en) {
hw->int_ena_timers.val |= BIT(timer_num);
} else {
hw->int_ena_timers.val &= ~BIT(timer_num);
}
}
__attribute__((always_inline))
static inline void timer_ll_clear_intr_status(_timg_dev_t *hw, uint32_t timer_num)
{
hw->int_clr_timers.val = BIT(timer_num);
}
__attribute__((always_inline))
static inline uint32_t timer_ll_get_intr_status(_timg_dev_t *hw)
{
return hw->int_st_timers.val;
}
__attribute__((always_inline))
static inline uint32_t timer_ll_get_clock_prescale(_timg_dev_t *hw, uint32_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_divider;
}
#ifdef __cplusplus
}
#endif

View file

@ -1,598 +0,0 @@
/**
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Group: T0 Control and configuration registers */
/** Type of txconfig register
* Timer x configuration register
*/
typedef union {
struct {
uint32_t reserved_0: 9;
/** tx_use_xtal : R/W; bitpos: [9]; default: 0;
* 1: Use XTAL_CLK as the source clock of timer group. 0: Use APB_CLK as the source
* clock of timer group.
*/
uint32_t tx_use_xtal: 1;
/** tx_alarm_en : R/W/SC; bitpos: [10]; default: 0;
* When set, the alarm is enabled. This bit is automatically cleared once an
* alarm occurs.
*/
uint32_t tx_alarm_en: 1;
uint32_t reserved_11: 1;
/** tx_divcnt_rst : WT; bitpos: [12]; default: 0;
* When set, Timer x 's clock divider counter will be reset.
*/
uint32_t tx_divcnt_rst: 1;
/** tx_divider : R/W; bitpos: [28:13]; default: 1;
* Timer x clock (Tx_clk) prescaler value.
*/
uint32_t tx_divider: 16;
/** tx_autoreload : R/W; bitpos: [29]; default: 1;
* When set, timer x auto-reload at alarm is enabled.
*/
uint32_t tx_autoreload: 1;
/** tx_increase : R/W; bitpos: [30]; default: 1;
* When set, the timer x time-base counter will increment every clock tick. When
* cleared, the timer x time-base counter will decrement.
*/
uint32_t tx_increase: 1;
/** tx_en : R/W; bitpos: [31]; default: 0;
* When set, the timer x time-base counter is enabled.
*/
uint32_t tx_en: 1;
};
uint32_t val;
} _timg_txconfig_reg_t;
/** Type of txlo register
* Timer x current value, low 32 bits
*/
typedef union {
struct {
/** tx_lo : RO; bitpos: [31:0]; default: 0;
* After writing to TIMG_TxUPDATE_REG, the low 32 bits of the time-base counter
* of timer x can be read here.
*/
uint32_t tx_lo: 32;
};
uint32_t val;
} _timg_txlo_reg_t;
/** Type of txhi register
* Timer $x current value, high 22 bits
*/
typedef union {
struct {
/** tx_hi : RO; bitpos: [21:0]; default: 0;
* After writing to TIMG_T$xUPDATE_REG, the high 22 bits of the time-base counter
* of timer $x can be read here.
*/
uint32_t tx_hi: 22;
uint32_t reserved_22: 10;
};
uint32_t val;
} _timg_txhi_reg_t;
/** Type of txupdate register
* Write to copy current timer value to TIMGn_T$x_(LO/HI)_REG
*/
typedef union {
struct {
uint32_t reserved_0: 31;
/** tx_update : R/W/SC; bitpos: [31]; default: 0;
* After writing 0 or 1 to TIMG_T$xUPDATE_REG, the counter value is latched.
*/
uint32_t tx_update: 1;
};
uint32_t val;
} _timg_txupdate_reg_t;
/** Type of txalarmlo register
* Timer $x alarm value, low 32 bits
*/
typedef union {
struct {
/** tx_alarm_lo : R/W; bitpos: [31:0]; default: 0;
* Timer $x alarm trigger time-base counter value, low 32 bits.
*/
uint32_t tx_alarm_lo: 32;
};
uint32_t val;
} _timg_txalarmlo_reg_t;
/** Type of txalarmhi register
* Timer $x alarm value, high bits
*/
typedef union {
struct {
/** tx_alarm_hi : R/W; bitpos: [21:0]; default: 0;
* Timer $x alarm trigger time-base counter value, high 22 bits.
*/
uint32_t tx_alarm_hi: 22;
uint32_t reserved_22: 10;
};
uint32_t val;
} _timg_txalarmhi_reg_t;
/** Type of txloadlo register
* Timer $x reload value, low 32 bits
*/
typedef union {
struct {
/** tx_load_lo : R/W; bitpos: [31:0]; default: 0;
* Low 32 bits of the value that a reload will load onto timer $x time-base
* Counter.
*/
uint32_t tx_load_lo: 32;
};
uint32_t val;
} _timg_txloadlo_reg_t;
/** Type of txloadhi register
* Timer $x reload value, high 22 bits
*/
typedef union {
struct {
/** tx_load_hi : R/W; bitpos: [21:0]; default: 0;
* High 22 bits of the value that a reload will load onto timer $x time-base
* counter.
*/
uint32_t tx_load_hi: 22;
uint32_t reserved_22: 10;
};
uint32_t val;
} _timg_txloadhi_reg_t;
/** Type of txload register
* Write to reload timer from TIMG_T$x_(LOADLOLOADHI)_REG
*/
typedef union {
struct {
/** tx_load : WT; bitpos: [31:0]; default: 0;
*
* Write any value to trigger a timer $x time-base counter reload.
*/
uint32_t tx_load: 32;
};
uint32_t val;
} _timg_txload_reg_t;
/** Group: WDT Control and configuration registers */
/** Type of wdtconfig0 register
* Watchdog timer configuration register
*/
typedef union {
struct {
uint32_t reserved_0: 12;
/** wdt_appcpu_reset_en : R/W; bitpos: [12]; default: 0;
* WDT reset CPU enable.
*/
uint32_t wdt_appcpu_reset_en: 1;
/** wdt_procpu_reset_en : R/W; bitpos: [13]; default: 0;
* WDT reset CPU enable.
*/
uint32_t wdt_procpu_reset_en: 1;
/** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1;
* When set, Flash boot protection is enabled.
*/
uint32_t wdt_flashboot_mod_en: 1;
/** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1;
* System reset signal length selection. 0: 100 ns, 1: 200 ns,
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/
uint32_t wdt_sys_reset_length: 3;
/** wdt_cpu_reset_length : R/W; bitpos: [20:18]; default: 1;
* CPU reset signal length selection. 0: 100 ns, 1: 200 ns,
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/
uint32_t wdt_cpu_reset_length: 3;
/** wdt_use_xtal : R/W; bitpos: [21]; default: 0;
* choose WDT clock:0-apb_clk; 1-xtal_clk.
*/
uint32_t wdt_use_xtal: 1;
/** wdt_conf_update_en : WT; bitpos: [22]; default: 0;
* update the WDT configuration registers
*/
uint32_t wdt_conf_update_en: 1;
/** wdt_stg3 : R/W; bitpos: [24:23]; default: 0;
* Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/
uint32_t wdt_stg3: 2;
/** wdt_stg2 : R/W; bitpos: [26:25]; default: 0;
* Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/
uint32_t wdt_stg2: 2;
/** wdt_stg1 : R/W; bitpos: [28:27]; default: 0;
* Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/
uint32_t wdt_stg1: 2;
/** wdt_stg0 : R/W; bitpos: [30:29]; default: 0;
* Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/
uint32_t wdt_stg0: 2;
/** wdt_en : R/W; bitpos: [31]; default: 0;
* When set, MWDT is enabled.
*/
uint32_t wdt_en: 1;
};
uint32_t val;
} _timg_wdtconfig0_reg_t;
/** Type of wdtconfig1 register
* Watchdog timer prescaler register
*/
typedef union {
struct {
/** wdt_divcnt_rst : WT; bitpos: [0]; default: 0;
* When set, WDT 's clock divider counter will be reset.
*/
uint32_t wdt_divcnt_rst: 1;
uint32_t reserved_1: 15;
/** wdt_clk_prescale : R/W; bitpos: [31:16]; default: 1;
* MWDT clock prescaler value. MWDT clock period = 12.5 ns *
* TIMG_WDT_CLK_PRESCALE.
*/
uint32_t wdt_clk_prescale: 16;
};
uint32_t val;
} _timg_wdtconfig1_reg_t;
/** Type of wdtconfig2 register
* Watchdog timer stage 0 timeout value
*/
typedef union {
struct {
/** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000;
* Stage 0 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg0_hold: 32;
};
uint32_t val;
} _timg_wdtconfig2_reg_t;
/** Type of wdtconfig3 register
* Watchdog timer stage 1 timeout value
*/
typedef union {
struct {
/** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727;
* Stage 1 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg1_hold: 32;
};
uint32_t val;
} _timg_wdtconfig3_reg_t;
/** Type of wdtconfig4 register
* Watchdog timer stage 2 timeout value
*/
typedef union {
struct {
/** wdt_stg2_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 2 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg2_hold: 32;
};
uint32_t val;
} _timg_wdtconfig4_reg_t;
/** Type of wdtconfig5 register
* Watchdog timer stage 3 timeout value
*/
typedef union {
struct {
/** wdt_stg3_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 3 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg3_hold: 32;
};
uint32_t val;
} _timg_wdtconfig5_reg_t;
/** Type of wdtfeed register
* Write to feed the watchdog timer
*/
typedef union {
struct {
/** wdt_feed : WT; bitpos: [31:0]; default: 0;
* Write any value to feed the MWDT. (WO)
*/
uint32_t wdt_feed: 32;
};
uint32_t val;
} _timg_wdtfeed_reg_t;
/** Type of wdtwprotect register
* Watchdog write protect register
*/
typedef union {
struct {
/** wdt_wkey : R/W; bitpos: [31:0]; default: 1356348065;
* If the register contains a different value than its reset value, write
* protection is enabled.
*/
uint32_t wdt_wkey: 32;
};
uint32_t val;
} _timg_wdtwprotect_reg_t;
/** Group: RTC CALI Control and configuration registers */
/** Type of rtccalicfg register
* RTC calibration configure register
*/
typedef union {
struct {
uint32_t reserved_0: 12;
/** rtc_cali_start_cycling : R/W; bitpos: [12]; default: 1;
* Reserved
*/
uint32_t rtc_cali_start_cycling: 1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1;
* 0:rtc slow clock. 1:clk_8m, 2:xtal_32k.
*/
uint32_t rtc_cali_clk_sel: 2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0;
* Reserved
*/
uint32_t rtc_cali_rdy: 1;
/** rtc_cali_max : R/W; bitpos: [30:16]; default: 1;
* Reserved
*/
uint32_t rtc_cali_max: 15;
/** rtc_cali_start : R/W; bitpos: [31]; default: 0;
* Reserved
*/
uint32_t rtc_cali_start: 1;
};
uint32_t val;
} _timg_rtccalicfg_reg_t;
/** Type of rtccalicfg1 register
* RTC calibration configure1 register
*/
typedef union {
struct {
/** rtc_cali_cycling_data_vld : RO; bitpos: [0]; default: 0;
* Reserved
*/
uint32_t rtc_cali_cycling_data_vld: 1;
uint32_t reserved_1: 6;
/** rtc_cali_value : RO; bitpos: [31:7]; default: 0;
* Reserved
*/
uint32_t rtc_cali_value: 25;
};
uint32_t val;
} _timg_rtccalicfg1_reg_t;
/** Type of rtccalicfg2 register
* Timer group calibration register
*/
typedef union {
struct {
/** rtc_cali_timeout : RO; bitpos: [0]; default: 0;
* RTC calibration timeout indicator
*/
uint32_t rtc_cali_timeout: 1;
uint32_t reserved_1: 2;
/** rtc_cali_timeout_rst_cnt : R/W; bitpos: [6:3]; default: 3;
* Cycles that release calibration timeout reset
*/
uint32_t rtc_cali_timeout_rst_cnt: 4;
/** rtc_cali_timeout_thres : R/W; bitpos: [31:7]; default: 33554431;
* Threshold value for the RTC calibration timer. If the calibration timer's value
* exceeds this threshold, a timeout is triggered.
*/
uint32_t rtc_cali_timeout_thres: 25;
};
uint32_t val;
} _timg_rtccalicfg2_reg_t;
/** Group: Interrupt registers */
/** Type of int_ena_timers register
* Interrupt enable bits
*/
typedef union {
struct {
/** t0_int_ena : R/W; bitpos: [0]; default: 0;
* The interrupt enable bit for the TIMG_T$x_INT interrupt.
*/
uint32_t t0_int_ena: 1;
/** wdt_int_ena : R/W; bitpos: [1]; default: 0;
* The interrupt enable bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_ena: 1;
uint32_t reserved_2: 30;
};
uint32_t val;
} _timg_int_ena_timers_reg_t;
/** Type of int_raw_timers register
* Raw interrupt status
*/
typedef union {
struct {
/** t0_int_raw : R/SS/WTC; bitpos: [0]; default: 0;
* The raw interrupt status bit for the TIMG_T$x_INT interrupt.
*/
uint32_t t0_int_raw: 1;
/** wdt_int_raw : R/SS/WTC; bitpos: [1]; default: 0;
* The raw interrupt status bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_raw: 1;
uint32_t reserved_2: 30;
};
uint32_t val;
} _timg_int_raw_timers_reg_t;
/** Type of int_st_timers register
* Masked interrupt status
*/
typedef union {
struct {
/** t0_int_st : RO; bitpos: [0]; default: 0;
* The masked interrupt status bit for the TIMG_T$x_INT interrupt.
*/
uint32_t t0_int_st: 1;
/** wdt_int_st : RO; bitpos: [1]; default: 0;
* The masked interrupt status bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_st: 1;
uint32_t reserved_2: 30;
};
uint32_t val;
} _timg_int_st_timers_reg_t;
/** Type of int_clr_timers register
* Interrupt clear bits
*/
typedef union {
struct {
/** t0_int_clr : WT; bitpos: [0]; default: 0;
* Set this bit to clear the TIMG_T$x_INT interrupt.
*/
uint32_t t0_int_clr: 1;
/** wdt_int_clr : WT; bitpos: [1]; default: 0;
* Set this bit to clear the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_clr: 1;
uint32_t reserved_2: 30;
};
uint32_t val;
} _timg_int_clr_timers_reg_t;
/** Group: Version register */
/** Type of ntimers_date register
* Timer version control register
*/
typedef union {
struct {
/** ntimgs_date : R/W; bitpos: [27:0]; default: 33579409;
* Timer version control register
*/
uint32_t ntimgs_date: 28;
uint32_t reserved_28: 4;
};
uint32_t val;
} _timg_ntimers_date_reg_t;
/** Group: Clock configuration registers */
/** Type of regclk register
* Timer group clock gate register
*/
typedef union {
struct {
uint32_t reserved_0: 29;
/** wdt_clk_is_active : R/W; bitpos: [29]; default: 1;
* enable WDT's clock
*/
uint32_t wdt_clk_is_active: 1;
/** timer_clk_is_active : R/W; bitpos: [30]; default: 1;
* enable Timer $x's clock
*/
uint32_t timer_clk_is_active: 1;
/** clk_en : R/W; bitpos: [31]; default: 0;
* Register clock gate signal. 1: Registers can be read and written to by software. 0:
* Registers can not be read or written to by software.
*/
uint32_t clk_en: 1;
};
uint32_t val;
} _timg_regclk_reg_t;
typedef struct {
volatile _timg_txconfig_reg_t config;
volatile _timg_txlo_reg_t lo;
volatile _timg_txhi_reg_t hi;
volatile _timg_txupdate_reg_t update;
volatile _timg_txalarmlo_reg_t alarmlo;
volatile _timg_txalarmhi_reg_t alarmhi;
volatile _timg_txloadlo_reg_t loadlo;
volatile _timg_txloadhi_reg_t loadhi;
volatile _timg_txload_reg_t load;
} _timg_hwtimer_reg_t;
typedef struct _timg_dev_t {
volatile _timg_hwtimer_reg_t hw_timer[1];
uint32_t _reserved_024[9];
volatile _timg_wdtconfig0_reg_t wdtconfig0;
volatile _timg_wdtconfig1_reg_t wdtconfig1;
volatile _timg_wdtconfig2_reg_t wdtconfig2;
volatile _timg_wdtconfig3_reg_t wdtconfig3;
volatile _timg_wdtconfig4_reg_t wdtconfig4;
volatile _timg_wdtconfig5_reg_t wdtconfig5;
volatile _timg_wdtfeed_reg_t wdtfeed;
volatile _timg_wdtwprotect_reg_t wdtwprotect;
volatile _timg_rtccalicfg_reg_t rtccalicfg;
volatile _timg_rtccalicfg1_reg_t rtccalicfg1;
volatile _timg_int_ena_timers_reg_t int_ena_timers;
volatile _timg_int_raw_timers_reg_t int_raw_timers;
volatile _timg_int_st_timers_reg_t int_st_timers;
volatile _timg_int_clr_timers_reg_t int_clr_timers;
volatile _timg_rtccalicfg2_reg_t rtccalicfg2;
uint32_t _reserved_084[29];
volatile _timg_ntimers_date_reg_t ntimers_date;
volatile _timg_regclk_reg_t regclk;
} _timg_dev_t;
#define TIMERG0_BASE 0x6001F000
#define TIMERG1_BASE 0x60020000
#define TIMERG0 ((_timg_dev_t*) TIMERG0_BASE)
#define TIMERG1 ((_timg_dev_t*) TIMERG1_BASE)
__attribute__((always_inline))
static inline void timer_ll_enable_alarm(_timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tx_alarm_en = en;
}
__attribute__((always_inline))
static inline void timer_ll_enable_counter(_timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tx_en = en;
}
__attribute__((always_inline))
static inline void timer_ll_enable_intr(_timg_dev_t *hw, uint32_t timer_num, bool en)
{
if (en) {
hw->int_ena_timers.val |= BIT(timer_num);
} else {
hw->int_ena_timers.val &= ~BIT(timer_num);
}
}
__attribute__((always_inline))
static inline void timer_ll_clear_intr_status(_timg_dev_t *hw, uint32_t timer_num)
{
hw->int_clr_timers.val = BIT(timer_num);
}
static inline uint32_t timer_ll_get_intr_status(_timg_dev_t *hw)
{
return hw->int_st_timers.val;
}
static inline uint32_t timer_ll_get_clock_prescale(_timg_dev_t *hw, uint32_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_divider;
}
#ifdef __cplusplus
}
#endif

View file

@ -1,828 +0,0 @@
/**
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Group: Configuration and Control Register */
/** Type of txconfig register
* Timer x configuration register
*/
typedef union {
struct {
uint32_t reserved_0: 9;
/** tx_use_xtal : R/W; bitpos: [9]; default: 0;
* 1: Use XTAL_CLK as the source clock of timer group. 0: Use APB_CLK as the source
* clock of timer group.
*/
uint32_t tx_use_xtal: 1;
/** tx_alarm_en : R/W; bitpos: [10]; default: 0;
* When set, the alarm is enabled. This bit is automatically cleared once an
*
* alarm occurs.
*/
uint32_t tx_alarm_en: 1;
/** tx_level_int_en : R/W; bitpos: [11]; default: 0;
* When set, an alarm will generate a level type interrupt.
*/
uint32_t tx_level_int_en: 1;
/** tx_edge_int_en : R/W; bitpos: [12]; default: 0;
* When set, an alarm will generate an edge type interrupt.
*/
uint32_t tx_edge_int_en: 1;
/** tx_divider : R/W; bitpos: [28:13]; default: 1;
* Timer x clock (Tx_clk) prescaler value.
*/
uint32_t tx_divider: 16;
/** tx_autoreload : R/W; bitpos: [29]; default: 1;
* When set, timer x auto-reload at alarm is enabled.
*/
uint32_t tx_autoreload: 1;
/** tx_increase : R/W; bitpos: [30]; default: 1;
* When set, the timer x time-base counter will increment every clock tick. When
*
* cleared, the timer x time-base counter will decrement.
*/
uint32_t tx_increase: 1;
/** tx_en : R/W; bitpos: [31]; default: 0;
* When set, the timer x time-base counter is enabled.
*/
uint32_t tx_en: 1;
};
uint32_t val;
} _timg_txconfig_reg_t;
/** Type of txlo register
* Timer x current value, low 32 bits
*/
typedef union {
struct {
/** tx_lo : RO; bitpos: [31:0]; default: 0;
* After writing to TIMG_TxUPDATE_REG, the low 32 bits of the time-base counter
*
* of timer x can be read here.
*/
uint32_t tx_lo: 32;
};
uint32_t val;
} _timg_txlo_reg_t;
/** Type of txhi register
* Timer x current value, high 32 bits
*/
typedef union {
struct {
/** tx_hi : RO; bitpos: [31:0]; default: 0;
* After writing to TIMG_TxUPDATE_REG, the high 32 bits of the time-base counter
*
* of timer x can be read here.
*/
uint32_t tx_hi: 32;
};
uint32_t val;
} _timg_txhi_reg_t;
/** Type of txupdate register
* Write to copy current timer value to TIMGn_Tx_(LO/HI)_REG
*/
typedef union {
struct {
uint32_t reserved_0: 31;
/** tx_update : R/W; bitpos: [31]; default: 0;
* After writing 0 or 1 to TIMG_TxUPDATE_REG, the counter value is latched.
*/
uint32_t tx_update: 1;
};
uint32_t val;
} _timg_txupdate_reg_t;
/** Type of txalarmlo register
* Timer x alarm value, low 32 bits
*/
typedef union {
struct {
/** tx_alarm_lo : R/W; bitpos: [31:0]; default: 0;
* Timer x alarm trigger time-base counter value, low 32 bits.
*/
uint32_t tx_alarm_lo: 32;
};
uint32_t val;
} _timg_txalarmlo_reg_t;
/** Type of txalarmhi register
* Timer x alarm value, high bits
*/
typedef union {
struct {
/** tx_alarm_hi : R/W; bitpos: [31:0]; default: 0;
*
*
* Timer x alarm trigger time-base counter value, high 32 bits.
*/
uint32_t tx_alarm_hi: 32;
};
uint32_t val;
} _timg_txalarmhi_reg_t;
/** Type of txloadlo register
* Timer x reload value, low 32 bits
*/
typedef union {
struct {
/** tx_load_lo : R/W; bitpos: [31:0]; default: 0;
*
*
* Low 32 bits of the value that a reload will load onto timer x time-base
*
* Counter.
*/
uint32_t tx_load_lo: 32;
};
uint32_t val;
} _timg_txloadlo_reg_t;
/** Type of txloadhi register
* Timer x reload value, high 32 bits
*/
typedef union {
struct {
/** tx_load_hi : R/W; bitpos: [31:0]; default: 0;
*
*
* High 32 bits of the value that a reload will load onto timer x time-base
*
* counter.
*/
uint32_t tx_load_hi: 32;
};
uint32_t val;
} _timg_txloadhi_reg_t;
/** Type of txload register
* Write to reload timer from TIMG_T0_(LOADLOLOADHI)_REG
*/
typedef union {
struct {
/** tx_load : WO; bitpos: [31:0]; default: 0;
*
*
* Write any value to trigger a timer x time-base counter reload.
*/
uint32_t tx_load: 32;
};
uint32_t val;
} _timg_txload_reg_t;
/** Group: Configuration and Control Register for WDT */
/** Type of wdtconfig0 register
* Watchdog timer configuration register
*/
typedef union {
struct {
uint32_t reserved_0: 12;
/** wdt_appcpu_reset_en : R/W; bitpos: [12]; default: 0;
* Reserved
*/
uint32_t wdt_appcpu_reset_en: 1;
/** wdt_procpu_reset_en : R/W; bitpos: [13]; default: 0;
* WDT reset CPU enable.
*/
uint32_t wdt_procpu_reset_en: 1;
/** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1;
* When set, Flash boot protection is enabled.
*/
uint32_t wdt_flashboot_mod_en: 1;
/** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1;
* System reset signal length selection. 0: 100 ns, 1: 200 ns,
*
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/
uint32_t wdt_sys_reset_length: 3;
/** wdt_cpu_reset_length : R/W; bitpos: [20:18]; default: 1;
* CPU reset signal length selection. 0: 100 ns, 1: 200 ns,
*
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/
uint32_t wdt_cpu_reset_length: 3;
/** wdt_level_int_en : R/W; bitpos: [21]; default: 0;
* When set, a level type interrupt will occur at the timeout of a stage
*
* configured to generate an interrupt.
*/
uint32_t wdt_level_int_en: 1;
/** wdt_edge_int_en : R/W; bitpos: [22]; default: 0;
* When set, an edge type interrupt will occur at the timeout of a stage
*
* configured to generate an interrupt.
*/
uint32_t wdt_edge_int_en: 1;
/** wdt_stg3 : R/W; bitpos: [24:23]; default: 0;
* Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*
*/
uint32_t wdt_stg3: 2;
/** wdt_stg2 : R/W; bitpos: [26:25]; default: 0;
* Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*
*/
uint32_t wdt_stg2: 2;
/** wdt_stg1 : R/W; bitpos: [28:27]; default: 0;
* Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*
*/
uint32_t wdt_stg1: 2;
/** wdt_stg0 : R/W; bitpos: [30:29]; default: 0;
* Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*
*/
uint32_t wdt_stg0: 2;
/** wdt_en : R/W; bitpos: [31]; default: 0;
* When set, MWDT is enabled.
*/
uint32_t wdt_en: 1;
};
uint32_t val;
} _timg_wdtconfig0_reg_t;
/** Type of wdtconfig1 register
* Watchdog timer prescaler register
*/
typedef union {
struct {
uint32_t reserved_0: 16;
/** wdt_clk_prescaler : R/W; bitpos: [31:16]; default: 1;
* MWDT clock prescaler value. MWDT clock period = 12.5 ns *
*
* TIMG_WDT_CLK_PRESCALE.
*/
uint32_t wdt_clk_prescaler: 16;
};
uint32_t val;
} _timg_wdtconfig1_reg_t;
/** Type of wdtconfig2 register
* Watchdog timer stage 0 timeout value
*/
typedef union {
struct {
/** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000;
* Stage 0 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg0_hold: 32;
};
uint32_t val;
} _timg_wdtconfig2_reg_t;
/** Type of wdtconfig3 register
* Watchdog timer stage 1 timeout value
*/
typedef union {
struct {
/** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727;
* Stage 1 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg1_hold: 32;
};
uint32_t val;
} _timg_wdtconfig3_reg_t;
/** Type of wdtconfig4 register
* Watchdog timer stage 2 timeout value
*/
typedef union {
struct {
/** wdt_stg2_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 2 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg2_hold: 32;
};
uint32_t val;
} _timg_wdtconfig4_reg_t;
/** Type of wdtconfig5 register
* Watchdog timer stage 3 timeout value
*/
typedef union {
struct {
/** wdt_stg3_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 3 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg3_hold: 32;
};
uint32_t val;
} _timg_wdtconfig5_reg_t;
/** Type of wdtfeed register
* Write to feed the watchdog timer
*/
typedef union {
struct {
/** wdt_feed : WO; bitpos: [31:0]; default: 0;
* Write any value to feed the MWDT. (WO)
*/
uint32_t wdt_feed: 32;
};
uint32_t val;
} _timg_wdtfeed_reg_t;
/** Type of wdtwprotect register
* Watchdog write protect register
*/
typedef union {
struct {
/** wdt_wkey : R/W; bitpos: [31:0]; default: 1356348065;
* If the register contains a different value than its reset value, write
*
* protection is enabled.
*/
uint32_t wdt_wkey: 32;
};
uint32_t val;
} _timg_wdtwprotect_reg_t;
/** Group: Configuration and Control Register for RTC CALI */
/** Type of rtccalicfg register
* RTC calibration configuration register
*/
typedef union {
struct {
uint32_t reserved_0: 12;
/** rtc_cali_start_cycling : R/W; bitpos: [12]; default: 1;
* Reserved
*/
uint32_t rtc_cali_start_cycling: 1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1;
* 0:rtcslowclock. 1:clk_80m. 2:xtal_32k.
*/
uint32_t rtc_cali_clk_sel: 2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0;
* Reserved
*/
uint32_t rtc_cali_rdy: 1;
/** rtc_cali_max : R/W; bitpos: [30:16]; default: 1;
* Reserved
*/
uint32_t rtc_cali_max: 15;
/** rtc_cali_start : R/W; bitpos: [31]; default: 0;
* Reserved
*/
uint32_t rtc_cali_start: 1;
};
uint32_t val;
} _timg_rtccalicfg_reg_t;
/** Type of rtccalicfg1 register
* RTC calibration configuration1 register
*/
typedef union {
struct {
/** rtc_cali_cycling_data_vld : RO; bitpos: [0]; default: 0;
* Reserved
*/
uint32_t rtc_cali_cycling_data_vld: 1;
uint32_t reserved_1: 6;
/** rtc_cali_value : RO; bitpos: [31:7]; default: 0;
* Reserved
*/
uint32_t rtc_cali_value: 25;
};
uint32_t val;
} _timg_rtccalicfg1_reg_t;
/** Type of rtccalicfg2 register
* Timer group calibration register
*/
typedef union {
struct {
/** rtc_cali_timeout : RO; bitpos: [0]; default: 0;
* RTC calibration timeout indicator
*/
uint32_t rtc_cali_timeout: 1;
uint32_t reserved_1: 2;
/** rtc_cali_timeout_rst_cnt : R/W; bitpos: [6:3]; default: 3;
* Cycles that release calibration timeout reset
*/
uint32_t rtc_cali_timeout_rst_cnt: 4;
/** rtc_cali_timeout_thres : R/W; bitpos: [31:7]; default: 33554431;
* Threshold value for the RTC calibration timer. If the calibration timer's value
* exceeds this threshold, a timeout is triggered.
*/
uint32_t rtc_cali_timeout_thres: 25;
};
uint32_t val;
} _timg_rtccalicfg2_reg_t;
/** Group: Configuration and Control Register for LACT */
/** Type of lactconfig register
* LACT configuration register
*/
typedef union {
struct {
uint32_t reserved_0: 6;
/** lact_use_reftick : R/W; bitpos: [6]; default: 0;
* Reserved
*/
uint32_t lact_use_reftick: 1;
/** lact_rtc_only : R/W; bitpos: [7]; default: 0;
* Reserved
*/
uint32_t lact_rtc_only: 1;
/** lact_cpst_en : R/W; bitpos: [8]; default: 1;
* Reserved
*/
uint32_t lact_cpst_en: 1;
/** lact_lac_en : R/W; bitpos: [9]; default: 1;
* Reserved
*/
uint32_t lact_lac_en: 1;
/** lact_alarm_en : R/W; bitpos: [10]; default: 0;
* Reserved
*/
uint32_t lact_alarm_en: 1;
/** lact_level_int_en : R/W; bitpos: [11]; default: 0;
* Reserved
*/
uint32_t lact_level_int_en: 1;
/** lact_edge_int_en : R/W; bitpos: [12]; default: 0;
* Reserved
*/
uint32_t lact_edge_int_en: 1;
/** lact_divider : R/W; bitpos: [28:13]; default: 1;
* Reserved
*/
uint32_t lact_divider: 16;
/** lact_autoreload : R/W; bitpos: [29]; default: 1;
* Reserved
*/
uint32_t lact_autoreload: 1;
/** lact_increase : R/W; bitpos: [30]; default: 1;
* Reserved
*/
uint32_t lact_increase: 1;
/** lact_en : R/W; bitpos: [31]; default: 0;
* Reserved
*/
uint32_t lact_en: 1;
};
uint32_t val;
} _timg_lactconfig_reg_t;
/** Type of lactrtc register
* LACT RTC register
*/
typedef union {
struct {
uint32_t reserved_0: 6;
/** lact_rtc_step_len : R/W; bitpos: [31:6]; default: 0;
* Reserved
*/
uint32_t lact_rtc_step_len: 26;
};
uint32_t val;
} _timg_lactrtc_reg_t;
/** Type of lactlo register
* LACT low register
*/
typedef union {
struct {
/** lact_lo : RO; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_lo: 32;
};
uint32_t val;
} _timg_lactlo_reg_t;
/** Type of lacthi register
* LACT high register
*/
typedef union {
struct {
/** lact_hi : RO; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_hi: 32;
};
uint32_t val;
} _timg_lacthi_reg_t;
/** Type of lactupdate register
* LACT update register
*/
typedef union {
struct {
/** lact_update : WO; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_update: 32;
};
uint32_t val;
} _timg_lactupdate_reg_t;
/** Type of lactalarmlo register
* LACT alarm low register
*/
typedef union {
struct {
/** lact_alarm_lo : R/W; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_alarm_lo: 32;
};
uint32_t val;
} _timg_lactalarmlo_reg_t;
/** Type of lactalarmhi register
* LACT alarm high register
*/
typedef union {
struct {
/** lact_alarm_hi : R/W; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_alarm_hi: 32;
};
uint32_t val;
} _timg_lactalarmhi_reg_t;
/** Type of lactloadlo register
* LACT load low register
*/
typedef union {
struct {
/** lact_load_lo : R/W; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_load_lo: 32;
};
uint32_t val;
} _timg_lactloadlo_reg_t;
/** Type of lactloadhi register
* Timer LACT load high register
*/
typedef union {
struct {
/** lact_load_hi : R/W; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_load_hi: 32;
};
uint32_t val;
} _timg_lactloadhi_reg_t;
/** Type of lactload register
* Timer LACT load register
*/
typedef union {
struct {
/** lact_load : WO; bitpos: [31:0]; default: 0;
* Reserved
*/
uint32_t lact_load: 32;
};
uint32_t val;
} _timg_lactload_reg_t;
/** Group: Interrupt Register */
/** Type of int_ena_timers register
* Interrupt enable bits
*/
typedef union {
struct {
/** t0_int_ena : R/W; bitpos: [0]; default: 0;
* The interrupt enable bit for the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_ena: 1;
/** t1_int_ena : R/W; bitpos: [1]; default: 0;
* The interrupt enable bit for the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_ena: 1;
/** wdt_int_ena : R/W; bitpos: [2]; default: 0;
* The interrupt enable bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_ena: 1;
/** lact_int_ena : R/W; bitpos: [3]; default: 0;
* The interrupt enable bit for the TIMG_LACT_INT interrupt.
*/
uint32_t lact_int_ena: 1;
uint32_t reserved_4: 28;
};
uint32_t val;
} _timg_int_ena_timers_reg_t;
/** Type of int_raw_timers register
* Raw interrupt status
*/
typedef union {
struct {
/** t0_int_raw : RO; bitpos: [0]; default: 0;
* The raw interrupt status bit for the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_raw: 1;
/** t1_int_raw : RO; bitpos: [1]; default: 0;
* The raw interrupt status bit for the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_raw: 1;
/** wdt_int_raw : RO; bitpos: [2]; default: 0;
* The raw interrupt status bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_raw: 1;
/** lact_int_raw : RO; bitpos: [3]; default: 0;
* The raw interrupt status bit for the TIMG_LACT_INT interrupt.
*/
uint32_t lact_int_raw: 1;
uint32_t reserved_4: 28;
};
uint32_t val;
} _timg_int_raw_timers_reg_t;
/** Type of int_st_timers register
* Masked interrupt status
*/
typedef union {
struct {
/** t0_int_st : RO; bitpos: [0]; default: 0;
* The masked interrupt status bit for the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_st: 1;
/** t1_int_st : RO; bitpos: [1]; default: 0;
* The masked interrupt status bit for the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_st: 1;
/** wdt_int_st : RO; bitpos: [2]; default: 0;
* The masked interrupt status bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_st: 1;
/** lact_int_st : RO; bitpos: [3]; default: 0;
* The masked interrupt status bit for the TIMG_LACT_INT interrupt.
*/
uint32_t lact_int_st: 1;
uint32_t reserved_4: 28;
};
uint32_t val;
} _timg_int_st_timers_reg_t;
/** Type of int_clr_timers register
* Interrupt clear bits
*/
typedef union {
struct {
/** t0_int_clr : WO; bitpos: [0]; default: 0;
* Set this bit to clear the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_clr: 1;
/** t1_int_clr : WO; bitpos: [1]; default: 0;
* Set this bit to clear the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_clr: 1;
/** wdt_int_clr : WO; bitpos: [2]; default: 0;
* Set this bit to clear the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_clr: 1;
/** lact_int_clr : WO; bitpos: [3]; default: 0;
* Set this bit to clear the TIMG_LACT_INT interrupt.
*/
uint32_t lact_int_clr: 1;
uint32_t reserved_4: 28;
};
uint32_t val;
} _timg_int_clr_timers_reg_t;
/** Group: Version Register */
/** Type of timers_date register
* Version control register
*/
typedef union {
struct {
/** timers_date : R/W; bitpos: [27:0]; default: 26243681;
* Version control register.
*/
uint32_t timers_date: 28;
uint32_t reserved_28: 4;
};
uint32_t val;
} _timg_timers_date_reg_t;
/** Group: Configuration Register */
/** Type of regclk register
* Timer group clock gate register
*/
typedef union {
struct {
uint32_t reserved_0: 31;
/** clk_en : R/W; bitpos: [31]; default: 0;
* Register clock gate signal. 1: Registers can be read and written to by software. 0:
* Registers can not be read or written to by software.
*/
uint32_t clk_en: 1;
};
uint32_t val;
} _timg_regclk_reg_t;
typedef struct {
volatile _timg_txconfig_reg_t config;
volatile _timg_txlo_reg_t lo;
volatile _timg_txhi_reg_t hi;
volatile _timg_txupdate_reg_t update;
volatile _timg_txalarmlo_reg_t alarmlo;
volatile _timg_txalarmhi_reg_t alarmhi;
volatile _timg_txloadlo_reg_t loadlo;
volatile _timg_txloadhi_reg_t loadhi;
volatile _timg_txload_reg_t load;
} _timg_hwtimer_reg_t;
typedef struct _timg_dev_t {
volatile _timg_hwtimer_reg_t hw_timer[2];
volatile _timg_wdtconfig0_reg_t wdtconfig0;
volatile _timg_wdtconfig1_reg_t wdtconfig1;
volatile _timg_wdtconfig2_reg_t wdtconfig2;
volatile _timg_wdtconfig3_reg_t wdtconfig3;
volatile _timg_wdtconfig4_reg_t wdtconfig4;
volatile _timg_wdtconfig5_reg_t wdtconfig5;
volatile _timg_wdtfeed_reg_t wdtfeed;
volatile _timg_wdtwprotect_reg_t wdtwprotect;
volatile _timg_rtccalicfg_reg_t rtccalicfg;
volatile _timg_rtccalicfg1_reg_t rtccalicfg1;
volatile _timg_lactconfig_reg_t lactconfig;
volatile _timg_lactrtc_reg_t lactrtc;
volatile _timg_lactlo_reg_t lactlo;
volatile _timg_lacthi_reg_t lacthi;
volatile _timg_lactupdate_reg_t lactupdate;
volatile _timg_lactalarmlo_reg_t lactalarmlo;
volatile _timg_lactalarmhi_reg_t lactalarmhi;
volatile _timg_lactloadlo_reg_t lactloadlo;
volatile _timg_lactloadhi_reg_t lactloadhi;
volatile _timg_lactload_reg_t lactload;
volatile _timg_int_ena_timers_reg_t int_ena_timers;
volatile _timg_int_raw_timers_reg_t int_raw_timers;
volatile _timg_int_st_timers_reg_t int_st_timers;
volatile _timg_int_clr_timers_reg_t int_clr_timers;
volatile _timg_rtccalicfg2_reg_t rtccalicfg2;
uint32_t _reserved_0ac[19];
volatile _timg_timers_date_reg_t timers_date;
volatile _timg_regclk_reg_t regclk;
} _timg_dev_t;
#define TIMERG0_BASE 0x3f41F000
#define TIMERG1_BASE 0x3f420000
#define TIMERG0 ((_timg_dev_t*) TIMERG0_BASE)
#define TIMERG1 ((_timg_dev_t*) TIMERG1_BASE)
__attribute__((always_inline))
static inline void timer_ll_enable_alarm(_timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tx_alarm_en = en;
// use level type interrupt
hw->hw_timer[timer_num].config.tx_level_int_en = en;
}
__attribute__((always_inline))
static inline void timer_ll_enable_counter(_timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tx_en = en;
}
__attribute__((always_inline))
static inline void timer_ll_enable_intr(_timg_dev_t *hw, uint32_t timer_num, bool en)
{
if (en) {
hw->int_ena_timers.val |= BIT(timer_num);
} else {
hw->int_ena_timers.val &= ~BIT(timer_num);
}
}
__attribute__((always_inline))
static inline void timer_ll_clear_intr_status(_timg_dev_t *hw, uint32_t timer_num)
{
hw->int_clr_timers.val = BIT(timer_num);
}
static inline uint32_t timer_ll_get_intr_status(_timg_dev_t *hw)
{
return hw->int_st_timers.val;
}
static inline uint32_t timer_ll_get_clock_prescale(_timg_dev_t *hw, uint32_t timer_num)
{
return hw->hw_timer[timer_num].config.tx_divider;
}
#ifdef __cplusplus
}
#endif

View file

@ -1,593 +0,0 @@
/**
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Group: Configuration and control registers */
/** Type of tnconfig register
* Timer n configuration register
*/
typedef union {
struct {
uint32_t reserved_0: 9;
/** tn_use_xtal : R/W; bitpos: [9]; default: 0;
* 1: Use XTAL_CLK as the source clock of timer group. 0: Use APB_CLK as the source
* clock of timer group.
*/
uint32_t tn_use_xtal: 1;
/** tn_alarm_en : R/W/SC; bitpos: [10]; default: 0;
* When set, the alarm is enabled. This bit is automatically cleared once an
* alarm occurs.
*/
uint32_t tn_alarm_en: 1;
uint32_t reserved_11: 1;
/** tn_divcnt_rst : WT; bitpos: [12]; default: 0;
* When set, Timer n 's clock divider counter will be reset.
*/
uint32_t tn_divcnt_rst: 1;
/** tn_divider : R/W; bitpos: [28:13]; default: 1;
* Timer n clock (Tn_clk) prescaler value.
*/
uint32_t tn_divider: 16;
/** tn_autoreload : R/W; bitpos: [29]; default: 1;
* When set, timer n auto-reload at alarm is enabled.
*/
uint32_t tn_autoreload: 1;
/** tn_increase : R/W; bitpos: [30]; default: 1;
* When set, the timer n time-base counter will increment every clock tick. When
* cleared, the timer n time-base counter will decrement.
*/
uint32_t tn_increase: 1;
/** tn_en : R/W; bitpos: [31]; default: 0;
* When set, the timer n time-base counter is enabled.
*/
uint32_t tn_en: 1;
};
uint32_t val;
} _timg_tnconfig_reg_t;
/** Type of tnlo register
* Timer n current value, low 32 bits
*/
typedef union {
struct {
/** tn_lo : RO; bitpos: [31:0]; default: 0;
* After writing to TIMG_TnUPDATE_REG, the low 32 bits of the time-base counter
* of timer n can be read here.
*/
uint32_t tn_lo: 32;
};
uint32_t val;
} _timg_tnlo_reg_t;
/** Type of tnhi register
* Timer n current value, high 22 bits
*/
typedef union {
struct {
/** tn_hi : RO; bitpos: [21:0]; default: 0;
* After writing to TIMG_TnUPDATE_REG, the high 22 bits of the time-base counter
* of timer n can be read here.
*/
uint32_t tn_hi: 22;
uint32_t reserved_22: 10;
};
uint32_t val;
} _timg_tnhi_reg_t;
/** Type of tnupdate register
* Write to copy current timer value to TIMGn_Tn_(LO/HI)_REG
*/
typedef union {
struct {
uint32_t reserved_0: 31;
/** tn_update : R/W/SC; bitpos: [31]; default: 0;
* After writing 0 or 1 to TIMG_TnUPDATE_REG, the counter value is latched.
*/
uint32_t tn_update: 1;
};
uint32_t val;
} _timg_tnupdate_reg_t;
/** Type of tnalarmlo register
* Timer n alarm value, low 32 bits
*/
typedef union {
struct {
/** tn_alarm_lo : R/W; bitpos: [31:0]; default: 0;
* Timer n alarm trigger time-base counter value, low 32 bits.
*/
uint32_t tn_alarm_lo: 32;
};
uint32_t val;
} _timg_tnalarmlo_reg_t;
/** Type of tnalarmhi register
* Timer n alarm value, high bits
*/
typedef union {
struct {
/** tn_alarm_hi : R/W; bitpos: [21:0]; default: 0;
* Timer n alarm trigger time-base counter value, high 22 bits.
*/
uint32_t tn_alarm_hi: 22;
uint32_t reserved_22: 10;
};
uint32_t val;
} _timg_tnalarmhi_reg_t;
/** Type of tnloadlo register
* Timer n reload value, low 32 bits
*/
typedef union {
struct {
/** tn_load_lo : R/W; bitpos: [31:0]; default: 0;
* Low 32 bits of the value that a reload will load onto timer n time-base
* Counter.
*/
uint32_t tn_load_lo: 32;
};
uint32_t val;
} _timg_tnloadlo_reg_t;
/** Type of tnloadhi register
* Timer n reload value, high 22 bits
*/
typedef union {
struct {
/** tn_load_hi : R/W; bitpos: [21:0]; default: 0;
* High 22 bits of the value that a reload will load onto timer n time-base
* counter.
*/
uint32_t tn_load_hi: 22;
uint32_t reserved_22: 10;
};
uint32_t val;
} _timg_tnloadhi_reg_t;
/** Type of tnload register
* Write to reload timer from TIMG_Tn_(LOADLOLOADHI)_REG
*/
typedef union {
struct {
/** tn_load : WT; bitpos: [31:0]; default: 0;
*
* Write any value to trigger a timer n time-base counter reload.
*/
uint32_t tn_load: 32;
};
uint32_t val;
} _timg_tnload_reg_t;
/** Group: Configuration and control registers for WDT */
/** Type of wdtconfig0 register
* Watchdog timer configuration register
*/
typedef union {
struct {
uint32_t reserved_0: 12;
/** wdt_appcpu_reset_en : R/W; bitpos: [12]; default: 0;
* Reserved
*/
uint32_t wdt_appcpu_reset_en: 1;
/** wdt_procpu_reset_en : R/W; bitpos: [13]; default: 0;
* WDT reset CPU enable.
*/
uint32_t wdt_procpu_reset_en: 1;
/** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1;
* When set, Flash boot protection is enabled.
*/
uint32_t wdt_flashboot_mod_en: 1;
/** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1;
* System reset signal length selection. 0: 100 ns, 1: 200 ns,
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/
uint32_t wdt_sys_reset_length: 3;
/** wdt_cpu_reset_length : R/W; bitpos: [20:18]; default: 1;
* CPU reset signal length selection. 0: 100 ns, 1: 200 ns,
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/
uint32_t wdt_cpu_reset_length: 3;
uint32_t reserved_21: 2;
/** wdt_stg3 : R/W; bitpos: [24:23]; default: 0;
* Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/
uint32_t wdt_stg3: 2;
/** wdt_stg2 : R/W; bitpos: [26:25]; default: 0;
* Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/
uint32_t wdt_stg2: 2;
/** wdt_stg1 : R/W; bitpos: [28:27]; default: 0;
* Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/
uint32_t wdt_stg1: 2;
/** wdt_stg0 : R/W; bitpos: [30:29]; default: 0;
* Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/
uint32_t wdt_stg0: 2;
/** wdt_en : R/W; bitpos: [31]; default: 0;
* When set, MWDT is enabled.
*/
uint32_t wdt_en: 1;
};
uint32_t val;
} _timg_wdtconfig0_reg_t;
/** Type of wdtconfig1 register
* Watchdog timer prescaler register
*/
typedef union {
struct {
uint32_t reserved_0: 16;
/** wdt_clk_prescale : R/W; bitpos: [31:16]; default: 1;
* MWDT clock prescaler value. MWDT clock period = 12.5 ns *
* TIMG_WDT_CLK_PRESCALE.
*/
uint32_t wdt_clk_prescale: 16;
};
uint32_t val;
} _timg_wdtconfig1_reg_t;
/** Type of wdtconfig2 register
* Watchdog timer stage 0 timeout value
*/
typedef union {
struct {
/** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000;
* Stage 0 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg0_hold: 32;
};
uint32_t val;
} _timg_wdtconfig2_reg_t;
/** Type of wdtconfig3 register
* Watchdog timer stage 1 timeout value
*/
typedef union {
struct {
/** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727;
* Stage 1 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg1_hold: 32;
};
uint32_t val;
} _timg_wdtconfig3_reg_t;
/** Type of wdtconfig4 register
* Watchdog timer stage 2 timeout value
*/
typedef union {
struct {
/** wdt_stg2_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 2 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg2_hold: 32;
};
uint32_t val;
} _timg_wdtconfig4_reg_t;
/** Type of wdtconfig5 register
* Watchdog timer stage 3 timeout value
*/
typedef union {
struct {
/** wdt_stg3_hold : R/W; bitpos: [31:0]; default: 1048575;
* Stage 3 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg3_hold: 32;
};
uint32_t val;
} _timg_wdtconfig5_reg_t;
/** Type of wdtfeed register
* Write to feed the watchdog timer
*/
typedef union {
struct {
/** wdt_feed : WT; bitpos: [31:0]; default: 0;
* Write any value to feed the MWDT. (WO)
*/
uint32_t wdt_feed: 32;
};
uint32_t val;
} _timg_wdtfeed_reg_t;
/** Type of wdtwprotect register
* Watchdog write protect register
*/
typedef union {
struct {
/** wdt_wkey : R/W; bitpos: [31:0]; default: 1356348065;
* If the register contains a different value than its reset value, write
* protection is enabled.
*/
uint32_t wdt_wkey: 32;
};
uint32_t val;
} _timg_wdtwprotect_reg_t;
/** Group: Configuration and control registers for RTC CALI */
/** Type of rtccalicfg register
* RTC calibration configure register
*/
typedef union {
struct {
uint32_t reserved_0: 12;
/** rtc_cali_start_cycling : R/W; bitpos: [12]; default: 1;
* Reserved
*/
uint32_t rtc_cali_start_cycling: 1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1;
* 0:rtc slow clock. 1:clk_80m. 2:xtal_32k.
*/
uint32_t rtc_cali_clk_sel: 2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0;
* Reserved
*/
uint32_t rtc_cali_rdy: 1;
/** rtc_cali_max : R/W; bitpos: [30:16]; default: 1;
* Reserved
*/
uint32_t rtc_cali_max: 15;
/** rtc_cali_start : R/W; bitpos: [31]; default: 0;
* Reserved
*/
uint32_t rtc_cali_start: 1;
};
uint32_t val;
} _timg_rtccalicfg_reg_t;
/** Type of rtccalicfg1 register
* RTC calibration configure1 register
*/
typedef union {
struct {
/** rtc_cali_cycling_data_vld : RO; bitpos: [0]; default: 0;
* Reserved
*/
uint32_t rtc_cali_cycling_data_vld: 1;
uint32_t reserved_1: 6;
/** rtc_cali_value : RO; bitpos: [31:7]; default: 0;
* Reserved
*/
uint32_t rtc_cali_value: 25;
};
uint32_t val;
} _timg_rtccalicfg1_reg_t;
/** Type of rtccalicfg2 register
* Timer group calibration register
*/
typedef union {
struct {
/** rtc_cali_timeout : RO; bitpos: [0]; default: 0;
* RTC calibration timeout indicator
*/
uint32_t rtc_cali_timeout: 1;
uint32_t reserved_1: 2;
/** rtc_cali_timeout_rst_cnt : R/W; bitpos: [6:3]; default: 3;
* Cycles that release calibration timeout reset
*/
uint32_t rtc_cali_timeout_rst_cnt: 4;
/** rtc_cali_timeout_thres : R/W; bitpos: [31:7]; default: 33554431;
* Threshold value for the RTC calibration timer. If the calibration timer's value
* exceeds this threshold, a timeout is triggered.
*/
uint32_t rtc_cali_timeout_thres: 25;
};
uint32_t val;
} _timg_rtccalicfg2_reg_t;
/** Group: Interrupt registers */
/** Type of int_ena_timers register
* Interrupt enable bits
*/
typedef union {
struct {
/** t0_int_ena : R/W; bitpos: [0]; default: 0;
* The interrupt enable bit for the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_ena: 1;
/** t1_int_ena : R/W; bitpos: [1]; default: 0;
* The interrupt enable bit for the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_ena: 1;
/** wdt_int_ena : R/W; bitpos: [2]; default: 0;
* The interrupt enable bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_ena: 1;
uint32_t reserved_3: 29;
};
uint32_t val;
} _timg_int_ena_timers_reg_t;
/** Type of int_raw_timers register
* Raw interrupt status
*/
typedef union {
struct {
/** t0_int_raw : R/WTC/SS; bitpos: [0]; default: 0;
* The raw interrupt status bit for the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_raw: 1;
/** t1_int_raw : R/WTC/SS; bitpos: [1]; default: 0;
* The raw interrupt status bit for the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_raw: 1;
/** wdt_int_raw : R/WTC/SS; bitpos: [2]; default: 0;
* The raw interrupt status bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_raw: 1;
uint32_t reserved_3: 29;
};
uint32_t val;
} _timg_int_raw_timers_reg_t;
/** Type of int_st_timers register
* Masked interrupt status
*/
typedef union {
struct {
/** t0_int_st : RO; bitpos: [0]; default: 0;
* The masked interrupt status bit for the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_st: 1;
/** t1_int_st : RO; bitpos: [1]; default: 0;
* The masked interrupt status bit for the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_st: 1;
/** wdt_int_st : RO; bitpos: [2]; default: 0;
* The masked interrupt status bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_st: 1;
uint32_t reserved_3: 29;
};
uint32_t val;
} _timg_int_st_timers_reg_t;
/** Type of int_clr_timers register
* Interrupt clear bits
*/
typedef union {
struct {
/** t0_int_clr : WT; bitpos: [0]; default: 0;
* Set this bit to clear the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_clr: 1;
/** t1_int_clr : WT; bitpos: [1]; default: 0;
* Set this bit to clear the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_clr: 1;
/** wdt_int_clr : WT; bitpos: [2]; default: 0;
* Set this bit to clear the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_clr: 1;
uint32_t reserved_3: 29;
};
uint32_t val;
} _timg_int_clr_timers_reg_t;
/** Group: Configuration registers */
/** Type of ntimers_date register
* Timer version control register
*/
typedef union {
struct {
/** ntimers_date : R/W; bitpos: [27:0]; default: 33566833;
* Timer version control register
*/
uint32_t ntimers_date: 28;
uint32_t reserved_28: 4;
};
uint32_t val;
} _timg_ntimers_date_reg_t;
/** Type of regclk register
* Timer group clock gate register
*/
typedef union {
struct {
uint32_t reserved_0: 31;
/** clk_en : R/W; bitpos: [31]; default: 0;
* Register clock gate signal. 1: The clock for software to read and write registers
* is always on. 0: The clock for software to read and write registers only exits when
* the operation happens.
*/
uint32_t clk_en: 1;
};
uint32_t val;
} _timg_regclk_reg_t;
typedef struct {
volatile _timg_tnconfig_reg_t config;
volatile _timg_tnlo_reg_t lo;
volatile _timg_tnhi_reg_t hi;
volatile _timg_tnupdate_reg_t update;
volatile _timg_tnalarmlo_reg_t alarmlo;
volatile _timg_tnalarmhi_reg_t alarmhi;
volatile _timg_tnloadlo_reg_t loadlo;
volatile _timg_tnloadhi_reg_t loadhi;
volatile _timg_tnload_reg_t load;
} _timg_hwtimer_reg_t;
typedef struct _timg_dev_t {
volatile _timg_hwtimer_reg_t hw_timer[2];
volatile _timg_wdtconfig0_reg_t wdtconfig0;
volatile _timg_wdtconfig1_reg_t wdtconfig1;
volatile _timg_wdtconfig2_reg_t wdtconfig2;
volatile _timg_wdtconfig3_reg_t wdtconfig3;
volatile _timg_wdtconfig4_reg_t wdtconfig4;
volatile _timg_wdtconfig5_reg_t wdtconfig5;
volatile _timg_wdtfeed_reg_t wdtfeed;
volatile _timg_wdtwprotect_reg_t wdtwprotect;
volatile _timg_rtccalicfg_reg_t rtccalicfg;
volatile _timg_rtccalicfg1_reg_t rtccalicfg1;
volatile _timg_int_ena_timers_reg_t int_ena_timers;
volatile _timg_int_raw_timers_reg_t int_raw_timers;
volatile _timg_int_st_timers_reg_t int_st_timers;
volatile _timg_int_clr_timers_reg_t int_clr_timers;
volatile _timg_rtccalicfg2_reg_t rtccalicfg2;
uint32_t _reserved_084[29];
volatile _timg_ntimers_date_reg_t ntimers_date;
volatile _timg_regclk_reg_t regclk;
} _timg_dev_t;
#define TIMERG0_BASE 0x6001F000
#define TIMERG1_BASE 0x60020000
#define TIMERG0 ((_timg_dev_t*) TIMERG0_BASE)
#define TIMERG1 ((_timg_dev_t*) TIMERG1_BASE)
__attribute__((always_inline))
static inline void timer_ll_enable_alarm(_timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tn_alarm_en = en;
}
__attribute__((always_inline))
static inline void timer_ll_enable_counter(_timg_dev_t *hw, uint32_t timer_num, bool en)
{
hw->hw_timer[timer_num].config.tn_en = en;
}
__attribute__((always_inline))
static inline void timer_ll_enable_intr(_timg_dev_t *hw, uint32_t timer_num, bool en)
{
if (en) {
hw->int_ena_timers.val |= BIT(timer_num);
} else {
hw->int_ena_timers.val &= ~BIT(timer_num);
}
}
__attribute__((always_inline))
static inline void timer_ll_clear_intr_status(_timg_dev_t *hw, uint32_t timer_num)
{
hw->int_clr_timers.val = BIT(timer_num);
}
static inline uint32_t timer_ll_get_intr_status(_timg_dev_t *hw)
{
return hw->int_st_timers.val;
}
static inline uint32_t timer_ll_get_clock_prescale(_timg_dev_t *hw, uint32_t timer_num)
{
return hw->hw_timer[timer_num].config.tn_divider;
}
#ifdef __cplusplus
}
#endif

View file

@ -1,524 +0,0 @@
// Copyright 2010-2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#if CONFIG_IDF_TARGET_ESP32S3
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_heap_caps.h"
#include "esp_log.h"
#include "esp32s3/rom/lldesc.h"
#include "esp32s3/rom/gpio.h"
#include "driver/gpio.h"
#include "soc/gpio_periph.h"
#include "soc/system_reg.h"
#include "soc/lcd_cam_struct.h"
#include "soc/lcd_cam_reg.h"
#include "soc/gdma_struct.h"
#include "soc/gdma_periph.h"
#include "soc/gdma_reg.h"
#include "i2s_lcd_driver.h"
static const char *TAG = "ESP32S3_LCD";
#define LCD_CHECK(a, str, ret) if (!(a)) { \
ESP_LOGE(TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
return (ret); \
}
#define LCD_CAM_DMA_NODE_BUFFER_MAX_SIZE (4000)
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
#define ets_delay_us esp_rom_delay_us
#define portTICK_RATE_MS portTICK_PERIOD_MS
#endif
typedef struct {
uint32_t dma_buffer_size;
uint32_t dma_half_buffer_size;
uint32_t dma_node_buffer_size;
uint32_t dma_node_cnt;
uint32_t dma_half_node_cnt;
lldesc_t *dma;
uint8_t *dma_buffer;
QueueHandle_t event_queue;
uint8_t width;
bool swap_data;
uint8_t dma_num;
intr_handle_t dma_out_intr_handle;
} lcd_cam_obj_t;
typedef struct {
int rs_io_num;
lcd_cam_obj_t *i2s_lcd_obj;
SemaphoreHandle_t mutex;
} i2s_lcd_driver_t;
static void IRAM_ATTR dma_isr(void *arg)
{
BaseType_t woken = pdFALSE;
lcd_cam_obj_t *lcd_cam_obj = (lcd_cam_obj_t *)arg;
uint32_t out_status = GDMA.channel[lcd_cam_obj->dma_num].out.int_st.val;
if (out_status & GDMA_OUT_EOF_CH0_INT_ST) {
GDMA.channel[lcd_cam_obj->dma_num].out.int_clr.val = GDMA_OUT_EOF_CH0_INT_ST;
xQueueSendFromISR(lcd_cam_obj->event_queue, &out_status, &woken);
}
if (woken == pdTRUE) {
portYIELD_FROM_ISR();
}
}
static void lcd_dma_set_int(lcd_cam_obj_t *lcd_cam_obj)
{
// Generate a data DMA linked list
for (int x = 0; x < lcd_cam_obj->dma_node_cnt; x++) {
lcd_cam_obj->dma[x].size = lcd_cam_obj->dma_node_buffer_size;
lcd_cam_obj->dma[x].length = lcd_cam_obj->dma_node_buffer_size;
lcd_cam_obj->dma[x].buf = (lcd_cam_obj->dma_buffer + lcd_cam_obj->dma_node_buffer_size * x);
lcd_cam_obj->dma[x].eof = !((x + 1) % lcd_cam_obj->dma_half_node_cnt);
lcd_cam_obj->dma[x].empty = (uint32_t)&lcd_cam_obj->dma[(x + 1) % lcd_cam_obj->dma_node_cnt];
}
lcd_cam_obj->dma[lcd_cam_obj->dma_half_node_cnt - 1].empty = (uint32_t)NULL;
lcd_cam_obj->dma[lcd_cam_obj->dma_node_cnt - 1].empty = (uint32_t)NULL;
}
static void lcd_dma_set_left(lcd_cam_obj_t *lcd_cam_obj, int pos, size_t len)
{
int end_pos = 0, size = 0;
// Processing data length is an integer multiple of lcd_cam_obj->lcd.dma_node_buffer_size
if (len % lcd_cam_obj->dma_node_buffer_size) {
end_pos = (pos % 2) * lcd_cam_obj->dma_half_node_cnt + len / lcd_cam_obj->dma_node_buffer_size;
size = len % lcd_cam_obj->dma_node_buffer_size;
} else {
end_pos = (pos % 2) * lcd_cam_obj->dma_half_node_cnt + len / lcd_cam_obj->dma_node_buffer_size - 1;
size = lcd_cam_obj->dma_node_buffer_size;
}
// Process the tail node to make it a DMA tail
lcd_cam_obj->dma[end_pos].size = size;
lcd_cam_obj->dma[end_pos].length = size;
lcd_cam_obj->dma[end_pos].eof = 1;
lcd_cam_obj->dma[end_pos].empty = (uint32_t)NULL;
}
static void lcd_start(uint32_t dma_num, uint32_t addr, size_t len)
{
while (LCD_CAM.lcd_user.lcd_start);
LCD_CAM.lcd_user.lcd_reset = 1;
LCD_CAM.lcd_user.lcd_reset = 0;
LCD_CAM.lcd_misc.lcd_afifo_reset = 1;
LCD_CAM.lcd_misc.lcd_afifo_reset = 0;
while (GDMA.channel[dma_num].out.link.start);
GDMA.channel[dma_num].out.conf0.val = 0;
GDMA.channel[dma_num].out.conf1.val = 0;
GDMA.channel[dma_num].out.int_clr.val = ~0;
GDMA.channel[dma_num].out.int_ena.val = 0;
GDMA.channel[dma_num].out.conf0.out_rst = 1;
GDMA.channel[dma_num].out.conf0.out_rst = 0;
GDMA.channel[dma_num].out.conf0.outdscr_burst_en = 1;
GDMA.channel[dma_num].out.conf0.out_data_burst_en = 1;
GDMA.channel[dma_num].out.peri_sel.sel = 5;
GDMA.channel[dma_num].out.pri.tx_pri = 1;
GDMA.channel[dma_num].out.int_ena.out_eof = 1;
GDMA.channel[dma_num].out.link.addr = addr;
GDMA.channel[dma_num].out.link.start = 1;
ets_delay_us(1);
LCD_CAM.lcd_user.lcd_update = 1;
LCD_CAM.lcd_user.lcd_start = 1;
}
static void lcd_write_data(lcd_cam_obj_t *lcd_cam_obj, const uint8_t *data, size_t len)
{
int event = 0;
int x = 0, left = 0, cnt = 0;
if (len <= 0) {
ESP_LOGE(TAG, "wrong len!");
return;
}
lcd_dma_set_int(lcd_cam_obj);
uint32_t half_buffer_size = lcd_cam_obj->dma_half_buffer_size;
cnt = len / half_buffer_size;
// Start signal
xQueueSend(lcd_cam_obj->event_queue, &event, 0);
// Process a complete piece of data, ping-pong operation
for (x = 0; x < cnt; x++) {
uint8_t *out = (uint8_t *)lcd_cam_obj->dma[(x % 2) * lcd_cam_obj->dma_half_node_cnt].buf;
const uint8_t *in = data;
if (lcd_cam_obj->swap_data) {
LCD_CAM.lcd_user.lcd_8bits_order = 1;
memcpy(out, in, half_buffer_size);
} else {
LCD_CAM.lcd_user.lcd_8bits_order = 0;
memcpy(out, in, half_buffer_size);
}
data += half_buffer_size;
xQueueReceive(lcd_cam_obj->event_queue, (void *)&event, portMAX_DELAY);
lcd_start(lcd_cam_obj->dma_num, ((uint32_t)&lcd_cam_obj->dma[(x % 2) * lcd_cam_obj->dma_half_node_cnt]) & 0xfffff, half_buffer_size);
}
left = len % half_buffer_size;
// Process remaining incomplete segment data
if (left) {
uint8_t *out = (uint8_t *)lcd_cam_obj->dma[(x % 2) * lcd_cam_obj->dma_half_node_cnt].buf;
const uint8_t *in = data;
cnt = left - left % 2;
if (cnt) {
if (lcd_cam_obj->swap_data) {
LCD_CAM.lcd_user.lcd_8bits_order = 1;
memcpy(out, in, cnt);
} else {
LCD_CAM.lcd_user.lcd_8bits_order = 0;
memcpy(out, in, cnt);
}
}
if (left % 2) {
LCD_CAM.lcd_user.lcd_8bits_order = 0;
out[cnt] = in[cnt];
}
lcd_dma_set_left(lcd_cam_obj, x, left);
xQueueReceive(lcd_cam_obj->event_queue, (void *)&event, portMAX_DELAY);
lcd_start(lcd_cam_obj->dma_num, ((uint32_t)&lcd_cam_obj->dma[(x % 2) * lcd_cam_obj->dma_half_node_cnt]) & 0xfffff, left);
}
xQueueReceive(lcd_cam_obj->event_queue, (void *)&event, portMAX_DELAY);
}
static esp_err_t lcd_cam_config(const i2s_lcd_config_t *config, uint32_t dma_num)
{
GDMA.channel[dma_num].out.conf0.val = 0;
GDMA.channel[dma_num].out.conf1.val = 0;
GDMA.channel[dma_num].in.conf0.val = 0;
GDMA.channel[dma_num].in.conf1.val = 0;
GDMA.channel[dma_num].out.int_clr.val = ~0;
GDMA.channel[dma_num].out.int_ena.val = 0;
GDMA.channel[dma_num].in.int_clr.val = ~0;
GDMA.channel[dma_num].in.int_ena.val = 0;
LCD_CAM.lcd_clock.val = 0;
LCD_CAM.lcd_clock.clk_en = 1;
LCD_CAM.lcd_clock.lcd_clk_sel = 3;
LCD_CAM.lcd_clock.lcd_clkm_div_b = 0;
LCD_CAM.lcd_clock.lcd_clkm_div_a = 10;
LCD_CAM.lcd_clock.lcd_clkm_div_num = 2;
LCD_CAM.lcd_clock.lcd_clkcnt_n = 80000000 / config->clk_freq - 1;
LCD_CAM.lcd_clock.lcd_clk_equ_sysclk = 0;
LCD_CAM.lcd_clock.lcd_ck_idle_edge = 1; // After lcd_clk_equ_sysclk is set to 1, this bit has no effect
LCD_CAM.lcd_clock.lcd_ck_out_edge = 0; // After lcd_clk_equ_sysclk is set to 1, this bit has no effect
LCD_CAM.lcd_user.val = 0;
LCD_CAM.lcd_user.lcd_2byte_en = (config->data_width == 16) ? 1 : 0;
LCD_CAM.lcd_user.lcd_byte_order = 0;
LCD_CAM.lcd_user.lcd_bit_order = 0;
LCD_CAM.lcd_user.lcd_cmd = 0; // FSM CMD phase
LCD_CAM.lcd_user.lcd_cmd_2_cycle_en = 0; // 2 cycle command
LCD_CAM.lcd_user.lcd_dout = 1; // FSM DOUT phase
LCD_CAM.lcd_user.lcd_dout_cyclelen = 2 - 1;
LCD_CAM.lcd_user.lcd_8bits_order = 0;
LCD_CAM.lcd_user.lcd_always_out_en = 1;
LCD_CAM.lcd_misc.val = 0;
LCD_CAM.lcd_misc.lcd_afifo_threshold_num = 11;
LCD_CAM.lcd_misc.lcd_vfk_cyclelen = 3;
LCD_CAM.lcd_misc.lcd_vbk_cyclelen = 0;
LCD_CAM.lcd_misc.lcd_cd_idle_edge = 1; // idle edge of CD is set to 0
LCD_CAM.lcd_misc.lcd_cd_cmd_set = 1;
LCD_CAM.lcd_misc.lcd_cd_dummy_set = 0;
LCD_CAM.lcd_misc.lcd_cd_data_set = 0; // change when DOUT start
LCD_CAM.lcd_misc.lcd_bk_en = 1;
LCD_CAM.lcd_misc.lcd_afifo_reset = 1;
LCD_CAM.lcd_misc.lcd_afifo_reset = 0;
LCD_CAM.lcd_ctrl.val = 0;
LCD_CAM.lcd_ctrl.lcd_rgb_mode_en = 0;
LCD_CAM.lcd_cmd_val.val = 0; // write command
LCD_CAM.lcd_user.lcd_update = 1;
GDMA.channel[dma_num].out.conf0.out_rst = 1;
GDMA.channel[dma_num].out.conf0.out_rst = 0;
GDMA.channel[dma_num].out.conf0.outdscr_burst_en = 1;
GDMA.channel[dma_num].out.conf0.out_data_burst_en = 1;
GDMA.channel[dma_num].out.peri_sel.sel = (config->data_width == 1) ? 1 : 5;
GDMA.channel[dma_num].out.pri.tx_pri = 1;
GDMA.channel[dma_num].out.int_ena.out_eof = 1;
return ESP_OK;
}
static void lcd_set_pin(const i2s_lcd_config_t *config)
{
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[config->pin_num_wr], PIN_FUNC_GPIO);
gpio_set_direction(config->pin_num_wr, GPIO_MODE_OUTPUT);
gpio_set_pull_mode(config->pin_num_wr, GPIO_FLOATING);
gpio_matrix_out(config->pin_num_wr, LCD_PCLK_IDX, false, false);
for (int i = 0; i < config->data_width; i++) {
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[config->pin_data_num[i]], PIN_FUNC_GPIO);
gpio_set_direction(config->pin_data_num[i], GPIO_MODE_OUTPUT);
gpio_set_pull_mode(config->pin_data_num[i], GPIO_FLOATING);
gpio_matrix_out(config->pin_data_num[i], LCD_DATA_OUT0_IDX + i, false, false);
}
}
static esp_err_t lcd_dma_config(lcd_cam_obj_t *lcd_cam_obj, const i2s_lcd_config_t *config)
{
int cnt = 0;
if (LCD_CAM_DMA_NODE_BUFFER_MAX_SIZE % 2 != 0) {
ESP_LOGE(TAG, "need 2-byte aligned data length");
return ESP_FAIL;
}
if (config->buffer_size >= LCD_CAM_DMA_NODE_BUFFER_MAX_SIZE * 2) {
lcd_cam_obj->dma_node_buffer_size = LCD_CAM_DMA_NODE_BUFFER_MAX_SIZE;
for (cnt = 0; cnt < config->buffer_size - 8; cnt++) { // Find a buffer size that can divide dma_size
if ((config->buffer_size - cnt) % (lcd_cam_obj->dma_node_buffer_size * 2) == 0) {
break;
}
}
lcd_cam_obj->dma_buffer_size = config->buffer_size - cnt;
} else {
lcd_cam_obj->dma_node_buffer_size = config->buffer_size / 2;
lcd_cam_obj->dma_buffer_size = lcd_cam_obj->dma_node_buffer_size * 2;
}
lcd_cam_obj->dma_half_buffer_size = lcd_cam_obj->dma_buffer_size / 2;
lcd_cam_obj->dma_node_cnt = (lcd_cam_obj->dma_buffer_size) / lcd_cam_obj->dma_node_buffer_size; // Number of DMA nodes
lcd_cam_obj->dma_half_node_cnt = lcd_cam_obj->dma_node_cnt / 2;
ESP_LOGI(TAG, "lcd_buffer_size: %d, lcd_dma_size: %d, lcd_dma_node_cnt: %d", lcd_cam_obj->dma_buffer_size, lcd_cam_obj->dma_node_buffer_size, lcd_cam_obj->dma_node_cnt);
lcd_cam_obj->dma = (lldesc_t *)heap_caps_malloc(lcd_cam_obj->dma_node_cnt * sizeof(lldesc_t), MALLOC_CAP_DMA);
lcd_cam_obj->dma_buffer = (uint8_t *)heap_caps_malloc(lcd_cam_obj->dma_buffer_size * sizeof(uint8_t), MALLOC_CAP_DMA);
return ESP_OK;
}
esp_err_t lcd_cam_deinit(i2s_lcd_driver_t *drv)
{
if (!drv->i2s_lcd_obj) {
return ESP_FAIL;
}
if (drv->i2s_lcd_obj->event_queue) {
vQueueDelete(drv->i2s_lcd_obj->event_queue);
}
if (drv->i2s_lcd_obj->dma) {
free(drv->i2s_lcd_obj->dma);
}
if (drv->i2s_lcd_obj->dma_buffer) {
free(drv->i2s_lcd_obj->dma_buffer);
}
if (drv->i2s_lcd_obj->dma_out_intr_handle) {
esp_intr_free(drv->i2s_lcd_obj->dma_out_intr_handle);
}
GDMA.channel[drv->i2s_lcd_obj->dma_num].out.link.start = 0x0;
free(drv->i2s_lcd_obj);
drv->i2s_lcd_obj = NULL;
return ESP_OK;
}
static esp_err_t lcd_cam_init(i2s_lcd_driver_t *drv, const i2s_lcd_config_t *config)
{
esp_err_t ret = ESP_OK;
lcd_cam_obj_t *lcd_cam_obj = (lcd_cam_obj_t *)heap_caps_calloc(1, sizeof(lcd_cam_obj_t), MALLOC_CAP_DMA);
if (lcd_cam_obj == NULL) {
ESP_LOGE(TAG, "lcd_cam object malloc error");
return ESP_ERR_NO_MEM;
}
drv->i2s_lcd_obj = lcd_cam_obj;
//Enable LCD_CAM periph
if (REG_GET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_LCD_CAM_CLK_EN) == 0) {
REG_CLR_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_LCD_CAM_CLK_EN);
REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_LCD_CAM_CLK_EN);
REG_SET_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_LCD_CAM_RST);
REG_CLR_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_LCD_CAM_RST);
}
if (REG_GET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_DMA_CLK_EN) == 0) {
REG_CLR_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_DMA_CLK_EN);
REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_DMA_CLK_EN);
REG_SET_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
REG_CLR_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
}
for (int x = SOC_GDMA_PAIRS_PER_GROUP - 1; x >= 0; x--) {
if (GDMA.channel[x].out.link.start == 0x0) {
lcd_cam_obj->dma_num = x;
break;
}
if (x == SOC_GDMA_PAIRS_PER_GROUP - 1) {
ESP_LOGE(TAG, "DMA error");
lcd_cam_deinit(drv);
return ESP_FAIL;
}
}
ret |= lcd_cam_config(config, lcd_cam_obj->dma_num);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "lcd_cam config fail!");
lcd_cam_deinit(drv);
return ESP_FAIL;
}
lcd_set_pin(config);
ret |= lcd_dma_config(lcd_cam_obj, config);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "lcd config fail!");
lcd_cam_deinit(drv);
return ESP_FAIL;
}
lcd_cam_obj->event_queue = xQueueCreate(1, sizeof(int));
lcd_cam_obj->width = config->data_width;
lcd_cam_obj->swap_data = config->swap_data;
if (lcd_cam_obj->event_queue == NULL) {
ESP_LOGE(TAG, "lcd config fail!");
lcd_cam_deinit(drv);
return ESP_FAIL;
}
ret |= esp_intr_alloc_intrstatus(gdma_periph_signals.groups[0].pairs[lcd_cam_obj->dma_num].tx_irq_id,
ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_IRAM,
(uint32_t)&GDMA.channel[lcd_cam_obj->dma_num].out.int_st, GDMA_OUT_EOF_CH0_INT_ST,
dma_isr, lcd_cam_obj, &lcd_cam_obj->dma_out_intr_handle);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "lcd_cam intr alloc fail!");
lcd_cam_deinit(drv);
return ESP_FAIL;
}
ESP_LOGI(TAG, "lcd init ok");
return ESP_OK;
}
/**< Public functions */
i2s_lcd_handle_t i2s_lcd_driver_init(const i2s_lcd_config_t *config)
{
LCD_CHECK(NULL != config, "config pointer invalid", NULL);
LCD_CHECK(GPIO_IS_VALID_GPIO(config->pin_num_wr), "GPIO WR invalid", NULL);
LCD_CHECK(GPIO_IS_VALID_GPIO(config->pin_num_rs), "GPIO RS invalid", NULL);
LCD_CHECK(config->data_width > 0 && config->data_width <= 16, "Bit width out of range", NULL);
LCD_CHECK(0 == (config->data_width % 8), "Bit width must be a multiple of 8", NULL);
uint64_t pin_mask = 0;
for (size_t i = 0; i < config->data_width; i++) {
uint64_t mask = 1ULL << config->pin_data_num[i];
LCD_CHECK(!(pin_mask & mask), "Data bus GPIO has a duplicate", NULL);
LCD_CHECK(GPIO_IS_VALID_GPIO(config->pin_data_num[i]), "Data bus gpio invalid", NULL);
pin_mask |= mask;
}
i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)heap_caps_malloc(sizeof(i2s_lcd_driver_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
LCD_CHECK(NULL != i2s_lcd_drv, "Error malloc handle of i2s lcd driver", NULL);
esp_err_t ret = lcd_cam_init(i2s_lcd_drv, config);
if (ESP_OK != ret) {
ESP_LOGE(TAG, "%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, "i2s lcd driver initialize failed");
heap_caps_free(i2s_lcd_drv);
return NULL;
}
i2s_lcd_drv->mutex = xSemaphoreCreateMutex();
if (i2s_lcd_drv->mutex == NULL) {
ESP_LOGE(TAG, "%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, "lcd create mutex failed");
lcd_cam_deinit(i2s_lcd_drv);
heap_caps_free(i2s_lcd_drv);
return NULL;
}
if (config->pin_num_cs >= 0) {
gpio_pad_select_gpio(config->pin_num_cs);
gpio_set_direction(config->pin_num_cs, GPIO_MODE_OUTPUT);
gpio_set_level(config->pin_num_cs, 0);
}
gpio_pad_select_gpio(config->pin_num_rs);
gpio_set_direction(config->pin_num_rs, GPIO_MODE_OUTPUT);
gpio_set_level(config->pin_num_rs, LCD_DATA_LEV);
i2s_lcd_drv->rs_io_num = config->pin_num_rs;
return (i2s_lcd_handle_t)i2s_lcd_drv;
}
esp_err_t i2s_lcd_driver_deinit(i2s_lcd_handle_t handle)
{
i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)handle;
LCD_CHECK(NULL != i2s_lcd_drv, "handle pointer invalid", ESP_ERR_INVALID_ARG);
lcd_cam_deinit(i2s_lcd_drv);
vSemaphoreDelete(i2s_lcd_drv->mutex);
heap_caps_free(handle);
return ESP_OK;
}
esp_err_t i2s_lcd_write_data(i2s_lcd_handle_t handle, uint16_t data)
{
i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)handle;
LCD_CHECK(NULL != i2s_lcd_drv, "handle pointer invalid", ESP_ERR_INVALID_ARG);
lcd_write_data(i2s_lcd_drv->i2s_lcd_obj, (uint8_t *)&data, i2s_lcd_drv->i2s_lcd_obj->width == 16 ? 2 : 1);
return ESP_OK;
}
esp_err_t i2s_lcd_write_cmd(i2s_lcd_handle_t handle, uint16_t cmd)
{
i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)handle;
LCD_CHECK(NULL != i2s_lcd_drv, "handle pointer invalid", ESP_ERR_INVALID_ARG);
gpio_set_level(i2s_lcd_drv->rs_io_num, LCD_CMD_LEV);
lcd_write_data(i2s_lcd_drv->i2s_lcd_obj, (uint8_t *)&cmd, i2s_lcd_drv->i2s_lcd_obj->width == 16 ? 2 : 1);
gpio_set_level(i2s_lcd_drv->rs_io_num, LCD_DATA_LEV);
return ESP_OK;
}
esp_err_t i2s_lcd_write_command(i2s_lcd_handle_t handle, const uint8_t *cmd, uint32_t length)
{
i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)handle;
LCD_CHECK(NULL != i2s_lcd_drv, "handle pointer invalid", ESP_ERR_INVALID_ARG);
gpio_set_level(i2s_lcd_drv->rs_io_num, LCD_CMD_LEV);
lcd_write_data(i2s_lcd_drv->i2s_lcd_obj, cmd, length);
gpio_set_level(i2s_lcd_drv->rs_io_num, LCD_DATA_LEV);
return ESP_OK;
}
esp_err_t i2s_lcd_write(i2s_lcd_handle_t handle, const uint8_t *data, uint32_t length)
{
i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)handle;
LCD_CHECK(NULL != i2s_lcd_drv, "handle pointer invalid", ESP_ERR_INVALID_ARG);
lcd_write_data(i2s_lcd_drv->i2s_lcd_obj, data, length);
return ESP_OK;
}
esp_err_t i2s_lcd_acquire(i2s_lcd_handle_t handle)
{
i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)handle;
LCD_CHECK(NULL != i2s_lcd_drv, "handle pointer invalid", ESP_ERR_INVALID_ARG);
BaseType_t ret = xSemaphoreTake(i2s_lcd_drv->mutex, portMAX_DELAY);
LCD_CHECK(pdTRUE == ret, "Take semaphore failed", ESP_FAIL);
return ESP_OK;
}
esp_err_t i2s_lcd_release(i2s_lcd_handle_t handle)
{
i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)handle;
LCD_CHECK(NULL != i2s_lcd_drv, "handle pointer invalid", ESP_ERR_INVALID_ARG);
BaseType_t ret = xSemaphoreGive(i2s_lcd_drv->mutex);
LCD_CHECK(pdTRUE == ret, "Give semaphore failed", ESP_FAIL);
return ESP_OK;
}
#endif

View file

@ -1,3 +1,2 @@
idf_component_register(SRC_DIRS "." idf_component_register(SRC_DIRS "."
INCLUDE_DIRS "include" INCLUDE_DIRS "include" )
REQUIRES driver)

View file

@ -20,13 +20,8 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/semphr.h"
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
#include "esp32/rom/lldesc.h" #include "esp32/rom/lldesc.h"
#include "esp32/rom/gpio.h"
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
#include "esp_private/periph_ctrl.h"
#endif
#include "soc/dport_access.h" #include "soc/dport_access.h"
#include "soc/dport_reg.h" #include "soc/dport_reg.h"
#include "soc/i2s_struct.h" #include "soc/i2s_struct.h"
@ -41,11 +36,6 @@ static const char *TAG = "ESP32_I2S_LCD";
return (ret); \ return (ret); \
} }
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
#define ets_delay_us esp_rom_delay_us
#define portTICK_RATE_MS portTICK_PERIOD_MS
#endif
#define LCD_CAM_DMA_NODE_BUFFER_MAX_SIZE (4000) // 4-byte aligned #define LCD_CAM_DMA_NODE_BUFFER_MAX_SIZE (4000) // 4-byte aligned
#define LCD_DATA_MAX_WIDTH (24) /*!< Maximum width of LCD data bus */ #define LCD_DATA_MAX_WIDTH (24) /*!< Maximum width of LCD data bus */
@ -576,16 +566,6 @@ esp_err_t i2s_lcd_write_cmd(i2s_lcd_handle_t handle, uint16_t cmd)
return ESP_OK; return ESP_OK;
} }
esp_err_t i2s_lcd_write_command(i2s_lcd_handle_t handle, const uint8_t *cmd, uint32_t length)
{
i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)handle;
I2S_CHECK(NULL != i2s_lcd_drv, "handle pointer invalid", ESP_ERR_INVALID_ARG);
gpio_set_level(i2s_lcd_drv->rs_io_num, LCD_CMD_LEV);
i2s_lcd_drv->i2s_write_data_func(i2s_lcd_drv->i2s_lcd_obj, (uint8_t *)cmd, length);
gpio_set_level(i2s_lcd_drv->rs_io_num, LCD_DATA_LEV);
return ESP_OK;
}
esp_err_t i2s_lcd_write(i2s_lcd_handle_t handle, const uint8_t *data, uint32_t length) esp_err_t i2s_lcd_write(i2s_lcd_handle_t handle, const uint8_t *data, uint32_t length)
{ {
i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)handle; i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)handle;

View file

@ -22,13 +22,7 @@
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "esp_log.h" #include "esp_log.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#include "esp32s2/rom/gpio.h"
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
#include "esp_private/periph_ctrl.h"
#endif
#include "soc/gpio_periph.h"
#include "driver/i2s.h" #include "driver/i2s.h"
#include "soc/i2s_struct.h"
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
#include "esp32s2/rom/lldesc.h" #include "esp32s2/rom/lldesc.h"
#include "soc/system_reg.h" #include "soc/system_reg.h"
@ -45,11 +39,6 @@ static const char *TAG = "ESP32S2_I2S_LCD";
#define LCD_CAM_DMA_NODE_BUFFER_MAX_SIZE (4000) // 4-byte aligned #define LCD_CAM_DMA_NODE_BUFFER_MAX_SIZE (4000) // 4-byte aligned
#define LCD_DATA_MAX_WIDTH (24) /*!< Maximum width of LCD data bus */ #define LCD_DATA_MAX_WIDTH (24) /*!< Maximum width of LCD data bus */
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
#define ets_delay_us esp_rom_delay_us
#define portTICK_RATE_MS portTICK_PERIOD_MS
#endif
typedef struct { typedef struct {
uint32_t dma_buffer_size; uint32_t dma_buffer_size;
uint32_t dma_half_buffer_size; uint32_t dma_half_buffer_size;
@ -450,16 +439,6 @@ esp_err_t i2s_lcd_write_cmd(i2s_lcd_handle_t handle, uint16_t cmd)
return ESP_OK; return ESP_OK;
} }
esp_err_t i2s_lcd_write_command(i2s_lcd_handle_t handle, const uint8_t *cmd, uint32_t length)
{
i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)handle;
I2S_CHECK(NULL != i2s_lcd_drv, "handle pointer invalid", ESP_ERR_INVALID_ARG);
gpio_set_level(i2s_lcd_drv->rs_io_num, LCD_CMD_LEV);
i2s_write_data(i2s_lcd_drv->i2s_lcd_obj, (uint8_t *)cmd, length);
gpio_set_level(i2s_lcd_drv->rs_io_num, LCD_DATA_LEV);
return ESP_OK;
}
esp_err_t i2s_lcd_write(i2s_lcd_handle_t handle, const uint8_t *data, uint32_t length) esp_err_t i2s_lcd_write(i2s_lcd_handle_t handle, const uint8_t *data, uint32_t length)
{ {
i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)handle; i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)handle;

View file

@ -25,11 +25,6 @@ extern "C"
{ {
#endif #endif
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
#define gpio_pad_select_gpio esp_rom_gpio_pad_select_gpio
#define portTICK_RATE_MS portTICK_PERIOD_MS
#endif
/**************************************** Public Functions (Application level)*********************************************/ /**************************************** Public Functions (Application level)*********************************************/
/** /**

View file

@ -86,19 +86,6 @@ esp_err_t i2s_lcd_write_data(i2s_lcd_handle_t handle, uint16_t data);
*/ */
esp_err_t i2s_lcd_write_cmd(i2s_lcd_handle_t handle, uint16_t cmd); esp_err_t i2s_lcd_write_cmd(i2s_lcd_handle_t handle, uint16_t cmd);
/**
* @brief Write a command to LCD
*
* @param handle Handle of i2s lcd driver
* @param cmd command to write
* @param length length of command
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG handle is invalid
*/
esp_err_t i2s_lcd_write_command(i2s_lcd_handle_t handle, const uint8_t *cmd, uint32_t length);
/** /**
* @brief Write block data to LCD * @brief Write block data to LCD
* *

View file

@ -69,12 +69,12 @@ spi_bus_handle_t spi_bus_create(spi_host_device_t host_id, const spi_config_t *b
.quadhd_io_num = -1, .quadhd_io_num = -1,
.max_transfer_sz = bus_conf->max_transfer_sz, .max_transfer_sz = bus_conf->max_transfer_sz,
}; };
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0)) #if CONFIG_IDF_TARGET_ESP32S3
esp_err_t ret = spi_bus_initialize(host_id, &buscfg, SPI_DMA_CH_AUTO); int dma_chan = SPI_DMA_CH_AUTO;
#else #else
int dma_chan = host_id; //set dma channel equals to host_id by default int dma_chan = host_id; //set dma channel equals to host_id by default
esp_err_t ret = spi_bus_initialize(host_id, &buscfg, dma_chan);
#endif #endif
esp_err_t ret = spi_bus_initialize(host_id, &buscfg, dma_chan);
SPI_BUS_CHECK(ESP_OK == ret, "spi bus create failed", NULL); SPI_BUS_CHECK(ESP_OK == ret, "spi bus create failed", NULL);
s_spi_bus[index].host_id = host_id; s_spi_bus[index].host_id = host_id;
memcpy(&s_spi_bus[index].conf, &buscfg, sizeof(spi_bus_config_t)); memcpy(&s_spi_bus[index].conf, &buscfg, sizeof(spi_bus_config_t));
@ -203,7 +203,7 @@ esp_err_t spi_bus_transfer_bytes(spi_bus_device_handle_t dev_handle, const uint8
return ESP_OK; return ESP_OK;
} }
/**************************************** Public Functions (Low level)*********************************************/ /**************************************** Public Functions (Low level)*********************************************/
esp_err_t spi_bus_transmit_begin(spi_bus_device_handle_t dev_handle, spi_transaction_t *p_trans) esp_err_t spi_bus_transmit_begin(spi_bus_device_handle_t dev_handle, spi_transaction_t *p_trans)
{ {

View file

@ -1,12 +1,3 @@
set(PRIVREQ esp_timer)
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.0")
list(APPEND PRIVREQ esp_adc)
else()
list(APPEND PRIVREQ esp_adc_cal)
endif()
idf_component_register(SRCS "button_adc.c" "button_gpio.c" "iot_button.c" idf_component_register(SRCS "button_adc.c" "button_gpio.c" "iot_button.c"
INCLUDE_DIRS include INCLUDE_DIRS include
REQUIRES driver PRIV_REQUIRES esp_adc_cal)
PRIV_REQUIRES ${PRIVREQ})

View file

@ -1,17 +0,0 @@
# Component: Button
[Chinese documentation](https://docs.espressif.com/projects/espressif-esp-iot-solution/en/latest/input_device/button.html)
After creating a new button object by calling function `button_create()`, the button object can create press events, every press event can have its own callback.
List of supported events:
* Button pressed
* Button released
* Button pressed - repeated
* Button single click
* Button double click
* Button long press start
* Button long press hold
There are two ways this driver can handle buttons:
1. Buttons connected to standard digital GPIO
2. Multiple buttons connected to single ADC channel

View file

@ -31,7 +31,11 @@ static const char *TAG = "adc button";
#define DEFAULT_VREF 1100 #define DEFAULT_VREF 1100
#define NO_OF_SAMPLES CONFIG_ADC_BUTTON_SAMPLE_TIMES //Multisampling #define NO_OF_SAMPLES CONFIG_ADC_BUTTON_SAMPLE_TIMES //Multisampling
#define ADC_BUTTON_WIDTH ADC_WIDTH_MAX-1 #if CONFIG_IDF_TARGET_ESP32
#define ADC_BUTTON_WIDTH ADC_WIDTH_BIT_12
#elif CONFIG_IDF_TARGET_ESP32S2
#define ADC_BUTTON_WIDTH ADC_WIDTH_BIT_13
#endif
#define ADC_BUTTON_ATTEN ADC_ATTEN_DB_11 #define ADC_BUTTON_ATTEN ADC_ATTEN_DB_11
#define ADC_BUTTON_ADC_UNIT ADC_UNIT_1 #define ADC_BUTTON_ADC_UNIT ADC_UNIT_1
#define ADC_BUTTON_MAX_CHANNEL CONFIG_ADC_BUTTON_MAX_CHANNEL #define ADC_BUTTON_MAX_CHANNEL CONFIG_ADC_BUTTON_MAX_CHANNEL

View file

@ -1,5 +0,0 @@
version: "2.2.0"
description: GPIO and ADC button driver
url: https://github.com/espressif/esp-iot-solution/tree/master/components/button
dependencies:
idf: ">=4.0"

View file

@ -21,7 +21,7 @@
extern "C" { extern "C" {
#endif #endif
typedef void (* button_cb_t)(void *, void *); typedef void (* button_cb_t)(void *);
typedef void *button_handle_t; typedef void *button_handle_t;
/** /**
@ -87,13 +87,12 @@ esp_err_t iot_button_delete(button_handle_t btn_handle);
* @param btn_handle A button handle to register * @param btn_handle A button handle to register
* @param event Button event * @param event Button event
* @param cb Callback function. * @param cb Callback function.
* @param usr_data user data
* *
* @return * @return
* - ESP_OK on success * - ESP_OK on success
* - ESP_ERR_INVALID_ARG Arguments is invalid. * - ESP_ERR_INVALID_ARG Arguments is invalid.
*/ */
esp_err_t iot_button_register_cb(button_handle_t btn_handle, button_event_t event, button_cb_t cb, void *usr_data); esp_err_t iot_button_register_cb(button_handle_t btn_handle, button_event_t event, button_cb_t cb);
/** /**
* @brief Unregister the button event callback function. * @brief Unregister the button event callback function.

View file

@ -39,8 +39,7 @@ typedef struct Button {
uint8_t debounce_cnt: 3; uint8_t debounce_cnt: 3;
uint8_t active_level: 1; uint8_t active_level: 1;
uint8_t button_level: 1; uint8_t button_level: 1;
uint8_t (*hal_button_Level)(void *hardware_data); uint8_t (*hal_button_Level)(void *usr_data);
void *hardware_data;
void *usr_data; void *usr_data;
button_type_t type; button_type_t type;
button_cb_t cb[BUTTON_EVENT_MAX]; button_cb_t cb[BUTTON_EVENT_MAX];
@ -57,14 +56,14 @@ static bool g_is_timer_running = false;
#define SHORT_TICKS (CONFIG_BUTTON_SHORT_PRESS_TIME_MS /TICKS_INTERVAL) #define SHORT_TICKS (CONFIG_BUTTON_SHORT_PRESS_TIME_MS /TICKS_INTERVAL)
#define LONG_TICKS (CONFIG_BUTTON_LONG_PRESS_TIME_MS /TICKS_INTERVAL) #define LONG_TICKS (CONFIG_BUTTON_LONG_PRESS_TIME_MS /TICKS_INTERVAL)
#define CALL_EVENT_CB(ev) if(btn->cb[ev])btn->cb[ev](btn, btn->usr_data) #define CALL_EVENT_CB(ev) if(btn->cb[ev])btn->cb[ev](btn)
/** /**
* @brief Button driver core function, driver state machine. * @brief Button driver core function, driver state machine.
*/ */
static void button_handler(button_dev_t *btn) static void button_handler(button_dev_t *btn)
{ {
uint8_t read_gpio_level = btn->hal_button_Level(btn->hardware_data); uint8_t read_gpio_level = btn->hal_button_Level(btn->usr_data);
/** ticks counter working.. */ /** ticks counter working.. */
if ((btn->state) > 0) { if ((btn->state) > 0) {
@ -164,13 +163,13 @@ static void button_cb(void *args)
} }
} }
static button_dev_t *button_create_com(uint8_t active_level, uint8_t (*hal_get_key_state)(void *hardware_data), void *hardware_data) static button_dev_t *button_create_com(uint8_t active_level, uint8_t (*hal_get_key_state)(void *usr_data), void *usr_data)
{ {
BTN_CHECK(NULL != hal_get_key_state, "Function pointer is invalid", NULL); BTN_CHECK(NULL != hal_get_key_state, "Function pointer is invalid", NULL);
button_dev_t *btn = (button_dev_t *) calloc(1, sizeof(button_dev_t)); button_dev_t *btn = (button_dev_t *) calloc(1, sizeof(button_dev_t));
BTN_CHECK(NULL != btn, "Button memory alloc failed", NULL); BTN_CHECK(NULL != btn, "Button memory alloc failed", NULL);
btn->hardware_data = hardware_data; btn->usr_data = usr_data;
btn->event = BUTTON_NONE_PRESS; btn->event = BUTTON_NONE_PRESS;
btn->active_level = active_level; btn->active_level = active_level;
btn->hal_button_Level = hal_get_key_state; btn->hal_button_Level = hal_get_key_state;
@ -260,10 +259,10 @@ esp_err_t iot_button_delete(button_handle_t btn_handle)
button_dev_t *btn = (button_dev_t *)btn_handle; button_dev_t *btn = (button_dev_t *)btn_handle;
switch (btn->type) { switch (btn->type) {
case BUTTON_TYPE_GPIO: case BUTTON_TYPE_GPIO:
ret = button_gpio_deinit((int)(btn->hardware_data)); ret = button_gpio_deinit((int)(btn->usr_data));
break; break;
case BUTTON_TYPE_ADC: case BUTTON_TYPE_ADC:
ret = button_adc_deinit(ADC_BUTTON_SPLIT_CHANNEL(btn->hardware_data), ADC_BUTTON_SPLIT_INDEX(btn->hardware_data)); ret = button_adc_deinit(ADC_BUTTON_SPLIT_CHANNEL(btn->usr_data), ADC_BUTTON_SPLIT_INDEX(btn->usr_data));
break; break;
default: default:
break; break;
@ -273,13 +272,12 @@ esp_err_t iot_button_delete(button_handle_t btn_handle)
return ESP_OK; return ESP_OK;
} }
esp_err_t iot_button_register_cb(button_handle_t btn_handle, button_event_t event, button_cb_t cb, void *usr_data) esp_err_t iot_button_register_cb(button_handle_t btn_handle, button_event_t event, button_cb_t cb)
{ {
BTN_CHECK(NULL != btn_handle, "Pointer of handle is invalid", ESP_ERR_INVALID_ARG); BTN_CHECK(NULL != btn_handle, "Pointer of handle is invalid", ESP_ERR_INVALID_ARG);
BTN_CHECK(event < BUTTON_EVENT_MAX, "event is invalid", ESP_ERR_INVALID_ARG); BTN_CHECK(event < BUTTON_EVENT_MAX, "event is invalid", ESP_ERR_INVALID_ARG);
button_dev_t *btn = (button_dev_t *) btn_handle; button_dev_t *btn = (button_dev_t *) btn_handle;
btn->cb[event] = cb; btn->cb[event] = cb;
btn->usr_data = usr_data;
return ESP_OK; return ESP_OK;
} }

View file

@ -1,18 +1,15 @@
set(SCREEN_DIR "controller_driver/ili9341" set(SCREEN_DIR "controller_driver/ili9341"
"controller_driver/ili9342"
"controller_driver/st7789" "controller_driver/st7789"
"controller_driver/st7796" "controller_driver/st7796"
"controller_driver/nt35510" "controller_driver/nt35510"
"controller_driver/ili9806" "controller_driver/ili9806"
"controller_driver/ili9486" "controller_driver/ili9486"
"controller_driver/ili9488"
"controller_driver/ssd1351" "controller_driver/ssd1351"
"controller_driver/rm68120" "controller_driver/rm68120"
"controller_driver/ssd1306" "controller_driver/ssd1306"
"controller_driver/ssd1307" "controller_driver/ssd1307"
"controller_driver/ssd1322" "controller_driver/ssd1322"
"controller_driver/ssd1963"
) )
idf_component_register(SRC_DIRS "${SCREEN_DIR}" "screen_utility" "interface_driver" "." idf_component_register(SRC_DIRS "${SCREEN_DIR}" "screen_utility" "interface_driver" "."

View file

@ -4,18 +4,12 @@ menu "LCD Drivers"
config LCD_DRIVER_SCREEN_CONTROLLER_ILI9341 config LCD_DRIVER_SCREEN_CONTROLLER_ILI9341
bool "ILI9341" bool "ILI9341"
default y default y
config LCD_DRIVER_SCREEN_CONTROLLER_ILI9342
bool "ILI9342"
default y
config LCD_DRIVER_SCREEN_CONTROLLER_ILI9486 config LCD_DRIVER_SCREEN_CONTROLLER_ILI9486
bool "ILI9486" bool "ILI9486"
default n default n
config LCD_DRIVER_SCREEN_CONTROLLER_ILI9806 config LCD_DRIVER_SCREEN_CONTROLLER_ILI9806
bool "ILI9806" bool "ILI9806"
default n default n
config LCD_DRIVER_SCREEN_CONTROLLER_ILI9488
bool "ILI9488"
default n
config LCD_DRIVER_SCREEN_CONTROLLER_NT35510 config LCD_DRIVER_SCREEN_CONTROLLER_NT35510
bool "NT35510" bool "NT35510"
default n default n
@ -25,9 +19,6 @@ menu "LCD Drivers"
config LCD_DRIVER_SCREEN_CONTROLLER_SSD1351 config LCD_DRIVER_SCREEN_CONTROLLER_SSD1351
bool "SSD1351" bool "SSD1351"
default n default n
config LCD_DRIVER_SCREEN_CONTROLLER_SSD1963
bool "SSD1963"
default n
config LCD_DRIVER_SCREEN_CONTROLLER_ST7789 config LCD_DRIVER_SCREEN_CONTROLLER_ST7789
bool "ST7789" bool "ST7789"
default n default n

View file

@ -5,19 +5,16 @@
SCREEN_DIR = controller_driver/ili9341 \ SCREEN_DIR = controller_driver/ili9341 \
controller_driver/ili9342 \
controller_driver/st7789 \ controller_driver/st7789 \
controller_driver/st7796 \ controller_driver/st7796 \
controller_driver/nt35510 \ controller_driver/nt35510 \
controller_driver/ili9806 \ controller_driver/ili9806 \
controller_driver/ili9486 \ controller_driver/ili9486 \
controller_driver/ili9488 \
controller_driver/ssd1351 \ controller_driver/ssd1351 \
controller_driver/rm68120 \ controller_driver/rm68120 \
controller_driver/ssd1306 \ controller_driver/ssd1306 \
controller_driver/ssd1307 \ controller_driver/ssd1307 \
controller_driver/ssd1322 \ controller_driver/ssd1322
controller_driver/ssd1963
COMPONENT_ADD_INCLUDEDIRS := . interface_driver $(SCREEN_DIR) screen_utility COMPONENT_ADD_INCLUDEDIRS := . iface_driver $(SCREEN_DIR) screen_utility
COMPONENT_SRCDIRS := . interface_driver $(SCREEN_DIR) screen_utility COMPONENT_SRCDIRS := . iface_driver $(SCREEN_DIR) screen_utility

View file

@ -79,7 +79,7 @@ esp_err_t lcd_ili9341_init(const scr_controller_config_t *lcd_conf)
LCD_CHECK(lcd_conf->width <= ILI9341_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->width <= ILI9341_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(lcd_conf->height <= ILI9341_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->height <= ILI9341_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG); LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG);
LCD_CHECK((NULL != lcd_conf->interface_drv->write_command && \ LCD_CHECK((NULL != lcd_conf->interface_drv->write_cmd && \
NULL != lcd_conf->interface_drv->write_data && \ NULL != lcd_conf->interface_drv->write_data && \
NULL != lcd_conf->interface_drv->write && \ NULL != lcd_conf->interface_drv->write && \
NULL != lcd_conf->interface_drv->read && \ NULL != lcd_conf->interface_drv->read && \

View file

@ -1,394 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) Co. Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "screen_driver.h"
#include "screen_utility.h"
#include "ili9342.h"
static const char *TAG = "lcd ili9342";
#define LCD_CHECK(a, str, ret) if(!(a)) { \
ESP_LOGE(TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
return (ret); \
}
#define LCD_NAME "ILI9342"
#define LCD_BPP 16
/** commands of ILI9342 */
#define LCD_SWRESET 0x01 // Software Reset
#define LCD_RDDID 0x04 // Read Display ID
#define LCD_INVOFF 0x20 // Display Inversion Off
#define LCD_INVON 0x21 // Display Inversion On
#define LCD_CASET 0x2A // Column Address Set
#define LCD_PASET 0x2B // Row Address Set
#define LCD_RAMWR 0x2C // Memory Writ
#define LCD_RAMRD 0x2E // Memory Read
#define LCD_MADCTL 0x36 // Memory Data Access Contro
/* MADCTL Defines */
#define MADCTL_MY 0x80
#define MADCTL_MX 0x40
#define MADCTL_MV 0x20
#define MADCTL_ML 0x10
#define MADCTL_RGB 0x08
#define MADCTL_MH 0x04
#define ILI9342_RESOLUTION_HOR 320
#define ILI9342_RESOLUTION_VER 240
static scr_handle_t g_lcd_handle;
/**
* This header file is only used to redefine the function to facilitate the call.
* It can only be placed in this position, not in the head of the file.
*/
#include "interface_drv_def.h"
scr_driver_t lcd_ili9342_default_driver = {
.init = lcd_ili9342_init,
.deinit = lcd_ili9342_deinit,
.set_direction = lcd_ili9342_set_rotation,
.set_window = lcd_ili9342_set_window,
.write_ram_data = lcd_ili9342_write_ram_data,
.draw_pixel = lcd_ili9342_draw_pixel,
.draw_bitmap = lcd_ili9342_draw_bitmap,
.get_info = lcd_ili9342_get_info,
};
static esp_err_t lcd_ili9342_init_reg(void);
esp_err_t lcd_ili9342_init(const scr_controller_config_t *lcd_conf)
{
LCD_CHECK(lcd_conf->width <= ILI9342_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(lcd_conf->height <= ILI9342_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG);
LCD_CHECK((NULL != lcd_conf->interface_drv->write_command && \
NULL != lcd_conf->interface_drv->write_data && \
NULL != lcd_conf->interface_drv->write && \
NULL != lcd_conf->interface_drv->read && \
NULL != lcd_conf->interface_drv->bus_acquire && \
NULL != lcd_conf->interface_drv->bus_release),
"Interface driver invalid", ESP_ERR_INVALID_ARG);
esp_err_t ret;
// Reset the display
if (lcd_conf->pin_num_rst >= 0) {
gpio_pad_select_gpio(lcd_conf->pin_num_rst);
gpio_set_direction(lcd_conf->pin_num_rst, GPIO_MODE_OUTPUT);
gpio_set_level(lcd_conf->pin_num_rst, (lcd_conf->rst_active_level) & 0x1);
vTaskDelay(100 / portTICK_RATE_MS);
gpio_set_level(lcd_conf->pin_num_rst, (~(lcd_conf->rst_active_level)) & 0x1);
vTaskDelay(100 / portTICK_RATE_MS);
}
g_lcd_handle.interface_drv = lcd_conf->interface_drv;
g_lcd_handle.original_width = lcd_conf->width;
g_lcd_handle.original_height = lcd_conf->height;
g_lcd_handle.offset_hor = lcd_conf->offset_hor;
g_lcd_handle.offset_ver = lcd_conf->offset_ver;
ret = lcd_ili9342_init_reg();
LCD_CHECK(ESP_OK == ret, "Write lcd register encounter error", ESP_FAIL);
// Enable invert
ret = lcd_ili9342_set_invert(true);
LCD_CHECK(ESP_OK == ret, "Write lcd register invert error", ESP_FAIL);
// Enable backlight
if (lcd_conf->pin_num_bckl >= 0) {
gpio_pad_select_gpio(lcd_conf->pin_num_bckl);
gpio_set_direction(lcd_conf->pin_num_bckl, GPIO_MODE_OUTPUT);
gpio_set_level(lcd_conf->pin_num_bckl, (lcd_conf->bckl_active_level) & 0x1);
}
return lcd_ili9342_set_rotation(lcd_conf->rotate);
}
esp_err_t lcd_ili9342_deinit(void)
{
memset(&g_lcd_handle, 0, sizeof(scr_handle_t));
return ESP_OK;
}
esp_err_t lcd_ili9342_set_rotation(scr_dir_t dir)
{
esp_err_t ret;
uint8_t reg_data = 0;
reg_data |= MADCTL_RGB;
if (SCR_DIR_MAX < dir) {
dir >>= 5;
}
LCD_CHECK(dir < 8, "Unsupport rotate direction", ESP_ERR_INVALID_ARG);
switch (dir) {
case SCR_DIR_LRTB:
g_lcd_handle.width = g_lcd_handle.original_width;
g_lcd_handle.height = g_lcd_handle.original_height;
break;
case SCR_DIR_LRBT:
reg_data |= MADCTL_MY;
g_lcd_handle.width = g_lcd_handle.original_width;
g_lcd_handle.height = g_lcd_handle.original_height;
break;
case SCR_DIR_RLTB:
reg_data |= MADCTL_MX;
g_lcd_handle.width = g_lcd_handle.original_width;
g_lcd_handle.height = g_lcd_handle.original_height;
break;
case SCR_DIR_RLBT:
reg_data |= MADCTL_MX | MADCTL_MY;
g_lcd_handle.width = g_lcd_handle.original_width;
g_lcd_handle.height = g_lcd_handle.original_height;
break;
case SCR_DIR_TBLR:
reg_data |= MADCTL_MV;
g_lcd_handle.width = g_lcd_handle.original_height;
g_lcd_handle.height = g_lcd_handle.original_width;
break;
case SCR_DIR_BTLR:
reg_data |= MADCTL_MY | MADCTL_MV;
g_lcd_handle.width = g_lcd_handle.original_height;
g_lcd_handle.height = g_lcd_handle.original_width;
break;
case SCR_DIR_TBRL:
reg_data |= MADCTL_MX | MADCTL_MV;
g_lcd_handle.width = g_lcd_handle.original_height;
g_lcd_handle.height = g_lcd_handle.original_width;
break;
case SCR_DIR_BTRL:
reg_data |= MADCTL_MX | MADCTL_MY | MADCTL_MV;
g_lcd_handle.width = g_lcd_handle.original_height;
g_lcd_handle.height = g_lcd_handle.original_width;
break;
default: break;
}
ESP_LOGI(TAG, "MADCTL=%x", reg_data);
ret = LCD_WRITE_REG(LCD_MADCTL, reg_data);
LCD_CHECK(ESP_OK == ret, "Set screen rotate failed", ESP_FAIL);
g_lcd_handle.dir = dir;
return ESP_OK;
}
esp_err_t lcd_ili9342_get_info(scr_info_t *info)
{
LCD_CHECK(NULL != info, "info pointer invalid", ESP_ERR_INVALID_ARG);
info->width = g_lcd_handle.width;
info->height = g_lcd_handle.height;
info->dir = g_lcd_handle.dir;
info->name = LCD_NAME;
info->color_type = SCR_COLOR_TYPE_RGB565;
info->bpp = LCD_BPP;
return ESP_OK;
}
esp_err_t lcd_ili9342_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
LCD_CHECK((x1 < g_lcd_handle.width) && (y1 < g_lcd_handle.height), "The set coordinates exceed the screen size", ESP_ERR_INVALID_ARG);
LCD_CHECK((x0 <= x1) && (y0 <= y1), "Window coordinates invalid", ESP_ERR_INVALID_ARG);
esp_err_t ret = ESP_OK;
scr_utility_apply_offset(&g_lcd_handle, ILI9342_RESOLUTION_HOR, ILI9342_RESOLUTION_VER, &x0, &y0, &x1, &y1);
ret |= LCD_WRITE_CMD(LCD_CASET);
ret |= LCD_WRITE_DATA(x0 >> 8);
ret |= LCD_WRITE_DATA(x0 & 0xff);
ret |= LCD_WRITE_DATA(x1 >> 8);
ret |= LCD_WRITE_DATA(x1 & 0xff);
ret |= LCD_WRITE_CMD(LCD_PASET);
ret |= LCD_WRITE_DATA(y0 >> 8);
ret |= LCD_WRITE_DATA(y0 & 0xff);
ret |= LCD_WRITE_DATA(y1 >> 8);
ret |= LCD_WRITE_DATA(y1 & 0xff);
ret |= LCD_WRITE_CMD(LCD_RAMWR);
LCD_CHECK(ESP_OK == ret, "Set window failed", ESP_FAIL);
return ESP_OK;
}
esp_err_t lcd_ili9342_set_invert(bool is_invert)
{
return LCD_WRITE_CMD(is_invert ? LCD_INVON : LCD_INVOFF);
}
esp_err_t lcd_ili9342_write_ram_data(uint16_t color)
{
static uint8_t data[2];
data[0] = (uint8_t)(color & 0xff);
data[1] = (uint8_t)(color >> 8);
return LCD_WRITE(data, 2);
}
esp_err_t lcd_ili9342_draw_pixel(uint16_t x, uint16_t y, uint16_t color)
{
esp_err_t ret;
ret = lcd_ili9342_set_window(x, y, x, y);
if (ESP_OK != ret) {
return ESP_FAIL;
}
return lcd_ili9342_write_ram_data(color);
}
esp_err_t lcd_ili9342_draw_bitmap(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t *bitmap)
{
esp_err_t ret;
LCD_CHECK(NULL != bitmap, "bitmap pointer invalid", ESP_ERR_INVALID_ARG);
LCD_IFACE_ACQUIRE();
ret = lcd_ili9342_set_window(x, y, x + w - 1, y + h - 1);
if (ESP_OK != ret) {
return ESP_FAIL;
}
uint32_t len = w * h;
ret = LCD_WRITE((uint8_t *)bitmap, 2 * len);
LCD_IFACE_RELEASE();
LCD_CHECK(ESP_OK == ret, "lcd write ram data failed", ESP_FAIL);
return ESP_OK;
}
static esp_err_t lcd_ili9342_init_reg(void)
{
//SOFTWARE RESET
LCD_WRITE_CMD(0x01);
vTaskDelay(pdMS_TO_TICKS(100));
//POWER CONTROL A
LCD_WRITE_CMD(0xCB);
LCD_WRITE_DATA(0x39);
LCD_WRITE_DATA(0x2C);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x34);
LCD_WRITE_DATA(0x02);
//POWER CONTROL B
LCD_WRITE_CMD(0xCF);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0xC1);
LCD_WRITE_DATA(0x30);
//DRIVER TIMING CONTROL A
LCD_WRITE_CMD(0xE8);
LCD_WRITE_DATA(0x85);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x78);
//DRIVER TIMING CONTROL B
LCD_WRITE_CMD(0xEA);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x00);
//POWER ON SEQUENCE CONTROL
LCD_WRITE_CMD(0xED);
LCD_WRITE_DATA(0x64);
LCD_WRITE_DATA(0x03);
LCD_WRITE_DATA(0x12);
LCD_WRITE_DATA(0x81);
//PUMP RATIO CONTROL
LCD_WRITE_CMD(0xF7);
LCD_WRITE_DATA(0x20);
//POWER CONTROL,VRH[5:0]
LCD_WRITE_CMD(0xC0);
LCD_WRITE_DATA(0x23);
//POWER CONTROL,SAP[2:0];BT[3:0]
LCD_WRITE_CMD(0xC1);
LCD_WRITE_DATA(0x10);
//VCM CONTROL
LCD_WRITE_CMD(0xC5);
LCD_WRITE_DATA(0x3E);
LCD_WRITE_DATA(0x28);
//VCM CONTROL 2
LCD_WRITE_CMD(0xC7);
LCD_WRITE_DATA(0x86);
//MEMORY ACCESS CONTROL
LCD_WRITE_CMD(0x36);
LCD_WRITE_DATA(0x48);
//PIXEL FORMAT
LCD_WRITE_CMD(0x3A);
LCD_WRITE_DATA(0x55);
//FRAME RATIO CONTROL, STANDARD RGB COLOR
LCD_WRITE_CMD(0xB1);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x18);
//DISPLAY FUNCTION CONTROL
LCD_WRITE_CMD(0xB6);
LCD_WRITE_DATA(0x08);
LCD_WRITE_DATA(0x82);
LCD_WRITE_DATA(0x27);
//3GAMMA FUNCTION DISABLE
LCD_WRITE_CMD(0xF2);
LCD_WRITE_DATA(0x00);
//GAMMA CURVE SELECTED
LCD_WRITE_CMD(0x26);
LCD_WRITE_DATA(0x01);
//POSITIVE GAMMA CORRECTION
LCD_WRITE_CMD(0xE0);
LCD_WRITE_DATA(0x0F);
LCD_WRITE_DATA(0x31);
LCD_WRITE_DATA(0x2B);
LCD_WRITE_DATA(0x0C);
LCD_WRITE_DATA(0x0E);
LCD_WRITE_DATA(0x08);
LCD_WRITE_DATA(0x4E);
LCD_WRITE_DATA(0xF1);
LCD_WRITE_DATA(0x37);
LCD_WRITE_DATA(0x07);
LCD_WRITE_DATA(0x10);
LCD_WRITE_DATA(0x03);
LCD_WRITE_DATA(0x0E);
LCD_WRITE_DATA(0x09);
LCD_WRITE_DATA(0x00);
//NEGATIVE GAMMA CORRECTION
LCD_WRITE_CMD(0xE1);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x0E);
LCD_WRITE_DATA(0x14);
LCD_WRITE_DATA(0x03);
LCD_WRITE_DATA(0x11);
LCD_WRITE_DATA(0x07);
LCD_WRITE_DATA(0x31);
LCD_WRITE_DATA(0xC1);
LCD_WRITE_DATA(0x48);
LCD_WRITE_DATA(0x08);
LCD_WRITE_DATA(0x0F);
LCD_WRITE_DATA(0x0C);
LCD_WRITE_DATA(0x31);
LCD_WRITE_DATA(0x36);
LCD_WRITE_DATA(0x0F);
//EXIT SLEEP
LCD_WRITE_CMD(0x11);
vTaskDelay(pdMS_TO_TICKS(120));
//TURN ON DISPLAY
LCD_WRITE_CMD(0x29);
return ESP_OK;
}

View file

@ -1,134 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) Co. Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _IOT_LCD_ILI9342_H_
#define _IOT_LCD_ILI9342_H_
#include "screen_driver.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize screen
*
* @param lcd_conf Pointer to a structure with lcd config arguments.
*
* @return
* - ESP_OK on success
* - ESP_FAIL Driver not installed
*/
esp_err_t lcd_ili9342_init(const scr_controller_config_t *lcd_conf);
/**
* @brief Deinitialize screen
*
* @return
* - ESP_OK on success
* - ESP_FAIL Deinitialize failed
* - ESP_ERR_NOT_SUPPORTED unsupported
*/
esp_err_t lcd_ili9342_deinit(void);
/**
* @brief Set screen direction of rotation
*
* @param dir Pointer to a scr_dir_t structure.
*
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ili9342_set_rotation(scr_dir_t dir);
/**
* @brief Get screen information
*
* @param info Pointer to a scr_info_t structure.
*
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ili9342_get_info(scr_info_t *info);
/**
* @brief Set screen window
*
* @param x0 Starting point in X direction
* @param y0 Starting point in Y direction
* @param x1 End point in X direction
* @param y1 End point in Y direction
*
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ili9342_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
/**
* @brief Set screen color invert
*
* @param is_invert true: color invert on, false: color invert off
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ili9342_set_invert(bool is_invert);
/**
* @brief Write a RAM data
*
* @param color New color of a pixel
*
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ili9342_write_ram_data(uint16_t color);
/**
* @brief Draw one pixel in screen with color
*
* @param x X co-ordinate of set orientation
* @param y Y co-ordinate of set orientation
* @param color New color of the pixel
*
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ili9342_draw_pixel(uint16_t x, uint16_t y, uint16_t color);
/**
* @brief Fill the pixels on LCD screen with bitmap
*
* @param x Starting point in X direction
* @param y Starting point in Y direction
* @param w width of image in bitmap array
* @param h height of image in bitmap array
* @param bitmap pointer to bitmap array
*
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ili9342_draw_bitmap(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t *bitmap);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -74,7 +74,7 @@ esp_err_t lcd_ili9486_init(const scr_controller_config_t *lcd_conf)
LCD_CHECK(lcd_conf->width <= ILI9486_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->width <= ILI9486_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(lcd_conf->height <= ILI9486_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->height <= ILI9486_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG); LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG);
LCD_CHECK((NULL != lcd_conf->interface_drv->write_command && \ LCD_CHECK((NULL != lcd_conf->interface_drv->write_cmd && \
NULL != lcd_conf->interface_drv->write_data && \ NULL != lcd_conf->interface_drv->write_data && \
NULL != lcd_conf->interface_drv->write && \ NULL != lcd_conf->interface_drv->write && \
NULL != lcd_conf->interface_drv->read && \ NULL != lcd_conf->interface_drv->read && \

View file

@ -1,401 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) Co. Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "screen_driver.h"
#include "screen_utility.h"
#include "ili9488.h"
static const char *TAG = "ILI9488";
#define LCD_CHECK(a, str, ret) if(!(a)) { \
ESP_LOGE(TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
return (ret); \
}
#define ILI9488_NOP 0x00
#define ILI9488_SWRESET 0x01
#define ILI9488_RDDID 0x04
#define ILI9488_RDDST 0x09
#define ILI9488_SLPIN 0x10
#define ILI9488_SLPOUT 0x11
#define ILI9488_PTLON 0x12
#define ILI9488_NORON 0x13
#define ILI9488_RDMODE 0x0A
#define ILI9488_RDMADCTL 0x0B
#define ILI9488_RDPIXFMT 0x0C
#define ILI9488_RDIMGFMT 0x0D
#define ILI9488_RDSELFDIAG 0x0F
#define ILI9488_INVOFF 0x20
#define ILI9488_INVON 0x21
#define ILI9488_GAMMASET 0x26
#define ILI9488_DISPOFF 0x28
#define ILI9488_DISPON 0x29
#define ILI9488_CASET 0x2A
#define ILI9488_PASET 0x2B
#define ILI9488_RAMWR 0x2C
#define ILI9488_RAMRD 0x2E
#define ILI9488_PTLAR 0x30
#define ILI9488_VSCRDEF 0x33
#define ILI9488_MADCTL 0x36
#define ILI9488_VSCRSADD 0x37
#define ILI9488_PIXFMT 0x3A
#define ILI9488_RAMWRCONT 0x3C
#define ILI9488_RAMRDCONT 0x3E
#define ILI9488_IMCTR 0xB0
#define ILI9488_FRMCTR1 0xB1
#define ILI9488_FRMCTR2 0xB2
#define ILI9488_FRMCTR3 0xB3
#define ILI9488_INVCTR 0xB4
#define ILI9488_DFUNCTR 0xB6
#define ILI9488_PWCTR1 0xC0
#define ILI9488_PWCTR2 0xC1
#define ILI9488_PWCTR3 0xC2
#define ILI9488_PWCTR4 0xC3
#define ILI9488_PWCTR5 0xC4
#define ILI9488_VMCTR1 0xC5
#define ILI9488_VMCTR2 0xC7
#define ILI9488_RDID1 0xDA
#define ILI9488_RDID2 0xDB
#define ILI9488_RDID3 0xDC
#define ILI9488_RDID4 0xDD
#define ILI9488_GMCTRP1 0xE0
#define ILI9488_GMCTRN1 0xE1
#define ILI9488_IMGFUNCT 0xE9
#define ILI9488_ADJCTR3 0xF7
#define ILI9488_MAD_RGB 0x08
#define ILI9488_MAD_BGR 0x00
#define ILI9488_MAD_VERTICAL 0x20
#define ILI9488_MAD_X_LEFT 0x00
#define ILI9488_MAD_X_RIGHT 0x40
#define ILI9488_MAD_Y_UP 0x80
#define ILI9488_MAD_Y_DOWN 0x00
/* MADCTL Defines */
#define MADCTL_MY 0x80
#define MADCTL_MX 0x40
#define MADCTL_MV 0x20
#define MADCTL_ML 0x10
#define MADCTL_RGB 0x08
#define MADCTL_MH 0x04
#define LCD_NAME "ILI9488"
#define LCD_BPP 16
#define ILI9488_RESOLUTION_HOR 320
#define ILI9488_RESOLUTION_VER 480
static scr_handle_t g_lcd_handle;
/**
* This header file is only used to redefine the function to facilitate the call.
* It can only be placed in this position, not in the head of the file.
*/
#include "interface_drv_def.h"
scr_driver_t lcd_ili9488_default_driver = {
.init = lcd_ili9488_init,
.deinit = lcd_ili9488_deinit,
.set_direction = lcd_ili9488_set_rotation,
.set_window = lcd_ili9488_set_window,
.write_ram_data = lcd_ili9488_write_ram_data,
.draw_pixel = lcd_ili9488_draw_pixel,
.draw_bitmap = lcd_ili9488_draw_bitmap,
.get_info = lcd_ili9488_get_info,
};
static void lcd_ili9488_init_reg(void);
esp_err_t lcd_ili9488_init(const scr_controller_config_t *lcd_conf)
{
LCD_CHECK(lcd_conf->width <= ILI9488_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(lcd_conf->height <= ILI9488_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG);
LCD_CHECK((NULL != lcd_conf->interface_drv->write_command && \
NULL != lcd_conf->interface_drv->write_data && \
NULL != lcd_conf->interface_drv->write && \
NULL != lcd_conf->interface_drv->read && \
NULL != lcd_conf->interface_drv->bus_acquire && \
NULL != lcd_conf->interface_drv->bus_release),
"Interface driver invalid", ESP_ERR_INVALID_ARG);
esp_err_t ret;
// Reset the display
if (lcd_conf->pin_num_rst >= 0) {
gpio_pad_select_gpio(lcd_conf->pin_num_rst);
gpio_set_direction(lcd_conf->pin_num_rst, GPIO_MODE_OUTPUT);
gpio_set_level(lcd_conf->pin_num_rst, (lcd_conf->rst_active_level) & 0x1);
vTaskDelay(100 / portTICK_RATE_MS);
gpio_set_level(lcd_conf->pin_num_rst, (~(lcd_conf->rst_active_level)) & 0x1);
vTaskDelay(100 / portTICK_RATE_MS);
}
g_lcd_handle.interface_drv = lcd_conf->interface_drv;
g_lcd_handle.original_width = lcd_conf->width;
g_lcd_handle.original_height = lcd_conf->height;
g_lcd_handle.offset_hor = lcd_conf->offset_hor;
g_lcd_handle.offset_ver = lcd_conf->offset_ver;
lcd_ili9488_init_reg();
// Enable backlight
if (lcd_conf->pin_num_bckl >= 0) {
gpio_pad_select_gpio(lcd_conf->pin_num_bckl);
gpio_set_direction(lcd_conf->pin_num_bckl, GPIO_MODE_OUTPUT);
gpio_set_level(lcd_conf->pin_num_bckl, (lcd_conf->bckl_active_level) & 0x1);
}
ret = lcd_ili9488_set_rotation(lcd_conf->rotate);
LCD_CHECK(ESP_OK == ret, "set rotation failed", ESP_FAIL);
ret = lcd_ili9488_set_invert(1); /**< ILI9488 setting the reverse color is the normal color */
LCD_CHECK(ESP_OK == ret, "Set color invert failed", ESP_FAIL);
return ESP_OK;
}
esp_err_t lcd_ili9488_deinit(void)
{
memset(&g_lcd_handle, 0, sizeof(scr_handle_t));
return ESP_OK;
}
esp_err_t lcd_ili9488_set_rotation(scr_dir_t dir)
{
esp_err_t ret;
uint8_t reg_data = MADCTL_RGB;
if (SCR_DIR_MAX < dir) {
dir >>= 5;
}
LCD_CHECK(dir < 8, "Unsupport rotate direction", ESP_ERR_INVALID_ARG);
switch (dir) {
case SCR_DIR_LRTB:
g_lcd_handle.width = g_lcd_handle.original_width;
g_lcd_handle.height = g_lcd_handle.original_height;
break;
case SCR_DIR_LRBT:
reg_data |= MADCTL_MY;
g_lcd_handle.width = g_lcd_handle.original_width;
g_lcd_handle.height = g_lcd_handle.original_height;
break;
case SCR_DIR_RLTB:
reg_data |= MADCTL_MX;
g_lcd_handle.width = g_lcd_handle.original_width;
g_lcd_handle.height = g_lcd_handle.original_height;
break;
case SCR_DIR_RLBT:
reg_data |= MADCTL_MX | MADCTL_MY;
g_lcd_handle.width = g_lcd_handle.original_width;
g_lcd_handle.height = g_lcd_handle.original_height;
break;
case SCR_DIR_TBLR:
reg_data |= MADCTL_MV;
g_lcd_handle.width = g_lcd_handle.original_height;
g_lcd_handle.height = g_lcd_handle.original_width;
break;
case SCR_DIR_BTLR:
reg_data |= MADCTL_MY | MADCTL_MV;
g_lcd_handle.width = g_lcd_handle.original_height;
g_lcd_handle.height = g_lcd_handle.original_width;
break;
case SCR_DIR_TBRL:
reg_data |= MADCTL_MX | MADCTL_MV;
g_lcd_handle.width = g_lcd_handle.original_height;
g_lcd_handle.height = g_lcd_handle.original_width;
break;
case SCR_DIR_BTRL:
reg_data |= MADCTL_MX | MADCTL_MY | MADCTL_MV;
g_lcd_handle.width = g_lcd_handle.original_height;
g_lcd_handle.height = g_lcd_handle.original_width;
break;
default: break;
}
ESP_LOGI(TAG, "MADCTL=0x%x", reg_data);
ret = LCD_WRITE_REG(ILI9488_MADCTL, reg_data);
LCD_CHECK(ESP_OK == ret, "Set screen rotate failed", ESP_FAIL);
g_lcd_handle.dir = dir;
return ESP_OK;
}
esp_err_t lcd_ili9488_get_info(scr_info_t *info)
{
LCD_CHECK(NULL != info, "info pointer invalid", ESP_ERR_INVALID_ARG);
info->width = g_lcd_handle.width;
info->height = g_lcd_handle.height;
info->dir = g_lcd_handle.dir;
info->name = LCD_NAME;
info->color_type = SCR_COLOR_TYPE_RGB565;
info->bpp = LCD_BPP;
return ESP_OK;
}
esp_err_t lcd_ili9488_set_invert(bool is_invert)
{
return LCD_WRITE_CMD(is_invert ? ILI9488_INVON : ILI9488_INVOFF);
}
esp_err_t lcd_ili9488_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
LCD_CHECK((x1 < g_lcd_handle.width) && (y1 < g_lcd_handle.height), "The set coordinates exceed the screen size", ESP_ERR_INVALID_ARG);
LCD_CHECK((x0 <= x1) && (y0 <= y1), "Window coordinates invalid", ESP_ERR_INVALID_ARG);
esp_err_t ret = ESP_OK;
scr_utility_apply_offset(&g_lcd_handle, ILI9488_RESOLUTION_HOR, ILI9488_RESOLUTION_VER, &x0, &y0, &x1, &y1);
ret |= LCD_WRITE_CMD(ILI9488_CASET);
ret |= LCD_WRITE_DATA(x0 >> 8);
ret |= LCD_WRITE_DATA(x0 & 0xff);
ret |= LCD_WRITE_DATA(x1 >> 8);
ret |= LCD_WRITE_DATA(x1 & 0xff);
ret |= LCD_WRITE_CMD(ILI9488_PASET);
ret |= LCD_WRITE_DATA(y0 >> 8);
ret |= LCD_WRITE_DATA(y0 & 0xff);
ret |= LCD_WRITE_DATA(y1 >> 8);
ret |= LCD_WRITE_DATA(y1 & 0xff);
ret |= LCD_WRITE_CMD(ILI9488_RAMWR);
LCD_CHECK(ESP_OK == ret, "Set window failed", ESP_FAIL);
return ESP_OK;
}
esp_err_t lcd_ili9488_write_ram_data(uint16_t color)
{
static uint8_t data[2];
data[0] = (uint8_t)(color & 0xff);
data[1] = (uint8_t)(color >> 8);
return LCD_WRITE(data, 2);
}
esp_err_t lcd_ili9488_draw_pixel(uint16_t x, uint16_t y, uint16_t color)
{
esp_err_t ret;
ret = lcd_ili9488_set_window(x, y, x, y);
if (ESP_OK != ret) {
return ESP_FAIL;
}
return lcd_ili9488_write_ram_data(color);
}
esp_err_t lcd_ili9488_draw_bitmap(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t *bitmap)
{
esp_err_t ret;
LCD_CHECK(NULL != bitmap, "bitmap pointer invalid", ESP_ERR_INVALID_ARG);
LCD_IFACE_ACQUIRE();
ret = lcd_ili9488_set_window(x, y, x + w - 1, y + h - 1);
if (ESP_OK != ret) {
return ESP_FAIL;
}
uint32_t len = w * h;
ret = LCD_WRITE((uint8_t *)bitmap, 2 * len);
LCD_IFACE_RELEASE();
LCD_CHECK(ESP_OK == ret, "lcd write ram data failed", ESP_FAIL);
return ESP_OK;
}
static void lcd_ili9488_init_reg(void)
{
LCD_WRITE_CMD(ILI9488_SWRESET);
vTaskDelay(120 / portTICK_RATE_MS);
// positive gamma control
LCD_WRITE_CMD(ILI9488_GMCTRP1);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x03);
LCD_WRITE_DATA(0x09);
LCD_WRITE_DATA(0x08);
LCD_WRITE_DATA(0x16);
LCD_WRITE_DATA(0x0A);
LCD_WRITE_DATA(0x3F);
LCD_WRITE_DATA(0x78);
LCD_WRITE_DATA(0x4C);
LCD_WRITE_DATA(0x09);
LCD_WRITE_DATA(0x0A);
LCD_WRITE_DATA(0x08);
LCD_WRITE_DATA(0x16);
LCD_WRITE_DATA(0x1A);
LCD_WRITE_DATA(0x0F);
// negative gamma control
LCD_WRITE_CMD(ILI9488_GMCTRN1);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x16);
LCD_WRITE_DATA(0x19);
LCD_WRITE_DATA(0x03);
LCD_WRITE_DATA(0x0F);
LCD_WRITE_DATA(0x05);
LCD_WRITE_DATA(0x32);
LCD_WRITE_DATA(0x45);
LCD_WRITE_DATA(0x46);
LCD_WRITE_DATA(0x04);
LCD_WRITE_DATA(0x0E);
LCD_WRITE_DATA(0x0D);
LCD_WRITE_DATA(0x35);
LCD_WRITE_DATA(0x37);
LCD_WRITE_DATA(0x0F);
// Power Control 1 (Vreg1out, Verg2out)
LCD_WRITE_CMD(ILI9488_PWCTR1);
LCD_WRITE_DATA(0x17);
LCD_WRITE_DATA(0x15);
// Power Control 2 (VGH,VGL)
LCD_WRITE_CMD(ILI9488_PWCTR2);
LCD_WRITE_DATA(0x41);
// Power Control 3 (Vcom)
LCD_WRITE_CMD(ILI9488_VMCTR1);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x12);
LCD_WRITE_DATA(0x80);
LCD_WRITE_CMD(ILI9488_IMCTR); LCD_WRITE_DATA(0x80); // Interface Mode Control (SDO NOT USE)
LCD_WRITE_CMD(ILI9488_PIXFMT); LCD_WRITE_DATA(0x55); // Interface Pixel Format (16 bit)
LCD_WRITE_CMD(ILI9488_FRMCTR1); LCD_WRITE_DATA(0xA0); // Frame rate (60Hz)
LCD_WRITE_CMD(ILI9488_INVCTR); LCD_WRITE_DATA(0x02); // Display Inversion Control (2-dot)
LCD_WRITE_CMD(ILI9488_DFUNCTR); // Display Function Control RGB/MCU Interface Control
LCD_WRITE_DATA(0x02);
LCD_WRITE_DATA(0x02);
LCD_WRITE_CMD(ILI9488_IMGFUNCT); // Set Image Functio (Disable 24 bit data)
LCD_WRITE_DATA(0x00);
LCD_WRITE_CMD(ILI9488_ADJCTR3); // Adjust Control (D7 stream, loose)
LCD_WRITE_DATA(0xa9);
LCD_WRITE_DATA(0x51);
LCD_WRITE_DATA(0x2c);
LCD_WRITE_DATA(0x82);
LCD_WRITE_CMD(ILI9488_SLPOUT); // Exit Sleep
LCD_WRITE_CMD(ILI9488_DISPON); // Display on
vTaskDelay(120 / portTICK_RATE_MS);
}

View file

@ -1,138 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) Co. Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _IOT_ILI9488_H_
#define _IOT_ILI9488_H_
#include "screen_driver.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize screen
*
* @param lcd_conf Pointer to a structure with lcd config arguments.
*
* @return
* - ESP_OK on success
* - ESP_FAIL Driver not installed
*/
esp_err_t lcd_ili9488_init(const scr_controller_config_t *lcd_conf);
/**
* @brief Deinitialize screen
*
* @return
* - ESP_OK on success
* - ESP_FAIL Deinitialize failed
* - ESP_ERR_NOT_SUPPORTED unsupported
*/
esp_err_t lcd_ili9488_deinit(void);
/**
* @brief Set screen direction of rotation
*
* @param dir Pointer to a scr_dir_t structure.
*
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ili9488_set_rotation(scr_dir_t dir);
/**
* @brief Get screen information
*
* @param info Pointer to a scr_info_t structure.
*
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ili9488_get_info(scr_info_t *info);
/**
* @brief Set screen color invert
*
* @param is_invert true: color invert on, false: color invert off
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ili9488_set_invert(bool is_invert);
/**
* @brief Set screen window
*
* @param x0 Starting point in X direction
* @param y0 Starting point in Y direction
* @param x1 End point in X direction
* @param y1 End point in Y direction
*
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ili9488_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
/**
* @brief Write a RAM data
*
* @param color New color of a pixel
*
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ili9488_write_ram_data(uint16_t color);
/**
* @brief Draw one pixel in screen with color
*
* @param x X co-ordinate of set orientation
* @param y Y co-ordinate of set orientation
* @param color New color of the pixel
*
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ili9488_draw_pixel(uint16_t x, uint16_t y, uint16_t color);
/**
* @brief Fill the pixels on LCD screen with bitmap
*
* @param x Starting point in X direction
* @param y Starting point in Y direction
* @param w width of image in bitmap array
* @param h height of image in bitmap array
* @param bitmap pointer to bitmap array
*
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ili9488_draw_bitmap(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t *bitmap);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -76,7 +76,7 @@ esp_err_t lcd_ili9806_init(const scr_controller_config_t *lcd_conf)
LCD_CHECK(lcd_conf->width <= ILI9806_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->width <= ILI9806_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(lcd_conf->height <= ILI9806_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->height <= ILI9806_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG); LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG);
LCD_CHECK((NULL != lcd_conf->interface_drv->write_command && \ LCD_CHECK((NULL != lcd_conf->interface_drv->write_cmd && \
NULL != lcd_conf->interface_drv->write_data && \ NULL != lcd_conf->interface_drv->write_data && \
NULL != lcd_conf->interface_drv->write && \ NULL != lcd_conf->interface_drv->write && \
NULL != lcd_conf->interface_drv->read && \ NULL != lcd_conf->interface_drv->read && \

View file

@ -77,7 +77,7 @@ esp_err_t lcd_nt35510_init(const scr_controller_config_t *lcd_conf)
LCD_CHECK(lcd_conf->width <= NT35510_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->width <= NT35510_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(lcd_conf->height <= NT35510_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->height <= NT35510_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG); LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG);
LCD_CHECK((NULL != lcd_conf->interface_drv->write_command && \ LCD_CHECK((NULL != lcd_conf->interface_drv->write_cmd && \
NULL != lcd_conf->interface_drv->write_data && \ NULL != lcd_conf->interface_drv->write_data && \
NULL != lcd_conf->interface_drv->write && \ NULL != lcd_conf->interface_drv->write && \
NULL != lcd_conf->interface_drv->read && \ NULL != lcd_conf->interface_drv->read && \
@ -176,7 +176,7 @@ esp_err_t lcd_nt35510_set_rotation(scr_dir_t dir)
default: break; default: break;
} }
ESP_LOGI(TAG, "MADCTL=0x%x", reg_data); ESP_LOGI(TAG, "MADCTL=0x%x", reg_data);
ret = LCD_WRITE_REG_16B(NT35510_MADCTL, reg_data); ret = LCD_WRITE_REG(NT35510_MADCTL, reg_data);
LCD_CHECK(ESP_OK == ret, "Set screen rotate failed", ESP_FAIL); LCD_CHECK(ESP_OK == ret, "Set screen rotate failed", ESP_FAIL);
g_lcd_handle.dir = dir; g_lcd_handle.dir = dir;
return ESP_OK; return ESP_OK;
@ -201,16 +201,16 @@ esp_err_t lcd_nt35510_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
scr_utility_apply_offset(&g_lcd_handle, NT35510_RESOLUTION_HOR, NT35510_RESOLUTION_VER, &x0, &y0, &x1, &y1); scr_utility_apply_offset(&g_lcd_handle, NT35510_RESOLUTION_HOR, NT35510_RESOLUTION_VER, &x0, &y0, &x1, &y1);
ret |= LCD_WRITE_REG_16B(NT35510_CASET, x0 >> 8); ret |= LCD_WRITE_REG(NT35510_CASET, x0 >> 8);
ret |= LCD_WRITE_REG_16B(NT35510_CASET + 1, x0 & 0xff); ret |= LCD_WRITE_REG(NT35510_CASET + 1, x0 & 0xff);
ret |= LCD_WRITE_REG_16B(NT35510_CASET + 2, x1 >> 8); ret |= LCD_WRITE_REG(NT35510_CASET + 2, x1 >> 8);
ret |= LCD_WRITE_REG_16B(NT35510_CASET + 3, x1 & 0xff); ret |= LCD_WRITE_REG(NT35510_CASET + 3, x1 & 0xff);
ret |= LCD_WRITE_REG_16B(NT35510_RASET, y0 >> 8); ret |= LCD_WRITE_REG(NT35510_RASET, y0 >> 8);
ret |= LCD_WRITE_REG_16B(NT35510_RASET + 1, y0 & 0xff); ret |= LCD_WRITE_REG(NT35510_RASET + 1, y0 & 0xff);
ret |= LCD_WRITE_REG_16B(NT35510_RASET + 2, y1 >> 8); ret |= LCD_WRITE_REG(NT35510_RASET + 2, y1 >> 8);
ret |= LCD_WRITE_REG_16B(NT35510_RASET + 3, y1 & 0xff); ret |= LCD_WRITE_REG(NT35510_RASET + 3, y1 & 0xff);
ret |= LCD_WRITE_CMD_16B(NT35510_RAMWR); ret |= LCD_WRITE_CMD(NT35510_RAMWR);
LCD_CHECK(ESP_OK == ret, "Set window failed", ESP_FAIL); LCD_CHECK(ESP_OK == ret, "Set window failed", ESP_FAIL);
return ESP_OK; return ESP_OK;
} }
@ -253,426 +253,387 @@ esp_err_t lcd_nt35510_draw_bitmap(uint16_t x, uint16_t y, uint16_t w, uint16_t h
static void lcd_nt35510_init_reg(void) static void lcd_nt35510_init_reg(void)
{ {
// Software Reset LCD_WRITE_CMD(0x0100); // Software Reset
LCD_WRITE_CMD_16B(0x0100);
vTaskDelay(10 / portTICK_RATE_MS); vTaskDelay(10 / portTICK_RATE_MS);
LCD_WRITE_CMD(0x1200);
LCD_WRITE_REG(0xf000, 0x0055);
LCD_WRITE_REG(0xf001, 0x00aa);
LCD_WRITE_REG(0xf002, 0x0052);
LCD_WRITE_REG(0xf003, 0x0008);
LCD_WRITE_REG(0xf004, 0x0001);
// Partial mode on LCD_WRITE_REG(0xbc01, 0x0086);
LCD_WRITE_CMD_16B(0x1200); LCD_WRITE_REG(0xbc02, 0x006a);
LCD_WRITE_REG(0xbd01, 0x0086);
LCD_WRITE_REG(0xbd02, 0x006a);
LCD_WRITE_REG(0xbe01, 0x0067);
// Enable manufacturer command set, select page 1 LCD_WRITE_REG(0xd100, 0x0000);
LCD_WRITE_REG_16B(0xf000, 0x0055); LCD_WRITE_REG(0xd101, 0x005d);
LCD_WRITE_REG_16B(0xf001, 0x00aa); LCD_WRITE_REG(0xd102, 0x0000);
LCD_WRITE_REG_16B(0xf002, 0x0052); LCD_WRITE_REG(0xd103, 0x006b);
LCD_WRITE_REG_16B(0xf003, 0x0008); LCD_WRITE_REG(0xd104, 0x0000);
LCD_WRITE_REG_16B(0xf004, 0x0001); LCD_WRITE_REG(0xd105, 0x0084);
LCD_WRITE_REG(0xd106, 0x0000);
LCD_WRITE_REG(0xd107, 0x009c);
LCD_WRITE_REG(0xd108, 0x0000);
LCD_WRITE_REG(0xd109, 0x00b1);
LCD_WRITE_REG(0xd10a, 0x0000);
LCD_WRITE_REG(0xd10b, 0x00d9);
LCD_WRITE_REG(0xd10c, 0x0000);
LCD_WRITE_REG(0xd10d, 0x00fd);
LCD_WRITE_REG(0xd10e, 0x0001);
LCD_WRITE_REG(0xd10f, 0x0038);
LCD_WRITE_REG(0xd110, 0x0001);
LCD_WRITE_REG(0xd111, 0x0068);
LCD_WRITE_REG(0xd112, 0x0001);
LCD_WRITE_REG(0xd113, 0x00b9);
LCD_WRITE_REG(0xd114, 0x0001);
LCD_WRITE_REG(0xd115, 0x00fb);
LCD_WRITE_REG(0xd116, 0x0002);
LCD_WRITE_REG(0xd117, 0x0063);
LCD_WRITE_REG(0xd118, 0x0002);
LCD_WRITE_REG(0xd119, 0x00b9);
LCD_WRITE_REG(0xd11a, 0x0002);
LCD_WRITE_REG(0xd11b, 0x00bb);
LCD_WRITE_REG(0xd11c, 0x0003);
LCD_WRITE_REG(0xd11d, 0x0003);
LCD_WRITE_REG(0xd11e, 0x0003);
LCD_WRITE_REG(0xd11f, 0x0046);
LCD_WRITE_REG(0xd120, 0x0003);
LCD_WRITE_REG(0xd121, 0x0069);
LCD_WRITE_REG(0xd122, 0x0003);
LCD_WRITE_REG(0xd123, 0x008f);
LCD_WRITE_REG(0xd124, 0x0003);
LCD_WRITE_REG(0xd125, 0x00a4);
LCD_WRITE_REG(0xd126, 0x0003);
LCD_WRITE_REG(0xd127, 0x00b9);
LCD_WRITE_REG(0xd128, 0x0003);
LCD_WRITE_REG(0xd129, 0x00c7);
LCD_WRITE_REG(0xd12a, 0x0003);
LCD_WRITE_REG(0xd12b, 0x00c9);
LCD_WRITE_REG(0xd12c, 0x0003);
LCD_WRITE_REG(0xd12d, 0x00cb);
LCD_WRITE_REG(0xd12e, 0x0003);
LCD_WRITE_REG(0xd12f, 0x00cb);
LCD_WRITE_REG(0xd130, 0x0003);
LCD_WRITE_REG(0xd131, 0x00cb);
LCD_WRITE_REG(0xd132, 0x0003);
LCD_WRITE_REG(0xd133, 0x00cc);
// VGML and VGSP voltages (regulator output voltage VGMP/VGSP for positive gamma divider) LCD_WRITE_REG(0xd200, 0x0000);
LCD_WRITE_REG_16B(0xbc01, 0x0086); LCD_WRITE_REG(0xd201, 0x005d);
LCD_WRITE_REG_16B(0xbc02, 0x006a); LCD_WRITE_REG(0xd202, 0x0000);
LCD_WRITE_REG(0xd203, 0x006b);
LCD_WRITE_REG(0xd204, 0x0000);
LCD_WRITE_REG(0xd205, 0x0084);
LCD_WRITE_REG(0xd206, 0x0000);
LCD_WRITE_REG(0xd207, 0x009c);
LCD_WRITE_REG(0xd208, 0x0000);
LCD_WRITE_REG(0xd209, 0x00b1);
LCD_WRITE_REG(0xd20a, 0x0000);
LCD_WRITE_REG(0xd20b, 0x00d9);
LCD_WRITE_REG(0xd20c, 0x0000);
LCD_WRITE_REG(0xd20d, 0x00fd);
LCD_WRITE_REG(0xd20e, 0x0001);
LCD_WRITE_REG(0xd20f, 0x0038);
LCD_WRITE_REG(0xd210, 0x0001);
LCD_WRITE_REG(0xd211, 0x0068);
LCD_WRITE_REG(0xd212, 0x0001);
LCD_WRITE_REG(0xd213, 0x00b9);
LCD_WRITE_REG(0xd214, 0x0001);
LCD_WRITE_REG(0xd215, 0x00fb);
LCD_WRITE_REG(0xd216, 0x0002);
LCD_WRITE_REG(0xd217, 0x0063);
LCD_WRITE_REG(0xd218, 0x0002);
LCD_WRITE_REG(0xd219, 0x00b9);
LCD_WRITE_REG(0xd21a, 0x0002);
LCD_WRITE_REG(0xd21b, 0x00bb);
LCD_WRITE_REG(0xd21c, 0x0003);
LCD_WRITE_REG(0xd21d, 0x0003);
LCD_WRITE_REG(0xd21e, 0x0003);
LCD_WRITE_REG(0xd21f, 0x0046);
LCD_WRITE_REG(0xd220, 0x0003);
LCD_WRITE_REG(0xd221, 0x0069);
LCD_WRITE_REG(0xd222, 0x0003);
LCD_WRITE_REG(0xd223, 0x008f);
LCD_WRITE_REG(0xd224, 0x0003);
LCD_WRITE_REG(0xd225, 0x00a4);
LCD_WRITE_REG(0xd226, 0x0003);
LCD_WRITE_REG(0xd227, 0x00b9);
LCD_WRITE_REG(0xd228, 0x0003);
LCD_WRITE_REG(0xd229, 0x00c7);
LCD_WRITE_REG(0xd22a, 0x0003);
LCD_WRITE_REG(0xd22b, 0x00c9);
LCD_WRITE_REG(0xd22c, 0x0003);
LCD_WRITE_REG(0xd22d, 0x00cb);
LCD_WRITE_REG(0xd22e, 0x0003);
LCD_WRITE_REG(0xd22f, 0x00cb);
LCD_WRITE_REG(0xd230, 0x0003);
LCD_WRITE_REG(0xd231, 0x00cb);
LCD_WRITE_REG(0xd232, 0x0003);
LCD_WRITE_REG(0xd233, 0x00cc);
// VGML and VGSP voltages (regulator output voltage VGMP/VGSP for negative gamma divider) LCD_WRITE_REG(0xd300, 0x0000);
LCD_WRITE_REG_16B(0xbd01, 0x0086); LCD_WRITE_REG(0xd301, 0x005d);
LCD_WRITE_REG_16B(0xbd02, 0x006a); LCD_WRITE_REG(0xd302, 0x0000);
LCD_WRITE_REG(0xd303, 0x006b);
LCD_WRITE_REG(0xd304, 0x0000);
LCD_WRITE_REG(0xd305, 0x0084);
LCD_WRITE_REG(0xd306, 0x0000);
LCD_WRITE_REG(0xd307, 0x009c);
LCD_WRITE_REG(0xd308, 0x0000);
LCD_WRITE_REG(0xd309, 0x00b1);
LCD_WRITE_REG(0xd30a, 0x0000);
LCD_WRITE_REG(0xd30b, 0x00d9);
LCD_WRITE_REG(0xd30c, 0x0000);
LCD_WRITE_REG(0xd30d, 0x00fd);
LCD_WRITE_REG(0xd30e, 0x0001);
LCD_WRITE_REG(0xd30f, 0x0038);
LCD_WRITE_REG(0xd310, 0x0001);
LCD_WRITE_REG(0xd311, 0x0068);
LCD_WRITE_REG(0xd312, 0x0001);
LCD_WRITE_REG(0xd313, 0x00b9);
LCD_WRITE_REG(0xd314, 0x0001);
LCD_WRITE_REG(0xd315, 0x00fb);
LCD_WRITE_REG(0xd316, 0x0002);
LCD_WRITE_REG(0xd317, 0x0063);
LCD_WRITE_REG(0xd318, 0x0002);
LCD_WRITE_REG(0xd319, 0x00b9);
LCD_WRITE_REG(0xd31a, 0x0002);
LCD_WRITE_REG(0xd31b, 0x00bb);
LCD_WRITE_REG(0xd31c, 0x0003);
LCD_WRITE_REG(0xd31d, 0x0003);
LCD_WRITE_REG(0xd31e, 0x0003);
LCD_WRITE_REG(0xd31f, 0x0046);
LCD_WRITE_REG(0xd320, 0x0003);
LCD_WRITE_REG(0xd321, 0x0069);
LCD_WRITE_REG(0xd322, 0x0003);
LCD_WRITE_REG(0xd323, 0x008f);
LCD_WRITE_REG(0xd324, 0x0003);
LCD_WRITE_REG(0xd325, 0x00a4);
LCD_WRITE_REG(0xd326, 0x0003);
LCD_WRITE_REG(0xd327, 0x00b9);
LCD_WRITE_REG(0xd328, 0x0003);
LCD_WRITE_REG(0xd329, 0x00c7);
LCD_WRITE_REG(0xd32a, 0x0003);
LCD_WRITE_REG(0xd32b, 0x00c9);
LCD_WRITE_REG(0xd32c, 0x0003);
LCD_WRITE_REG(0xd32d, 0x00cb);
LCD_WRITE_REG(0xd32e, 0x0003);
LCD_WRITE_REG(0xd32f, 0x00cb);
LCD_WRITE_REG(0xd330, 0x0003);
LCD_WRITE_REG(0xd331, 0x00cb);
LCD_WRITE_REG(0xd332, 0x0003);
LCD_WRITE_REG(0xd333, 0x00cc);
// VCOM Offset Voltage LCD_WRITE_REG(0xd400, 0x0000);
LCD_WRITE_REG_16B(0xbe01, 0x0067); LCD_WRITE_REG(0xd401, 0x005d);
LCD_WRITE_REG(0xd402, 0x0000);
LCD_WRITE_REG(0xd403, 0x006b);
LCD_WRITE_REG(0xd404, 0x0000);
LCD_WRITE_REG(0xd405, 0x0084);
LCD_WRITE_REG(0xd406, 0x0000);
LCD_WRITE_REG(0xd407, 0x009c);
LCD_WRITE_REG(0xd408, 0x0000);
LCD_WRITE_REG(0xd409, 0x00b1);
LCD_WRITE_REG(0xd40a, 0x0000);
LCD_WRITE_REG(0xd40b, 0x00d9);
LCD_WRITE_REG(0xd40c, 0x0000);
LCD_WRITE_REG(0xd40d, 0x00fd);
LCD_WRITE_REG(0xd40e, 0x0001);
LCD_WRITE_REG(0xd40f, 0x0038);
LCD_WRITE_REG(0xd410, 0x0001);
LCD_WRITE_REG(0xd411, 0x0068);
LCD_WRITE_REG(0xd412, 0x0001);
LCD_WRITE_REG(0xd413, 0x00b9);
LCD_WRITE_REG(0xd414, 0x0001);
LCD_WRITE_REG(0xd415, 0x00fb);
LCD_WRITE_REG(0xd416, 0x0002);
LCD_WRITE_REG(0xd417, 0x0063);
LCD_WRITE_REG(0xd418, 0x0002);
LCD_WRITE_REG(0xd419, 0x00b9);
LCD_WRITE_REG(0xd41a, 0x0002);
LCD_WRITE_REG(0xd41b, 0x00bb);
LCD_WRITE_REG(0xd41c, 0x0003);
LCD_WRITE_REG(0xd41d, 0x0003);
LCD_WRITE_REG(0xd41e, 0x0003);
LCD_WRITE_REG(0xd41f, 0x0046);
LCD_WRITE_REG(0xd420, 0x0003);
LCD_WRITE_REG(0xd421, 0x0069);
LCD_WRITE_REG(0xd422, 0x0003);
LCD_WRITE_REG(0xd423, 0x008f);
LCD_WRITE_REG(0xd424, 0x0003);
LCD_WRITE_REG(0xd425, 0x00a4);
LCD_WRITE_REG(0xd426, 0x0003);
LCD_WRITE_REG(0xd427, 0x00b9);
LCD_WRITE_REG(0xd428, 0x0003);
LCD_WRITE_REG(0xd429, 0x00c7);
LCD_WRITE_REG(0xd42a, 0x0003);
LCD_WRITE_REG(0xd42b, 0x00c9);
LCD_WRITE_REG(0xd42c, 0x0003);
LCD_WRITE_REG(0xd42d, 0x00cb);
LCD_WRITE_REG(0xd42e, 0x0003);
LCD_WRITE_REG(0xd42f, 0x00cb);
LCD_WRITE_REG(0xd430, 0x0003);
LCD_WRITE_REG(0xd431, 0x00cb);
LCD_WRITE_REG(0xd432, 0x0003);
LCD_WRITE_REG(0xd433, 0x00cc);
// Gamma 2.2 Correction for Red (Positive) LCD_WRITE_REG(0xd500, 0x0000);
LCD_WRITE_REG_16B(0xd100, 0x0000); LCD_WRITE_REG(0xd501, 0x005d);
LCD_WRITE_REG_16B(0xd101, 0x005d); LCD_WRITE_REG(0xd502, 0x0000);
LCD_WRITE_REG_16B(0xd102, 0x0000); LCD_WRITE_REG(0xd503, 0x006b);
LCD_WRITE_REG_16B(0xd103, 0x006b); LCD_WRITE_REG(0xd504, 0x0000);
LCD_WRITE_REG_16B(0xd104, 0x0000); LCD_WRITE_REG(0xd505, 0x0084);
LCD_WRITE_REG_16B(0xd105, 0x0084); LCD_WRITE_REG(0xd506, 0x0000);
LCD_WRITE_REG_16B(0xd106, 0x0000); LCD_WRITE_REG(0xd507, 0x009c);
LCD_WRITE_REG_16B(0xd107, 0x009c); LCD_WRITE_REG(0xd508, 0x0000);
LCD_WRITE_REG_16B(0xd108, 0x0000); LCD_WRITE_REG(0xd509, 0x00b1);
LCD_WRITE_REG_16B(0xd109, 0x00b1); LCD_WRITE_REG(0xd50a, 0x0000);
LCD_WRITE_REG_16B(0xd10a, 0x0000); LCD_WRITE_REG(0xd50b, 0x00D9);
LCD_WRITE_REG_16B(0xd10b, 0x00d9); LCD_WRITE_REG(0xd50c, 0x0000);
LCD_WRITE_REG_16B(0xd10c, 0x0000); LCD_WRITE_REG(0xd50d, 0x00fd);
LCD_WRITE_REG_16B(0xd10d, 0x00fd); LCD_WRITE_REG(0xd50e, 0x0001);
LCD_WRITE_REG_16B(0xd10e, 0x0001); LCD_WRITE_REG(0xd50f, 0x0038);
LCD_WRITE_REG_16B(0xd10f, 0x0038); LCD_WRITE_REG(0xd510, 0x0001);
LCD_WRITE_REG_16B(0xd110, 0x0001); LCD_WRITE_REG(0xd511, 0x0068);
LCD_WRITE_REG_16B(0xd111, 0x0068); LCD_WRITE_REG(0xd512, 0x0001);
LCD_WRITE_REG_16B(0xd112, 0x0001); LCD_WRITE_REG(0xd513, 0x00b9);
LCD_WRITE_REG_16B(0xd113, 0x00b9); LCD_WRITE_REG(0xd514, 0x0001);
LCD_WRITE_REG_16B(0xd114, 0x0001); LCD_WRITE_REG(0xd515, 0x00fb);
LCD_WRITE_REG_16B(0xd115, 0x00fb); LCD_WRITE_REG(0xd516, 0x0002);
LCD_WRITE_REG_16B(0xd116, 0x0002); LCD_WRITE_REG(0xd517, 0x0063);
LCD_WRITE_REG_16B(0xd117, 0x0063); LCD_WRITE_REG(0xd518, 0x0002);
LCD_WRITE_REG_16B(0xd118, 0x0002); LCD_WRITE_REG(0xd519, 0x00b9);
LCD_WRITE_REG_16B(0xd119, 0x00b9); LCD_WRITE_REG(0xd51a, 0x0002);
LCD_WRITE_REG_16B(0xd11a, 0x0002); LCD_WRITE_REG(0xd51b, 0x00bb);
LCD_WRITE_REG_16B(0xd11b, 0x00bb); LCD_WRITE_REG(0xd51c, 0x0003);
LCD_WRITE_REG_16B(0xd11c, 0x0003); LCD_WRITE_REG(0xd51d, 0x0003);
LCD_WRITE_REG_16B(0xd11d, 0x0003); LCD_WRITE_REG(0xd51e, 0x0003);
LCD_WRITE_REG_16B(0xd11e, 0x0003); LCD_WRITE_REG(0xd51f, 0x0046);
LCD_WRITE_REG_16B(0xd11f, 0x0046); LCD_WRITE_REG(0xd520, 0x0003);
LCD_WRITE_REG_16B(0xd120, 0x0003); LCD_WRITE_REG(0xd521, 0x0069);
LCD_WRITE_REG_16B(0xd121, 0x0069); LCD_WRITE_REG(0xd522, 0x0003);
LCD_WRITE_REG_16B(0xd122, 0x0003); LCD_WRITE_REG(0xd523, 0x008f);
LCD_WRITE_REG_16B(0xd123, 0x008f); LCD_WRITE_REG(0xd524, 0x0003);
LCD_WRITE_REG_16B(0xd124, 0x0003); LCD_WRITE_REG(0xd525, 0x00a4);
LCD_WRITE_REG_16B(0xd125, 0x00a4); LCD_WRITE_REG(0xd526, 0x0003);
LCD_WRITE_REG_16B(0xd126, 0x0003); LCD_WRITE_REG(0xd527, 0x00b9);
LCD_WRITE_REG_16B(0xd127, 0x00b9); LCD_WRITE_REG(0xd528, 0x0003);
LCD_WRITE_REG_16B(0xd128, 0x0003); LCD_WRITE_REG(0xd529, 0x00c7);
LCD_WRITE_REG_16B(0xd129, 0x00c7); LCD_WRITE_REG(0xd52a, 0x0003);
LCD_WRITE_REG_16B(0xd12a, 0x0003); LCD_WRITE_REG(0xd52b, 0x00c9);
LCD_WRITE_REG_16B(0xd12b, 0x00c9); LCD_WRITE_REG(0xd52c, 0x0003);
LCD_WRITE_REG_16B(0xd12c, 0x0003); LCD_WRITE_REG(0xd52d, 0x00cb);
LCD_WRITE_REG_16B(0xd12d, 0x00cb); LCD_WRITE_REG(0xd52e, 0x0003);
LCD_WRITE_REG_16B(0xd12e, 0x0003); LCD_WRITE_REG(0xd52f, 0x00cb);
LCD_WRITE_REG_16B(0xd12f, 0x00cb); LCD_WRITE_REG(0xd530, 0x0003);
LCD_WRITE_REG_16B(0xd130, 0x0003); LCD_WRITE_REG(0xd531, 0x00cb);
LCD_WRITE_REG_16B(0xd131, 0x00cb); LCD_WRITE_REG(0xd532, 0x0003);
LCD_WRITE_REG_16B(0xd132, 0x0003); LCD_WRITE_REG(0xd533, 0x00cc);
LCD_WRITE_REG_16B(0xd133, 0x00cc);
// Gamma 2.2 Correction for Green (Positive) LCD_WRITE_REG(0xd600, 0x0000);
LCD_WRITE_REG_16B(0xd200, 0x0000); LCD_WRITE_REG(0xd601, 0x005d);
LCD_WRITE_REG_16B(0xd201, 0x005d); LCD_WRITE_REG(0xd602, 0x0000);
LCD_WRITE_REG_16B(0xd202, 0x0000); LCD_WRITE_REG(0xd603, 0x006b);
LCD_WRITE_REG_16B(0xd203, 0x006b); LCD_WRITE_REG(0xd604, 0x0000);
LCD_WRITE_REG_16B(0xd204, 0x0000); LCD_WRITE_REG(0xd605, 0x0084);
LCD_WRITE_REG_16B(0xd205, 0x0084); LCD_WRITE_REG(0xd606, 0x0000);
LCD_WRITE_REG_16B(0xd206, 0x0000); LCD_WRITE_REG(0xd607, 0x009c);
LCD_WRITE_REG_16B(0xd207, 0x009c); LCD_WRITE_REG(0xd608, 0x0000);
LCD_WRITE_REG_16B(0xd208, 0x0000); LCD_WRITE_REG(0xd609, 0x00b1);
LCD_WRITE_REG_16B(0xd209, 0x00b1); LCD_WRITE_REG(0xd60a, 0x0000);
LCD_WRITE_REG_16B(0xd20a, 0x0000); LCD_WRITE_REG(0xd60b, 0x00d9);
LCD_WRITE_REG_16B(0xd20b, 0x00d9); LCD_WRITE_REG(0xd60c, 0x0000);
LCD_WRITE_REG_16B(0xd20c, 0x0000); LCD_WRITE_REG(0xd60d, 0x00fd);
LCD_WRITE_REG_16B(0xd20d, 0x00fd); LCD_WRITE_REG(0xd60e, 0x0001);
LCD_WRITE_REG_16B(0xd20e, 0x0001); LCD_WRITE_REG(0xd60f, 0x0038);
LCD_WRITE_REG_16B(0xd20f, 0x0038); LCD_WRITE_REG(0xd610, 0x0001);
LCD_WRITE_REG_16B(0xd210, 0x0001); LCD_WRITE_REG(0xd611, 0x0068);
LCD_WRITE_REG_16B(0xd211, 0x0068); LCD_WRITE_REG(0xd612, 0x0001);
LCD_WRITE_REG_16B(0xd212, 0x0001); LCD_WRITE_REG(0xd613, 0x00b9);
LCD_WRITE_REG_16B(0xd213, 0x00b9); LCD_WRITE_REG(0xd614, 0x0001);
LCD_WRITE_REG_16B(0xd214, 0x0001); LCD_WRITE_REG(0xd615, 0x00fb);
LCD_WRITE_REG_16B(0xd215, 0x00fb); LCD_WRITE_REG(0xd616, 0x0002);
LCD_WRITE_REG_16B(0xd216, 0x0002); LCD_WRITE_REG(0xd617, 0x0063);
LCD_WRITE_REG_16B(0xd217, 0x0063); LCD_WRITE_REG(0xd618, 0x0002);
LCD_WRITE_REG_16B(0xd218, 0x0002); LCD_WRITE_REG(0xd619, 0x00b9);
LCD_WRITE_REG_16B(0xd219, 0x00b9); LCD_WRITE_REG(0xd61a, 0x0002);
LCD_WRITE_REG_16B(0xd21a, 0x0002); LCD_WRITE_REG(0xd61b, 0x00bb);
LCD_WRITE_REG_16B(0xd21b, 0x00bb); LCD_WRITE_REG(0xd61c, 0x0003);
LCD_WRITE_REG_16B(0xd21c, 0x0003); LCD_WRITE_REG(0xd61d, 0x0003);
LCD_WRITE_REG_16B(0xd21d, 0x0003); LCD_WRITE_REG(0xd61e, 0x0003);
LCD_WRITE_REG_16B(0xd21e, 0x0003); LCD_WRITE_REG(0xd61f, 0x0046);
LCD_WRITE_REG_16B(0xd21f, 0x0046); LCD_WRITE_REG(0xd620, 0x0003);
LCD_WRITE_REG_16B(0xd220, 0x0003); LCD_WRITE_REG(0xd621, 0x0069);
LCD_WRITE_REG_16B(0xd221, 0x0069); LCD_WRITE_REG(0xd622, 0x0003);
LCD_WRITE_REG_16B(0xd222, 0x0003); LCD_WRITE_REG(0xd623, 0x008f);
LCD_WRITE_REG_16B(0xd223, 0x008f); LCD_WRITE_REG(0xd624, 0x0003);
LCD_WRITE_REG_16B(0xd224, 0x0003); LCD_WRITE_REG(0xd625, 0x00a4);
LCD_WRITE_REG_16B(0xd225, 0x00a4); LCD_WRITE_REG(0xd626, 0x0003);
LCD_WRITE_REG_16B(0xd226, 0x0003); LCD_WRITE_REG(0xd627, 0x00b9);
LCD_WRITE_REG_16B(0xd227, 0x00b9); LCD_WRITE_REG(0xd628, 0x0003);
LCD_WRITE_REG_16B(0xd228, 0x0003); LCD_WRITE_REG(0xd629, 0x00c7);
LCD_WRITE_REG_16B(0xd229, 0x00c7); LCD_WRITE_REG(0xd62a, 0x0003);
LCD_WRITE_REG_16B(0xd22a, 0x0003); LCD_WRITE_REG(0xd62b, 0x00c9);
LCD_WRITE_REG_16B(0xd22b, 0x00c9); LCD_WRITE_REG(0xd62c, 0x0003);
LCD_WRITE_REG_16B(0xd22c, 0x0003); LCD_WRITE_REG(0xd62d, 0x00cb);
LCD_WRITE_REG_16B(0xd22d, 0x00cb); LCD_WRITE_REG(0xd62e, 0x0003);
LCD_WRITE_REG_16B(0xd22e, 0x0003); LCD_WRITE_REG(0xd62f, 0x00cb);
LCD_WRITE_REG_16B(0xd22f, 0x00cb); LCD_WRITE_REG(0xd630, 0x0003);
LCD_WRITE_REG_16B(0xd230, 0x0003); LCD_WRITE_REG(0xd631, 0x00cb);
LCD_WRITE_REG_16B(0xd231, 0x00cb); LCD_WRITE_REG(0xd632, 0x0003);
LCD_WRITE_REG_16B(0xd232, 0x0003); LCD_WRITE_REG(0xd633, 0x00cc);
LCD_WRITE_REG_16B(0xd233, 0x00cc);
// Gamma 2.2 Correction for Blue (Positive) LCD_WRITE_REG(0xba00, 0x0024);
LCD_WRITE_REG_16B(0xd300, 0x0000); LCD_WRITE_REG(0xba01, 0x0024);
LCD_WRITE_REG_16B(0xd301, 0x005d); LCD_WRITE_REG(0xba02, 0x0024);
LCD_WRITE_REG_16B(0xd302, 0x0000);
LCD_WRITE_REG_16B(0xd303, 0x006b);
LCD_WRITE_REG_16B(0xd304, 0x0000);
LCD_WRITE_REG_16B(0xd305, 0x0084);
LCD_WRITE_REG_16B(0xd306, 0x0000);
LCD_WRITE_REG_16B(0xd307, 0x009c);
LCD_WRITE_REG_16B(0xd308, 0x0000);
LCD_WRITE_REG_16B(0xd309, 0x00b1);
LCD_WRITE_REG_16B(0xd30a, 0x0000);
LCD_WRITE_REG_16B(0xd30b, 0x00d9);
LCD_WRITE_REG_16B(0xd30c, 0x0000);
LCD_WRITE_REG_16B(0xd30d, 0x00fd);
LCD_WRITE_REG_16B(0xd30e, 0x0001);
LCD_WRITE_REG_16B(0xd30f, 0x0038);
LCD_WRITE_REG_16B(0xd310, 0x0001);
LCD_WRITE_REG_16B(0xd311, 0x0068);
LCD_WRITE_REG_16B(0xd312, 0x0001);
LCD_WRITE_REG_16B(0xd313, 0x00b9);
LCD_WRITE_REG_16B(0xd314, 0x0001);
LCD_WRITE_REG_16B(0xd315, 0x00fb);
LCD_WRITE_REG_16B(0xd316, 0x0002);
LCD_WRITE_REG_16B(0xd317, 0x0063);
LCD_WRITE_REG_16B(0xd318, 0x0002);
LCD_WRITE_REG_16B(0xd319, 0x00b9);
LCD_WRITE_REG_16B(0xd31a, 0x0002);
LCD_WRITE_REG_16B(0xd31b, 0x00bb);
LCD_WRITE_REG_16B(0xd31c, 0x0003);
LCD_WRITE_REG_16B(0xd31d, 0x0003);
LCD_WRITE_REG_16B(0xd31e, 0x0003);
LCD_WRITE_REG_16B(0xd31f, 0x0046);
LCD_WRITE_REG_16B(0xd320, 0x0003);
LCD_WRITE_REG_16B(0xd321, 0x0069);
LCD_WRITE_REG_16B(0xd322, 0x0003);
LCD_WRITE_REG_16B(0xd323, 0x008f);
LCD_WRITE_REG_16B(0xd324, 0x0003);
LCD_WRITE_REG_16B(0xd325, 0x00a4);
LCD_WRITE_REG_16B(0xd326, 0x0003);
LCD_WRITE_REG_16B(0xd327, 0x00b9);
LCD_WRITE_REG_16B(0xd328, 0x0003);
LCD_WRITE_REG_16B(0xd329, 0x00c7);
LCD_WRITE_REG_16B(0xd32a, 0x0003);
LCD_WRITE_REG_16B(0xd32b, 0x00c9);
LCD_WRITE_REG_16B(0xd32c, 0x0003);
LCD_WRITE_REG_16B(0xd32d, 0x00cb);
LCD_WRITE_REG_16B(0xd32e, 0x0003);
LCD_WRITE_REG_16B(0xd32f, 0x00cb);
LCD_WRITE_REG_16B(0xd330, 0x0003);
LCD_WRITE_REG_16B(0xd331, 0x00cb);
LCD_WRITE_REG_16B(0xd332, 0x0003);
LCD_WRITE_REG_16B(0xd333, 0x00cc);
// Gamma 2.2 Correction for Red (Negative) LCD_WRITE_REG(0xb900, 0x0024);
LCD_WRITE_REG_16B(0xd400, 0x0000); LCD_WRITE_REG(0xb901, 0x0024);
LCD_WRITE_REG_16B(0xd401, 0x005d); LCD_WRITE_REG(0xb902, 0x0024);
LCD_WRITE_REG_16B(0xd402, 0x0000);
LCD_WRITE_REG_16B(0xd403, 0x006b);
LCD_WRITE_REG_16B(0xd404, 0x0000);
LCD_WRITE_REG_16B(0xd405, 0x0084);
LCD_WRITE_REG_16B(0xd406, 0x0000);
LCD_WRITE_REG_16B(0xd407, 0x009c);
LCD_WRITE_REG_16B(0xd408, 0x0000);
LCD_WRITE_REG_16B(0xd409, 0x00b1);
LCD_WRITE_REG_16B(0xd40a, 0x0000);
LCD_WRITE_REG_16B(0xd40b, 0x00d9);
LCD_WRITE_REG_16B(0xd40c, 0x0000);
LCD_WRITE_REG_16B(0xd40d, 0x00fd);
LCD_WRITE_REG_16B(0xd40e, 0x0001);
LCD_WRITE_REG_16B(0xd40f, 0x0038);
LCD_WRITE_REG_16B(0xd410, 0x0001);
LCD_WRITE_REG_16B(0xd411, 0x0068);
LCD_WRITE_REG_16B(0xd412, 0x0001);
LCD_WRITE_REG_16B(0xd413, 0x00b9);
LCD_WRITE_REG_16B(0xd414, 0x0001);
LCD_WRITE_REG_16B(0xd415, 0x00fb);
LCD_WRITE_REG_16B(0xd416, 0x0002);
LCD_WRITE_REG_16B(0xd417, 0x0063);
LCD_WRITE_REG_16B(0xd418, 0x0002);
LCD_WRITE_REG_16B(0xd419, 0x00b9);
LCD_WRITE_REG_16B(0xd41a, 0x0002);
LCD_WRITE_REG_16B(0xd41b, 0x00bb);
LCD_WRITE_REG_16B(0xd41c, 0x0003);
LCD_WRITE_REG_16B(0xd41d, 0x0003);
LCD_WRITE_REG_16B(0xd41e, 0x0003);
LCD_WRITE_REG_16B(0xd41f, 0x0046);
LCD_WRITE_REG_16B(0xd420, 0x0003);
LCD_WRITE_REG_16B(0xd421, 0x0069);
LCD_WRITE_REG_16B(0xd422, 0x0003);
LCD_WRITE_REG_16B(0xd423, 0x008f);
LCD_WRITE_REG_16B(0xd424, 0x0003);
LCD_WRITE_REG_16B(0xd425, 0x00a4);
LCD_WRITE_REG_16B(0xd426, 0x0003);
LCD_WRITE_REG_16B(0xd427, 0x00b9);
LCD_WRITE_REG_16B(0xd428, 0x0003);
LCD_WRITE_REG_16B(0xd429, 0x00c7);
LCD_WRITE_REG_16B(0xd42a, 0x0003);
LCD_WRITE_REG_16B(0xd42b, 0x00c9);
LCD_WRITE_REG_16B(0xd42c, 0x0003);
LCD_WRITE_REG_16B(0xd42d, 0x00cb);
LCD_WRITE_REG_16B(0xd42e, 0x0003);
LCD_WRITE_REG_16B(0xd42f, 0x00cb);
LCD_WRITE_REG_16B(0xd430, 0x0003);
LCD_WRITE_REG_16B(0xd431, 0x00cb);
LCD_WRITE_REG_16B(0xd432, 0x0003);
LCD_WRITE_REG_16B(0xd433, 0x00cc);
// Gamma 2.2 Correction for Green (Negative) LCD_WRITE_REG(0xf000, 0x0055);
LCD_WRITE_REG_16B(0xd500, 0x0000); LCD_WRITE_REG(0xf001, 0x00aa);
LCD_WRITE_REG_16B(0xd501, 0x005d); LCD_WRITE_REG(0xf002, 0x0052);
LCD_WRITE_REG_16B(0xd502, 0x0000); LCD_WRITE_REG(0xf003, 0x0008);
LCD_WRITE_REG_16B(0xd503, 0x006b); LCD_WRITE_REG(0xf004, 0x0000);
LCD_WRITE_REG_16B(0xd504, 0x0000);
LCD_WRITE_REG_16B(0xd505, 0x0084);
LCD_WRITE_REG_16B(0xd506, 0x0000);
LCD_WRITE_REG_16B(0xd507, 0x009c);
LCD_WRITE_REG_16B(0xd508, 0x0000);
LCD_WRITE_REG_16B(0xd509, 0x00b1);
LCD_WRITE_REG_16B(0xd50a, 0x0000);
LCD_WRITE_REG_16B(0xd50b, 0x00D9);
LCD_WRITE_REG_16B(0xd50c, 0x0000);
LCD_WRITE_REG_16B(0xd50d, 0x00fd);
LCD_WRITE_REG_16B(0xd50e, 0x0001);
LCD_WRITE_REG_16B(0xd50f, 0x0038);
LCD_WRITE_REG_16B(0xd510, 0x0001);
LCD_WRITE_REG_16B(0xd511, 0x0068);
LCD_WRITE_REG_16B(0xd512, 0x0001);
LCD_WRITE_REG_16B(0xd513, 0x00b9);
LCD_WRITE_REG_16B(0xd514, 0x0001);
LCD_WRITE_REG_16B(0xd515, 0x00fb);
LCD_WRITE_REG_16B(0xd516, 0x0002);
LCD_WRITE_REG_16B(0xd517, 0x0063);
LCD_WRITE_REG_16B(0xd518, 0x0002);
LCD_WRITE_REG_16B(0xd519, 0x00b9);
LCD_WRITE_REG_16B(0xd51a, 0x0002);
LCD_WRITE_REG_16B(0xd51b, 0x00bb);
LCD_WRITE_REG_16B(0xd51c, 0x0003);
LCD_WRITE_REG_16B(0xd51d, 0x0003);
LCD_WRITE_REG_16B(0xd51e, 0x0003);
LCD_WRITE_REG_16B(0xd51f, 0x0046);
LCD_WRITE_REG_16B(0xd520, 0x0003);
LCD_WRITE_REG_16B(0xd521, 0x0069);
LCD_WRITE_REG_16B(0xd522, 0x0003);
LCD_WRITE_REG_16B(0xd523, 0x008f);
LCD_WRITE_REG_16B(0xd524, 0x0003);
LCD_WRITE_REG_16B(0xd525, 0x00a4);
LCD_WRITE_REG_16B(0xd526, 0x0003);
LCD_WRITE_REG_16B(0xd527, 0x00b9);
LCD_WRITE_REG_16B(0xd528, 0x0003);
LCD_WRITE_REG_16B(0xd529, 0x00c7);
LCD_WRITE_REG_16B(0xd52a, 0x0003);
LCD_WRITE_REG_16B(0xd52b, 0x00c9);
LCD_WRITE_REG_16B(0xd52c, 0x0003);
LCD_WRITE_REG_16B(0xd52d, 0x00cb);
LCD_WRITE_REG_16B(0xd52e, 0x0003);
LCD_WRITE_REG_16B(0xd52f, 0x00cb);
LCD_WRITE_REG_16B(0xd530, 0x0003);
LCD_WRITE_REG_16B(0xd531, 0x00cb);
LCD_WRITE_REG_16B(0xd532, 0x0003);
LCD_WRITE_REG_16B(0xd533, 0x00cc);
// Gamma 2.2 Correction for Blue (Negative) LCD_WRITE_REG(0xb100, 0x00cc);
LCD_WRITE_REG_16B(0xd600, 0x0000); LCD_WRITE_REG(0xB500, 0x0050);
LCD_WRITE_REG_16B(0xd601, 0x005d);
LCD_WRITE_REG_16B(0xd602, 0x0000);
LCD_WRITE_REG_16B(0xd603, 0x006b);
LCD_WRITE_REG_16B(0xd604, 0x0000);
LCD_WRITE_REG_16B(0xd605, 0x0084);
LCD_WRITE_REG_16B(0xd606, 0x0000);
LCD_WRITE_REG_16B(0xd607, 0x009c);
LCD_WRITE_REG_16B(0xd608, 0x0000);
LCD_WRITE_REG_16B(0xd609, 0x00b1);
LCD_WRITE_REG_16B(0xd60a, 0x0000);
LCD_WRITE_REG_16B(0xd60b, 0x00d9);
LCD_WRITE_REG_16B(0xd60c, 0x0000);
LCD_WRITE_REG_16B(0xd60d, 0x00fd);
LCD_WRITE_REG_16B(0xd60e, 0x0001);
LCD_WRITE_REG_16B(0xd60f, 0x0038);
LCD_WRITE_REG_16B(0xd610, 0x0001);
LCD_WRITE_REG_16B(0xd611, 0x0068);
LCD_WRITE_REG_16B(0xd612, 0x0001);
LCD_WRITE_REG_16B(0xd613, 0x00b9);
LCD_WRITE_REG_16B(0xd614, 0x0001);
LCD_WRITE_REG_16B(0xd615, 0x00fb);
LCD_WRITE_REG_16B(0xd616, 0x0002);
LCD_WRITE_REG_16B(0xd617, 0x0063);
LCD_WRITE_REG_16B(0xd618, 0x0002);
LCD_WRITE_REG_16B(0xd619, 0x00b9);
LCD_WRITE_REG_16B(0xd61a, 0x0002);
LCD_WRITE_REG_16B(0xd61b, 0x00bb);
LCD_WRITE_REG_16B(0xd61c, 0x0003);
LCD_WRITE_REG_16B(0xd61d, 0x0003);
LCD_WRITE_REG_16B(0xd61e, 0x0003);
LCD_WRITE_REG_16B(0xd61f, 0x0046);
LCD_WRITE_REG_16B(0xd620, 0x0003);
LCD_WRITE_REG_16B(0xd621, 0x0069);
LCD_WRITE_REG_16B(0xd622, 0x0003);
LCD_WRITE_REG_16B(0xd623, 0x008f);
LCD_WRITE_REG_16B(0xd624, 0x0003);
LCD_WRITE_REG_16B(0xd625, 0x00a4);
LCD_WRITE_REG_16B(0xd626, 0x0003);
LCD_WRITE_REG_16B(0xd627, 0x00b9);
LCD_WRITE_REG_16B(0xd628, 0x0003);
LCD_WRITE_REG_16B(0xd629, 0x00c7);
LCD_WRITE_REG_16B(0xd62a, 0x0003);
LCD_WRITE_REG_16B(0xd62b, 0x00c9);
LCD_WRITE_REG_16B(0xd62c, 0x0003);
LCD_WRITE_REG_16B(0xd62d, 0x00cb);
LCD_WRITE_REG_16B(0xd62e, 0x0003);
LCD_WRITE_REG_16B(0xd62f, 0x00cb);
LCD_WRITE_REG_16B(0xd630, 0x0003);
LCD_WRITE_REG_16B(0xd631, 0x00cb);
LCD_WRITE_REG_16B(0xd632, 0x0003);
LCD_WRITE_REG_16B(0xd633, 0x00cc);
// BT5 Power Control for VGLX LCD_WRITE_REG(0xbc00, 0x0005);
LCD_WRITE_REG_16B(0xba00, 0x0024); LCD_WRITE_REG(0xbc01, 0x0005);
LCD_WRITE_REG_16B(0xba01, 0x0024); LCD_WRITE_REG(0xbc02, 0x0005);
LCD_WRITE_REG_16B(0xba02, 0x0024);
// BT4 Power Control for VGH LCD_WRITE_REG(0xb800, 0x0001);
LCD_WRITE_REG_16B(0xb900, 0x0024); LCD_WRITE_REG(0xb801, 0x0003);
LCD_WRITE_REG_16B(0xb901, 0x0024); LCD_WRITE_REG(0xb802, 0x0003);
LCD_WRITE_REG_16B(0xb902, 0x0024); LCD_WRITE_REG(0xb803, 0x0003);
// Enable manufacturer command set, select page 0 LCD_WRITE_REG(0xbd02, 0x0007);
LCD_WRITE_REG_16B(0xf000, 0x0055); LCD_WRITE_REG(0xbd03, 0x0031);
LCD_WRITE_REG_16B(0xf001, 0x00aa); LCD_WRITE_REG(0xbe02, 0x0007);
LCD_WRITE_REG_16B(0xf002, 0x0052); LCD_WRITE_REG(0xbe03, 0x0031);
LCD_WRITE_REG_16B(0xf003, 0x0008); LCD_WRITE_REG(0xbf02, 0x0007);
LCD_WRITE_REG_16B(0xf004, 0x0000); LCD_WRITE_REG(0xbf03, 0x0031);
// Display Option Control LCD_WRITE_REG(0xff00, 0x00aa);
LCD_WRITE_REG_16B(0xb100, 0x00cc); LCD_WRITE_REG(0xff01, 0x0055);
LCD_WRITE_REG(0xff02, 0x0025);
LCD_WRITE_REG(0xff03, 0x0001);
// Display Resolution Control LCD_WRITE_REG(0xf304, 0x0011);
LCD_WRITE_REG_16B(0xB500, 0x0050); // 480RGB X 800 LCD_WRITE_REG(0xf306, 0x0010);
LCD_WRITE_REG(0xf308, 0x0000);
// Inversion Driving Control
// 000: Column inversion
// 001: 1-dot inversion
// 010: 2-dot inversion
// 011: 3-dot inversion
// 100: 4-dot inversion
// 101: Zigzag inversion
LCD_WRITE_REG_16B(0xbc00, 0x0005); // Normal mode
LCD_WRITE_REG_16B(0xbc01, 0x0005); // Idle mode
LCD_WRITE_REG_16B(0xbc02, 0x0005); // Partial mode
// EQ Control Function for Source Driver
LCD_WRITE_REG_16B(0xb800, 0x0001); // EQ mode 1
LCD_WRITE_REG_16B(0xb801, 0x0003); // Normal mode, 0.5us per step = 1.5 us
LCD_WRITE_REG_16B(0xb802, 0x0003); // Idle mode, 0.5us per step = 1.5 us
LCD_WRITE_REG_16B(0xb803, 0x0003); // Partial mode, 0.5us per step = 1.5 us
// Display Timing Control
LCD_WRITE_REG_16B(0xbd02, 0x0007); // Normal mode
LCD_WRITE_REG_16B(0xbd03, 0x0031); // Normal mode
LCD_WRITE_REG_16B(0xbe02, 0x0007); // Idle mode
LCD_WRITE_REG_16B(0xbe03, 0x0031); // Idle mode
LCD_WRITE_REG_16B(0xbf02, 0x0007); // Parial mode
LCD_WRITE_REG_16B(0xbf03, 0x0031); // Parial mode
// Undocumented registers
LCD_WRITE_REG_16B(0xff00, 0x00aa);
LCD_WRITE_REG_16B(0xff01, 0x0055);
LCD_WRITE_REG_16B(0xff02, 0x0025);
LCD_WRITE_REG_16B(0xff03, 0x0001);
// Undocumented registers
LCD_WRITE_REG_16B(0xf304, 0x0011);
LCD_WRITE_REG_16B(0xf306, 0x0010);
LCD_WRITE_REG_16B(0xf308, 0x0000);
// Tearing effect line on
LCD_WRITE_REG_16B(0x3500, 0x0000); // Only v-blanking information
// Interface Pixel Format
LCD_WRITE_REG_16B(0x3A00, 0x0005); // I80 16-bit per pixel
// Display On
LCD_WRITE_CMD_16B(0x2900);
LCD_WRITE_REG(0x3500, 0x0000);
LCD_WRITE_REG(0x3A00, 0x0005);
//Display On
LCD_WRITE_CMD(0x2900);
// Out sleep // Out sleep
LCD_WRITE_CMD_16B(0x1100); LCD_WRITE_CMD(0x1100);
// Write continue // Write continue
LCD_WRITE_CMD_16B(0x2C00); LCD_WRITE_CMD(0x2C00);
} }

View file

@ -77,7 +77,7 @@ esp_err_t lcd_rm68120_init(const scr_controller_config_t *lcd_conf)
LCD_CHECK(lcd_conf->width <= RM68120_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->width <= RM68120_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(lcd_conf->height <= RM68120_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->height <= RM68120_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG); LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG);
LCD_CHECK((NULL != lcd_conf->interface_drv->write_command && \ LCD_CHECK((NULL != lcd_conf->interface_drv->write_cmd && \
NULL != lcd_conf->interface_drv->write_data && \ NULL != lcd_conf->interface_drv->write_data && \
NULL != lcd_conf->interface_drv->write && \ NULL != lcd_conf->interface_drv->write && \
NULL != lcd_conf->interface_drv->read && \ NULL != lcd_conf->interface_drv->read && \
@ -176,7 +176,7 @@ esp_err_t lcd_rm68120_set_rotation(scr_dir_t dir)
default: break; default: break;
} }
ESP_LOGI(TAG, "MADCTL=0x%x", reg_data); ESP_LOGI(TAG, "MADCTL=0x%x", reg_data);
ret = LCD_WRITE_REG_16B(RM68120_MADCTL, reg_data); ret = LCD_WRITE_REG(RM68120_MADCTL, reg_data);
LCD_CHECK(ESP_OK == ret, "Set screen rotate failed", ESP_FAIL); LCD_CHECK(ESP_OK == ret, "Set screen rotate failed", ESP_FAIL);
g_lcd_handle.dir = dir; g_lcd_handle.dir = dir;
return ESP_OK; return ESP_OK;
@ -201,16 +201,16 @@ esp_err_t lcd_rm68120_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
scr_utility_apply_offset(&g_lcd_handle, RM68120_RESOLUTION_HOR, RM68120_RESOLUTION_VER, &x0, &y0, &x1, &y1); scr_utility_apply_offset(&g_lcd_handle, RM68120_RESOLUTION_HOR, RM68120_RESOLUTION_VER, &x0, &y0, &x1, &y1);
ret |= LCD_WRITE_REG_16B(RM68120_CASET, x0 >> 8); ret |= LCD_WRITE_REG(RM68120_CASET, x0 >> 8);
ret |= LCD_WRITE_REG_16B(RM68120_CASET + 1, x0 & 0xff); ret |= LCD_WRITE_REG(RM68120_CASET + 1, x0 & 0xff);
ret |= LCD_WRITE_REG_16B(RM68120_CASET + 2, x1 >> 8); ret |= LCD_WRITE_REG(RM68120_CASET + 2, x1 >> 8);
ret |= LCD_WRITE_REG_16B(RM68120_CASET + 3, x1 & 0xff); ret |= LCD_WRITE_REG(RM68120_CASET + 3, x1 & 0xff);
ret |= LCD_WRITE_REG_16B(RM68120_RASET, y0 >> 8); ret |= LCD_WRITE_REG(RM68120_RASET, y0 >> 8);
ret |= LCD_WRITE_REG_16B(RM68120_RASET + 1, y0 & 0xff); ret |= LCD_WRITE_REG(RM68120_RASET + 1, y0 & 0xff);
ret |= LCD_WRITE_REG_16B(RM68120_RASET + 2, y1 >> 8); ret |= LCD_WRITE_REG(RM68120_RASET + 2, y1 >> 8);
ret |= LCD_WRITE_REG_16B(RM68120_RASET + 3, y1 & 0xff); ret |= LCD_WRITE_REG(RM68120_RASET + 3, y1 & 0xff);
ret |= LCD_WRITE_CMD_16B(RM68120_RAMWR); ret |= LCD_WRITE_CMD(RM68120_RAMWR);
LCD_CHECK(ESP_OK == ret, "Set window failed", ESP_FAIL); LCD_CHECK(ESP_OK == ret, "Set window failed", ESP_FAIL);
return ESP_OK; return ESP_OK;
} }
@ -253,434 +253,434 @@ esp_err_t lcd_rm68120_draw_bitmap(uint16_t x, uint16_t y, uint16_t w, uint16_t h
static void lcd_rm68120_init_reg(void) static void lcd_rm68120_init_reg(void)
{ {
LCD_WRITE_CMD_16B(0x0100); // Software Reset LCD_WRITE_CMD(0x0100); // Software Reset
vTaskDelay(10 / portTICK_RATE_MS); vTaskDelay(10 / portTICK_RATE_MS);
LCD_WRITE_REG_16B(0xF000, 0x55); LCD_WRITE_REG(0xF000, 0x55);
LCD_WRITE_REG_16B(0xF001, 0xAA); LCD_WRITE_REG(0xF001, 0xAA);
LCD_WRITE_REG_16B(0xF002, 0x52); LCD_WRITE_REG(0xF002, 0x52);
LCD_WRITE_REG_16B(0xF003, 0x08); LCD_WRITE_REG(0xF003, 0x08);
LCD_WRITE_REG_16B(0xF004, 0x01); LCD_WRITE_REG(0xF004, 0x01);
//GAMMA SETING RED //GAMMA SETING RED
LCD_WRITE_REG_16B(0xD100, 0x00); LCD_WRITE_REG(0xD100, 0x00);
LCD_WRITE_REG_16B(0xD101, 0x00); LCD_WRITE_REG(0xD101, 0x00);
LCD_WRITE_REG_16B(0xD102, 0x1b); LCD_WRITE_REG(0xD102, 0x1b);
LCD_WRITE_REG_16B(0xD103, 0x44); LCD_WRITE_REG(0xD103, 0x44);
LCD_WRITE_REG_16B(0xD104, 0x62); LCD_WRITE_REG(0xD104, 0x62);
LCD_WRITE_REG_16B(0xD105, 0x00); LCD_WRITE_REG(0xD105, 0x00);
LCD_WRITE_REG_16B(0xD106, 0x7b); LCD_WRITE_REG(0xD106, 0x7b);
LCD_WRITE_REG_16B(0xD107, 0xa1); LCD_WRITE_REG(0xD107, 0xa1);
LCD_WRITE_REG_16B(0xD108, 0xc0); LCD_WRITE_REG(0xD108, 0xc0);
LCD_WRITE_REG_16B(0xD109, 0xee); LCD_WRITE_REG(0xD109, 0xee);
LCD_WRITE_REG_16B(0xD10A, 0x55); LCD_WRITE_REG(0xD10A, 0x55);
LCD_WRITE_REG_16B(0xD10B, 0x10); LCD_WRITE_REG(0xD10B, 0x10);
LCD_WRITE_REG_16B(0xD10C, 0x2c); LCD_WRITE_REG(0xD10C, 0x2c);
LCD_WRITE_REG_16B(0xD10D, 0x43); LCD_WRITE_REG(0xD10D, 0x43);
LCD_WRITE_REG_16B(0xD10E, 0x57); LCD_WRITE_REG(0xD10E, 0x57);
LCD_WRITE_REG_16B(0xD10F, 0x55); LCD_WRITE_REG(0xD10F, 0x55);
LCD_WRITE_REG_16B(0xD110, 0x68); LCD_WRITE_REG(0xD110, 0x68);
LCD_WRITE_REG_16B(0xD111, 0x78); LCD_WRITE_REG(0xD111, 0x78);
LCD_WRITE_REG_16B(0xD112, 0x87); LCD_WRITE_REG(0xD112, 0x87);
LCD_WRITE_REG_16B(0xD113, 0x94); LCD_WRITE_REG(0xD113, 0x94);
LCD_WRITE_REG_16B(0xD114, 0x55); LCD_WRITE_REG(0xD114, 0x55);
LCD_WRITE_REG_16B(0xD115, 0xa0); LCD_WRITE_REG(0xD115, 0xa0);
LCD_WRITE_REG_16B(0xD116, 0xac); LCD_WRITE_REG(0xD116, 0xac);
LCD_WRITE_REG_16B(0xD117, 0xb6); LCD_WRITE_REG(0xD117, 0xb6);
LCD_WRITE_REG_16B(0xD118, 0xc1); LCD_WRITE_REG(0xD118, 0xc1);
LCD_WRITE_REG_16B(0xD119, 0x55); LCD_WRITE_REG(0xD119, 0x55);
LCD_WRITE_REG_16B(0xD11A, 0xcb); LCD_WRITE_REG(0xD11A, 0xcb);
LCD_WRITE_REG_16B(0xD11B, 0xcd); LCD_WRITE_REG(0xD11B, 0xcd);
LCD_WRITE_REG_16B(0xD11C, 0xd6); LCD_WRITE_REG(0xD11C, 0xd6);
LCD_WRITE_REG_16B(0xD11D, 0xdf); LCD_WRITE_REG(0xD11D, 0xdf);
LCD_WRITE_REG_16B(0xD11E, 0x95); LCD_WRITE_REG(0xD11E, 0x95);
LCD_WRITE_REG_16B(0xD11F, 0xe8); LCD_WRITE_REG(0xD11F, 0xe8);
LCD_WRITE_REG_16B(0xD120, 0xf1); LCD_WRITE_REG(0xD120, 0xf1);
LCD_WRITE_REG_16B(0xD121, 0xfa); LCD_WRITE_REG(0xD121, 0xfa);
LCD_WRITE_REG_16B(0xD122, 0x02); LCD_WRITE_REG(0xD122, 0x02);
LCD_WRITE_REG_16B(0xD123, 0xaa); LCD_WRITE_REG(0xD123, 0xaa);
LCD_WRITE_REG_16B(0xD124, 0x0b); LCD_WRITE_REG(0xD124, 0x0b);
LCD_WRITE_REG_16B(0xD125, 0x13); LCD_WRITE_REG(0xD125, 0x13);
LCD_WRITE_REG_16B(0xD126, 0x1d); LCD_WRITE_REG(0xD126, 0x1d);
LCD_WRITE_REG_16B(0xD127, 0x26); LCD_WRITE_REG(0xD127, 0x26);
LCD_WRITE_REG_16B(0xD128, 0xaa); LCD_WRITE_REG(0xD128, 0xaa);
LCD_WRITE_REG_16B(0xD129, 0x30); LCD_WRITE_REG(0xD129, 0x30);
LCD_WRITE_REG_16B(0xD12A, 0x3c); LCD_WRITE_REG(0xD12A, 0x3c);
LCD_WRITE_REG_16B(0xD12B, 0x4A); LCD_WRITE_REG(0xD12B, 0x4A);
LCD_WRITE_REG_16B(0xD12C, 0x63); LCD_WRITE_REG(0xD12C, 0x63);
LCD_WRITE_REG_16B(0xD12D, 0xea); LCD_WRITE_REG(0xD12D, 0xea);
LCD_WRITE_REG_16B(0xD12E, 0x79); LCD_WRITE_REG(0xD12E, 0x79);
LCD_WRITE_REG_16B(0xD12F, 0xa6); LCD_WRITE_REG(0xD12F, 0xa6);
LCD_WRITE_REG_16B(0xD130, 0xd0); LCD_WRITE_REG(0xD130, 0xd0);
LCD_WRITE_REG_16B(0xD131, 0x20); LCD_WRITE_REG(0xD131, 0x20);
LCD_WRITE_REG_16B(0xD132, 0x0f); LCD_WRITE_REG(0xD132, 0x0f);
LCD_WRITE_REG_16B(0xD133, 0x8e); LCD_WRITE_REG(0xD133, 0x8e);
LCD_WRITE_REG_16B(0xD134, 0xff); LCD_WRITE_REG(0xD134, 0xff);
//GAMMA SETING GREEN //GAMMA SETING GREEN
LCD_WRITE_REG_16B(0xD200, 0x00); LCD_WRITE_REG(0xD200, 0x00);
LCD_WRITE_REG_16B(0xD201, 0x00); LCD_WRITE_REG(0xD201, 0x00);
LCD_WRITE_REG_16B(0xD202, 0x1b); LCD_WRITE_REG(0xD202, 0x1b);
LCD_WRITE_REG_16B(0xD203, 0x44); LCD_WRITE_REG(0xD203, 0x44);
LCD_WRITE_REG_16B(0xD204, 0x62); LCD_WRITE_REG(0xD204, 0x62);
LCD_WRITE_REG_16B(0xD205, 0x00); LCD_WRITE_REG(0xD205, 0x00);
LCD_WRITE_REG_16B(0xD206, 0x7b); LCD_WRITE_REG(0xD206, 0x7b);
LCD_WRITE_REG_16B(0xD207, 0xa1); LCD_WRITE_REG(0xD207, 0xa1);
LCD_WRITE_REG_16B(0xD208, 0xc0); LCD_WRITE_REG(0xD208, 0xc0);
LCD_WRITE_REG_16B(0xD209, 0xee); LCD_WRITE_REG(0xD209, 0xee);
LCD_WRITE_REG_16B(0xD20A, 0x55); LCD_WRITE_REG(0xD20A, 0x55);
LCD_WRITE_REG_16B(0xD20B, 0x10); LCD_WRITE_REG(0xD20B, 0x10);
LCD_WRITE_REG_16B(0xD20C, 0x2c); LCD_WRITE_REG(0xD20C, 0x2c);
LCD_WRITE_REG_16B(0xD20D, 0x43); LCD_WRITE_REG(0xD20D, 0x43);
LCD_WRITE_REG_16B(0xD20E, 0x57); LCD_WRITE_REG(0xD20E, 0x57);
LCD_WRITE_REG_16B(0xD20F, 0x55); LCD_WRITE_REG(0xD20F, 0x55);
LCD_WRITE_REG_16B(0xD210, 0x68); LCD_WRITE_REG(0xD210, 0x68);
LCD_WRITE_REG_16B(0xD211, 0x78); LCD_WRITE_REG(0xD211, 0x78);
LCD_WRITE_REG_16B(0xD212, 0x87); LCD_WRITE_REG(0xD212, 0x87);
LCD_WRITE_REG_16B(0xD213, 0x94); LCD_WRITE_REG(0xD213, 0x94);
LCD_WRITE_REG_16B(0xD214, 0x55); LCD_WRITE_REG(0xD214, 0x55);
LCD_WRITE_REG_16B(0xD215, 0xa0); LCD_WRITE_REG(0xD215, 0xa0);
LCD_WRITE_REG_16B(0xD216, 0xac); LCD_WRITE_REG(0xD216, 0xac);
LCD_WRITE_REG_16B(0xD217, 0xb6); LCD_WRITE_REG(0xD217, 0xb6);
LCD_WRITE_REG_16B(0xD218, 0xc1); LCD_WRITE_REG(0xD218, 0xc1);
LCD_WRITE_REG_16B(0xD219, 0x55); LCD_WRITE_REG(0xD219, 0x55);
LCD_WRITE_REG_16B(0xD21A, 0xcb); LCD_WRITE_REG(0xD21A, 0xcb);
LCD_WRITE_REG_16B(0xD21B, 0xcd); LCD_WRITE_REG(0xD21B, 0xcd);
LCD_WRITE_REG_16B(0xD21C, 0xd6); LCD_WRITE_REG(0xD21C, 0xd6);
LCD_WRITE_REG_16B(0xD21D, 0xdf); LCD_WRITE_REG(0xD21D, 0xdf);
LCD_WRITE_REG_16B(0xD21E, 0x95); LCD_WRITE_REG(0xD21E, 0x95);
LCD_WRITE_REG_16B(0xD21F, 0xe8); LCD_WRITE_REG(0xD21F, 0xe8);
LCD_WRITE_REG_16B(0xD220, 0xf1); LCD_WRITE_REG(0xD220, 0xf1);
LCD_WRITE_REG_16B(0xD221, 0xfa); LCD_WRITE_REG(0xD221, 0xfa);
LCD_WRITE_REG_16B(0xD222, 0x02); LCD_WRITE_REG(0xD222, 0x02);
LCD_WRITE_REG_16B(0xD223, 0xaa); LCD_WRITE_REG(0xD223, 0xaa);
LCD_WRITE_REG_16B(0xD224, 0x0b); LCD_WRITE_REG(0xD224, 0x0b);
LCD_WRITE_REG_16B(0xD225, 0x13); LCD_WRITE_REG(0xD225, 0x13);
LCD_WRITE_REG_16B(0xD226, 0x1d); LCD_WRITE_REG(0xD226, 0x1d);
LCD_WRITE_REG_16B(0xD227, 0x26); LCD_WRITE_REG(0xD227, 0x26);
LCD_WRITE_REG_16B(0xD228, 0xaa); LCD_WRITE_REG(0xD228, 0xaa);
LCD_WRITE_REG_16B(0xD229, 0x30); LCD_WRITE_REG(0xD229, 0x30);
LCD_WRITE_REG_16B(0xD22A, 0x3c); LCD_WRITE_REG(0xD22A, 0x3c);
LCD_WRITE_REG_16B(0xD22B, 0x4a); LCD_WRITE_REG(0xD22B, 0x4a);
LCD_WRITE_REG_16B(0xD22C, 0x63); LCD_WRITE_REG(0xD22C, 0x63);
LCD_WRITE_REG_16B(0xD22D, 0xea); LCD_WRITE_REG(0xD22D, 0xea);
LCD_WRITE_REG_16B(0xD22E, 0x79); LCD_WRITE_REG(0xD22E, 0x79);
LCD_WRITE_REG_16B(0xD22F, 0xa6); LCD_WRITE_REG(0xD22F, 0xa6);
LCD_WRITE_REG_16B(0xD230, 0xd0); LCD_WRITE_REG(0xD230, 0xd0);
LCD_WRITE_REG_16B(0xD231, 0x20); LCD_WRITE_REG(0xD231, 0x20);
LCD_WRITE_REG_16B(0xD232, 0x0f); LCD_WRITE_REG(0xD232, 0x0f);
LCD_WRITE_REG_16B(0xD233, 0x8e); LCD_WRITE_REG(0xD233, 0x8e);
LCD_WRITE_REG_16B(0xD234, 0xff); LCD_WRITE_REG(0xD234, 0xff);
//GAMMA SETING BLUE //GAMMA SETING BLUE
LCD_WRITE_REG_16B(0xD300, 0x00); LCD_WRITE_REG(0xD300, 0x00);
LCD_WRITE_REG_16B(0xD301, 0x00); LCD_WRITE_REG(0xD301, 0x00);
LCD_WRITE_REG_16B(0xD302, 0x1b); LCD_WRITE_REG(0xD302, 0x1b);
LCD_WRITE_REG_16B(0xD303, 0x44); LCD_WRITE_REG(0xD303, 0x44);
LCD_WRITE_REG_16B(0xD304, 0x62); LCD_WRITE_REG(0xD304, 0x62);
LCD_WRITE_REG_16B(0xD305, 0x00); LCD_WRITE_REG(0xD305, 0x00);
LCD_WRITE_REG_16B(0xD306, 0x7b); LCD_WRITE_REG(0xD306, 0x7b);
LCD_WRITE_REG_16B(0xD307, 0xa1); LCD_WRITE_REG(0xD307, 0xa1);
LCD_WRITE_REG_16B(0xD308, 0xc0); LCD_WRITE_REG(0xD308, 0xc0);
LCD_WRITE_REG_16B(0xD309, 0xee); LCD_WRITE_REG(0xD309, 0xee);
LCD_WRITE_REG_16B(0xD30A, 0x55); LCD_WRITE_REG(0xD30A, 0x55);
LCD_WRITE_REG_16B(0xD30B, 0x10); LCD_WRITE_REG(0xD30B, 0x10);
LCD_WRITE_REG_16B(0xD30C, 0x2c); LCD_WRITE_REG(0xD30C, 0x2c);
LCD_WRITE_REG_16B(0xD30D, 0x43); LCD_WRITE_REG(0xD30D, 0x43);
LCD_WRITE_REG_16B(0xD30E, 0x57); LCD_WRITE_REG(0xD30E, 0x57);
LCD_WRITE_REG_16B(0xD30F, 0x55); LCD_WRITE_REG(0xD30F, 0x55);
LCD_WRITE_REG_16B(0xD310, 0x68); LCD_WRITE_REG(0xD310, 0x68);
LCD_WRITE_REG_16B(0xD311, 0x78); LCD_WRITE_REG(0xD311, 0x78);
LCD_WRITE_REG_16B(0xD312, 0x87); LCD_WRITE_REG(0xD312, 0x87);
LCD_WRITE_REG_16B(0xD313, 0x94); LCD_WRITE_REG(0xD313, 0x94);
LCD_WRITE_REG_16B(0xD314, 0x55); LCD_WRITE_REG(0xD314, 0x55);
LCD_WRITE_REG_16B(0xD315, 0xa0); LCD_WRITE_REG(0xD315, 0xa0);
LCD_WRITE_REG_16B(0xD316, 0xac); LCD_WRITE_REG(0xD316, 0xac);
LCD_WRITE_REG_16B(0xD317, 0xb6); LCD_WRITE_REG(0xD317, 0xb6);
LCD_WRITE_REG_16B(0xD318, 0xc1); LCD_WRITE_REG(0xD318, 0xc1);
LCD_WRITE_REG_16B(0xD319, 0x55); LCD_WRITE_REG(0xD319, 0x55);
LCD_WRITE_REG_16B(0xD31A, 0xcb); LCD_WRITE_REG(0xD31A, 0xcb);
LCD_WRITE_REG_16B(0xD31B, 0xcd); LCD_WRITE_REG(0xD31B, 0xcd);
LCD_WRITE_REG_16B(0xD31C, 0xd6); LCD_WRITE_REG(0xD31C, 0xd6);
LCD_WRITE_REG_16B(0xD31D, 0xdf); LCD_WRITE_REG(0xD31D, 0xdf);
LCD_WRITE_REG_16B(0xD31E, 0x95); LCD_WRITE_REG(0xD31E, 0x95);
LCD_WRITE_REG_16B(0xD31F, 0xe8); LCD_WRITE_REG(0xD31F, 0xe8);
LCD_WRITE_REG_16B(0xD320, 0xf1); LCD_WRITE_REG(0xD320, 0xf1);
LCD_WRITE_REG_16B(0xD321, 0xfa); LCD_WRITE_REG(0xD321, 0xfa);
LCD_WRITE_REG_16B(0xD322, 0x02); LCD_WRITE_REG(0xD322, 0x02);
LCD_WRITE_REG_16B(0xD323, 0xaa); LCD_WRITE_REG(0xD323, 0xaa);
LCD_WRITE_REG_16B(0xD324, 0x0b); LCD_WRITE_REG(0xD324, 0x0b);
LCD_WRITE_REG_16B(0xD325, 0x13); LCD_WRITE_REG(0xD325, 0x13);
LCD_WRITE_REG_16B(0xD326, 0x1d); LCD_WRITE_REG(0xD326, 0x1d);
LCD_WRITE_REG_16B(0xD327, 0x26); LCD_WRITE_REG(0xD327, 0x26);
LCD_WRITE_REG_16B(0xD328, 0xaa); LCD_WRITE_REG(0xD328, 0xaa);
LCD_WRITE_REG_16B(0xD329, 0x30); LCD_WRITE_REG(0xD329, 0x30);
LCD_WRITE_REG_16B(0xD32A, 0x3c); LCD_WRITE_REG(0xD32A, 0x3c);
LCD_WRITE_REG_16B(0xD32B, 0x4A); LCD_WRITE_REG(0xD32B, 0x4A);
LCD_WRITE_REG_16B(0xD32C, 0x63); LCD_WRITE_REG(0xD32C, 0x63);
LCD_WRITE_REG_16B(0xD32D, 0xea); LCD_WRITE_REG(0xD32D, 0xea);
LCD_WRITE_REG_16B(0xD32E, 0x79); LCD_WRITE_REG(0xD32E, 0x79);
LCD_WRITE_REG_16B(0xD32F, 0xa6); LCD_WRITE_REG(0xD32F, 0xa6);
LCD_WRITE_REG_16B(0xD330, 0xd0); LCD_WRITE_REG(0xD330, 0xd0);
LCD_WRITE_REG_16B(0xD331, 0x20); LCD_WRITE_REG(0xD331, 0x20);
LCD_WRITE_REG_16B(0xD332, 0x0f); LCD_WRITE_REG(0xD332, 0x0f);
LCD_WRITE_REG_16B(0xD333, 0x8e); LCD_WRITE_REG(0xD333, 0x8e);
LCD_WRITE_REG_16B(0xD334, 0xff); LCD_WRITE_REG(0xD334, 0xff);
//GAMMA SETING RED //GAMMA SETING RED
LCD_WRITE_REG_16B(0xD400, 0x00); LCD_WRITE_REG(0xD400, 0x00);
LCD_WRITE_REG_16B(0xD401, 0x00); LCD_WRITE_REG(0xD401, 0x00);
LCD_WRITE_REG_16B(0xD402, 0x1b); LCD_WRITE_REG(0xD402, 0x1b);
LCD_WRITE_REG_16B(0xD403, 0x44); LCD_WRITE_REG(0xD403, 0x44);
LCD_WRITE_REG_16B(0xD404, 0x62); LCD_WRITE_REG(0xD404, 0x62);
LCD_WRITE_REG_16B(0xD405, 0x00); LCD_WRITE_REG(0xD405, 0x00);
LCD_WRITE_REG_16B(0xD406, 0x7b); LCD_WRITE_REG(0xD406, 0x7b);
LCD_WRITE_REG_16B(0xD407, 0xa1); LCD_WRITE_REG(0xD407, 0xa1);
LCD_WRITE_REG_16B(0xD408, 0xc0); LCD_WRITE_REG(0xD408, 0xc0);
LCD_WRITE_REG_16B(0xD409, 0xee); LCD_WRITE_REG(0xD409, 0xee);
LCD_WRITE_REG_16B(0xD40A, 0x55); LCD_WRITE_REG(0xD40A, 0x55);
LCD_WRITE_REG_16B(0xD40B, 0x10); LCD_WRITE_REG(0xD40B, 0x10);
LCD_WRITE_REG_16B(0xD40C, 0x2c); LCD_WRITE_REG(0xD40C, 0x2c);
LCD_WRITE_REG_16B(0xD40D, 0x43); LCD_WRITE_REG(0xD40D, 0x43);
LCD_WRITE_REG_16B(0xD40E, 0x57); LCD_WRITE_REG(0xD40E, 0x57);
LCD_WRITE_REG_16B(0xD40F, 0x55); LCD_WRITE_REG(0xD40F, 0x55);
LCD_WRITE_REG_16B(0xD410, 0x68); LCD_WRITE_REG(0xD410, 0x68);
LCD_WRITE_REG_16B(0xD411, 0x78); LCD_WRITE_REG(0xD411, 0x78);
LCD_WRITE_REG_16B(0xD412, 0x87); LCD_WRITE_REG(0xD412, 0x87);
LCD_WRITE_REG_16B(0xD413, 0x94); LCD_WRITE_REG(0xD413, 0x94);
LCD_WRITE_REG_16B(0xD414, 0x55); LCD_WRITE_REG(0xD414, 0x55);
LCD_WRITE_REG_16B(0xD415, 0xa0); LCD_WRITE_REG(0xD415, 0xa0);
LCD_WRITE_REG_16B(0xD416, 0xac); LCD_WRITE_REG(0xD416, 0xac);
LCD_WRITE_REG_16B(0xD417, 0xb6); LCD_WRITE_REG(0xD417, 0xb6);
LCD_WRITE_REG_16B(0xD418, 0xc1); LCD_WRITE_REG(0xD418, 0xc1);
LCD_WRITE_REG_16B(0xD419, 0x55); LCD_WRITE_REG(0xD419, 0x55);
LCD_WRITE_REG_16B(0xD41A, 0xcb); LCD_WRITE_REG(0xD41A, 0xcb);
LCD_WRITE_REG_16B(0xD41B, 0xcd); LCD_WRITE_REG(0xD41B, 0xcd);
LCD_WRITE_REG_16B(0xD41C, 0xd6); LCD_WRITE_REG(0xD41C, 0xd6);
LCD_WRITE_REG_16B(0xD41D, 0xdf); LCD_WRITE_REG(0xD41D, 0xdf);
LCD_WRITE_REG_16B(0xD41E, 0x95); LCD_WRITE_REG(0xD41E, 0x95);
LCD_WRITE_REG_16B(0xD41F, 0xe8); LCD_WRITE_REG(0xD41F, 0xe8);
LCD_WRITE_REG_16B(0xD420, 0xf1); LCD_WRITE_REG(0xD420, 0xf1);
LCD_WRITE_REG_16B(0xD421, 0xfa); LCD_WRITE_REG(0xD421, 0xfa);
LCD_WRITE_REG_16B(0xD422, 0x02); LCD_WRITE_REG(0xD422, 0x02);
LCD_WRITE_REG_16B(0xD423, 0xaa); LCD_WRITE_REG(0xD423, 0xaa);
LCD_WRITE_REG_16B(0xD424, 0x0b); LCD_WRITE_REG(0xD424, 0x0b);
LCD_WRITE_REG_16B(0xD425, 0x13); LCD_WRITE_REG(0xD425, 0x13);
LCD_WRITE_REG_16B(0xD426, 0x1d); LCD_WRITE_REG(0xD426, 0x1d);
LCD_WRITE_REG_16B(0xD427, 0x26); LCD_WRITE_REG(0xD427, 0x26);
LCD_WRITE_REG_16B(0xD428, 0xaa); LCD_WRITE_REG(0xD428, 0xaa);
LCD_WRITE_REG_16B(0xD429, 0x30); LCD_WRITE_REG(0xD429, 0x30);
LCD_WRITE_REG_16B(0xD42A, 0x3c); LCD_WRITE_REG(0xD42A, 0x3c);
LCD_WRITE_REG_16B(0xD42B, 0x4A); LCD_WRITE_REG(0xD42B, 0x4A);
LCD_WRITE_REG_16B(0xD42C, 0x63); LCD_WRITE_REG(0xD42C, 0x63);
LCD_WRITE_REG_16B(0xD42D, 0xea); LCD_WRITE_REG(0xD42D, 0xea);
LCD_WRITE_REG_16B(0xD42E, 0x79); LCD_WRITE_REG(0xD42E, 0x79);
LCD_WRITE_REG_16B(0xD42F, 0xa6); LCD_WRITE_REG(0xD42F, 0xa6);
LCD_WRITE_REG_16B(0xD430, 0xd0); LCD_WRITE_REG(0xD430, 0xd0);
LCD_WRITE_REG_16B(0xD431, 0x20); LCD_WRITE_REG(0xD431, 0x20);
LCD_WRITE_REG_16B(0xD432, 0x0f); LCD_WRITE_REG(0xD432, 0x0f);
LCD_WRITE_REG_16B(0xD433, 0x8e); LCD_WRITE_REG(0xD433, 0x8e);
LCD_WRITE_REG_16B(0xD434, 0xff); LCD_WRITE_REG(0xD434, 0xff);
//GAMMA SETING GREEN //GAMMA SETING GREEN
LCD_WRITE_REG_16B(0xD500, 0x00); LCD_WRITE_REG(0xD500, 0x00);
LCD_WRITE_REG_16B(0xD501, 0x00); LCD_WRITE_REG(0xD501, 0x00);
LCD_WRITE_REG_16B(0xD502, 0x1b); LCD_WRITE_REG(0xD502, 0x1b);
LCD_WRITE_REG_16B(0xD503, 0x44); LCD_WRITE_REG(0xD503, 0x44);
LCD_WRITE_REG_16B(0xD504, 0x62); LCD_WRITE_REG(0xD504, 0x62);
LCD_WRITE_REG_16B(0xD505, 0x00); LCD_WRITE_REG(0xD505, 0x00);
LCD_WRITE_REG_16B(0xD506, 0x7b); LCD_WRITE_REG(0xD506, 0x7b);
LCD_WRITE_REG_16B(0xD507, 0xa1); LCD_WRITE_REG(0xD507, 0xa1);
LCD_WRITE_REG_16B(0xD508, 0xc0); LCD_WRITE_REG(0xD508, 0xc0);
LCD_WRITE_REG_16B(0xD509, 0xee); LCD_WRITE_REG(0xD509, 0xee);
LCD_WRITE_REG_16B(0xD50A, 0x55); LCD_WRITE_REG(0xD50A, 0x55);
LCD_WRITE_REG_16B(0xD50B, 0x10); LCD_WRITE_REG(0xD50B, 0x10);
LCD_WRITE_REG_16B(0xD50C, 0x2c); LCD_WRITE_REG(0xD50C, 0x2c);
LCD_WRITE_REG_16B(0xD50D, 0x43); LCD_WRITE_REG(0xD50D, 0x43);
LCD_WRITE_REG_16B(0xD50E, 0x57); LCD_WRITE_REG(0xD50E, 0x57);
LCD_WRITE_REG_16B(0xD50F, 0x55); LCD_WRITE_REG(0xD50F, 0x55);
LCD_WRITE_REG_16B(0xD510, 0x68); LCD_WRITE_REG(0xD510, 0x68);
LCD_WRITE_REG_16B(0xD511, 0x78); LCD_WRITE_REG(0xD511, 0x78);
LCD_WRITE_REG_16B(0xD512, 0x87); LCD_WRITE_REG(0xD512, 0x87);
LCD_WRITE_REG_16B(0xD513, 0x94); LCD_WRITE_REG(0xD513, 0x94);
LCD_WRITE_REG_16B(0xD514, 0x55); LCD_WRITE_REG(0xD514, 0x55);
LCD_WRITE_REG_16B(0xD515, 0xa0); LCD_WRITE_REG(0xD515, 0xa0);
LCD_WRITE_REG_16B(0xD516, 0xac); LCD_WRITE_REG(0xD516, 0xac);
LCD_WRITE_REG_16B(0xD517, 0xb6); LCD_WRITE_REG(0xD517, 0xb6);
LCD_WRITE_REG_16B(0xD518, 0xc1); LCD_WRITE_REG(0xD518, 0xc1);
LCD_WRITE_REG_16B(0xD519, 0x55); LCD_WRITE_REG(0xD519, 0x55);
LCD_WRITE_REG_16B(0xD51A, 0xcb); LCD_WRITE_REG(0xD51A, 0xcb);
LCD_WRITE_REG_16B(0xD51B, 0xcd); LCD_WRITE_REG(0xD51B, 0xcd);
LCD_WRITE_REG_16B(0xD51C, 0xd6); LCD_WRITE_REG(0xD51C, 0xd6);
LCD_WRITE_REG_16B(0xD51D, 0xdf); LCD_WRITE_REG(0xD51D, 0xdf);
LCD_WRITE_REG_16B(0xD51E, 0x95); LCD_WRITE_REG(0xD51E, 0x95);
LCD_WRITE_REG_16B(0xD51F, 0xe8); LCD_WRITE_REG(0xD51F, 0xe8);
LCD_WRITE_REG_16B(0xD520, 0xf1); LCD_WRITE_REG(0xD520, 0xf1);
LCD_WRITE_REG_16B(0xD521, 0xfa); LCD_WRITE_REG(0xD521, 0xfa);
LCD_WRITE_REG_16B(0xD522, 0x02); LCD_WRITE_REG(0xD522, 0x02);
LCD_WRITE_REG_16B(0xD523, 0xaa); LCD_WRITE_REG(0xD523, 0xaa);
LCD_WRITE_REG_16B(0xD524, 0x0b); LCD_WRITE_REG(0xD524, 0x0b);
LCD_WRITE_REG_16B(0xD525, 0x13); LCD_WRITE_REG(0xD525, 0x13);
LCD_WRITE_REG_16B(0xD526, 0x1d); LCD_WRITE_REG(0xD526, 0x1d);
LCD_WRITE_REG_16B(0xD527, 0x26); LCD_WRITE_REG(0xD527, 0x26);
LCD_WRITE_REG_16B(0xD528, 0xaa); LCD_WRITE_REG(0xD528, 0xaa);
LCD_WRITE_REG_16B(0xD529, 0x30); LCD_WRITE_REG(0xD529, 0x30);
LCD_WRITE_REG_16B(0xD52A, 0x3c); LCD_WRITE_REG(0xD52A, 0x3c);
LCD_WRITE_REG_16B(0xD52B, 0x4a); LCD_WRITE_REG(0xD52B, 0x4a);
LCD_WRITE_REG_16B(0xD52C, 0x63); LCD_WRITE_REG(0xD52C, 0x63);
LCD_WRITE_REG_16B(0xD52D, 0xea); LCD_WRITE_REG(0xD52D, 0xea);
LCD_WRITE_REG_16B(0xD52E, 0x79); LCD_WRITE_REG(0xD52E, 0x79);
LCD_WRITE_REG_16B(0xD52F, 0xa6); LCD_WRITE_REG(0xD52F, 0xa6);
LCD_WRITE_REG_16B(0xD530, 0xd0); LCD_WRITE_REG(0xD530, 0xd0);
LCD_WRITE_REG_16B(0xD531, 0x20); LCD_WRITE_REG(0xD531, 0x20);
LCD_WRITE_REG_16B(0xD532, 0x0f); LCD_WRITE_REG(0xD532, 0x0f);
LCD_WRITE_REG_16B(0xD533, 0x8e); LCD_WRITE_REG(0xD533, 0x8e);
LCD_WRITE_REG_16B(0xD534, 0xff); LCD_WRITE_REG(0xD534, 0xff);
//GAMMA SETING BLUE //GAMMA SETING BLUE
LCD_WRITE_REG_16B(0xD600, 0x00); LCD_WRITE_REG(0xD600, 0x00);
LCD_WRITE_REG_16B(0xD601, 0x00); LCD_WRITE_REG(0xD601, 0x00);
LCD_WRITE_REG_16B(0xD602, 0x1b); LCD_WRITE_REG(0xD602, 0x1b);
LCD_WRITE_REG_16B(0xD603, 0x44); LCD_WRITE_REG(0xD603, 0x44);
LCD_WRITE_REG_16B(0xD604, 0x62); LCD_WRITE_REG(0xD604, 0x62);
LCD_WRITE_REG_16B(0xD605, 0x00); LCD_WRITE_REG(0xD605, 0x00);
LCD_WRITE_REG_16B(0xD606, 0x7b); LCD_WRITE_REG(0xD606, 0x7b);
LCD_WRITE_REG_16B(0xD607, 0xa1); LCD_WRITE_REG(0xD607, 0xa1);
LCD_WRITE_REG_16B(0xD608, 0xc0); LCD_WRITE_REG(0xD608, 0xc0);
LCD_WRITE_REG_16B(0xD609, 0xee); LCD_WRITE_REG(0xD609, 0xee);
LCD_WRITE_REG_16B(0xD60A, 0x55); LCD_WRITE_REG(0xD60A, 0x55);
LCD_WRITE_REG_16B(0xD60B, 0x10); LCD_WRITE_REG(0xD60B, 0x10);
LCD_WRITE_REG_16B(0xD60C, 0x2c); LCD_WRITE_REG(0xD60C, 0x2c);
LCD_WRITE_REG_16B(0xD60D, 0x43); LCD_WRITE_REG(0xD60D, 0x43);
LCD_WRITE_REG_16B(0xD60E, 0x57); LCD_WRITE_REG(0xD60E, 0x57);
LCD_WRITE_REG_16B(0xD60F, 0x55); LCD_WRITE_REG(0xD60F, 0x55);
LCD_WRITE_REG_16B(0xD610, 0x68); LCD_WRITE_REG(0xD610, 0x68);
LCD_WRITE_REG_16B(0xD611, 0x78); LCD_WRITE_REG(0xD611, 0x78);
LCD_WRITE_REG_16B(0xD612, 0x87); LCD_WRITE_REG(0xD612, 0x87);
LCD_WRITE_REG_16B(0xD613, 0x94); LCD_WRITE_REG(0xD613, 0x94);
LCD_WRITE_REG_16B(0xD614, 0x55); LCD_WRITE_REG(0xD614, 0x55);
LCD_WRITE_REG_16B(0xD615, 0xa0); LCD_WRITE_REG(0xD615, 0xa0);
LCD_WRITE_REG_16B(0xD616, 0xac); LCD_WRITE_REG(0xD616, 0xac);
LCD_WRITE_REG_16B(0xD617, 0xb6); LCD_WRITE_REG(0xD617, 0xb6);
LCD_WRITE_REG_16B(0xD618, 0xc1); LCD_WRITE_REG(0xD618, 0xc1);
LCD_WRITE_REG_16B(0xD619, 0x55); LCD_WRITE_REG(0xD619, 0x55);
LCD_WRITE_REG_16B(0xD61A, 0xcb); LCD_WRITE_REG(0xD61A, 0xcb);
LCD_WRITE_REG_16B(0xD61B, 0xcd); LCD_WRITE_REG(0xD61B, 0xcd);
LCD_WRITE_REG_16B(0xD61C, 0xd6); LCD_WRITE_REG(0xD61C, 0xd6);
LCD_WRITE_REG_16B(0xD61D, 0xdf); LCD_WRITE_REG(0xD61D, 0xdf);
LCD_WRITE_REG_16B(0xD61E, 0x95); LCD_WRITE_REG(0xD61E, 0x95);
LCD_WRITE_REG_16B(0xD61F, 0xe8); LCD_WRITE_REG(0xD61F, 0xe8);
LCD_WRITE_REG_16B(0xD620, 0xf1); LCD_WRITE_REG(0xD620, 0xf1);
LCD_WRITE_REG_16B(0xD621, 0xfa); LCD_WRITE_REG(0xD621, 0xfa);
LCD_WRITE_REG_16B(0xD622, 0x02); LCD_WRITE_REG(0xD622, 0x02);
LCD_WRITE_REG_16B(0xD623, 0xaa); LCD_WRITE_REG(0xD623, 0xaa);
LCD_WRITE_REG_16B(0xD624, 0x0b); LCD_WRITE_REG(0xD624, 0x0b);
LCD_WRITE_REG_16B(0xD625, 0x13); LCD_WRITE_REG(0xD625, 0x13);
LCD_WRITE_REG_16B(0xD626, 0x1d); LCD_WRITE_REG(0xD626, 0x1d);
LCD_WRITE_REG_16B(0xD627, 0x26); LCD_WRITE_REG(0xD627, 0x26);
LCD_WRITE_REG_16B(0xD628, 0xaa); LCD_WRITE_REG(0xD628, 0xaa);
LCD_WRITE_REG_16B(0xD629, 0x30); LCD_WRITE_REG(0xD629, 0x30);
LCD_WRITE_REG_16B(0xD62A, 0x3c); LCD_WRITE_REG(0xD62A, 0x3c);
LCD_WRITE_REG_16B(0xD62B, 0x4A); LCD_WRITE_REG(0xD62B, 0x4A);
LCD_WRITE_REG_16B(0xD62C, 0x63); LCD_WRITE_REG(0xD62C, 0x63);
LCD_WRITE_REG_16B(0xD62D, 0xea); LCD_WRITE_REG(0xD62D, 0xea);
LCD_WRITE_REG_16B(0xD62E, 0x79); LCD_WRITE_REG(0xD62E, 0x79);
LCD_WRITE_REG_16B(0xD62F, 0xa6); LCD_WRITE_REG(0xD62F, 0xa6);
LCD_WRITE_REG_16B(0xD630, 0xd0); LCD_WRITE_REG(0xD630, 0xd0);
LCD_WRITE_REG_16B(0xD631, 0x20); LCD_WRITE_REG(0xD631, 0x20);
LCD_WRITE_REG_16B(0xD632, 0x0f); LCD_WRITE_REG(0xD632, 0x0f);
LCD_WRITE_REG_16B(0xD633, 0x8e); LCD_WRITE_REG(0xD633, 0x8e);
LCD_WRITE_REG_16B(0xD634, 0xff); LCD_WRITE_REG(0xD634, 0xff);
//AVDD VOLTAGE SETTING //AVDD VOLTAGE SETTING
LCD_WRITE_REG_16B(0xB000, 0x05); LCD_WRITE_REG(0xB000, 0x05);
LCD_WRITE_REG_16B(0xB001, 0x05); LCD_WRITE_REG(0xB001, 0x05);
LCD_WRITE_REG_16B(0xB002, 0x05); LCD_WRITE_REG(0xB002, 0x05);
//AVEE VOLTAGE SETTING //AVEE VOLTAGE SETTING
LCD_WRITE_REG_16B(0xB100, 0x05); LCD_WRITE_REG(0xB100, 0x05);
LCD_WRITE_REG_16B(0xB101, 0x05); LCD_WRITE_REG(0xB101, 0x05);
LCD_WRITE_REG_16B(0xB102, 0x05); LCD_WRITE_REG(0xB102, 0x05);
//AVDD Boosting //AVDD Boosting
LCD_WRITE_REG_16B(0xB600, 0x34); LCD_WRITE_REG(0xB600, 0x34);
LCD_WRITE_REG_16B(0xB601, 0x34); LCD_WRITE_REG(0xB601, 0x34);
LCD_WRITE_REG_16B(0xB603, 0x34); LCD_WRITE_REG(0xB603, 0x34);
//AVEE Boosting //AVEE Boosting
LCD_WRITE_REG_16B(0xB700, 0x24); LCD_WRITE_REG(0xB700, 0x24);
LCD_WRITE_REG_16B(0xB701, 0x24); LCD_WRITE_REG(0xB701, 0x24);
LCD_WRITE_REG_16B(0xB702, 0x24); LCD_WRITE_REG(0xB702, 0x24);
//VCL Boosting //VCL Boosting
LCD_WRITE_REG_16B(0xB800, 0x24); LCD_WRITE_REG(0xB800, 0x24);
LCD_WRITE_REG_16B(0xB801, 0x24); LCD_WRITE_REG(0xB801, 0x24);
LCD_WRITE_REG_16B(0xB802, 0x24); LCD_WRITE_REG(0xB802, 0x24);
//VGLX VOLTAGE SETTING //VGLX VOLTAGE SETTING
LCD_WRITE_REG_16B(0xBA00, 0x14); LCD_WRITE_REG(0xBA00, 0x14);
LCD_WRITE_REG_16B(0xBA01, 0x14); LCD_WRITE_REG(0xBA01, 0x14);
LCD_WRITE_REG_16B(0xBA02, 0x14); LCD_WRITE_REG(0xBA02, 0x14);
//VCL Boosting //VCL Boosting
LCD_WRITE_REG_16B(0xB900, 0x24); LCD_WRITE_REG(0xB900, 0x24);
LCD_WRITE_REG_16B(0xB901, 0x24); LCD_WRITE_REG(0xB901, 0x24);
LCD_WRITE_REG_16B(0xB902, 0x24); LCD_WRITE_REG(0xB902, 0x24);
//Gamma Voltage //Gamma Voltage
LCD_WRITE_REG_16B(0xBc00, 0x00); LCD_WRITE_REG(0xBc00, 0x00);
LCD_WRITE_REG_16B(0xBc01, 0xa0);//vgmp=5.0 LCD_WRITE_REG(0xBc01, 0xa0);//vgmp=5.0
LCD_WRITE_REG_16B(0xBc02, 0x00); LCD_WRITE_REG(0xBc02, 0x00);
LCD_WRITE_REG_16B(0xBd00, 0x00); LCD_WRITE_REG(0xBd00, 0x00);
LCD_WRITE_REG_16B(0xBd01, 0xa0);//vgmn=5.0 LCD_WRITE_REG(0xBd01, 0xa0);//vgmn=5.0
LCD_WRITE_REG_16B(0xBd02, 0x00); LCD_WRITE_REG(0xBd02, 0x00);
//VCOM Setting //VCOM Setting
LCD_WRITE_REG_16B(0xBe01, 0x3d);//3 LCD_WRITE_REG(0xBe01, 0x3d);//3
//ENABLE PAGE 0 //ENABLE PAGE 0
LCD_WRITE_REG_16B(0xF000, 0x55); LCD_WRITE_REG(0xF000, 0x55);
LCD_WRITE_REG_16B(0xF001, 0xAA); LCD_WRITE_REG(0xF001, 0xAA);
LCD_WRITE_REG_16B(0xF002, 0x52); LCD_WRITE_REG(0xF002, 0x52);
LCD_WRITE_REG_16B(0xF003, 0x08); LCD_WRITE_REG(0xF003, 0x08);
LCD_WRITE_REG_16B(0xF004, 0x00); LCD_WRITE_REG(0xF004, 0x00);
//Vivid Color Function Control //Vivid Color Function Control
LCD_WRITE_REG_16B(0xB400, 0x10); LCD_WRITE_REG(0xB400, 0x10);
//Z-INVERSION //Z-INVERSION
LCD_WRITE_REG_16B(0xBC00, 0x05); LCD_WRITE_REG(0xBC00, 0x05);
LCD_WRITE_REG_16B(0xBC01, 0x05); LCD_WRITE_REG(0xBC01, 0x05);
LCD_WRITE_REG_16B(0xBC02, 0x05); LCD_WRITE_REG(0xBC02, 0x05);
//*************** add on 20111021**********************// //*************** add on 20111021**********************//
LCD_WRITE_REG_16B(0xB700, 0x22);//GATE EQ CONTROL LCD_WRITE_REG(0xB700, 0x22);//GATE EQ CONTROL
LCD_WRITE_REG_16B(0xB701, 0x22);//GATE EQ CONTROL LCD_WRITE_REG(0xB701, 0x22);//GATE EQ CONTROL
LCD_WRITE_REG_16B(0xC80B, 0x2A);//DISPLAY TIMING CONTROL LCD_WRITE_REG(0xC80B, 0x2A);//DISPLAY TIMING CONTROL
LCD_WRITE_REG_16B(0xC80C, 0x2A);//DISPLAY TIMING CONTROL LCD_WRITE_REG(0xC80C, 0x2A);//DISPLAY TIMING CONTROL
LCD_WRITE_REG_16B(0xC80F, 0x2A);//DISPLAY TIMING CONTROL LCD_WRITE_REG(0xC80F, 0x2A);//DISPLAY TIMING CONTROL
LCD_WRITE_REG_16B(0xC810, 0x2A);//DISPLAY TIMING CONTROL LCD_WRITE_REG(0xC810, 0x2A);//DISPLAY TIMING CONTROL
//*************** add on 20111021**********************// //*************** add on 20111021**********************//
//PWM_ENH_OE =1 //PWM_ENH_OE =1
LCD_WRITE_REG_16B(0xd000, 0x01); LCD_WRITE_REG(0xd000, 0x01);
//DM_SEL =1 //DM_SEL =1
LCD_WRITE_REG_16B(0xb300, 0x10); LCD_WRITE_REG(0xb300, 0x10);
//VBPDA=07h //VBPDA=07h
LCD_WRITE_REG_16B(0xBd02, 0x07); LCD_WRITE_REG(0xBd02, 0x07);
//VBPDb=07h //VBPDb=07h
LCD_WRITE_REG_16B(0xBe02, 0x07); LCD_WRITE_REG(0xBe02, 0x07);
//VBPDc=07h //VBPDc=07h
LCD_WRITE_REG_16B(0xBf02, 0x07); LCD_WRITE_REG(0xBf02, 0x07);
//ENABLE PAGE 2 //ENABLE PAGE 2
LCD_WRITE_REG_16B(0xF000, 0x55); LCD_WRITE_REG(0xF000, 0x55);
LCD_WRITE_REG_16B(0xF001, 0xAA); LCD_WRITE_REG(0xF001, 0xAA);
LCD_WRITE_REG_16B(0xF002, 0x52); LCD_WRITE_REG(0xF002, 0x52);
LCD_WRITE_REG_16B(0xF003, 0x08); LCD_WRITE_REG(0xF003, 0x08);
LCD_WRITE_REG_16B(0xF004, 0x02); LCD_WRITE_REG(0xF004, 0x02);
//SDREG0 =0 //SDREG0 =0
LCD_WRITE_REG_16B(0xc301, 0xa9); LCD_WRITE_REG(0xc301, 0xa9);
//DS=14 //DS=14
LCD_WRITE_REG_16B(0xfe01, 0x94); LCD_WRITE_REG(0xfe01, 0x94);
//OSC =60h //OSC =60h
LCD_WRITE_REG_16B(0xf600, 0x60); LCD_WRITE_REG(0xf600, 0x60);
//TE ON //TE ON
LCD_WRITE_REG_16B(0x3500, 0x00); LCD_WRITE_REG(0x3500, 0x00);
//SLEEP OUT //SLEEP OUT
LCD_WRITE_CMD_16B(0x1100); LCD_WRITE_CMD(0x1100);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
//DISPLY ON //DISPLY ON
LCD_WRITE_CMD_16B(0x2900); LCD_WRITE_CMD(0x2900);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
LCD_WRITE_REG_16B(0x3A00, 0x55); LCD_WRITE_REG(0x3A00, 0x55);
LCD_WRITE_REG_16B(0x3600, 0xA3); LCD_WRITE_REG(0x3600, 0xA3);
} }

View file

@ -95,7 +95,7 @@ esp_err_t lcd_ssd1351_init(const scr_controller_config_t *lcd_conf)
LCD_CHECK(lcd_conf->width <= SSD1351_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->width <= SSD1351_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(lcd_conf->height <= SSD1351_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->height <= SSD1351_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG); LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG);
LCD_CHECK((NULL != lcd_conf->interface_drv->write_command && \ LCD_CHECK((NULL != lcd_conf->interface_drv->write_cmd && \
NULL != lcd_conf->interface_drv->write_data && \ NULL != lcd_conf->interface_drv->write_data && \
NULL != lcd_conf->interface_drv->write && \ NULL != lcd_conf->interface_drv->write && \
NULL != lcd_conf->interface_drv->read && \ NULL != lcd_conf->interface_drv->read && \

View file

@ -1,345 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) Co. Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "screen_driver.h"
#include "screen_utility.h"
#include "ssd1963.h"
static const char *TAG = "lcd ssd1963";
#define LCD_CHECK(a, str, ret) if(!(a)) { \
ESP_LOGE(TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
return (ret); \
}
#define LCD_NAME "SSD1963"
#define LCD_BPP 16
#define SSD1963_CASET 0x2A
#define SSD1963_RASET 0x2B
#define SSD1963_RAMWR 0x2C
#define SSD1963_MADCTL 0x36
/* MADCTL Defines */
#define MADCTL_MY 0x01
#define MADCTL_MX 0x02
#define MADCTL_MV 0x20
#define MADCTL_ML 0x10
#define MADCTL_RGB 0x08
#define MADCTL_MH 0x04
#define SSD1963_RESOLUTION_HOR 800
#define SSD1963_RESOLUTION_VER 480
//LCD panel configuration
#define SSD_HOR_PULSE_WIDTH 1
#define SSD_HOR_BACK_PORCH 46
#define SSD_HOR_FRONT_PORCH 210
#define SSD_VER_PULSE_WIDTH 1
#define SSD_VER_BACK_PORCH 23
#define SSD_VER_FRONT_PORCH 22
#define SSD_HT (SSD1963_RESOLUTION_HOR+SSD_HOR_BACK_PORCH+SSD_HOR_FRONT_PORCH)
#define SSD_HPS (SSD_HOR_BACK_PORCH)
#define SSD_VT (SSD1963_RESOLUTION_VER+SSD_VER_BACK_PORCH+SSD_VER_FRONT_PORCH)
#define SSD_VPS (SSD_VER_BACK_PORCH)
static scr_handle_t g_lcd_handle;
/**
* This header file is only used to redefine the function to facilitate the call.
* It can only be placed in this position, not in the head of the file.
*/
#include "interface_drv_def.h"
scr_driver_t lcd_ssd1963_default_driver = {
.init = lcd_ssd1963_init,
.deinit = lcd_ssd1963_deinit,
.set_direction = lcd_ssd1963_set_rotation,
.set_window = lcd_ssd1963_set_window,
.write_ram_data = lcd_ssd1963_write_ram_data,
.draw_pixel = lcd_ssd1963_draw_pixel,
.draw_bitmap = lcd_ssd1963_draw_bitmap,
.get_info = lcd_ssd1963_get_info,
};
static void lcd_ssd1963_init_reg(void);
esp_err_t lcd_ssd1963_init(const scr_controller_config_t *lcd_conf)
{
LCD_CHECK(lcd_conf->width <= SSD1963_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(lcd_conf->height <= SSD1963_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG);
LCD_CHECK((NULL != lcd_conf->interface_drv->write_command && \
NULL != lcd_conf->interface_drv->write_data && \
NULL != lcd_conf->interface_drv->write && \
NULL != lcd_conf->interface_drv->read && \
NULL != lcd_conf->interface_drv->bus_acquire && \
NULL != lcd_conf->interface_drv->bus_release),
"Interface driver invalid", ESP_ERR_INVALID_ARG);
esp_err_t ret;
// Reset the display
if (lcd_conf->pin_num_rst >= 0) {
gpio_pad_select_gpio(lcd_conf->pin_num_rst);
gpio_set_direction(lcd_conf->pin_num_rst, GPIO_MODE_OUTPUT);
gpio_set_level(lcd_conf->pin_num_rst, (lcd_conf->rst_active_level) & 0x1);
vTaskDelay(100 / portTICK_RATE_MS);
gpio_set_level(lcd_conf->pin_num_rst, (~(lcd_conf->rst_active_level)) & 0x1);
vTaskDelay(100 / portTICK_RATE_MS);
}
g_lcd_handle.interface_drv = lcd_conf->interface_drv;
g_lcd_handle.original_width = lcd_conf->width;
g_lcd_handle.original_height = lcd_conf->height;
g_lcd_handle.offset_hor = lcd_conf->offset_hor;
g_lcd_handle.offset_ver = lcd_conf->offset_ver;
lcd_ssd1963_init_reg();
// Enable backlight
if (lcd_conf->pin_num_bckl >= 0) {
gpio_pad_select_gpio(lcd_conf->pin_num_bckl);
gpio_set_direction(lcd_conf->pin_num_bckl, GPIO_MODE_OUTPUT);
gpio_set_level(lcd_conf->pin_num_bckl, (lcd_conf->bckl_active_level) & 0x1);
}
ret = lcd_ssd1963_set_rotation(lcd_conf->rotate);
LCD_CHECK(ESP_OK == ret, "set rotation failed", ESP_FAIL);
return ESP_OK;
}
esp_err_t lcd_ssd1963_deinit(void)
{
memset(&g_lcd_handle, 0, sizeof(scr_handle_t));
return ESP_OK;
}
esp_err_t lcd_ssd1963_set_rotation(scr_dir_t dir)
{
esp_err_t ret;
uint8_t reg_data = 0;
reg_data &= ~MADCTL_RGB;
if (SCR_DIR_MAX < dir) {
dir >>= 5;
}
LCD_CHECK(dir < 8, "Unsupport rotate direction", ESP_ERR_INVALID_ARG);
switch (dir) {
case SCR_DIR_LRTB:
g_lcd_handle.width = g_lcd_handle.original_width;
g_lcd_handle.height = g_lcd_handle.original_height;
break;
case SCR_DIR_LRBT:
reg_data |= MADCTL_MY;
g_lcd_handle.width = g_lcd_handle.original_width;
g_lcd_handle.height = g_lcd_handle.original_height;
break;
case SCR_DIR_RLTB:
reg_data |= MADCTL_MX;
g_lcd_handle.width = g_lcd_handle.original_width;
g_lcd_handle.height = g_lcd_handle.original_height;
break;
case SCR_DIR_RLBT:
reg_data |= MADCTL_MX | MADCTL_MY;
g_lcd_handle.width = g_lcd_handle.original_width;
g_lcd_handle.height = g_lcd_handle.original_height;
break;
case SCR_DIR_TBLR:
reg_data |= MADCTL_MV;
g_lcd_handle.width = g_lcd_handle.original_height;
g_lcd_handle.height = g_lcd_handle.original_width;
break;
case SCR_DIR_BTLR:
reg_data |= MADCTL_MY | MADCTL_MV;
g_lcd_handle.width = g_lcd_handle.original_height;
g_lcd_handle.height = g_lcd_handle.original_width;
break;
case SCR_DIR_TBRL:
reg_data |= MADCTL_MX | MADCTL_MV;
g_lcd_handle.width = g_lcd_handle.original_height;
g_lcd_handle.height = g_lcd_handle.original_width;
break;
case SCR_DIR_BTRL:
reg_data |= MADCTL_MX | MADCTL_MY | MADCTL_MV;
g_lcd_handle.width = g_lcd_handle.original_height;
g_lcd_handle.height = g_lcd_handle.original_width;
break;
default: break;
}
ESP_LOGI(TAG, "MADCTL=0x%x", reg_data);
ret = LCD_WRITE_REG(SSD1963_MADCTL, reg_data);
LCD_CHECK(ESP_OK == ret, "Set screen rotate failed", ESP_FAIL);
g_lcd_handle.dir = dir;
return ESP_OK;
}
esp_err_t lcd_ssd1963_get_info(scr_info_t *info)
{
LCD_CHECK(NULL != info, "info pointer invalid", ESP_ERR_INVALID_ARG);
info->width = g_lcd_handle.width;
info->height = g_lcd_handle.height;
info->dir = g_lcd_handle.dir;
info->name = LCD_NAME;
info->color_type = SCR_COLOR_TYPE_RGB565;
info->bpp = LCD_BPP;
return ESP_OK;
}
esp_err_t lcd_ssd1963_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
LCD_CHECK((x1 < g_lcd_handle.width) && (y1 < g_lcd_handle.height), "The set coordinates exceed the screen size", ESP_ERR_INVALID_ARG);
LCD_CHECK((x0 <= x1) && (y0 <= y1), "Window coordinates invalid", ESP_ERR_INVALID_ARG);
esp_err_t ret = ESP_OK;
scr_utility_apply_offset(&g_lcd_handle, SSD1963_RESOLUTION_HOR, SSD1963_RESOLUTION_VER, &x0, &y0, &x1, &y1);
LCD_WRITE_CMD(SSD1963_CASET);
LCD_WRITE_DATA(x0 >> 8);
LCD_WRITE_DATA(x0 & 0XFF);
LCD_WRITE_DATA(x1 >> 8);
LCD_WRITE_DATA(x1 & 0XFF);
LCD_WRITE_CMD(SSD1963_RASET);
LCD_WRITE_DATA(y0 >> 8);
LCD_WRITE_DATA(y0 & 0XFF);
LCD_WRITE_DATA(y1 >> 8);
LCD_WRITE_DATA(y1 & 0XFF);
ret |= LCD_WRITE_CMD(SSD1963_RAMWR);
LCD_CHECK(ESP_OK == ret, "Set window failed", ESP_FAIL);
return ESP_OK;
}
esp_err_t lcd_ssd1963_write_ram_data(uint16_t color)
{
static uint8_t data[2];
data[0] = (uint8_t)(color & 0xff);
data[1] = (uint8_t)(color >> 8);
return LCD_WRITE(data, 2);
}
esp_err_t lcd_ssd1963_draw_pixel(uint16_t x, uint16_t y, uint16_t color)
{
esp_err_t ret;
ret = lcd_ssd1963_set_window(x, y, x, y);
if (ESP_OK != ret) {
return ESP_FAIL;
}
return lcd_ssd1963_write_ram_data(color);
}
esp_err_t lcd_ssd1963_draw_bitmap(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t *bitmap)
{
LCD_CHECK((x + w <= g_lcd_handle.width) && (y + h <= g_lcd_handle.height), "The set coordinates exceed the screen size", ESP_ERR_INVALID_ARG);
esp_err_t ret = ESP_OK;
uint8_t *p = (uint8_t *)bitmap;
LCD_IFACE_ACQUIRE();
ret = lcd_ssd1963_set_window(x, y, x + w - 1, y + h - 1);
if (ESP_OK != ret) {
return ESP_FAIL;
}
ret = LCD_WRITE(p, w * LCD_BPP / 8 * h);
LCD_IFACE_RELEASE();
LCD_CHECK(ESP_OK == ret, "Draw bitmap failed", ESP_FAIL);
return ESP_OK;
}
static void lcd_ssd1963_init_reg(void)
{
LCD_WRITE_CMD(0xE2); //Set PLL with OSC = 10MHz (hardware), Multiplier N = 35, 250MHz < VCO < 800MHz = OSC*(N+1), VCO = 300MHz
LCD_WRITE_DATA(0x1D); //
LCD_WRITE_DATA(0x02); //Divider M = 2, PLL = 300/(M+1) = 100MHz
LCD_WRITE_DATA(0x04); //Validate M and N values
vTaskDelay(pdMS_TO_TICKS(1));
LCD_WRITE_CMD(0xE0); // Start PLL command
LCD_WRITE_DATA(0x01); // enable PLL
vTaskDelay(pdMS_TO_TICKS(10));
LCD_WRITE_CMD(0xE0); // Start PLL command again
LCD_WRITE_DATA(0x03); // now, use PLL output as system clock
vTaskDelay(pdMS_TO_TICKS(12));
LCD_WRITE_CMD(0x01); //soft-reset
vTaskDelay(pdMS_TO_TICKS(10));
LCD_WRITE_CMD(0xE6); //set pixel frequency,33Mhz
LCD_WRITE_DATA(0x2F);
LCD_WRITE_DATA(0xFF);
LCD_WRITE_DATA(0xFF);
LCD_WRITE_CMD(0xB0); //set LCD mode
LCD_WRITE_DATA(0x20); //24-bit mode
LCD_WRITE_DATA(0x00); //TFT
LCD_WRITE_DATA((SSD1963_RESOLUTION_HOR - 1) >> 8); //set LCD horizontal pixel number
LCD_WRITE_DATA((SSD1963_RESOLUTION_HOR - 1) & 0xff);
LCD_WRITE_DATA((SSD1963_RESOLUTION_VER - 1) >> 8); //set LCD vertical pixel number
LCD_WRITE_DATA((SSD1963_RESOLUTION_VER - 1) & 0xff);
LCD_WRITE_DATA(0x00); //RGB
LCD_WRITE_CMD(0xB4); //Set horizontal period
LCD_WRITE_DATA((SSD_HT - 1) >> 8);
LCD_WRITE_DATA((SSD_HT - 1) & 0xff);
LCD_WRITE_DATA(SSD_HPS >> 8);
LCD_WRITE_DATA((SSD_HPS) & 0xff);
LCD_WRITE_DATA(SSD_HOR_PULSE_WIDTH - 1);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x00);
LCD_WRITE_CMD(0xB6); //Set vertical period
LCD_WRITE_DATA((SSD_VT - 1) >> 8);
LCD_WRITE_DATA((SSD_VT - 1) & 0xff);
LCD_WRITE_DATA(SSD_VPS >> 8);
LCD_WRITE_DATA((SSD_VPS) & 0xff);
LCD_WRITE_DATA(SSD_VER_FRONT_PORCH - 1);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x00);
LCD_WRITE_CMD(0xF0); //set SSD1963 interface is 16bit
LCD_WRITE_DATA(0x03); //16-bit(565 format) data for 16bpp
LCD_WRITE_CMD(0x29); //display on
LCD_WRITE_CMD(0xD0);
LCD_WRITE_DATA(0x00); //disable
LCD_WRITE_CMD(0xBE); //configuration PWM output
LCD_WRITE_DATA(0x05); //1 PWM frequency
LCD_WRITE_DATA(0xFE); //2 PWM duty
LCD_WRITE_DATA(0x01); //3 C
LCD_WRITE_DATA(0x00); //4 D
LCD_WRITE_DATA(0x00); //5 E
LCD_WRITE_DATA(0x00); //6 F
LCD_WRITE_CMD(0xB8); //set GPIO
LCD_WRITE_DATA(0x03);
LCD_WRITE_DATA(0x01);
LCD_WRITE_CMD(0xBA);
LCD_WRITE_DATA(0X01); //GPIO[1:0]=01
}

View file

@ -1,123 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) Co. Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef __LCD_SSD1963_H__
#define __LCD_SSD1963_H__
#include "screen_driver.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief device initialization
*
* @param lcd_conf configuration struct of ssd1963
*
* @return
* - ESP_OK Success
* - ESP_FAIL Fail
*/
esp_err_t lcd_ssd1963_init(const scr_controller_config_t *lcd_conf);
/**
* @brief Deinitial screen
*
* @return
* - ESP_OK Success
* - ESP_FAIL Fail
*/
esp_err_t lcd_ssd1963_deinit(void);
/**
* @brief Get screen information
*
* @param info Pointer to a scr_info_t structure.
*
* @return
* - ESP_OK Success
* - ESP_FAIL Fail
*/
esp_err_t lcd_ssd1963_get_info(scr_info_t *info);
/**
* @brief Set screen direction of rotation
*
* @param dir Pointer to a scr_dir_t structure.
*
* @return
* - ESP_OK Success
* - ESP_FAIL Fail
*/
esp_err_t lcd_ssd1963_set_rotation(scr_dir_t dir);
/**
* @brief Set screen window
*
* @param x0 Starting point in X direction
* @param y0 Starting point in Y direction
* @param x1 End point in X direction
* @param y1 End point in Y direction
*
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ssd1963_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
/**
* @brief Write a RAM data
*
* @param color New color of a pixel
*
* @return
* - ESP_OK on success
* - ESP_FAIL Failed
*/
esp_err_t lcd_ssd1963_write_ram_data(uint16_t color);
/**
* @brief Draw one pixel in screen with color
*
* @param x X co-ordinate of set orientation
* @param y Y co-ordinate of set orientation
* @param color New color of the pixel
*
* @return
* - ESP_OK Success
* - ESP_FAIL Fail
*/
esp_err_t lcd_ssd1963_draw_pixel(uint16_t x, uint16_t y, uint16_t color);
/**
* @brief Fill the pixels on LCD screen with bitmap
*
* @param x Starting point in X direction
* @param y Starting point in Y direction
* @param w width of image in bitmap array
* @param h height of image in bitmap array
* @param bitmap pointer to bitmap array
*
* @return
* - ESP_OK Success
* - ESP_FAIL Fail
*/
esp_err_t lcd_ssd1963_draw_bitmap(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t *bitmap);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -151,7 +151,7 @@ esp_err_t lcd_st7789_init(const scr_controller_config_t *lcd_conf)
LCD_CHECK(lcd_conf->width <= ST7789_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->width <= ST7789_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(lcd_conf->height <= ST7789_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->height <= ST7789_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG); LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG);
LCD_CHECK((NULL != lcd_conf->interface_drv->write_command && \ LCD_CHECK((NULL != lcd_conf->interface_drv->write_cmd && \
NULL != lcd_conf->interface_drv->write_data && \ NULL != lcd_conf->interface_drv->write_data && \
NULL != lcd_conf->interface_drv->write && \ NULL != lcd_conf->interface_drv->write && \
NULL != lcd_conf->interface_drv->read && \ NULL != lcd_conf->interface_drv->read && \

View file

@ -81,7 +81,7 @@ esp_err_t lcd_st7796_init(const scr_controller_config_t *lcd_conf)
LCD_CHECK(lcd_conf->width <= ST7796_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->width <= ST7796_RESOLUTION_HOR, "Width greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(lcd_conf->height <= ST7796_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG); LCD_CHECK(lcd_conf->height <= ST7796_RESOLUTION_VER, "Height greater than maximum", ESP_ERR_INVALID_ARG);
LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG); LCD_CHECK(NULL != lcd_conf, "config pointer invalid", ESP_ERR_INVALID_ARG);
LCD_CHECK((NULL != lcd_conf->interface_drv->write_command && \ LCD_CHECK((NULL != lcd_conf->interface_drv->write_cmd && \
NULL != lcd_conf->interface_drv->write_data && \ NULL != lcd_conf->interface_drv->write_data && \
NULL != lcd_conf->interface_drv->write && \ NULL != lcd_conf->interface_drv->write && \
NULL != lcd_conf->interface_drv->read && \ NULL != lcd_conf->interface_drv->read && \

View file

@ -28,11 +28,6 @@ static const char *TAG = "screen interface";
return (ret); \ return (ret); \
} }
#if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S3)
#define SOC_SUPPORT_8080_IFACE 1
#endif
#ifdef SOC_SUPPORT_8080_IFACE
/**--------------------- I2S interface driver ----------------------*/ /**--------------------- I2S interface driver ----------------------*/
typedef struct { typedef struct {
i2s_lcd_handle_t i2s_lcd_handle; i2s_lcd_handle_t i2s_lcd_handle;
@ -41,20 +36,32 @@ typedef struct {
static esp_err_t _i2s_lcd_write_data(void *handle, uint16_t data) static esp_err_t _i2s_lcd_write_data(void *handle, uint16_t data)
{ {
#ifndef CONFIG_IDF_TARGET_ESP32S3
interface_i2s_handle_t *interface_i2s = __containerof(handle, interface_i2s_handle_t, interface_drv); interface_i2s_handle_t *interface_i2s = __containerof(handle, interface_i2s_handle_t, interface_drv);
return i2s_lcd_write_data(interface_i2s->i2s_lcd_handle, data); return i2s_lcd_write_data(interface_i2s->i2s_lcd_handle, data);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
} }
static esp_err_t _i2s_lcd_write_command(void *handle, const uint8_t *cmd, uint32_t length) static esp_err_t _i2s_lcd_write_cmd(void *handle, uint16_t cmd)
{ {
#ifndef CONFIG_IDF_TARGET_ESP32S3
interface_i2s_handle_t *interface_i2s = __containerof(handle, interface_i2s_handle_t, interface_drv); interface_i2s_handle_t *interface_i2s = __containerof(handle, interface_i2s_handle_t, interface_drv);
return i2s_lcd_write_command(interface_i2s->i2s_lcd_handle, cmd, length); return i2s_lcd_write_cmd(interface_i2s->i2s_lcd_handle, cmd);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
} }
static esp_err_t _i2s_lcd_write(void *handle, const uint8_t *data, uint32_t length) static esp_err_t _i2s_lcd_write(void *handle, const uint8_t *data, uint32_t length)
{ {
#ifndef CONFIG_IDF_TARGET_ESP32S3
interface_i2s_handle_t *interface_i2s = __containerof(handle, interface_i2s_handle_t, interface_drv); interface_i2s_handle_t *interface_i2s = __containerof(handle, interface_i2s_handle_t, interface_drv);
return i2s_lcd_write(interface_i2s->i2s_lcd_handle, data, length); return i2s_lcd_write(interface_i2s->i2s_lcd_handle, data, length);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
} }
static esp_err_t _i2s_lcd_read(void *handle, uint8_t *data, uint32_t length) static esp_err_t _i2s_lcd_read(void *handle, uint8_t *data, uint32_t length)
@ -64,16 +71,23 @@ static esp_err_t _i2s_lcd_read(void *handle, uint8_t *data, uint32_t length)
static esp_err_t _i2s_lcd_acquire(void *handle) static esp_err_t _i2s_lcd_acquire(void *handle)
{ {
#ifndef CONFIG_IDF_TARGET_ESP32S3
interface_i2s_handle_t *interface_i2s = __containerof(handle, interface_i2s_handle_t, interface_drv); interface_i2s_handle_t *interface_i2s = __containerof(handle, interface_i2s_handle_t, interface_drv);
return i2s_lcd_acquire(interface_i2s->i2s_lcd_handle); return i2s_lcd_acquire(interface_i2s->i2s_lcd_handle);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
} }
static esp_err_t _i2s_lcd_release(void *handle) static esp_err_t _i2s_lcd_release(void *handle)
{ {
#ifndef CONFIG_IDF_TARGET_ESP32S3
interface_i2s_handle_t *interface_i2s = __containerof(handle, interface_i2s_handle_t, interface_drv); interface_i2s_handle_t *interface_i2s = __containerof(handle, interface_i2s_handle_t, interface_drv);
return i2s_lcd_release(interface_i2s->i2s_lcd_handle); return i2s_lcd_release(interface_i2s->i2s_lcd_handle);
} #else
return ESP_ERR_NOT_SUPPORTED;
#endif #endif
}
/**--------------------- I2C interface driver ----------------------*/ /**--------------------- I2C interface driver ----------------------*/
#define SSD1306_WRITE_CMD 0x00 #define SSD1306_WRITE_CMD 0x00
@ -116,11 +130,10 @@ static esp_err_t i2c_lcd_write_byte(i2c_bus_device_handle_t i2c_dev, uint8_t ctr
return ESP_OK; return ESP_OK;
} }
static esp_err_t i2c_lcd_write_command(void *handle, const uint8_t *cmd, uint32_t length) static esp_err_t i2c_lcd_write_cmd(void *handle, uint16_t cmd)
{ {
(void)length;// TODO: In most cases, the length is 1
interface_i2c_handle_t *interface_i2c = __containerof(handle, interface_i2c_handle_t, interface_drv); interface_i2c_handle_t *interface_i2c = __containerof(handle, interface_i2c_handle_t, interface_drv);
uint8_t v = *cmd; uint8_t v = cmd;
return i2c_lcd_write_byte(interface_i2c->i2c_dev, SSD1306_WRITE_CMD, v); return i2c_lcd_write_byte(interface_i2c->i2c_dev, SSD1306_WRITE_CMD, v);
} }
@ -169,7 +182,7 @@ typedef struct {
static esp_err_t spi_lcd_driver_init(const scr_interface_spi_config_t *cfg, interface_spi_handle_t *out_interface_spi) static esp_err_t spi_lcd_driver_init(const scr_interface_spi_config_t *cfg, interface_spi_handle_t *out_interface_spi)
{ {
LCD_IFACE_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(cfg->pin_num_cs) || cfg->pin_num_cs == -1, "gpio cs invalid", ESP_ERR_INVALID_ARG); LCD_IFACE_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(cfg->pin_num_cs), "gpio cs invalid", ESP_ERR_INVALID_ARG);
LCD_IFACE_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(cfg->pin_num_dc), "gpio dc invalid", ESP_ERR_INVALID_ARG); LCD_IFACE_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(cfg->pin_num_dc), "gpio dc invalid", ESP_ERR_INVALID_ARG);
//Initialize non-SPI GPIOs //Initialize non-SPI GPIOs
@ -211,12 +224,13 @@ static esp_err_t _lcd_spi_rw(spi_bus_device_handle_t spi, const uint8_t *output,
return spi_bus_transfer_bytes(spi, output, input, length); return spi_bus_transfer_bytes(spi, output, input, length);
} }
static esp_err_t spi_lcd_driver_write_command(void *handle, const uint8_t *cmd, uint32_t length) static esp_err_t spi_lcd_driver_write_cmd(void *handle, uint16_t value)
{ {
interface_spi_handle_t *interface_spi = __containerof(handle, interface_spi_handle_t, interface_drv); interface_spi_handle_t *interface_spi = __containerof(handle, interface_spi_handle_t, interface_drv);
esp_err_t ret; esp_err_t ret;
gpio_set_level(interface_spi->pin_num_dc, LCD_CMD_LEV); gpio_set_level(interface_spi->pin_num_dc, LCD_CMD_LEV);
ret = _lcd_spi_rw(interface_spi->spi_wr_dev, cmd, NULL, length); uint8_t data = value;
ret = _lcd_spi_rw(interface_spi->spi_wr_dev, &data, NULL, 1);
gpio_set_level(interface_spi->pin_num_dc, LCD_DATA_LEV); gpio_set_level(interface_spi->pin_num_dc, LCD_DATA_LEV);
LCD_IFACE_CHECK(ESP_OK == ret, "Send cmd failed", ESP_FAIL); LCD_IFACE_CHECK(ESP_OK == ret, "Send cmd failed", ESP_FAIL);
return ESP_OK; return ESP_OK;
@ -284,8 +298,8 @@ esp_err_t scr_interface_create(scr_interface_type_t type, void *config, scr_inte
LCD_IFACE_CHECK(NULL != out_driver, "Pointer of driver is invalid", ESP_ERR_INVALID_ARG); LCD_IFACE_CHECK(NULL != out_driver, "Pointer of driver is invalid", ESP_ERR_INVALID_ARG);
switch (type) { switch (type) {
#ifdef SOC_SUPPORT_8080_IFACE
case SCREEN_IFACE_8080: { case SCREEN_IFACE_8080: {
#ifndef CONFIG_IDF_TARGET_ESP32S3
interface_i2s_handle_t *interface_i2s = heap_caps_malloc(sizeof(interface_i2s_handle_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); interface_i2s_handle_t *interface_i2s = heap_caps_malloc(sizeof(interface_i2s_handle_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
LCD_IFACE_CHECK(NULL != interface_i2s, "memory of iface i2s is not enough", ESP_ERR_NO_MEM); LCD_IFACE_CHECK(NULL != interface_i2s, "memory of iface i2s is not enough", ESP_ERR_NO_MEM);
interface_i2s->i2s_lcd_handle = i2s_lcd_driver_init((i2s_lcd_config_t *)config); interface_i2s->i2s_lcd_handle = i2s_lcd_driver_init((i2s_lcd_config_t *)config);
@ -296,7 +310,7 @@ esp_err_t scr_interface_create(scr_interface_type_t type, void *config, scr_inte
} }
interface_i2s->interface_drv.type = type; interface_i2s->interface_drv.type = type;
interface_i2s->interface_drv.write_command = _i2s_lcd_write_command; interface_i2s->interface_drv.write_cmd = _i2s_lcd_write_cmd;
interface_i2s->interface_drv.write_data = _i2s_lcd_write_data; interface_i2s->interface_drv.write_data = _i2s_lcd_write_data;
interface_i2s->interface_drv.write = _i2s_lcd_write; interface_i2s->interface_drv.write = _i2s_lcd_write;
interface_i2s->interface_drv.read = _i2s_lcd_read; interface_i2s->interface_drv.read = _i2s_lcd_read;
@ -304,8 +318,10 @@ esp_err_t scr_interface_create(scr_interface_type_t type, void *config, scr_inte
interface_i2s->interface_drv.bus_release = _i2s_lcd_release; interface_i2s->interface_drv.bus_release = _i2s_lcd_release;
*out_driver = &interface_i2s->interface_drv; *out_driver = &interface_i2s->interface_drv;
} break; #else
return ESP_ERR_NOT_SUPPORTED;
#endif #endif
} break;
case SCREEN_IFACE_SPI: { case SCREEN_IFACE_SPI: {
interface_spi_handle_t *interface_spi = heap_caps_malloc(sizeof(interface_spi_handle_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); interface_spi_handle_t *interface_spi = heap_caps_malloc(sizeof(interface_spi_handle_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
LCD_IFACE_CHECK(NULL != interface_spi, "memory of iface spi is not enough", ESP_ERR_NO_MEM); LCD_IFACE_CHECK(NULL != interface_spi, "memory of iface spi is not enough", ESP_ERR_NO_MEM);
@ -317,7 +333,7 @@ esp_err_t scr_interface_create(scr_interface_type_t type, void *config, scr_inte
} }
interface_spi->interface_drv.type = type; interface_spi->interface_drv.type = type;
interface_spi->interface_drv.write_command = spi_lcd_driver_write_command; interface_spi->interface_drv.write_cmd = spi_lcd_driver_write_cmd;
interface_spi->interface_drv.write_data = spi_lcd_driver_write_data; interface_spi->interface_drv.write_data = spi_lcd_driver_write_data;
interface_spi->interface_drv.write = spi_lcd_driver_write; interface_spi->interface_drv.write = spi_lcd_driver_write;
interface_spi->interface_drv.read = spi_lcd_driver_read; interface_spi->interface_drv.read = spi_lcd_driver_read;
@ -338,7 +354,7 @@ esp_err_t scr_interface_create(scr_interface_type_t type, void *config, scr_inte
} }
interface_i2c->interface_drv.type = type; interface_i2c->interface_drv.type = type;
interface_i2c->interface_drv.write_command = i2c_lcd_write_command; interface_i2c->interface_drv.write_cmd = i2c_lcd_write_cmd;
interface_i2c->interface_drv.write_data = i2c_lcd_write_data; interface_i2c->interface_drv.write_data = i2c_lcd_write_data;
interface_i2c->interface_drv.write = i2c_lcd_write; interface_i2c->interface_drv.write = i2c_lcd_write;
interface_i2c->interface_drv.read = i2c_lcd_read; interface_i2c->interface_drv.read = i2c_lcd_read;
@ -360,13 +376,11 @@ esp_err_t scr_interface_delete(const scr_interface_driver_t *driver)
LCD_IFACE_CHECK(NULL != driver, "Pointer of driver is invalid", ESP_ERR_INVALID_ARG); LCD_IFACE_CHECK(NULL != driver, "Pointer of driver is invalid", ESP_ERR_INVALID_ARG);
switch (driver->type) { switch (driver->type) {
#ifdef SOC_SUPPORT_8080_IFACE
case SCREEN_IFACE_8080: { case SCREEN_IFACE_8080: {
interface_i2s_handle_t *interface_i2s = __containerof(driver, interface_i2s_handle_t, interface_drv); interface_i2s_handle_t *interface_i2s = __containerof(driver, interface_i2s_handle_t, interface_drv);
i2s_lcd_driver_deinit(interface_i2s->i2s_lcd_handle); i2s_lcd_driver_deinit(interface_i2s->i2s_lcd_handle);
heap_caps_free(interface_i2s); heap_caps_free(interface_i2s);
} break; } break;
#endif
case SCREEN_IFACE_SPI: { case SCREEN_IFACE_SPI: {
interface_spi_handle_t *interface_spi = __containerof(driver, interface_spi_handle_t, interface_drv); interface_spi_handle_t *interface_spi = __containerof(driver, interface_spi_handle_t, interface_drv);
spi_lcd_driver_deinit(interface_spi); spi_lcd_driver_deinit(interface_spi);

View file

@ -62,7 +62,7 @@ typedef enum {
*/ */
typedef struct { typedef struct {
scr_interface_type_t type; /*!< Interface bus type, see scr_interface_type_t struct */ scr_interface_type_t type; /*!< Interface bus type, see scr_interface_type_t struct */
esp_err_t (*write_command)(void *handle, const uint8_t *cmd, uint32_t length); /*!< Function to write command */ esp_err_t (*write_cmd)(void *handle, uint16_t cmd); /*!< Function to write a command */
esp_err_t (*write_data)(void *handle, uint16_t data); /*!< Function to write a data */ esp_err_t (*write_data)(void *handle, uint16_t data); /*!< Function to write a data */
esp_err_t (*write)(void *handle, const uint8_t *data, uint32_t length); /*!< Function to write a block data */ esp_err_t (*write)(void *handle, const uint8_t *data, uint32_t length); /*!< Function to write a block data */
esp_err_t (*read)(void *handle, uint8_t *data, uint32_t length); /*!< Function to read a block data */ esp_err_t (*read)(void *handle, uint8_t *data, uint32_t length); /*!< Function to read a block data */

View file

@ -31,18 +31,12 @@ static const char *TAG = "screen driver";
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9341 #ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9341
extern scr_driver_t lcd_ili9341_default_driver; extern scr_driver_t lcd_ili9341_default_driver;
#endif #endif
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9342
extern scr_driver_t lcd_ili9342_default_driver;
#endif
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9486 #ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9486
extern scr_driver_t lcd_ili9486_default_driver; extern scr_driver_t lcd_ili9486_default_driver;
#endif #endif
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9806 #ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9806
extern scr_driver_t lcd_ili9806_default_driver; extern scr_driver_t lcd_ili9806_default_driver;
#endif #endif
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9488
extern scr_driver_t lcd_ili9488_default_driver;
#endif
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_NT35510 #ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_NT35510
extern scr_driver_t lcd_nt35510_default_driver; extern scr_driver_t lcd_nt35510_default_driver;
#endif #endif
@ -52,9 +46,6 @@ extern scr_driver_t lcd_rm68120_default_driver;
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_SSD1351 #ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_SSD1351
extern scr_driver_t lcd_ssd1351_default_driver; extern scr_driver_t lcd_ssd1351_default_driver;
#endif #endif
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_SSD1963
extern scr_driver_t lcd_ssd1963_default_driver;
#endif
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ST7789 #ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ST7789
extern scr_driver_t lcd_st7789_default_driver; extern scr_driver_t lcd_st7789_default_driver;
#endif #endif
@ -85,11 +76,6 @@ esp_err_t scr_find_driver(scr_controller_t controller, scr_driver_t *out_screen)
*out_screen = lcd_ili9341_default_driver; *out_screen = lcd_ili9341_default_driver;
break; break;
#endif #endif
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9342
case SCREEN_CONTROLLER_ILI9342:
*out_screen = lcd_ili9342_default_driver;
break;
#endif
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9806 #ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9806
case SCREEN_CONTROLLER_ILI9806: case SCREEN_CONTROLLER_ILI9806:
*out_screen = lcd_ili9806_default_driver; *out_screen = lcd_ili9806_default_driver;
@ -100,11 +86,6 @@ esp_err_t scr_find_driver(scr_controller_t controller, scr_driver_t *out_screen)
*out_screen = lcd_ili9486_default_driver; *out_screen = lcd_ili9486_default_driver;
break; break;
#endif #endif
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9488
case SCREEN_CONTROLLER_ILI9488:
*out_screen = lcd_ili9488_default_driver;
break;
#endif
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_NT35510 #ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_NT35510
case SCREEN_CONTROLLER_NT35510: case SCREEN_CONTROLLER_NT35510:
*out_screen = lcd_nt35510_default_driver; *out_screen = lcd_nt35510_default_driver;
@ -130,11 +111,6 @@ esp_err_t scr_find_driver(scr_controller_t controller, scr_driver_t *out_screen)
*out_screen = lcd_ssd1351_default_driver; *out_screen = lcd_ssd1351_default_driver;
break; break;
#endif #endif
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_SSD1963
case SCREEN_CONTROLLER_SSD1963:
*out_screen = lcd_ssd1963_default_driver;
break;
#endif
/**< Monochrome screen */ /**< Monochrome screen */
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_SSD1306 #ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_SSD1306

View file

@ -126,16 +126,13 @@ typedef enum {
typedef enum { typedef enum {
/* color screen */ /* color screen */
SCREEN_CONTROLLER_ILI9341, SCREEN_CONTROLLER_ILI9341,
SCREEN_CONTROLLER_ILI9342,
SCREEN_CONTROLLER_ILI9806, SCREEN_CONTROLLER_ILI9806,
SCREEN_CONTROLLER_ILI9486, SCREEN_CONTROLLER_ILI9486,
SCREEN_CONTROLLER_ILI9488,
SCREEN_CONTROLLER_NT35510, SCREEN_CONTROLLER_NT35510,
SCREEN_CONTROLLER_RM68120, SCREEN_CONTROLLER_RM68120,
SCREEN_CONTROLLER_ST7789, SCREEN_CONTROLLER_ST7789,
SCREEN_CONTROLLER_ST7796, SCREEN_CONTROLLER_ST7796,
SCREEN_CONTROLLER_SSD1351, SCREEN_CONTROLLER_SSD1351,
SCREEN_CONTROLLER_SSD1963,
/* monochrome screen */ /* monochrome screen */
SCREEN_CONTROLLER_SSD1306, SCREEN_CONTROLLER_SSD1306,

View file

@ -19,40 +19,15 @@
extern "C" { extern "C" {
#endif #endif
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
#define gpio_pad_select_gpio esp_rom_gpio_pad_select_gpio
#define portTICK_RATE_MS portTICK_PERIOD_MS
#endif
/**< Define the function of interface instance */ /**< Define the function of interface instance */
#define LCD_WRITE_COMMAND(data, length) g_lcd_handle.interface_drv->write_command(g_lcd_handle.interface_drv, (data), (length)) #define LCD_WRITE_CMD(cmd) g_lcd_handle.interface_drv->write_cmd(g_lcd_handle.interface_drv, (cmd))
#define LCD_WRITE_DATA(data) g_lcd_handle.interface_drv->write_data(g_lcd_handle.interface_drv, (data))
#define LCD_WRITE(data, length) g_lcd_handle.interface_drv->write(g_lcd_handle.interface_drv, (data), (length)) #define LCD_WRITE(data, length) g_lcd_handle.interface_drv->write(g_lcd_handle.interface_drv, (data), (length))
#define LCD_READ(data, length) g_lcd_handle.interface_drv->read(g_lcd_handle.interface_drv, (data), (length)) #define LCD_READ(data, length) g_lcd_handle.interface_drv->read(g_lcd_handle.interface_drv, (data), (length))
#define LCD_IFACE_ACQUIRE() g_lcd_handle.interface_drv->bus_acquire(g_lcd_handle.interface_drv) #define LCD_IFACE_ACQUIRE() g_lcd_handle.interface_drv->bus_acquire(g_lcd_handle.interface_drv)
#define LCD_IFACE_RELEASE() g_lcd_handle.interface_drv->bus_release(g_lcd_handle.interface_drv) #define LCD_IFACE_RELEASE() g_lcd_handle.interface_drv->bus_release(g_lcd_handle.interface_drv)
static inline esp_err_t LCD_WRITE_REG(uint16_t cmd, uint16_t data)
static inline esp_err_t LCD_WRITE_CMD(uint8_t cmd)
{
return LCD_WRITE_COMMAND((uint8_t*)&cmd, 1);
}
static inline esp_err_t LCD_WRITE_CMD_16B(uint16_t cmd)
{
return LCD_WRITE_COMMAND((uint8_t*)&cmd, 2);
}
static inline esp_err_t LCD_WRITE_DATA(uint8_t data)
{
return LCD_WRITE((uint8_t*)&data, 1);
}
static inline esp_err_t LCD_WRITE_DATA_16B(uint16_t data)
{
return LCD_WRITE((uint8_t*)&data, 2);
}
static inline esp_err_t LCD_WRITE_REG(uint8_t cmd, uint8_t data)
{ {
esp_err_t ret; esp_err_t ret;
ret = LCD_WRITE_CMD(cmd); ret = LCD_WRITE_CMD(cmd);
@ -64,18 +39,6 @@ static inline esp_err_t LCD_WRITE_REG(uint8_t cmd, uint8_t data)
return ESP_OK; return ESP_OK;
} }
static inline esp_err_t LCD_WRITE_REG_16B(uint16_t cmd, uint16_t data)
{
esp_err_t ret;
ret = LCD_WRITE_CMD_16B(cmd);
ret |= LCD_WRITE_DATA_16B(data);
if (ESP_OK != ret) {
return ESP_FAIL;
}
return ESP_OK;
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -406,34 +406,6 @@ TEST_CASE("Screen RM68210 8080 test", "[screen][iot]")
scr_interface_delete(iface_drv); scr_interface_delete(iface_drv);
} }
TEST_CASE("Screen SSD1963 8080 test", "[screen][iot]")
{
scr_driver_t lcd;
scr_interface_driver_t *iface_drv = get_8080_iface();
scr_controller_config_t lcd_cfg = {0};
lcd_cfg.interface_drv = iface_drv;
lcd_cfg.pin_num_rst = -1;
#ifdef CONFIG_IDF_TARGET_ESP32
lcd_cfg.pin_num_bckl = -1;
#else
lcd_cfg.pin_num_bckl = -1;
#endif
lcd_cfg.rst_active_level = 0;
lcd_cfg.bckl_active_level = 1;
lcd_cfg.offset_hor = 0;
lcd_cfg.offset_ver = 0;
lcd_cfg.width = 800;
lcd_cfg.height = 480;
lcd_cfg.rotate = SCR_DIR_LRTB;
TEST_ASSERT(ESP_OK == scr_find_driver(SCREEN_CONTROLLER_SSD1963, &lcd));
TEST_ASSERT(ESP_OK == lcd.init(&lcd_cfg));
lcd_colorful_test_all(&lcd);
lcd.deinit();
scr_interface_delete(iface_drv);
}
TEST_CASE("Screen ILI9341 SPI test", "[screen][iot]") TEST_CASE("Screen ILI9341 SPI test", "[screen][iot]")
{ {
scr_driver_t lcd; scr_driver_t lcd;

View file

@ -92,33 +92,28 @@ void painter_draw_char(int x, int y, char ascii_char, const font_t *font, uint16
PAINTER_CHECK(ascii_char >= ' ', "ACSII code invalid"); PAINTER_CHECK(ascii_char >= ' ', "ACSII code invalid");
PAINTER_CHECK(NULL != font, "Font pointer invalid"); PAINTER_CHECK(NULL != font, "Font pointer invalid");
int i, j; int i, j;
int x0 = x;
uint16_t char_size = font->Height * (font->Width / 8 + (font->Width % 8 ? 1 : 0)); uint16_t char_size = font->Height * (font->Width / 8 + (font->Width % 8 ? 1 : 0));
unsigned int char_offset = (ascii_char - ' ') * char_size; unsigned int char_offset = (ascii_char - ' ') * char_size;
const unsigned char *ptr = &font->table[char_offset]; const unsigned char *ptr = &font->table[char_offset];
uint16_t buf[18 * 25];
PAINTER_CHECK(font->Height * font->Width * sizeof(uint16_t) <= sizeof(buf), "Font size is too large");
int ox = 0;
int oy = 0;
for (i = 0; i < font->Width * font->Height; i++) {
buf[i] = g_back_color;
}
for (j = 0; j < char_size; j++) { for (j = 0; j < char_size; j++) {
uint8_t temp = ptr[j]; uint8_t temp = ptr[j];
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (temp & 0x80) { if (temp & 0x80) {
buf[ox + (font->Width * oy)] = g_point_color; g_lcd.draw_pixel(x, y, g_point_color);
} else {
g_lcd.draw_pixel(x, y, g_back_color);
} }
temp <<= 1; temp <<= 1;
ox++; x++;
if (ox == font->Width) { if ((x - x0) == font->Width) {
ox = 0; x = x0;
oy++; y++;
break; break;
} }
} }
} }
g_lcd.draw_bitmap(x, y, font->Width, font->Height, buf); // Draw NxN char
} }
void painter_draw_string(int x, int y, const char *text, const font_t *font, uint16_t color) void painter_draw_string(int x, int y, const char *text, const font_t *font, uint16_t color)
@ -154,7 +149,7 @@ void painter_draw_num(int x, int y, uint32_t num, uint8_t len, const font_t *fon
{ {
PAINTER_CHECK(len < 10, "The length of the number is too long"); PAINTER_CHECK(len < 10, "The length of the number is too long");
PAINTER_CHECK(NULL != font, "Font pointer invalid"); PAINTER_CHECK(NULL != font, "Font pointer invalid");
char buf[10] = {0}; char buf[10]={0};
int8_t num_len; int8_t num_len;
itoa(num, buf, 10); itoa(num, buf, 10);

View file

@ -286,7 +286,7 @@ esp_err_t touch_calibration_run(const scr_driver_t *screen,
calibrate_error = 0; calibrate_error = 0;
ESP_LOGI(TAG, "/ XL = (%f)X + (%f)Y + (%f)", g_caldata.ax, g_caldata.bx, g_caldata.cx); ESP_LOGI(TAG, "/ XL = (%f)X + (%f)Y + (%f)", g_caldata.ax, g_caldata.bx, g_caldata.cx);
ESP_LOGI(TAG, "\\ YL = (%f)X + (%f)Y + (%f)", g_caldata.ay, g_caldata.by, g_caldata.cy); ESP_LOGI(TAG, "\\ YL = (%f)X + (%f)Y + (%f)", g_caldata.ay, g_caldata.by, g_caldata.cy);
show_prompt_with_dir((w/2)-(Font16.Width*5), (h/2)+Font16.Height, "Successful", &Font16, COLOR_BLUE, old_dir); show_prompt_with_dir(30, h/2, "Successful", &Font16, COLOR_BLUE, old_dir);
touch_save_calibration(&g_caldata, sizeof(Calibration_t)); touch_save_calibration(&g_caldata, sizeof(Calibration_t));
vTaskDelay(2000 / portTICK_PERIOD_MS); vTaskDelay(2000 / portTICK_PERIOD_MS);
} }

View file

@ -1,7 +1,8 @@
file(GLOB_RECURSE srcs lvgl/src/*.c) file(GLOB_RECURSE srcs lvgl/src/*.c)
list(APPEND srcs "lvgl_gui.c") list(APPEND srcs "lvgl_gui.c"
"lvgl_adapter.c")
set(incdirs "." set(incdirs "."
"lvgl" "lvgl"
@ -9,6 +10,6 @@ set(incdirs "."
"lvgl/src") "lvgl/src")
idf_component_register(SRCS "${srcs}" idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS "${incdirs}" INCLUDE_DIRS "${incdirs}"
REQUIRES screen touch_panel esp_timer) REQUIRES screen touch_panel)
target_compile_definitions(${COMPONENT_LIB} INTERFACE LV_CONF_INCLUDE_SIMPLE=1) target_compile_definitions(${COMPONENT_LIB} INTERFACE LV_CONF_INCLUDE_SIMPLE=1)

View file

@ -0,0 +1 @@
[[中文]](../../../documents/hmi_solution/littlevgl/littlevgl_guide_cn.md)/[[EN]]((../../../documents/hmi_solution/littlevgl/littlevgl_guide_en.md))

View file

@ -1,16 +1,17 @@
#ifndef _COM_GUI_LVGL_H #ifndef _COM_GUI_LVGL_H
#define _COM_GUI_LVGL_H #define _COM_GUI_LVGL_H
#include "lv_conf.h"
#include "lvgl.h"
#include "touch_panel.h"
#include "screen_driver.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
{ {
#endif #endif
#include "sdkconfig.h"
#include "lv_conf.h"
#include "lvgl.h"
#include "lvgl_adapter.h"
/** /**
* @brief Initialize lvgl and register driver to lvgl * @brief Initialize lvgl and register driver to lvgl
* *
@ -25,22 +26,9 @@ extern "C"
*/ */
esp_err_t lvgl_init(scr_driver_t *lcd_drv, touch_panel_driver_t *touch_drv); esp_err_t lvgl_init(scr_driver_t *lcd_drv, touch_panel_driver_t *touch_drv);
/**
* @brief Acquire lock for LVGL
*
* @note If you wish to call any lvgl function from other threads/tasks you should lock on the very same semaphore
*
*/
void lvgl_acquire(void);
/**
* @brief Release lock for LVGL
*
*/
void lvgl_release(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* _COM_GUI_LVGL_H */ #endif /* _COM_GUI_LVGL_H */

View file

@ -0,0 +1,146 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "freertos/semphr.h"
#include "lvgl_adapter.h"
#include "sdkconfig.h"
static const char *TAG = "lvgl adapter";
static scr_driver_t lcd_obj;
static touch_panel_driver_t touch_obj;
static uint16_t g_screen_width = 240;
static uint16_t g_screen_height = 320;
/*Write the internal buffer (VDB) to the display. 'lv_flush_ready()' has to be called when finished*/
static void ex_disp_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
{
lcd_obj.draw_bitmap(area->x1, area->y1, (uint16_t)(area->x2 - area->x1 + 1), (uint16_t)(area->y2 - area->y1 + 1), (uint16_t *)color_map);
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(drv);
}
#define DISP_BUF_SIZE (g_screen_width * 64)
#define SIZE_TO_PIXEL(v) ((v) / sizeof(lv_color_t))
#define PIXEL_TO_SIZE(v) ((v) * sizeof(lv_color_t))
#define BUFFER_NUMBER (2)
esp_err_t lvgl_display_init(scr_driver_t *driver)
{
if (NULL == driver) {
ESP_LOGE(TAG, "Pointer of lcd driver is invalid");
return ESP_ERR_INVALID_ARG;
}
lcd_obj = *driver;
scr_info_t info;
lcd_obj.get_info(&info);
g_screen_width = info.width;
g_screen_height = info.height;
lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
disp_drv.hor_res = g_screen_width;
disp_drv.ver_res = g_screen_height;
disp_drv.flush_cb = ex_disp_flush; /*Used in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/
size_t free_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
const size_t remain_size = 60 * 1024; /**< Remain for other functions */
size_t alloc_pixel = DISP_BUF_SIZE;
if (((BUFFER_NUMBER * PIXEL_TO_SIZE(alloc_pixel)) + remain_size) > free_size) {
size_t allow_size = (free_size - remain_size) & 0xfffffffc;
alloc_pixel = SIZE_TO_PIXEL(allow_size / BUFFER_NUMBER);
ESP_LOGW(TAG, "Exceeded max free size, force shrink to %u Byte", allow_size);
}
lv_color_t *buf1 = heap_caps_malloc(PIXEL_TO_SIZE(alloc_pixel), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (NULL == buf1) {
ESP_LOGE(TAG, "Display buffer memory not enough");
return ESP_ERR_NO_MEM;
}
#if (BUFFER_NUMBER == 2)
lv_color_t *buf2 = heap_caps_malloc(PIXEL_TO_SIZE(alloc_pixel), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (NULL == buf2) {
heap_caps_free(buf1);
ESP_LOGE(TAG, "Display buffer memory not enough");
return ESP_ERR_NO_MEM;
}
#endif
ESP_LOGI(TAG, "Alloc memory total size: %u Byte", BUFFER_NUMBER * PIXEL_TO_SIZE(alloc_pixel));
static lv_disp_buf_t disp_buf;
#if (BUFFER_NUMBER == 2)
lv_disp_buf_init(&disp_buf, buf1, buf2, alloc_pixel);
#else
lv_disp_buf_init(&disp_buf, buf1, NULL, alloc_pixel);
#endif
disp_drv.buffer = &disp_buf;
/* Finally register the driver */
lv_disp_drv_register(&disp_drv);
return ESP_OK;
}
/*Function pointer to read data. Return 'true' if there is still data to be read (buffered)*/
static bool ex_tp_read(struct _lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
{
data->state = LV_INDEV_STATE_REL;
touch_panel_points_t points;
touch_obj.read_point_data(&points);
// please be sure that your touch driver every time return old (last clcked) value.
if (TOUCH_EVT_PRESS == points.event) {
int32_t x = points.curx[0];
int32_t y = points.cury[0];
data->point.x = x;
data->point.y = y;
data->state = LV_INDEV_STATE_PR;
}
return false;
}
/* Input device interfaceInitialize your touchpad */
esp_err_t lvgl_indev_init(touch_panel_driver_t *driver)
{
if (NULL == driver) {
ESP_LOGE(TAG, "Pointer of touch driver is invalid");
return ESP_ERR_INVALID_ARG;
}
touch_obj = *driver;
lv_indev_drv_t indev_drv; /*Descriptor of an input device driver*/
lv_indev_drv_init(&indev_drv); /*Basic initialization*/
indev_drv.type = LV_INDEV_TYPE_POINTER; /*The touchpad is pointer type device*/
indev_drv.read_cb = ex_tp_read; /*Library ready your touchpad via this function*/
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
return ESP_OK;
}

View file

@ -0,0 +1,41 @@
#ifndef _LVGL_LCD_ADAPTER_H
#define _LVGL_LCD_ADAPTER_H
#include "lvgl.h"
#include "esp_err.h"
#include "touch_panel.h"
#include "screen_driver.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Initiliaze display device for lvgl
* @note This function only registers the dispaly driver into lvgl, and does not initiliaze the display driver.
*
* @param driver Pointer to display driver
* @return
* - ESP_OK: Success
* - ESP_ERR_NO_MEM: Cannot allocate memory
* - ESP_ERR_INVALID_ARG: Invalid pointer of driver
*/
esp_err_t lvgl_display_init(scr_driver_t *driver);
/**
* @brief Initiliaze touch device for lvgl
* @note This function only registers the touch driver into lvgl, and does not initiliaze the touch driver.
*
* @param driver Pointer to display driver
* @return
* - ESP_OK: Success
* - ESP_ERR_INVALID_ARG: Invalid pointer of driver
*/
esp_err_t lvgl_indev_init(touch_panel_driver_t *driver);
#ifdef __cplusplus
}
#endif
#endif /* _LVGL_LCD_ADAPTER_H */

View file

@ -14,156 +14,75 @@
/* FreeRTOS includes */ /* FreeRTOS includes */
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_timer.h" /* LVGL includes */
#include "lvgl_gui.h" #include "lvgl_gui.h"
static const char *TAG = "lvgl_gui"; static const char *TAG = "lvgl_gui";
#define ESP_GOTO_ON_FALSE(a, err_code, goto_tag, log_tag, format, ...) do { \ typedef struct {
if (unlikely(!(a))) { \ scr_driver_t *lcd_drv;
ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \ touch_panel_driver_t *touch_drv;
ret = err_code; \ } lvgl_drv_t;
goto goto_tag; \
} \ // wait for execute lv_task_handler and lv_tick_inc to avoid some widget don't refresh.
} while (0) #define LVGL_TICK_MS 1
static void lv_tick_timercb(void *timer)
{
/* Initialize a Timer for 1 ms period and
* in its interrupt call
* lv_tick_inc(1); */
lv_tick_inc(LVGL_TICK_MS);
}
/* Creates a semaphore to handle concurrent call to lvgl stuff /* Creates a semaphore to handle concurrent call to lvgl stuff
* If you wish to call *any* lvgl function from other threads/tasks * If you wish to call *any* lvgl function from other threads/tasks
* you should lock on the very same semaphore! */ * you should lock on the very same semaphore! */
static SemaphoreHandle_t xGuiSemaphore = NULL; static SemaphoreHandle_t xGuiSemaphore = NULL;
static TaskHandle_t g_lvgl_task_handle;
#define LVGL_TICK_MS 5
static scr_driver_t lcd_obj;
static touch_panel_driver_t touch_obj;
static uint16_t g_screen_width = 240;
static uint16_t g_screen_height = 320;
/*Write the internal buffer (VDB) to the display. 'lv_flush_ready()' has to be called when finished*/
static void ex_disp_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
{
lcd_obj.draw_bitmap(area->x1, area->y1, (uint16_t)(area->x2 - area->x1 + 1), (uint16_t)(area->y2 - area->y1 + 1), (uint16_t *)color_map);
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(drv);
}
#define DISP_BUF_SIZE (g_screen_width * 64)
#define SIZE_TO_PIXEL(v) ((v) / sizeof(lv_color_t))
#define PIXEL_TO_SIZE(v) ((v) * sizeof(lv_color_t))
#define BUFFER_NUMBER (2)
static esp_err_t lvgl_display_init(scr_driver_t *driver)
{
if (NULL == driver) {
ESP_LOGE(TAG, "Pointer of lcd driver is invalid");
return ESP_ERR_INVALID_ARG;
}
lcd_obj = *driver;
scr_info_t info;
lcd_obj.get_info(&info);
g_screen_width = info.width;
g_screen_height = info.height;
lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
disp_drv.hor_res = g_screen_width;
disp_drv.ver_res = g_screen_height;
disp_drv.flush_cb = ex_disp_flush; /*Used in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/
size_t free_size = heap_caps_get_free_size(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
const size_t remain_size = 60 * 1024; /**< Remain for other functions */
size_t alloc_pixel = DISP_BUF_SIZE;
if (((BUFFER_NUMBER * PIXEL_TO_SIZE(alloc_pixel)) + remain_size) > free_size) {
size_t allow_size = (free_size - remain_size) & 0xfffffffc;
alloc_pixel = SIZE_TO_PIXEL(allow_size / BUFFER_NUMBER);
ESP_LOGW(TAG, "Exceeded max free size, force shrink to %u Byte", allow_size);
}
lv_color_t *buf1 = heap_caps_malloc(PIXEL_TO_SIZE(alloc_pixel), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (NULL == buf1) {
ESP_LOGE(TAG, "Display buffer memory not enough");
return ESP_ERR_NO_MEM;
}
#if (BUFFER_NUMBER == 2)
lv_color_t *buf2 = heap_caps_malloc(PIXEL_TO_SIZE(alloc_pixel), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (NULL == buf2) {
heap_caps_free(buf1);
ESP_LOGE(TAG, "Display buffer memory not enough");
return ESP_ERR_NO_MEM;
}
#endif
ESP_LOGI(TAG, "Alloc memory total size: %u Byte", BUFFER_NUMBER * PIXEL_TO_SIZE(alloc_pixel));
static lv_disp_buf_t disp_buf;
#if (BUFFER_NUMBER == 2)
lv_disp_buf_init(&disp_buf, buf1, buf2, alloc_pixel);
#else
lv_disp_buf_init(&disp_buf, buf1, NULL, alloc_pixel);
#endif
disp_drv.buffer = &disp_buf;
/* Finally register the driver */
lv_disp_drv_register(&disp_drv);
return ESP_OK;
}
/*Function pointer to read data. Return 'true' if there is still data to be read (buffered)*/
static bool ex_tp_read(struct _lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
{
data->state = LV_INDEV_STATE_REL;
touch_panel_points_t points;
touch_obj.read_point_data(&points);
// please be sure that your touch driver every time return old (last clcked) value.
if (TOUCH_EVT_PRESS == points.event) {
int32_t x = points.curx[0];
int32_t y = points.cury[0];
data->point.x = x;
data->point.y = y;
data->state = LV_INDEV_STATE_PR;
}
return false;
}
/* Input device interfaceInitialize your touchpad */
static esp_err_t lvgl_indev_init(touch_panel_driver_t *driver)
{
if (NULL == driver) {
ESP_LOGE(TAG, "Pointer of touch driver is invalid");
return ESP_ERR_INVALID_ARG;
}
touch_obj = *driver;
lv_indev_drv_t indev_drv; /*Descriptor of an input device driver*/
lv_indev_drv_init(&indev_drv); /*Basic initialization*/
indev_drv.type = LV_INDEV_TYPE_POINTER; /*The touchpad is pointer type device*/
indev_drv.read_cb = ex_tp_read; /*Library ready your touchpad via this function*/
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
return ESP_OK;
}
static void lv_tick_timercb(void *timer)
{
lv_tick_inc(LVGL_TICK_MS);
}
static void gui_task(void *args) static void gui_task(void *args)
{ {
esp_err_t ret;
lvgl_drv_t *lvgl_driver = (lvgl_drv_t *)args;
/* Initialize LittlevGL */
lv_init();
/* Display interface */
ret = lvgl_display_init(lvgl_driver->lcd_drv);
if (ESP_OK != ret) {
ESP_LOGE(TAG, "lvgl display initialize failed");
// lv_deinit(); /**< lvgl should be deinit here, but it seems lvgl doesn't support it */
vTaskDelete(NULL);
}
#if defined(CONFIG_LVGL_DRIVER_TOUCH_SCREEN_ENABLE)
if (NULL != lvgl_driver->touch_drv) {
/* Input device interface */
ret = lvgl_indev_init(lvgl_driver->touch_drv);
if (ESP_OK != ret) {
ESP_LOGE(TAG, "lvgl indev initialize failed");
// lv_deinit(); /**< lvgl should be deinit here, but it seems lvgl doesn't support it */
vTaskDelete(NULL);
}
}
#endif
esp_timer_create_args_t timer_conf = {
.callback = lv_tick_timercb,
.name = "lv_tick_timer"
};
esp_timer_handle_t g_wifi_connect_timer = NULL;
esp_timer_create(&timer_conf, &g_wifi_connect_timer);
esp_timer_start_periodic(g_wifi_connect_timer, LVGL_TICK_MS * 1000U);
xGuiSemaphore = xSemaphoreCreateMutex();
ESP_LOGI(TAG, "Start to run LVGL"); ESP_LOGI(TAG, "Start to run LVGL");
while (1) { while (1) {
/* Delay 1 tick (assumes FreeRTOS tick is 10ms */
vTaskDelay(pdMS_TO_TICKS(10)); vTaskDelay(pdMS_TO_TICKS(10));
/* Try to take the semaphore, call lvgl related function on success */ /* Try to take the semaphore, call lvgl related function on success */
@ -176,66 +95,27 @@ static void gui_task(void *args)
esp_err_t lvgl_init(scr_driver_t *lcd_drv, touch_panel_driver_t *touch_drv) esp_err_t lvgl_init(scr_driver_t *lcd_drv, touch_panel_driver_t *touch_drv)
{ {
esp_err_t ret; /* If you want to use a task to create the graphic, you NEED to create a Pinned task
esp_timer_handle_t tick_timer = NULL; * Otherwise there can be problem such as memory corruption and so on.
* NOTE: When not using Wi-Fi nor Bluetooth you can pin the gui_task to core 0 */
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
ESP_LOGI(TAG, "GUI Run at %s Pinned to Core%d", CONFIG_IDF_TARGET, chip_info.cores - 1);
/* Initialize LittlevGL */ static lvgl_drv_t lvgl_driver;
lv_init(); lvgl_driver.lcd_drv = lcd_drv;
lvgl_driver.touch_drv = touch_drv;
/* Display interface */ xTaskCreatePinnedToCore(gui_task, "lv gui", 1024 * 8, &lvgl_driver, 5, NULL, chip_info.cores - 1);
ret = lvgl_display_init(lcd_drv);
ESP_GOTO_ON_FALSE(ESP_OK == ret, ESP_FAIL, err, TAG, "lvgl display initialize failed");
#if defined(CONFIG_LVGL_DRIVER_TOUCH_SCREEN_ENABLE) uint16_t timeout = 20;
if (NULL != touch_drv) { while (NULL == xGuiSemaphore) {
/* Input device interface */ vTaskDelay(pdMS_TO_TICKS(100));
ret = lvgl_indev_init(touch_drv); timeout--;
ESP_GOTO_ON_FALSE(ESP_OK == ret, ESP_FAIL, err, TAG, "lvgl indev initialize failed"); if (0 == timeout) {
ESP_LOGW(TAG, "GUI Task Start Timeout");
return ESP_ERR_TIMEOUT;
}
} }
#endif
esp_timer_create_args_t timer_conf = {
.callback = lv_tick_timercb,
.name = "lv_tick_timer"
};
ret = esp_timer_create(&timer_conf, &tick_timer);
ESP_GOTO_ON_FALSE(ESP_OK == ret, ESP_FAIL, err, TAG, "lvgl tick timer initialize failed");
xGuiSemaphore = xSemaphoreCreateMutex();
ESP_GOTO_ON_FALSE(NULL != xGuiSemaphore, ESP_FAIL, err, TAG, "Create mutex for LVGL failed");
#if CONFIG_FREERTOS_UNICORE == 0
int err = xTaskCreatePinnedToCore(gui_task, "lv gui", 1024 * 8, NULL, 5, &g_lvgl_task_handle, 1);
#else
int err = xTaskCreatePinnedToCore(gui_task, "lv gui", 1024 * 8, NULL, 5, &g_lvgl_task_handle, 0);
#endif
ESP_GOTO_ON_FALSE(pdPASS == err, ESP_FAIL, err, TAG, "Create task for LVGL failed");
esp_timer_start_periodic(tick_timer, LVGL_TICK_MS * 1000U);
return ESP_OK; return ESP_OK;
err:
if (xGuiSemaphore) {
vSemaphoreDelete(xGuiSemaphore);
}
if (tick_timer) {
esp_timer_delete(tick_timer);
}
return ESP_FAIL;
}
void lvgl_acquire(void)
{
TaskHandle_t task = xTaskGetCurrentTaskHandle();
if (g_lvgl_task_handle != task) {
xSemaphoreTake(xGuiSemaphore, portMAX_DELAY);
}
}
void lvgl_release(void)
{
TaskHandle_t task = xTaskGetCurrentTaskHandle();
if (g_lvgl_task_handle != task) {
xSemaphoreGive(xGuiSemaphore);
}
} }

View file

@ -1,3 +1,2 @@
idf_component_register(SRCS "led_indicator.c" idf_component_register(SRCS "led_indicator.c"
INCLUDE_DIRS include INCLUDE_DIRS include)
REQUIRES driver)

View file

@ -255,6 +255,7 @@ static esp_err_t _led_set_state(int io_num, bool off_level, blink_step_state_t s
static void _blink_list_switch(_led_indicator_t *p_led_indicator) static void _blink_list_switch(_led_indicator_t *p_led_indicator)
{ {
p_led_indicator->active_blink = NULL_ACTIVE_BLINK; //stop active blink p_led_indicator->active_blink = NULL_ACTIVE_BLINK; //stop active blink
_led_set_state(p_led_indicator->io_num, p_led_indicator->off_level, LED_STATE_OFF); //turn off the led
for(size_t index = 0; index < BLINK_LIST_NUM; index ++) //find the first incomplete blink for(size_t index = 0; index < BLINK_LIST_NUM; index ++) //find the first incomplete blink
{ {
if (p_led_indicator->p_blink_steps[index] != LED_BLINK_STOP) if (p_led_indicator->p_blink_steps[index] != LED_BLINK_STOP)
@ -270,7 +271,7 @@ static void _blink_list_switch(_led_indicator_t *p_led_indicator)
* *
* @param xTimer handle of the timmer instance * @param xTimer handle of the timmer instance
*/ */
static void _blink_list_runner(TimerHandle_t xTimer) static void _blink_list_runner(xTimerHandle xTimer)
{ {
_led_indicator_t * p_led_indicator = (_led_indicator_t *)pvTimerGetTimerID(xTimer); _led_indicator_t * p_led_indicator = (_led_indicator_t *)pvTimerGetTimerID(xTimer);
bool leave = false; bool leave = false;
@ -286,9 +287,9 @@ static void _blink_list_runner(TimerHandle_t xTimer)
p_led_indicator->p_blink_steps[active_blink] += 1; p_led_indicator->p_blink_steps[active_blink] += 1;
if (pdFALSE == xSemaphoreTake(p_led_indicator->mutex, pdMS_TO_TICKS(100))) { if (pdFALSE == xSemaphoreTake(p_led_indicator->mutex, (100 / portTICK_RATE_MS))) {
ESP_LOGW(TAG, "blinks runner blockTime expired, try repairing..."); ESP_LOGW(TAG, "blinks runner blockTime expired, try repairing...");
xTimerChangePeriod(p_led_indicator->h_timer, pdMS_TO_TICKS(100), 0); xTimerChangePeriod(p_led_indicator->h_timer, (100 / portTICK_RATE_MS), 0);
xTimerStart(p_led_indicator->h_timer, 0); xTimerStart(p_led_indicator->h_timer, 0);
break; break;
} }
@ -307,7 +308,7 @@ static void _blink_list_runner(TimerHandle_t xTimer)
_led_set_state(p_led_indicator->io_num, p_led_indicator->off_level, p_blink_step->on_off); _led_set_state(p_led_indicator->io_num, p_led_indicator->off_level, p_blink_step->on_off);
if (p_blink_step->hold_time_ms == 0) if (p_blink_step->hold_time_ms == 0)
break; break;
xTimerChangePeriod(p_led_indicator->h_timer, pdMS_TO_TICKS(p_blink_step->hold_time_ms), 0); xTimerChangePeriod(p_led_indicator->h_timer, (p_blink_step->hold_time_ms / portTICK_RATE_MS), 0);
xTimerStart(p_led_indicator->h_timer, 0); xTimerStart(p_led_indicator->h_timer, 0);
leave=true; leave=true;
break; break;
@ -326,13 +327,13 @@ led_indicator_handle_t led_indicator_create(int io_num, const led_indicator_conf
char timmer_name[16] = {'\0'}; char timmer_name[16] = {'\0'};
snprintf(timmer_name, sizeof(timmer_name) - 1, "%s%02x", "led_tmr_", io_num); snprintf(timmer_name, sizeof(timmer_name) - 1, "%s%02x", "led_tmr_", io_num);
_led_indicator_t *p_led_indicator = (_led_indicator_t *)calloc(1, sizeof(_led_indicator_t)); _led_indicator_t *p_led_indicator = (_led_indicator_t *)calloc(1, sizeof(_led_indicator_t));
LED_INDICATOR_CHECK(p_led_indicator != NULL, "calloc indicator memory failed", NULL); LED_INDICATOR_CHECK(p_led_indicator != NULL, "calloc memory failed", NULL);
p_led_indicator->off_level = config->off_level; p_led_indicator->off_level = config->off_level;
p_led_indicator->io_num = io_num; p_led_indicator->io_num = io_num;
p_led_indicator->mode = config->mode; p_led_indicator->mode = config->mode;
p_led_indicator->active_blink = NULL_ACTIVE_BLINK; p_led_indicator->active_blink = NULL_ACTIVE_BLINK;
p_led_indicator->p_blink_steps = (int *)calloc(BLINK_LIST_NUM, sizeof(int)); p_led_indicator->p_blink_steps = (int *)calloc(BLINK_LIST_NUM, sizeof(int));
LED_INDICATOR_CHECK_GOTO(p_led_indicator->p_blink_steps != NULL, "calloc blink_steps memory failed", cleanup_indicator); LED_INDICATOR_CHECK_GOTO(p_led_indicator->p_blink_steps != NULL, "calloc memory failed 2", cleanup_indicator);
p_led_indicator->mutex = xSemaphoreCreateMutex(); p_led_indicator->mutex = xSemaphoreCreateMutex();
LED_INDICATOR_CHECK_GOTO(p_led_indicator->mutex != NULL, "create mutex failed", cleanup_indicator_blinkstep); LED_INDICATOR_CHECK_GOTO(p_led_indicator->mutex != NULL, "create mutex failed", cleanup_indicator_blinkstep);
@ -346,7 +347,7 @@ led_indicator_handle_t led_indicator_create(int io_num, const led_indicator_conf
{ {
bool ininted = _led_gpio_init(p_led_indicator->io_num); bool ininted = _led_gpio_init(p_led_indicator->io_num);
LED_INDICATOR_CHECK_GOTO(ininted != false, "init led gpio failed", cleanup_all); LED_INDICATOR_CHECK_GOTO(ininted != false, "init led gpio failed", cleanup_all);
p_led_indicator->h_timer = xTimerCreate(timmer_name, (pdMS_TO_TICKS(100)), pdFALSE, (void *)p_led_indicator, _blink_list_runner); p_led_indicator->h_timer = xTimerCreate(timmer_name, (100 / portTICK_RATE_MS), pdFALSE, (void *)p_led_indicator, _blink_list_runner);
LED_INDICATOR_CHECK_GOTO(p_led_indicator->h_timer != NULL, "led timmer create failed", cleanup_all); LED_INDICATOR_CHECK_GOTO(p_led_indicator->h_timer != NULL, "led timmer create failed", cleanup_all);
} }
break; break;
@ -439,10 +440,6 @@ esp_err_t led_indicator_stop(led_indicator_handle_t handle, led_indicator_blink_
p_led_indicator->p_blink_steps[blink_type] = LED_BLINK_STOP; p_led_indicator->p_blink_steps[blink_type] = LED_BLINK_STOP;
_blink_list_switch(p_led_indicator); //stop and swith to next blink steps _blink_list_switch(p_led_indicator); //stop and swith to next blink steps
xSemaphoreGive(p_led_indicator->mutex); xSemaphoreGive(p_led_indicator->mutex);
if(p_led_indicator->active_blink == blink_type) { //re-run from first step
_blink_list_runner(p_led_indicator->h_timer); _blink_list_runner(p_led_indicator->h_timer);
}
return ESP_OK; return ESP_OK;
} }

View file

@ -1,3 +1,2 @@
idf_component_register(SRCS "light.c" idf_component_register(SRCS "light.c"
INCLUDE_DIRS include INCLUDE_DIRS include)
REQUIRES driver)

View file

@ -143,7 +143,7 @@ esp_err_t iot_light_channel_regist(light_handle_t light_handle, uint8_t channel_
{ {
light_t* light = (light_t*)light_handle; light_t* light = (light_t*)light_handle;
POINT_ASSERT(TAG, light_handle); POINT_ASSERT(TAG, light_handle);
IOT_CHECK(TAG, channel_idx < light->channel_num, ESP_FAIL); IOT_CHECK(TAG, channel_idx < light->channel_num, FAIL);
if (light->channel_group[channel_idx] != NULL) { if (light->channel_group[channel_idx] != NULL) {
ESP_LOGE(TAG, "this channel index has been registered"); ESP_LOGE(TAG, "this channel index has been registered");
return ESP_FAIL; return ESP_FAIL;
@ -184,7 +184,7 @@ esp_err_t iot_light_breath_write(light_handle_t light_handle, uint8_t channel_id
{ {
light_t* light = (light_t*)light_handle; light_t* light = (light_t*)light_handle;
POINT_ASSERT(TAG, light_handle); POINT_ASSERT(TAG, light_handle);
IOT_CHECK(TAG, channel_id < light->channel_num, ESP_FAIL); IOT_CHECK(TAG, channel_id < light->channel_num, FAIL);
POINT_ASSERT(TAG, light->channel_group[channel_id]); POINT_ASSERT(TAG, light->channel_group[channel_id]);
light_channel_t* l_chn = light->channel_group[channel_id]; light_channel_t* l_chn = light->channel_group[channel_id];
if (l_chn->breath_period != breath_period_ms) { if (l_chn->breath_period != breath_period_ms) {

View file

@ -1,3 +1,2 @@
idf_component_register(SRCS "iot_servo.c" idf_component_register(SRCS "iot_servo.c"
INCLUDE_DIRS include INCLUDE_DIRS include)
REQUIRES driver)

View file

@ -1,3 +1,3 @@
idf_component_register(SRCS "sht3x.c" idf_component_register(SRCS "sht3x.c"
INCLUDE_DIRS include INCLUDE_DIRS include
REQUIRES bus esp_timer) REQUIRES bus)

View file

@ -17,7 +17,6 @@
#include "i2c_bus.h" #include "i2c_bus.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_system.h" #include "esp_system.h"
#include "esp_timer.h"
#include "sht3x.h" #include "sht3x.h"
typedef struct { typedef struct {

View file

@ -20,6 +20,7 @@
#include "esp_log.h" #include "esp_log.h"
#include "mpu6050.h" #include "mpu6050.h"
static const char *TAG = "MPU6050";
#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */ #define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */ #define READ_BIT I2C_MASTER_READ /*!< I2C master read */
@ -329,7 +330,6 @@ esp_err_t mpu6050_complimentory_filter(mpu6050_handle_t sensor, mpu6050_acce_val
/***sensors hal interface****/ /***sensors hal interface****/
#ifdef CONFIG_SENSOR_IMU_INCLUDED_MPU6050 #ifdef CONFIG_SENSOR_IMU_INCLUDED_MPU6050
static const char *TAG = "MPU6050";
static mpu6050_handle_t mpu6050 = NULL; static mpu6050_handle_t mpu6050 = NULL;
static bool is_init = false; static bool is_init = false;

View file

@ -9,4 +9,4 @@ list(APPEND requires bh1750 veml6040 veml6075)
idf_component_register(SRC_DIRS "." "hal" idf_component_register(SRC_DIRS "." "hal"
INCLUDE_DIRS "include" INCLUDE_DIRS "include"
REQUIRES "${requires}" "esp_timer") REQUIRES "${requires}")

View file

@ -16,7 +16,6 @@
#include <sys/queue.h> #include <sys/queue.h>
#include "esp_log.h" #include "esp_log.h"
#include "iot_sensor_hub.h" #include "iot_sensor_hub.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"

View file

@ -0,0 +1,3 @@
idf_component_register(SRC_DIRS "."
INCLUDE_DIRS "include" "${IDF_PATH}/components/usb/private_include"
REQUIRES usb)

View file

@ -0,0 +1,53 @@
menu "USB Host CDC"
config CDC_GET_DEVICE_DESC
bool "Get device descriptor during emum"
default y
config CDC_GET_CONFIG_DESC
bool "Get config descriptor during emum"
default y
config CDC_SEND_DTE_ACTIVE
bool "Set control line state during init"
default y
config USB_TASK_CORE_ID
int "usb task core_id"
default 0
range 0 0 if IDF_TARGET_ESP32S2
range 0 1 if IDF_TARGET_ESP32S3
help
pin usb task to specified core
config USB_TASK_BASE_PRIORITY
int "usb task base priority"
default 5
help
usb task base priority, usb task = base + 2, cdc task = base + 1
config CTRL_TRANSFER_DATA_MAX_BYTES
int "Max control transfer data size (Bytes)"
range 64 2048
default 256
config CDC_BULK_IN_URB_NUM
int "cdc bulk_in urb num"
default 2
help
bulk in urb numbers, increase this to handle heavy traffic
config CDC_BULK_OUT_URB_NUM
int "cdc bulk_out urb num"
default 2
help
bulk out urb numbers, increase this to handle heavy traffic
config CDC_BULK_IN_URB_BUFFER_SIZE
int "cdc bulk_in urb buffer size"
default 512
help
buffer size of each bulk in urb, should be multiple of endpoint mps
config CDC_BULK_OUT_URB_BUFFER_SIZE
int "cdc bulk_out urb buffer size"
default 512
help
buffer size of each bulk out urb
config CDC_USE_TRACE_FACILITY
bool "Trace internal memory status"
default n
help
set to trace internal buffer usage for debug
endmenu

View file

@ -0,0 +1,41 @@
* [中文版本](./README_cn.md)
## USB Host CDC
This component implements a simple version of the USB CDC host function. It only retains the default control endpoint and two bulk transfer endpoints, which streamlines the enumeration logic of the USB host. Users only need to bind the USB CDC device endpoint address to achieve fast Initialization. The component is suitable for the CDC-like vendor classes that require high startup speed.
The design logic of the component API is similar to the [ESP-IDF UART driver](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/peripherals/uart.html) interface, which can directly replace the UART interface to realize the update of the original code from UART to USB.
## API Guide
1. Using `usbh_cdc_driver_install` to configure and start internal USB tasks, most importantly the CDC bulk endpoint addresses `bulk_in_ep_addr` and `bulk_out_ep_addr` is required to be specified for communication, and the tramsfer buffer memory size needs to be configured too. user is allowed to config descriptor detials too through `bulk_in_ep` and `bulk_out_ep`.
```
/* @brief install usbh cdc driver with bulk endpoint configs and size of internal ringbuffer*/
static usbh_cdc_config_t config = {
/* use default endpoint descriptor with user address */
.bulk_in_ep_addr = EXAMPLE_BULK_IN_EP_ADDR,
.bulk_out_ep_addr = EXAMPLE_BULK_OUT_EP_ADDR,
.rx_buffer_size = IN_RINGBUF_SIZE,
.tx_buffer_size = OUT_RINGBUF_SIZE,
.conn_callback = usb_connect_callback,
.disconn_callback = usb_disconnect_callback,
};
/* install USB host CDC driver */
usbh_cdc_driver_install(&config);
/* Waitting for USB device connected */
usbh_cdc_wait_connect(portMAX_DELAY);
```
2. After the driver initialization, the internal state machine will automatically handle the hot plug of the USB, and user can also configure the hot plug related callback function `conn_callback` `disconn_callback`.
3. `usbh_cdc_wait_connect` can be used to block task until USB CDC Device is connected or timeout.
4. After successfully connected, the host will automatically receive USB data from CDC device to the internal `ringbuffer`, user can poll `usbh_cdc_get_buffered_data_len` to read buffered data size or register a receive callback to get notified when data is ready. Then `usbh_cdc_read_bytes` can be used to read buffered data out.
5. `usbh_cdc_write_bytes` can be used to send data to USB Device. The data is first written to the internal transmit `ringbuffer`then will be sent out during USB bus free.
6. `usbh_cdc_driver_delete` can uninstall the USB driver completely to release all resources.
## Examples
* [usb host cdc basic example](../../../examples/usb/host/usb_cdc_basic)
* [usb host cdc 4G modem](../../../examples/usb/host/usb_cdc_4g_module)

View file

@ -0,0 +1,41 @@
* [English version](./README.md)
## USB Host CDC
该组件实现了简易版本的 USB CDC 主机功能,仅保留了默认控制传输端点和 2 个批量传输端点,精简了 USB 主机的枚举逻辑,用户只需绑定 USB CDC 设备端点地址即可实现快速的初始化,适用于对启动速度要求较高的自定义类设备。
该组件 API 的设计逻辑与 [ESP-IDF UART 驱动](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/peripherals/uart.html)接口类似,可直接替换 UART 接口,实现原有代码 UART-> USB 的更新。
## API 使用说明
1. 使用 `usbh_cdc_driver_install` 来配置和启动内部 USB 任务,最重要的是需要指定 CDC 批量端点地址 `bulk_in_ep_addr``bulk_out_ep_addr` 用于通信,并且还需要配置 tramsfer 缓冲区内存大小。 用户也可以通过 `bulk_in_ep``bulk_out_ep` 配置整个描述符详细信息。
```
/* @brief install usbh cdc driver with bulk endpoint configs and size of internal ringbuffer*/
static usbh_cdc_config_t config = {
/* use default endpoint descriptor with user address */
.bulk_in_ep_addr = EXAMPLE_BULK_IN_EP_ADDR,
.bulk_out_ep_addr = EXAMPLE_BULK_OUT_EP_ADDR,
.rx_buffer_size = IN_RINGBUF_SIZE,
.tx_buffer_size = OUT_RINGBUF_SIZE,
.conn_callback = usb_connect_callback,
.disconn_callback = usb_disconnect_callback,
};
/* install USB host CDC driver */
usbh_cdc_driver_install(&config);
/* Waitting for USB device connected */
usbh_cdc_wait_connect(portMAX_DELAY);
```
2. 初始化成功以后,内部状态机会自动处理 USB 的热插拔,用户也可以在初始化时配置热插拔相关回调函数 `conn_callback``disconn_callback`
3. `usbh_cdc_wait_connect` 可用于阻塞任务,直到 USB CDC 设备连接或超时。
4. 连接成功后,主机会自动从 CDC 设备接收 USB 数据到内部 `ringbuffer`,用户可以轮询`usbh_cdc_get_buffered_data_len` 来读取缓存数据的大小或注册接收回调以在数据准备好时得到通知。然后可以使用 `usbh_cdc_read_bytes` 来读取缓冲的数据。
5. `usbh_cdc_write_bytes` 可用于向 USB 设备发送数据。 数据首先写入内部 `ringbuffer`,然后在 USB 总线空闲时发送出去。
5、`usbh_cdc_driver_delete` 可以完全卸载 USB 驱动,释放所有资源。
## Examples
* [CDC 基础功能示例](../../../examples/usb/host/usb_cdc_basic)
* [CDC 4G 上网](../../../examples/usb/host/usb_cdc_4g_module)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,113 @@
// Copyright 2019-2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "stdio.h"
#include "freertos/FreeRTOS.h"
#include "esp_err.h"
#include "hal/usbh_ll.h"
#include "hcd.h"
/**
* @brief USB receive callback type
*/
typedef void(*usbh_cdc_cb_t)(void *arg);
/**
* @brief USB host CDC configuration type, callbacks should not in block state
*/
typedef struct usbh_cdc_config{
uint8_t bulk_in_ep_addr; /*!< USB CDC bulk in endpoint address, will be overwritten if bulk_in_ep is specified */
uint8_t bulk_out_ep_addr; /*!< USB CDC bulk out endpoint address, will be overwritten if bulk_out_ep is specified */
int rx_buffer_size; /*!< USB receive/in ringbuffer size */
int tx_buffer_size; /*!< USB transport/out ringbuffer size */
usb_ep_desc_t *bulk_in_ep; /*!< USB CDC bulk in endpoint descriptor, set NULL if using default param */
usb_ep_desc_t *bulk_out_ep; /*!< USB CDC bulk out endpoint descriptor, set NULL if using default param */
usbh_cdc_cb_t conn_callback; /*!< USB connect calllback, set NULL if not use */
usbh_cdc_cb_t disconn_callback; /*!< USB disconnect calllback, usb cdc driver reset to connect waitting after disconnect, set NULL if not use */
usbh_cdc_cb_t rx_callback; /*!< packet receive callback, set NULL if not use */
void *conn_callback_arg; /*!< USB connect calllback args, set NULL if not use */
void *disconn_callback_arg; /*!< USB disconnect calllback args, set NULL if not use */
void *rx_callback_arg; /*!< packet receive callback args, set NULL if not use */
}usbh_cdc_config_t;
/**
* @brief Install USB CDC driver.
*
* @param config USB Host CDC configs
* @return
* ESP_ERR_INVALID_STATE driver has been installed
* ESP_ERR_INVALID_ARG args not supported
* ESP_FAIL driver install failed
* ESP_OK driver install succeed
*/
esp_err_t usbh_cdc_driver_install(const usbh_cdc_config_t *config);
/**
* @brief Uninstall USB driver.
*
* @return
* ESP_ERR_INVALID_STATE driver not installed
* ESP_OK start succeed
*/
esp_err_t usbh_cdc_driver_delete(void);
/**
* @brief Waitting until CDC device connect
*
* @param ticks_to_wait Wait timeout value, count in RTOS ticks
* @return
* ESP_ERR_INVALID_STATE driver not installed
* ESP_ERR_TIMEOUT wait timeout
* ESP_OK device connect succeed
*/
esp_err_t usbh_cdc_wait_connect(TickType_t ticks_to_wait);
/**
* @brief Send data to connected USB device from a given buffer and length,
* this function will return after copying all the data to tx ring buffer.
*
* @param buf data buffer address
* @param length data length to send
* @return int The number of bytes pushed to the tx buffer
*/
int usbh_cdc_write_bytes(const uint8_t *buf, size_t length);
/**
* @brief Get USB receive ring buffer cached data length.
*
* @param size
* @return
* ESP_ERR_INVALID_STATE cdc not configured, or not running
* ESP_ERR_INVALID_ARG args not supported
* ESP_FAIL start failed
* ESP_OK start succeed
*/
esp_err_t usbh_cdc_get_buffered_data_len(size_t *size);
/**
* @brief Read data bytes from USB receive/in buffer.
*
* @param buf data buffer address
* @param length data length to read
* @param ticks_to_wait sTimeout, count in RTOS ticks
* @return int The number of bytes read from USB FIFO
*/
int usbh_cdc_read_bytes(uint8_t *buf, size_t length, TickType_t ticks_to_wait);
/**
* @brief print internal memory usage for debug
* @return void
*/
void usbh_cdc_print_buffer_msg(void);

View file

@ -0,0 +1,2 @@
idf_component_register(SRC_DIRS "."
PRIV_REQUIRES cmock test_utils esp_usbh_cdc)

View file

@ -0,0 +1,96 @@
// Copyright 2019-2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "string.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "unity.h"
#include "test_utils.h"
#include "esp_usbh_cdc.h"
#include "esp_log.h"
#define IN_RINGBUF_SIZE (1024 * 1)
#define OUT_RINGBUF_SIZE (1024 * 1)
#define READ_TASK_KILL_BIT BIT1
#define TAG "host_cdc"
EventGroupHandle_t s_event_group_hdl = NULL;
static usb_ep_desc_t bulk_out_ep_desc = {
.bLength = sizeof(usb_ep_desc_t),
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = 0x01, //EP 1 OUT
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
.wMaxPacketSize = 64, //MPS of 64 bytes
.bInterval = 0,
};
static usb_ep_desc_t bulk_in_ep_desc = {
.bLength = sizeof(usb_ep_desc_t),
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = 0x81, //EP 2 IN
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
.wMaxPacketSize = 64, //MPS of 64 bytes
.bInterval = 0,
};
static void usb_read_task(void *param)
{
size_t data_len = 0;
uint8_t buf[256];
while (!(xEventGroupGetBits(s_event_group_hdl) & READ_TASK_KILL_BIT)) {
usbh_cdc_get_buffered_data_len(&data_len);
if (data_len == 0 || data_len > 256) {
vTaskDelay(1);
continue;
}
usbh_cdc_read_bytes(buf, data_len, 10);
ESP_LOGI(TAG, "RCV len=%d: %.*s", data_len, data_len, buf);
}
xEventGroupClearBits(s_event_group_hdl, READ_TASK_KILL_BIT);
ESP_LOGW(TAG, "CDC read task deleted");
vTaskDelete(NULL);
}
TEST_CASE("usb cdc R/W", "[esp_usbh_cdc]")
{
s_event_group_hdl = xEventGroupCreate();
TEST_ASSERT(s_event_group_hdl);
static usbh_cdc_config_t config = {
.bulk_in_ep = &bulk_in_ep_desc,
.bulk_out_ep = &bulk_out_ep_desc,
.rx_buffer_size = IN_RINGBUF_SIZE,
.tx_buffer_size = OUT_RINGBUF_SIZE,
};
TEST_ASSERT_EQUAL(ESP_OK, usbh_cdc_driver_install(&config));
/* Waitting for USB device connected */
TEST_ASSERT_EQUAL(ESP_OK, usbh_cdc_wait_connect(portMAX_DELAY));
xTaskCreate(usb_read_task, "usb_read", 4096, NULL, 2, NULL);
uint8_t buff[] = "AT\r\n";
uint8_t loop_num = 40;
while (--loop_num) {
int len = usbh_cdc_write_bytes(buff, 4);
ESP_LOGI(TAG, "Send len=%d: %s", len, buff);
vTaskDelay(pdMS_TO_TICKS(500));
}
xEventGroupSetBits(s_event_group_hdl, READ_TASK_KILL_BIT);
ESP_LOGW(TAG, "Waiting CDC read task delete");
while (xEventGroupGetBits(s_event_group_hdl) & READ_TASK_KILL_BIT) {
vTaskDelay(10 / portTICK_PERIOD_MS);
}
vEventGroupDelete(s_event_group_hdl);
TEST_ASSERT_EQUAL(ESP_OK, usbh_cdc_driver_delete());
}

View file

@ -0,0 +1,126 @@
idf_build_get_property(target IDF_TARGET)
set(srcs)
set(includes_public)
set(includes_private)
set(compile_options)
if(CONFIG_TINYUSB)
if(target STREQUAL "esp32s3")
set(tusb_mcu "OPT_MCU_ESP32S3")
set(tusb_family "esp32sx")
elseif(target STREQUAL "esp32s2")
set(tusb_mcu "OPT_MCU_ESP32S2")
set(tusb_family "esp32sx")
else()
# CONFIG_TINYUSB dependency has been garanteed by Kconfig logic,
# So it's not possible that cmake goes here
message(FATAL_ERROR "TinyUSB is not support on ${target}.")
return()
endif()
list(APPEND compile_options
"-DCFG_TUSB_MCU=${tusb_mcu}"
"-DCFG_TUSB_DEBUG=${CONFIG_TINYUSB_DEBUG_LEVEL}"
)
idf_component_get_property(freertos_component_dir freertos COMPONENT_DIR)
list(APPEND includes_private
"${IDF_PATH}/components/tinyusb/tinyusb/hw/bsp/"
"${IDF_PATH}/components/tinyusb/tinyusb/src/"
"${IDF_PATH}/components/tinyusb/tinyusb/src/device"
"${IDF_PATH}/components/tinyusb/tinyusb/src/class/bth"
#"additions/include_private"
)
list(APPEND includes_public
"${IDF_PATH}/components/tinyusb/tinyusb/src/"
"additions/include"
"additions/include_private"
"additions/tusb/src/lib/networking"
"additions/tusb/src/class/dfu"
"additions/tusb/src/class/vendor"
# The FreeRTOS API include convention in tinyusb is different from esp-idf
"${freertos_component_dir}/include/freertos"
)
list(APPEND srcs
"${IDF_PATH}/components/tinyusb/tinyusb/src/portable/espressif/${tusb_family}/dcd_${tusb_family}.c"
"${IDF_PATH}/components/tinyusb/tinyusb/src/class/cdc/cdc_device.c"
"${IDF_PATH}/components/tinyusb/tinyusb/src/class/hid/hid_device.c"
"${IDF_PATH}/components/tinyusb/tinyusb/src/class/midi/midi_device.c"
"${IDF_PATH}/components/tinyusb/tinyusb/src/class/msc/msc_device.c"
"${IDF_PATH}/components/tinyusb/tinyusb/src/class/vendor/vendor_device.c"
"${IDF_PATH}/components/tinyusb/tinyusb/src/common/tusb_fifo.c"
"${IDF_PATH}/components/tinyusb/tinyusb/src/device/usbd_control.c"
"${IDF_PATH}/components/tinyusb/tinyusb/src/tusb.c"
#"${IDF_PATH}/components/tinyusb/tinyusb/src/device/usbd.c"
#"${IDF_PATH}/components/tinyusb/additions/src/descriptors_control.c"
#"${IDF_PATH}/components/tinyusb/additions/src/tinyusb.c"
#"${IDF_PATH}/components/tinyusb/additions/src/tusb_tasks.c"
#"${IDF_PATH}/components/tinyusb/additions/src/usb_descriptors.c"
"additions/src/usbd.c"
"additions/src/descriptors_control.c"
"additions/src/tinyusb.c"
"additions/src/tusb_tasks.c"
"additions/src/usb_descriptors.c"
)
# when no builtin class driver is enabled, an uint8_t data compared with `BUILTIN_DRIVER_COUNT` will always be false
set_source_files_properties("tinyusb/src/device/usbd.c" PROPERTIES COMPILE_FLAGS "-Wno-type-limits")
if(CONFIG_TINYUSB_CDCACM_ENABLED)
list(APPEND srcs
"additions/src/cdc.c"
"additions/src/tusb_cdc_acm.c"
"additions/src/tusb_console.c"
"additions/src/vfs_tinyusb.c"
)
endif() # CONFIG_TINYUSB_CDCACM_ENABLED
if(CONFIG_TINYUSB_HID_ENABLED)
list(APPEND srcs
"additions/src/tusb_hid.c")
endif()
if(CONFIG_TINYUSB_MSC_ENABLED)
list(APPEND srcs
"additions/src/tusb_msc.c")
endif()
if(CONFIG_TINYUSB_NET_ENABLED)
list(APPEND srcs
"additions/src/tusb_net.c"
"additions/tusb/src/class/net/net_device.c"
"additions/tusb/src/lib/networking/rndis_reports.c")
endif()
if(CONFIG_TINYUSB_BTH_ENABLED)
list(APPEND srcs
"additions/src/tusb_bth.c"
"${IDF_PATH}/components/tinyusb/tinyusb/src/class/bth/bth_device.c")
endif()
if(CONFIG_TINYUSB_DFU_ENABLED)
list(APPEND srcs
"additions/src/tusb_dfu.c"
"additions/tusb/src/class/dfu/dfu_device.c")
endif()
if(CONFIG_TINYUSB_WEBUSB_ENABLED)
list(APPEND srcs
"additions/src/tusb_webusb.c"
"additions/tusb/src/class/vendor/vendor_device.c")
endif()
endif() # CONFIG_TINYUSB
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS ${includes_public}
PRIV_INCLUDE_DIRS ${includes_private}
PRIV_REQUIRES "vfs" "fatfs" "bt" "app_update"
)
if(CONFIG_TINYUSB)
target_compile_options(${COMPONENT_LIB} PRIVATE ${compile_options})
endif()

View file

@ -0,0 +1,273 @@
menu "TinyUSB Stack"
visible if USB_OTG_SUPPORTED
config TINYUSB
bool "Use TinyUSB Stack"
depends on USB_OTG_SUPPORTED
default n
help
Enable TinyUSB stack support.
Note that, esp-idf only uses the device stack provided by TinyUSB.
if TINYUSB
config TINYUSB_DEBUG_LEVEL
int "TinyUSB log level (0-3)"
default 0
range 0 3
help
Specify verbosity of TinyUSB log output.
menu "TinyUSB task configuration"
config TINYUSB_NO_DEFAULT_TASK
bool "Do not create a TinyUSB task"
default n
help
This option allows to not create the FreeRTOS task during the driver initialization.
User will have to handle TinyUSB events manually.
config TINYUSB_TASK_PRIORITY
int "TinyUSB task priority"
default 5
depends on !TINYUSB_NO_DEFAULT_TASK
help
Set the priority of the default TinyUSB main task.
config TINYUSB_TASK_STACK_SIZE
int "TinyUSB task stack size (bytes)"
default 4096
depends on !TINYUSB_NO_DEFAULT_TASK
help
Set the stack size of the default TinyUSB main task.
endmenu
menu "Descriptor configuration"
config TINYUSB_DESC_USE_ESPRESSIF_VID
bool "VID: Use Espressif's vendor ID"
default y
help
Enable this option, USB device will use Espressif's vendor ID as its VID.
This is helpful at product develop stage.
config TINYUSB_DESC_CUSTOM_VID
hex "VID: Custom vendor ID"
default 0x1234
depends on !TINYUSB_DESC_USE_ESPRESSIF_VID
help
Custom Vendor ID.
config TINYUSB_DESC_USE_DEFAULT_PID
bool "PID: Use a default PID assigned to TinyUSB"
default y
help
Default TinyUSB PID assigning uses values 0x4000...0x4007.
config TINYUSB_DESC_CUSTOM_PID
hex "PID: Custom product ID"
default 0x5678
depends on !TINYUSB_DESC_USE_DEFAULT_PID
help
Custom Product ID.
config TINYUSB_DESC_BCD_DEVICE
hex "bcdDevice"
default 0x0100
help
Version of the firmware of the USB device.
config TINYUSB_DESC_MANUFACTURER_STRING
string "Manufacturer name"
default "Espressif Systems"
help
Name of the manufacturer of the USB device.
config TINYUSB_DESC_PRODUCT_STRING
string "Product name"
default "Espressif Device"
help
Name of the USB device.
config TINYUSB_DESC_SERIAL_STRING
string "Serial string"
default "123456"
help
Serial number of the USB device.
config TINYUSB_DESC_CDC_STRING
depends on TINYUSB_CDC_ENABLED
string "CDC Device String"
default "Espressif CDC Device"
help
Name of the CDC device.
config TINYUSB_DESC_MSC_STRING
depends on TINYUSB_MSC_ENABLED
string "MSC Device String"
default "Espressif MSC Device"
help
Name of the MSC device.
config TINYUSB_DESC_HID_STRING
depends on TINYUSB_HID_ENABLED
string "HID Device String"
default "Espressif HID Device"
help
Name of the HID device
config TINYUSB_DESC_NET_STRING
depends on TINYUSB_NET_ENABLED
string "NET Device String"
default "Espressif NET Device"
help
Name of the NET device.
config TINYUSB_DESC_BTH_STRING
depends on TINYUSB_BTH_ENABLED
string "BTH String"
default "Espressif BTH Device"
help
Name of the BTH device.
endmenu # "Descriptor configuration"
menu "Massive Storage Class (MSC)"
config TINYUSB_MSC_ENABLED
bool "Enable TinyUSB MSC feature"
default n
help
Enable TinyUSB MSC feature.
config TINYUSB_MSC_BUFSIZE
depends on TINYUSB_MSC_ENABLED
int "MSC FIFO size"
default 512
help
MSC FIFO size, in bytes.
endmenu # "Massive Storage Class"
menu "Communication Device Class (CDC)"
config TINYUSB_CDC_ENABLED
bool "Enable TinyUSB CDC feature"
default n
help
Enable TinyUSB CDC feature.
config TINYUSB_CDC_RX_BUFSIZE
depends on TINYUSB_CDC_ENABLED
int "CDC FIFO size of RX channel"
default 64
help
CDC FIFO size of RX channel.
config TINYUSB_CDC_TX_BUFSIZE
depends on TINYUSB_CDC_ENABLED
int "CDC FIFO size of TX channel"
default 64
help
CDC FIFO size of TX channel.
menu "Abstract Control Model (ACM)"
depends on TINYUSB_CDC_ENABLED
config TINYUSB_CDCACM_ENABLED
bool "Enable TinyUSB CDC-ACM feature"
default n
help
Enable TinyUSB CDC-ACM feature.
config TINYUSB_CDC_PORT_NUM
depends on TINYUSB_CDCACM_ENABLED
int "Number of Serial (CDC) Port"
default 1
range 1 2
help
Number of Serial (CDC) Port.
endmenu # "Abstract Control Model"
endmenu # "Communication Device Class"
menu "WebUSB"
config TINYUSB_WEBUSB_ENABLED
bool "Enable TinyUSB WebUSB feature"
default n
help
Enable TinyUSB WebUSB feature.
endmenu # "WebUSB"
menu "Human Interface Device Class (HID)"
config TINYUSB_HID_ENABLED
bool "Enable TinyUSB HID feature"
default n
help
Enable TinyUSB HID feature.
config TINYUSB_HID_BUFSIZE
int "HID FIFO size"
default 64
depends on TINYUSB_HID_ENABLED
help
HID FIFO size
endmenu # "Human Interface Device Class"
menu "USB Network Class (RNDIS, ECM)"
config TINYUSB_NET_ENABLED
bool "Enable TinyUSB NET driver"
default n
help
Enable USB NET TinyUSB driver.
config TINYUSB_RNDIS_VENDOR
string "USB Vendor"
default "Espressif Incorporated"
depends on TINYUSB_NET_ENABLED
help
Vendor description.
choice TINYUSB_NET
prompt "Choose a network communication standard"
default TINYUSB_NET_RNDIS
depends on TINYUSB_NET_ENABLED
help
RNDIS and CDC-ECM
- Windows only works with RNDIS
- MacOS only works with CDC-ECM
- Linux will work on both
config TINYUSB_NET_RNDIS
bool "RNDIS"
help
RNDIS.
config TINYUSB_NET_ECM
bool "CDC-ECM"
help
CDC-ECM.
endchoice
endmenu # "usb network"
menu "Bluetooth Host Class (BTH)"
config TINYUSB_BTH_ENABLED
bool "Enable TinyUSB BTH feature"
default n
help
Enable TinyUSB BTH feature.
config TINYUSB_BTH_ISO_ALT_COUNT
depends on TINYUSB_BTH_ENABLED
int "BTH ISO ALT COUNT"
default 0
help
BTH ISO ALT COUNT.
endmenu # "Bluetooth Host Device Class"
menu "Firmware Upgrade Class (DFU)"
config TINYUSB_DFU_ENABLED
bool "Enable TinyUSB DFU feature"
default n
help
Enable TinyUSB DFU feature.
config TINYUSB_DFU_BUFSIZE
depends on TINYUSB_DFU_ENABLED
int "DFU XFER BUFFSIZE"
default 512
help
DFU XFER BUFFSIZE.
endmenu # "Firmware Upgrade Class"
endif # TINYUSB
endmenu # "TinyUSB Stack"

View file

@ -0,0 +1,103 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdbool.h>
#include "tusb.h"
#include "tusb_option.h"
#include "tusb_config.h"
#include "tinyusb_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* tinyusb uses buffers with type of uint8_t[] but in our driver we are reading them as a 32-bit word */
#if (CFG_TUD_ENDPOINT0_SIZE < 4)
# define CFG_TUD_ENDPOINT0_SIZE 4
# warning "CFG_TUD_ENDPOINT0_SIZE was too low and was set to 4"
#endif
#if TUSB_OPT_DEVICE_ENABLED
# if CFG_TUD_HID
# if (CFG_TUD_HID_BUFSIZE < 4)
# define CFG_TUD_HID_BUFSIZE 4
# warning "CFG_TUD_HID_BUFSIZE was too low and was set to 4"
# endif
# endif
# if CFG_TUD_CDC
# if (CFG_TUD_CDC_EP_BUFSIZE < 4)
# define CFG_TUD_CDC_EP_BUFSIZE 4
# warning "CFG_TUD_CDC_EP_BUFSIZE was too low and was set to 4"
# endif
# endif
# if CFG_TUD_MSC
# if (CFG_TUD_MSC_BUFSIZE < 4)
# define CFG_TUD_MSC_BUFSIZE 4
# warning "CFG_TUD_MSC_BUFSIZE was too low and was set to 4"
# endif
# endif
# if CFG_TUD_MIDI
# if (CFG_TUD_MIDI_EPSIZE < 4)
# define CFG_TUD_MIDI_EPSIZE 4
# warning "CFG_TUD_MIDI_EPSIZE was too low and was set to 4"
# endif
# endif
# if CFG_TUD_CUSTOM_CLASS
# warning "Please check that the buffer is more then 4 bytes"
# endif
#endif
/**
* @brief Configuration structure of the tinyUSB core
*/
typedef struct {
tusb_desc_device_t *descriptor; /*!< Pointer to a device descriptor */
const char **string_descriptor; /*!< Pointer to an array of string descriptors */
const uint8_t *config_descriptor; /*!< Pointer to config descriptors */
bool external_phy; /*!< Should USB use an external PHY */
} tinyusb_config_t;
/**
* @brief This is an all-in-one helper function, including:
* 1. USB device driver initialization
* 2. Descriptors preparation
* 3. TinyUSB stack initialization
* 4. Creates and start a task to handle usb events
*
* @note Don't change Custom descriptor, but if it has to be done,
* Suggest to define as follows in order to match the Interface Association Descriptor (IAD):
* bDeviceClass = TUSB_CLASS_MISC,
* bDeviceSubClass = MISC_SUBCLASS_COMMON,
*
* @param config tinyusb stack specific configuration
* @retval ESP_ERR_INVALID_ARG Install driver and tinyusb stack failed because of invalid argument
* @retval ESP_FAIL Install driver and tinyusb stack failed because of internal error
* @retval ESP_OK Install driver and tinyusb stack successfully
*/
esp_err_t tinyusb_driver_install(const tinyusb_config_t *config);
// TODO esp_err_t tinyusb_driver_uninstall(void); (IDF-1474)
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,32 @@
// Copyright 2020 Espressif Systems (Shanghai) Co. Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define USB_ESPRESSIF_VID 0x303A
#define USB_STRING_DESCRIPTOR_ARRAY_SIZE 7
typedef enum{
TINYUSB_USBDEV_0,
} tinyusb_usbdev_t;
typedef const char *tusb_desc_strarray_device_t[USB_STRING_DESCRIPTOR_ARRAY_SIZE];
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,39 @@
/**
* @copyright Copyright 2021 Espressif Systems (Shanghai) Co. Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "esp_err.h"
#include "tinyusb.h"
/* HCI message type definitions (for H4 messages) */
#define HCIT_TYPE_COMMAND 1
#define HCIT_TYPE_ACL_DATA 2
#define HCIT_TYPE_SCO_DATA 3
#define HCIT_TYPE_EVENT 4
/**
* @brief Initialize BTH Device.
*/
void tusb_bth_init(void);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,204 @@
// Copyright 2020 Espressif Systems (Shanghai) Co. Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/ringbuf.h"
#include "freertos/semphr.h"
#include "freertos/timers.h"
#include "tusb.h"
#include "tinyusb.h"
/**
* @brief CDC ports available to setup
*/
typedef enum{
TINYUSB_CDC_ACM_0 = 0x0,
TINYUSB_CDC_ACM_1,
TINYUSB_CDC_TOTAL
}tinyusb_cdcacm_itf_t;
/* Callbacks and events
********************************************************************* */
/**
* @brief Data provided to the input of the `callback_rx_wanted_char` callback
*/
typedef struct {
char wanted_char; /*!< Wanted character */
} cdcacm_event_rx_wanted_char_data_t;
/**
* @brief Data provided to the input of the `callback_line_state_changed` callback
*/
typedef struct {
bool dtr; /*!< Data Terminal Ready (DTR) line state */
bool rts; /*!< Request To Send (RTS) line state */
} cdcacm_event_line_state_changed_data_t;
/**
* @brief Data provided to the input of the `line_coding_changed` callback
*/
typedef struct {
cdc_line_coding_t const *p_line_coding; /*!< New line coding value */
} cdcacm_event_line_coding_changed_data_t;
/**
* @brief Types of CDC ACM events
*/
typedef enum {
CDC_EVENT_RX,
CDC_EVENT_RX_WANTED_CHAR,
CDC_EVENT_LINE_STATE_CHANGED,
CDC_EVENT_LINE_CODING_CHANGED
} cdcacm_event_type_t;
/**
* @brief Describes an event passing to the input of a callbacks
*/
typedef struct {
cdcacm_event_type_t type; /*!< Event type */
union {
cdcacm_event_rx_wanted_char_data_t rx_wanted_char_data; /*!< Data input of the `callback_rx_wanted_char` callback */
cdcacm_event_line_state_changed_data_t line_state_changed_data; /*!< Data input of the `callback_line_state_changed` callback */
cdcacm_event_line_coding_changed_data_t line_coding_changed_data; /*!< Data input of the `line_coding_changed` callback */
};
} cdcacm_event_t;
/**
* @brief CDC-ACM callback type
*/
typedef void(*tusb_cdcacm_callback_t)(int itf, cdcacm_event_t *event);
/*********************************************************************** Callbacks and events*/
/* Other structs
********************************************************************* */
/**
* @brief Configuration structure for CDC-ACM
*/
typedef struct {
tinyusb_usbdev_t usb_dev; /*!< Usb device to set up */
tinyusb_cdcacm_itf_t cdc_port; /*!< CDC port */
size_t rx_unread_buf_sz; /*!< Amount of data that can be passed to the AMC at once */
tusb_cdcacm_callback_t callback_rx; /*!< Pointer to the function with the `tusb_cdcacm_callback_t` type that will be handled as a callback */
tusb_cdcacm_callback_t callback_rx_wanted_char; /*!< Pointer to the function with the `tusb_cdcacm_callback_t` type that will be handled as a callback */
tusb_cdcacm_callback_t callback_line_state_changed; /*!< Pointer to the function with the `tusb_cdcacm_callback_t` type that will be handled as a callback */
tusb_cdcacm_callback_t callback_line_coding_changed; /*!< Pointer to the function with the `tusb_cdcacm_callback_t` type that will be handled as a callback */
} tinyusb_config_cdcacm_t;
/*********************************************************************** Other structs*/
/* Public functions
********************************************************************* */
/**
* @brief Initialize CDC ACM. Initialization will be finished with
* the `tud_cdc_line_state_cb` callback
*
* @param cfg - init configuration structure
* @return esp_err_t
*/
esp_err_t tusb_cdc_acm_init(const tinyusb_config_cdcacm_t *cfg);
/**
* @brief Register a callback invoking on CDC event. If the callback had been
* already registered, it will be overwritten
*
* @param itf - number of a CDC object
* @param event_type - type of registered event for a callback
* @param callback - callback function
* @return esp_err_t - ESP_OK or ESP_ERR_INVALID_ARG
*/
esp_err_t tinyusb_cdcacm_register_callback(tinyusb_cdcacm_itf_t itf,
cdcacm_event_type_t event_type,
tusb_cdcacm_callback_t callback);
/**
* @brief Unregister a callback invoking on CDC event.
*
* @param itf - number of a CDC object
* @param event_type - type of registered event for a callback
* @return esp_err_t - ESP_OK or ESP_ERR_INVALID_ARG
*/
esp_err_t tinyusb_cdcacm_unregister_callback(tinyusb_cdcacm_itf_t itf, cdcacm_event_type_t event_type);
/**
* @brief Sent one character to a write buffer
*
* @param itf - number of a CDC object
* @param ch - character to send
* @return size_t - amount of queued bytes
*/
size_t tinyusb_cdcacm_write_queue_char(tinyusb_cdcacm_itf_t itf, char ch);
/**
* @brief Write data to write buffer from a byte array
*
* @param itf - number of a CDC object
* @param in_buf - a source array
* @param in_size - size to write from arr_src
* @return size_t - amount of queued bytes
*/
size_t tinyusb_cdcacm_write_queue(tinyusb_cdcacm_itf_t itf, uint8_t *in_buf, size_t in_size);
/**
* @brief Send all data from a write buffer. Use `tinyusb_cdcacm_write_queue` to add data to the buffer.
*
* WARNING! TinyUSB can block output Endpoint for several RX callbacks, after will do additional flush
* after the each trasfer. That can leads to the situation when you requested a flush, but it will fail until
* ont of the next callbacks ends.
* SO USING OF THE FLUSH WITH TIMEOUTS IN CALLBACKS IS NOT RECOMENDED - YOU CAN GET A LOCK FOR THE TIMEOUT
*
* @param itf - number of a CDC object
* @param timeout_ticks - waiting until flush will be considered as failed
* @return esp_err_t - ESP_OK if (timeout_ticks > 0) and and flush was successful,
* ESP_ERR_TIMEOUT if timeout occurred3 or flush was successful with (timeout_ticks == 0)
* ESP_FAIL if flush was unsuccessful
*/
esp_err_t tinyusb_cdcacm_write_flush(tinyusb_cdcacm_itf_t itf, uint32_t timeout_ticks);
/**
* @brief Read a content to the array, and defines it's size to the sz_store
*
* @param itf - number of a CDC object
* @param out_buf - to this array will be stored the object from a CDC buffer
* @param out_buf_sz - size of buffer for results
* @param rx_data_size - to this address will be stored the object's size
* @return esp_err_t ESP_OK, ESP_FAIL or ESP_ERR_INVALID_STATE
*/
esp_err_t tinyusb_cdcacm_read(tinyusb_cdcacm_itf_t itf, uint8_t *out_buf, size_t out_buf_sz, size_t *rx_data_size);
/**
* @brief Check if the ACM initialized
*
* @param itf - number of a CDC object
* @return true or false
*/
bool tusb_cdc_acm_initialized(tinyusb_cdcacm_itf_t itf);
/*********************************************************************** Public functions*/
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,138 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org),
* Additions Copyright (c) 2020, Espressif Systems (Shanghai) PTE LTD
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#pragma once
#include <stdbool.h>
#include "tusb_option.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef CONFIG_TINYUSB_CDC_ENABLED
# define CONFIG_TINYUSB_CDC_ENABLED 0
#endif
#ifndef CONFIG_TINYUSB_CDCACM_ENABLED
# define CONFIG_TINYUSB_CDCACM_ENABLED 0
#endif
#ifndef CONFIG_TINYUSB_MSC_ENABLED
# define CONFIG_TINYUSB_MSC_ENABLED 0
#endif
#ifndef CONFIG_TINYUSB_HID_ENABLED
# define CONFIG_TINYUSB_HID_ENABLED 0
#endif
#ifndef CONFIG_TINYUSB_MIDI_ENABLED
# define CONFIG_TINYUSB_MIDI_ENABLED 0
#endif
#ifndef CONFIG_TINYUSB_CUSTOM_CLASS_ENABLED
# define CONFIG_TINYUSB_CUSTOM_CLASS_ENABLED 0
#endif
#ifndef CONFIG_TINYUSB_NET_ENABLED
# define CONFIG_TINYUSB_NET_ENABLED 0
#endif
#ifndef CONFIG_TINYUSB_WEBUSB_ENABLED
# define CONFIG_TINYUSB_WEBUSB_ENABLED 0
#endif
#ifndef CONFIG_TINYUSB_BTH_ENABLED
# define CONFIG_TINYUSB_BTH_ENABLED 0
# define CONFIG_TINYUSB_BTH_ISO_ALT_COUNT 0
#endif
#ifndef CONFIG_TINYUSB_DFU_ENABLED
# define CONFIG_TINYUSB_DFU_ENABLED 0
# define CONFIG_TINYUSB_DFU_BUFSIZE 512
#endif
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE | OPT_MODE_FULL_SPEED
#define CFG_TUSB_OS OPT_OS_FREERTOS
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
* Tinyusb use follows macros to declare transferring memory so that they can be put
* into those specific section.
* e.g
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
*/
#ifndef CFG_TUSB_MEM_SECTION
# define CFG_TUSB_MEM_SECTION
#endif
#ifndef CFG_TUSB_MEM_ALIGN
# define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4)
#endif
#ifndef CFG_TUD_ENDPOINT0_SIZE
#define CFG_TUD_ENDPOINT0_SIZE 64
#endif
// CDC FIFO size of TX and RX
#define CFG_TUD_CDC_RX_BUFSIZE CONFIG_TINYUSB_CDC_RX_BUFSIZE
#define CFG_TUD_CDC_TX_BUFSIZE CONFIG_TINYUSB_CDC_TX_BUFSIZE
// Vendor FIFO size of TX and RX
// If not configured vendor endpoints will not be buffered
#define CFG_TUD_VENDOR_RX_BUFSIZE 64
#define CFG_TUD_VENDOR_TX_BUFSIZE 64
// MSC Buffer size of Device Mass storage
#define CFG_TUD_MSC_BUFSIZE CONFIG_TINYUSB_MSC_BUFSIZE
// HID buffer size Should be sufficient to hold ID (if any) + Data
#define CFG_TUD_HID_BUFSIZE CONFIG_TINYUSB_HID_BUFSIZE
// Number of BTH ISO alternatives
#define CFG_TUD_BTH_ISO_ALT_COUNT CONFIG_TINYUSB_BTH_ISO_ALT_COUNT
#define CFG_TUD_DFU_XFER_BUFSIZE CONFIG_TINYUSB_DFU_BUFSIZE
// Enabled device class driver
#define CFG_TUD_CDC CONFIG_TINYUSB_CDC_ENABLED
#define CFG_TUD_CDCACM CONFIG_TINYUSB_CDCACM_ENABLED
#define CFG_TUD_MSC CONFIG_TINYUSB_MSC_ENABLED
#define CFG_TUD_HID CONFIG_TINYUSB_HID_ENABLED
#define CFG_TUD_MIDI CONFIG_TINYUSB_MIDI_ENABLED
#define CFG_TUD_CUSTOM_CLASS CONFIG_TINYUSB_CUSTOM_CLASS_ENABLED
#define CFG_TUD_NET CONFIG_TINYUSB_NET_ENABLED
#define CFG_TUD_BTH CONFIG_TINYUSB_BTH_ENABLED
#define CFG_TUD_DFU CONFIG_TINYUSB_DFU_ENABLED
#define CFG_TUD_VENDOR CONFIG_TINYUSB_WEBUSB_ENABLED
/* TODO: will be removed if upstream feat: Add net xmit status cb for application can block to get it #1001*/
__attribute__((weak)) void tud_network_idle_status_change_cb(bool idle);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,41 @@
// Copyright 2020 Espressif Systems (Shanghai) Co. Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "esp_err.h"
/**
* @brief Redirect output to the USB serial
* @param cdc_intf - interface number of TinyUSB's CDC
*
* @return esp_err_t - ESP_OK, ESP_FAIL or an error code
*/
esp_err_t esp_tusb_init_console(int cdc_intf);
/**
* @brief Switch log to the default output
* @param cdc_intf - interface number of TinyUSB's CDC
*
* @return esp_err_t
*/
esp_err_t esp_tusb_deinit_console(int cdc_intf);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,239 @@
// Copyright 2020-2021 Espressif Systems (Shanghai) Co. Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "tusb.h"
#include "tinyusb.h"
/**
* @brief Report delta movement of mouse.
*
* @param x Current delta x movement of the mouse
* @param y Current delta y movement on the mouse
* @param vertical Current delta wheel movement on the mouse
* @param horizontal using AC Pan
*/
void tinyusb_hid_mouse_move_report(int8_t x, int8_t y, int8_t vertical, int8_t horizontal);
/**
* @brief Report button click in the mouse, using bitmap here.
* eg. MOUSE_BUTTON_LEFT | MOUSE_BUTTON_RIGHT, if click left and right button at same time.
*
* @param buttons hid mouse button bit mask
*/
void tinyusb_hid_mouse_button_report(uint8_t buttons_map);
/**
* @brief Report key press in the keyboard, using array here, contains six keys at most.
*
* @param keycode hid keyboard code array
*/
void tinyusb_hid_keyboard_report(uint8_t keycode[]);
//--------------------------------------------------------------------+
// HID MOUSE BUTTON BIT MASK
//--------------------------------------------------------------------+
// MOUSE_BUTTON_LEFT = TU_BIT(0), ///< Left button
// MOUSE_BUTTON_RIGHT = TU_BIT(1), ///< Right button
// MOUSE_BUTTON_MIDDLE = TU_BIT(2), ///< Middle button
// MOUSE_BUTTON_BACKWARD = TU_BIT(3), ///< Backward button,
// MOUSE_BUTTON_FORWARD = TU_BIT(4), ///< Forward button,
//--------------------------------------------------------------------+
// HID KEYCODE
//--------------------------------------------------------------------+
// #define HID_KEY_NONE 0x00
// #define HID_KEY_A 0x04
// #define HID_KEY_B 0x05
// #define HID_KEY_C 0x06
// #define HID_KEY_D 0x07
// #define HID_KEY_E 0x08
// #define HID_KEY_F 0x09
// #define HID_KEY_G 0x0A
// #define HID_KEY_H 0x0B
// #define HID_KEY_I 0x0C
// #define HID_KEY_J 0x0D
// #define HID_KEY_K 0x0E
// #define HID_KEY_L 0x0F
// #define HID_KEY_M 0x10
// #define HID_KEY_N 0x11
// #define HID_KEY_O 0x12
// #define HID_KEY_P 0x13
// #define HID_KEY_Q 0x14
// #define HID_KEY_R 0x15
// #define HID_KEY_S 0x16
// #define HID_KEY_T 0x17
// #define HID_KEY_U 0x18
// #define HID_KEY_V 0x19
// #define HID_KEY_W 0x1A
// #define HID_KEY_X 0x1B
// #define HID_KEY_Y 0x1C
// #define HID_KEY_Z 0x1D
// #define HID_KEY_1 0x1E
// #define HID_KEY_2 0x1F
// #define HID_KEY_3 0x20
// #define HID_KEY_4 0x21
// #define HID_KEY_5 0x22
// #define HID_KEY_6 0x23
// #define HID_KEY_7 0x24
// #define HID_KEY_8 0x25
// #define HID_KEY_9 0x26
// #define HID_KEY_0 0x27
// #define HID_KEY_ENTER 0x28
// #define HID_KEY_ESCAPE 0x29
// #define HID_KEY_BACKSPACE 0x2A
// #define HID_KEY_TAB 0x2B
// #define HID_KEY_SPACE 0x2C
// #define HID_KEY_MINUS 0x2D
// #define HID_KEY_EQUAL 0x2E
// #define HID_KEY_BRACKET_LEFT 0x2F
// #define HID_KEY_BRACKET_RIGHT 0x30
// #define HID_KEY_BACKSLASH 0x31
// #define HID_KEY_EUROPE_1 0x32
// #define HID_KEY_SEMICOLON 0x33
// #define HID_KEY_APOSTROPHE 0x34
// #define HID_KEY_GRAVE 0x35
// #define HID_KEY_COMMA 0x36
// #define HID_KEY_PERIOD 0x37
// #define HID_KEY_SLASH 0x38
// #define HID_KEY_CAPS_LOCK 0x39
// #define HID_KEY_F1 0x3A
// #define HID_KEY_F2 0x3B
// #define HID_KEY_F3 0x3C
// #define HID_KEY_F4 0x3D
// #define HID_KEY_F5 0x3E
// #define HID_KEY_F6 0x3F
// #define HID_KEY_F7 0x40
// #define HID_KEY_F8 0x41
// #define HID_KEY_F9 0x42
// #define HID_KEY_F10 0x43
// #define HID_KEY_F11 0x44
// #define HID_KEY_F12 0x45
// #define HID_KEY_PRINT_SCREEN 0x46
// #define HID_KEY_SCROLL_LOCK 0x47
// #define HID_KEY_PAUSE 0x48
// #define HID_KEY_INSERT 0x49
// #define HID_KEY_HOME 0x4A
// #define HID_KEY_PAGE_UP 0x4B
// #define HID_KEY_DELETE 0x4C
// #define HID_KEY_END 0x4D
// #define HID_KEY_PAGE_DOWN 0x4E
// #define HID_KEY_ARROW_RIGHT 0x4F
// #define HID_KEY_ARROW_LEFT 0x50
// #define HID_KEY_ARROW_DOWN 0x51
// #define HID_KEY_ARROW_UP 0x52
// #define HID_KEY_NUM_LOCK 0x53
// #define HID_KEY_KEYPAD_DIVIDE 0x54
// #define HID_KEY_KEYPAD_MULTIPLY 0x55
// #define HID_KEY_KEYPAD_SUBTRACT 0x56
// #define HID_KEY_KEYPAD_ADD 0x57
// #define HID_KEY_KEYPAD_ENTER 0x58
// #define HID_KEY_KEYPAD_1 0x59
// #define HID_KEY_KEYPAD_2 0x5A
// #define HID_KEY_KEYPAD_3 0x5B
// #define HID_KEY_KEYPAD_4 0x5C
// #define HID_KEY_KEYPAD_5 0x5D
// #define HID_KEY_KEYPAD_6 0x5E
// #define HID_KEY_KEYPAD_7 0x5F
// #define HID_KEY_KEYPAD_8 0x60
// #define HID_KEY_KEYPAD_9 0x61
// #define HID_KEY_KEYPAD_0 0x62
// #define HID_KEY_KEYPAD_DECIMAL 0x63
// #define HID_KEY_EUROPE_2 0x64
// #define HID_KEY_APPLICATION 0x65
// #define HID_KEY_POWER 0x66
// #define HID_KEY_KEYPAD_EQUAL 0x67
// #define HID_KEY_F13 0x68
// #define HID_KEY_F14 0x69
// #define HID_KEY_F15 0x6A
// #define HID_KEY_F16 0x6B
// #define HID_KEY_F17 0x6C
// #define HID_KEY_F18 0x6D
// #define HID_KEY_F19 0x6E
// #define HID_KEY_F20 0x6F
// #define HID_KEY_F21 0x70
// #define HID_KEY_F22 0x71
// #define HID_KEY_F23 0x72
// #define HID_KEY_F24 0x73
// #define HID_KEY_EXECUTE 0x74
// #define HID_KEY_HELP 0x75
// #define HID_KEY_MENU 0x76
// #define HID_KEY_SELECT 0x77
// #define HID_KEY_STOP 0x78
// #define HID_KEY_AGAIN 0x79
// #define HID_KEY_UNDO 0x7A
// #define HID_KEY_CUT 0x7B
// #define HID_KEY_COPY 0x7C
// #define HID_KEY_PASTE 0x7D
// #define HID_KEY_FIND 0x7E
// #define HID_KEY_MUTE 0x7F
// #define HID_KEY_VOLUME_UP 0x80
// #define HID_KEY_VOLUME_DOWN 0x81
// #define HID_KEY_LOCKING_CAPS_LOCK 0x82
// #define HID_KEY_LOCKING_NUM_LOCK 0x83
// #define HID_KEY_LOCKING_SCROLL_LOCK 0x84
// #define HID_KEY_KEYPAD_COMMA 0x85
// #define HID_KEY_KEYPAD_EQUAL_SIGN 0x86
// #define HID_KEY_KANJI1 0x87
// #define HID_KEY_KANJI2 0x88
// #define HID_KEY_KANJI3 0x89
// #define HID_KEY_KANJI4 0x8A
// #define HID_KEY_KANJI5 0x8B
// #define HID_KEY_KANJI6 0x8C
// #define HID_KEY_KANJI7 0x8D
// #define HID_KEY_KANJI8 0x8E
// #define HID_KEY_KANJI9 0x8F
// #define HID_KEY_LANG1 0x90
// #define HID_KEY_LANG2 0x91
// #define HID_KEY_LANG3 0x92
// #define HID_KEY_LANG4 0x93
// #define HID_KEY_LANG5 0x94
// #define HID_KEY_LANG6 0x95
// #define HID_KEY_LANG7 0x96
// #define HID_KEY_LANG8 0x97
// #define HID_KEY_LANG9 0x98
// #define HID_KEY_ALTERNATE_ERASE 0x99
// #define HID_KEY_SYSREQ_ATTENTION 0x9A
// #define HID_KEY_CANCEL 0x9B
// #define HID_KEY_CLEAR 0x9C
// #define HID_KEY_PRIOR 0x9D
// #define HID_KEY_RETURN 0x9E
// #define HID_KEY_SEPARATOR 0x9F
// #define HID_KEY_OUT 0xA0
// #define HID_KEY_OPER 0xA1
// #define HID_KEY_CLEAR_AGAIN 0xA2
// #define HID_KEY_CRSEL_PROPS 0xA3
// #define HID_KEY_EXSEL 0xA4
// //RESERVED 0xA5-DF
// #define HID_KEY_CONTROL_LEFT 0xE0
// #define HID_KEY_SHIFT_LEFT 0xE1
// #define HID_KEY_ALT_LEFT 0xE2
// #define HID_KEY_GUI_LEFT 0xE3
// #define HID_KEY_CONTROL_RIGHT 0xE4
// #define HID_KEY_SHIFT_RIGHT 0xE5
// #define HID_KEY_ALT_RIGHT 0xE6
// #define HID_KEY_GUI_RIGHT 0xE7
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,42 @@
// Copyright 2020-2021 Espressif Systems (Shanghai) Co. Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "tusb.h"
#include "tinyusb.h"
/**
* @brief Configuration structure for MSC
*/
typedef struct {
uint8_t pdrv; /* Physical drive nmuber (0..) */
} tinyusb_config_msc_t;
/**
* @brief Initialize MSC Device.
*
* @param cfg - init configuration structure
* @return esp_err_t
*/
esp_err_t tusb_msc_init(const tinyusb_config_msc_t *cfg);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,49 @@
/**
* @copyright Copyright 2021 Espressif Systems (Shanghai) Co. Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "esp_err.h"
#include "tinyusb.h"
/**
* @brief Forward packets from Wi-Fi to USB.
*
* @param buffer - Data pointer
*
* @param len - Data length
*
* @return esp_err_t
*/
esp_err_t pkt_wifi2usb(void *buffer, uint16_t len, void *eb);
/**
* @brief Initialize NET Device.
*/
void tusb_net_init(void);
void ecm_close(void);
void ecm_open(void);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,46 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief This helper function creates and starts a task which wraps `tud_task()`.
*
* The wrapper function basically wraps tud_task and some log.
* Default parameters: stack size and priority as configured, argument = NULL, not pinned to any core.
* If you have more requirements for this task, you can create your own task which calls tud_task as the last step.
*
* @retval ESP_OK run tinyusb main task successfully
* @retval ESP_FAIL run tinyusb main task failed of internal error
* @retval ESP_ERR_INVALID_STATE tinyusb main task has been created before
*/
esp_err_t tusb_run_task(void);
/**
* @brief This helper function stops and destroys the task created by `tusb_run_task()`
*
* @retval ESP_OK stop and destory tinyusb main task successfully
* @retval ESP_ERR_INVALID_STATE tinyusb main task hasn't been created yet
*/
esp_err_t tusb_stop_task(void);
#ifdef __cplusplus
}
#endif

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