Compare commits
59 commits
usb/add_us
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
feeeb6b98e | ||
|
|
8ccd278a7e | ||
|
|
b25236bff2 | ||
|
|
5e1e715395 | ||
|
|
fbf56a4c37 | ||
|
|
8aefe2dea3 | ||
|
|
4e481f0ee6 | ||
|
|
c18cf2ee8d | ||
|
|
a444d89f2b | ||
|
|
7ccf82a262 | ||
|
|
d6967b5f23 | ||
|
|
47df7d1205 | ||
|
|
b63def61df | ||
|
|
b1a3bea83e | ||
|
|
7a0eee234e | ||
|
|
4fa6a72bd4 | ||
|
|
5e5c4aa34c | ||
|
|
fd38b168d6 | ||
|
|
a5e1f94299 | ||
|
|
39ddd5dd99 | ||
|
|
ff6da11453 | ||
|
|
2961285a8e | ||
|
|
ce1d460938 | ||
|
|
fae526efcd | ||
|
|
8607a04658 | ||
|
|
1ffd999ac7 | ||
|
|
7133529944 | ||
|
|
1a913daf7a | ||
|
|
a49b22308f | ||
|
|
bbdb938242 | ||
|
|
5e224b0939 | ||
|
|
47a494a356 | ||
|
|
611cca278a | ||
|
|
239cac6c75 | ||
|
|
ecd5e3247d | ||
|
|
0caa2de556 | ||
|
|
527c817da0 | ||
|
|
67bc36471a | ||
|
|
8d917a8065 | ||
|
|
21350012e9 | ||
|
|
63421202d6 | ||
|
|
f26cfdcea2 | ||
|
|
87e76fd295 | ||
|
|
1f566dd957 | ||
|
|
9849ac04ed | ||
|
|
783b67ab24 | ||
|
|
2be68ac9bc | ||
|
|
68bfe795f9 | ||
|
|
1770f425f8 | ||
|
|
6b0b1c4cd4 | ||
|
|
db53a62a7a | ||
|
|
f664e8ed24 | ||
|
|
e412568b84 | ||
|
|
c23ceeba00 | ||
|
|
e4672a5208 | ||
|
|
bd0702ddb6 | ||
|
|
0f47c1d04a | ||
|
|
34591c45d8 | ||
|
|
af4cd0980e |
192 changed files with 15352 additions and 1414 deletions
20
.github/workflows/upload_component.yml
vendored
Normal file
20
.github/workflows/upload_component.yml
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
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 }}
|
||||
82
.gitignore
vendored
82
.gitignore
vendored
|
|
@ -1,19 +1,19 @@
|
|||
build/
|
||||
.settings
|
||||
.config
|
||||
*.o
|
||||
*.pyc
|
||||
*.d
|
||||
*.old
|
||||
*.cproject
|
||||
|
||||
# gtags
|
||||
GTAGS
|
||||
GRTAGS
|
||||
GPATH
|
||||
|
||||
# vscode setting
|
||||
.vscode/
|
||||
# emacs
|
||||
.dir-locals.el
|
||||
|
||||
# emacs temp file suffixes
|
||||
*~
|
||||
.#*
|
||||
\#*#
|
||||
|
||||
# eclipse setting
|
||||
.settings
|
||||
|
|
@ -21,6 +21,16 @@ GPATH
|
|||
# MacOS directory files
|
||||
.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
|
||||
docs/**/_build/
|
||||
docs/**/doxygen-warning-log.txt
|
||||
|
|
@ -29,12 +39,10 @@ docs/**/sphinx-warning-log-sanitized.txt
|
|||
docs/**/xml/
|
||||
docs/**/xml_in/
|
||||
docs/**/man/
|
||||
docs/doxygen_sqlite3.db
|
||||
|
||||
# Example project files
|
||||
examples/**/sdkconfig
|
||||
examples/**/sdkconfig.old
|
||||
examples/**/build
|
||||
# Downloaded font files
|
||||
docs/_static/DejaVuSans.ttf
|
||||
docs/_static/NotoSansSC-Regular.otf
|
||||
|
||||
# Unit test app files
|
||||
tools/unit-test-app/sdkconfig
|
||||
|
|
@ -42,6 +50,52 @@ tools/unit-test-app/sdkconfig.old
|
|||
tools/unit-test-app/build
|
||||
tools/unit-test-app/builds
|
||||
tools/unit-test-app/output
|
||||
tools/unit-test-app/test_configs
|
||||
|
||||
# ESP-IDF library
|
||||
build
|
||||
# Unit Test CMake compile log folder
|
||||
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
|
||||
|
||||
# lock files for examples and components
|
||||
dependencies.lock
|
||||
|
||||
# managed_components for examples
|
||||
managed_components
|
||||
|
||||
# pytest log
|
||||
pytest_embedded_log/
|
||||
|
|
|
|||
|
|
@ -30,28 +30,38 @@ before_script:
|
|||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $BUILD_PATH/*/*/build/*.bin
|
||||
- $BUILD_PATH/*/*/build/*.elf
|
||||
- $BUILD_PATH/*/*/build/*.map
|
||||
- $BUILD_PATH/*/*/build/download.config
|
||||
- $BUILD_PATH/*/*/build/bootloader/*.bin
|
||||
- $LOG_PATH
|
||||
- $BUILD_PATH/*/*/*/build/*.bin
|
||||
- $BUILD_PATH/*/*/*/build/*/*.bin
|
||||
- $BUILD_PATH/*/*/*/build/*.json
|
||||
- $BUILD_PATH/*.json
|
||||
- $LOG_PATH/*
|
||||
expire_in: 1 week
|
||||
variables:
|
||||
IDF_CI_BUILD: "1"
|
||||
LOG_PATH: "$CI_PROJECT_DIR/log_examples"
|
||||
BUILD_PATH: "$CI_PROJECT_DIR/build_examples"
|
||||
SIZE_INFO_LOCATION: "$CI_PROJECT_DIR/log_examples/size_info.txt"
|
||||
PEDANTIC_CFLAGS: ""
|
||||
PEDANTIC_CXXFLAGS: ""
|
||||
script:
|
||||
# it's not possible to build 100% out-of-tree and have the "artifacts"
|
||||
# mechanism work, but this is the next best thing
|
||||
- rm -rf ${BUILD_PATH}
|
||||
- mkdir ${BUILD_PATH}
|
||||
- mkdir -p ${LOG_PATH}
|
||||
# build some of examples
|
||||
- ${IOT_SOLUTION_PATH}/tools/ci/build_examples.sh "${CI_JOB_NAME}"
|
||||
- python ${IOT_SOLUTION_PATH}/tools/ci/genarate_build_json.py
|
||||
- ${IOT_SOLUTION_PATH}/tools/ci/build_examples.sh
|
||||
|
||||
build_examples_00:
|
||||
build_examples_00_with_idf_v4.2:
|
||||
<<: *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:
|
||||
stage: build
|
||||
|
|
@ -74,6 +84,8 @@ build_docs:
|
|||
expire_in: 1 mos
|
||||
script:
|
||||
- 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
|
||||
- cd docs
|
||||
- ./check_lang_folder_sync.sh
|
||||
|
|
|
|||
6
.gitmodules
vendored
6
.gitmodules
vendored
|
|
@ -4,3 +4,9 @@
|
|||
[submodule "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
|
||||
[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
|
||||
|
|
|
|||
|
|
@ -14,4 +14,5 @@ formats:
|
|||
python:
|
||||
version: 3.7
|
||||
install:
|
||||
- requirements: docs/setuptools.requirements.txt
|
||||
- requirements: docs/requirements.txt
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
idf_component_register(SRCS "dac_audio.c"
|
||||
INCLUDE_DIRS "include"
|
||||
)
|
||||
REQUIRES driver)
|
||||
|
|
|
|||
|
|
@ -12,17 +12,15 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include "driver/i2s.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";
|
||||
|
||||
#define DAC_AUDIO_CHECK(a, str, ret_val) \
|
||||
|
|
@ -156,7 +154,11 @@ 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.sample_rate = cfg->sample_rate;
|
||||
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;
|
||||
#endif
|
||||
if (I2S_DAC_CHANNEL_RIGHT_EN == cfg->dac_mode) {
|
||||
i2s_config.channel_format = I2S_CHANNEL_FMT_ALL_RIGHT;
|
||||
} else if (I2S_DAC_CHANNEL_LEFT_EN == cfg->dac_mode) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
set(pwm_audio_srcs "pwm_audio.c")
|
||||
|
||||
idf_component_register(SRCS "${pwm_audio_srcs}"
|
||||
INCLUDE_DIRS "include")
|
||||
idf_component_register(SRCS "pwm_audio.c"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES driver)
|
||||
|
|
|
|||
13
components/audio/pwm_audio/README.md
Normal file
13
components/audio/pwm_audio/README.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# 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.
|
||||
5
components/audio/pwm_audio/idf_component.yml
Normal file
5
components/audio/pwm_audio/idf_component.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
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"
|
||||
202
components/audio/pwm_audio/license.txt
Normal file
202
components/audio/pwm_audio/license.txt
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
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.
|
||||
|
|
@ -12,6 +12,8 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#define _SOC_TIMG_STRUCT_H_ // to exclude `timer_group_struct.h` file
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
|
@ -19,18 +21,25 @@
|
|||
#include "freertos/task.h"
|
||||
#include "driver/ledc.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "driver/timer.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/ledc_struct.h"
|
||||
#include "soc/ledc_reg.h"
|
||||
#include "pwm_audio.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32)
|
||||
#if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3)
|
||||
|
||||
#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";
|
||||
|
||||
#define PWM_AUDIO_CHECK(a, str, ret_val) \
|
||||
|
|
@ -58,6 +67,10 @@ static const char *PWM_AUDIO_NOT_INITIALIZED = "PWM AUDIO Uninitialized";
|
|||
#define CHANNEL_RIGHT_MASK (0x02)
|
||||
#define VOLUME_0DB (16)
|
||||
|
||||
#ifndef TIMER_BASE_CLK
|
||||
#define TIMER_BASE_CLK 80000000
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Debug Configuration
|
||||
**/
|
||||
|
|
@ -77,7 +90,7 @@ typedef struct {
|
|||
pwm_audio_config_t config; /**< pwm audio config struct */
|
||||
ledc_channel_config_t ledc_channel[PWM_AUDIO_CH_MAX]; /**< ledc channel 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 */
|
||||
uint32_t channel_mask; /**< channel gpio mask */
|
||||
uint32_t channel_set_num; /**< channel audio set number */
|
||||
|
|
@ -121,7 +134,7 @@ static esp_err_t rb_destroy(ringbuf_handle_t *rb)
|
|||
rb = NULL;
|
||||
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)) {
|
||||
ESP_LOGE(TAG, "Invalid buffer size, Minimum = %d", (int32_t)(BUFFER_MIN_SIZE << 2));
|
||||
|
|
@ -249,7 +262,6 @@ static inline void ledc_set_right_duty_fast(uint32_t duty_val)
|
|||
*g_ledc_right_conf1_val |= 0x80000000;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Timer group ISR handler
|
||||
*/
|
||||
|
|
@ -260,31 +272,14 @@ static void IRAM_ATTR timer_group_isr(void *para)
|
|||
if (handle == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
|
||||
/* Clear the interrupt */
|
||||
if ((handle->timg_dev)->int_st.val & BIT(handle->config.timer_num)) {
|
||||
(handle->timg_dev)->int_clr.val |= (1UL << handle->config.timer_num);
|
||||
}
|
||||
|
||||
// uint32_t st = timer_ll_get_intr_status(handle->timg_dev);
|
||||
// if (st & (1UL << handle->config.timer_num)) {
|
||||
timer_ll_clear_intr_status(handle->timg_dev, 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_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 */
|
||||
we need enable it again, so it is triggered the next time */
|
||||
timer_ll_enable_alarm(handle->timg_dev, handle->config.timer_num, 1);
|
||||
|
||||
static uint8_t wave_h, wave_l;
|
||||
static uint16_t value;
|
||||
|
|
@ -441,9 +436,9 @@ esp_err_t pwm_audio_init(const pwm_audio_config_t *cfg)
|
|||
|
||||
/**< Get timer group register pointer */
|
||||
if (cfg->tg_num == TIMER_GROUP_0) {
|
||||
handle->timg_dev = &TIMERG0;
|
||||
handle->timg_dev = TIMERG0;
|
||||
} else {
|
||||
handle->timg_dev = &TIMERG1;
|
||||
handle->timg_dev = TIMERG1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -557,7 +552,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);
|
||||
|
||||
/* Configure the alarm value and the interrupt on alarm. */
|
||||
uint32_t divider = handle->timg_dev->hw_timer[handle->config.timer_num].config.divider;
|
||||
uint32_t divider = timer_ll_get_clock_prescale(handle->timg_dev, handle->config.timer_num);
|
||||
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);
|
||||
return res;
|
||||
|
|
@ -572,7 +567,7 @@ esp_err_t pwm_audio_set_sample_rate(int rate)
|
|||
|
||||
pwm_audio_data_t *handle = g_pwm_audio_handle;
|
||||
handle->framerate = rate;
|
||||
uint32_t divider = handle->timg_dev->hw_timer[handle->config.timer_num].config.divider;
|
||||
uint32_t divider = timer_ll_get_clock_prescale(handle->timg_dev, handle->config.timer_num);
|
||||
res = timer_set_alarm_value(handle->config.tg_num, handle->config.timer_num, (TIMER_BASE_CLK / divider) / handle->framerate);
|
||||
return res;
|
||||
}
|
||||
|
|
@ -751,10 +746,9 @@ esp_err_t pwm_audio_start(void)
|
|||
|
||||
/**< timer enable interrupt */
|
||||
portENTER_CRITICAL_SAFE(&timer_spinlock);
|
||||
handle->timg_dev->int_ena.val |= BIT(handle->config.timer_num);
|
||||
handle->timg_dev->hw_timer[handle->config.timer_num].config.enable = 1;
|
||||
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;
|
||||
timer_ll_enable_intr(handle->timg_dev, handle->config.timer_num, 1);
|
||||
timer_ll_enable_counter(handle->timg_dev, handle->config.timer_num, 1);
|
||||
timer_ll_enable_alarm(handle->timg_dev, handle->config.timer_num, 1); /** Make sure the interrupt is enabled*/
|
||||
portEXIT_CRITICAL_SAFE(&timer_spinlock);
|
||||
|
||||
res = timer_start(handle->config.tg_num, handle->config.timer_num);
|
||||
|
|
@ -770,9 +764,8 @@ esp_err_t pwm_audio_stop(void)
|
|||
/**< just disable timer ,keep pwm output to reduce switching nosie */
|
||||
/**< timer disable interrupt */
|
||||
portENTER_CRITICAL_SAFE(&timer_spinlock);
|
||||
handle->timg_dev->hw_timer[handle->config.timer_num].config.enable = 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;
|
||||
timer_ll_enable_intr(handle->timg_dev, handle->config.timer_num, 0);
|
||||
timer_ll_enable_counter(handle->timg_dev, handle->config.timer_num, 0);
|
||||
portEXIT_CRITICAL_SAFE(&timer_spinlock);
|
||||
|
||||
// timer_pause(handle->config.tg_num, handle->config.timer_num);
|
||||
|
|
|
|||
784
components/audio/pwm_audio/reg_struct/esp32_timer_group_struct.h
Normal file
784
components/audio/pwm_audio/reg_struct/esp32_timer_group_struct.h
Normal file
|
|
@ -0,0 +1,784 @@
|
|||
/**
|
||||
* 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
|
||||
|
|
@ -0,0 +1,598 @@
|
|||
/**
|
||||
* 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
|
||||
|
|
@ -0,0 +1,828 @@
|
|||
/**
|
||||
* 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
|
||||
|
|
@ -0,0 +1,593 @@
|
|||
/**
|
||||
* 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
|
||||
524
components/bus/8080_lcd_esp32s3.c
Normal file
524
components/bus/8080_lcd_esp32s3.c
Normal file
|
|
@ -0,0 +1,524 @@
|
|||
// 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
|
||||
|
|
@ -1,2 +1,3 @@
|
|||
idf_component_register(SRC_DIRS "."
|
||||
INCLUDE_DIRS "include" )
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES driver)
|
||||
|
|
@ -20,8 +20,13 @@
|
|||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_heap_caps.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_reg.h"
|
||||
#include "soc/i2s_struct.h"
|
||||
|
|
@ -36,6 +41,11 @@ static const char *TAG = "ESP32_I2S_LCD";
|
|||
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_DATA_MAX_WIDTH (24) /*!< Maximum width of LCD data bus */
|
||||
|
||||
|
|
@ -566,6 +576,16 @@ esp_err_t i2s_lcd_write_cmd(i2s_lcd_handle_t handle, uint16_t cmd)
|
|||
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)
|
||||
{
|
||||
i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)handle;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,13 @@
|
|||
#include "freertos/semphr.h"
|
||||
#include "esp_log.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 "soc/i2s_struct.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp32s2/rom/lldesc.h"
|
||||
#include "soc/system_reg.h"
|
||||
|
|
@ -39,6 +45,11 @@ static const char *TAG = "ESP32S2_I2S_LCD";
|
|||
#define LCD_CAM_DMA_NODE_BUFFER_MAX_SIZE (4000) // 4-byte aligned
|
||||
#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 {
|
||||
uint32_t dma_buffer_size;
|
||||
uint32_t dma_half_buffer_size;
|
||||
|
|
@ -439,6 +450,16 @@ esp_err_t i2s_lcd_write_cmd(i2s_lcd_handle_t handle, uint16_t cmd)
|
|||
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)
|
||||
{
|
||||
i2s_lcd_driver_t *i2s_lcd_drv = (i2s_lcd_driver_t *)handle;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@ extern "C"
|
|||
{
|
||||
#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)*********************************************/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -86,6 +86,19 @@ 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);
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -69,8 +69,12 @@ spi_bus_handle_t spi_bus_create(spi_host_device_t host_id, const spi_config_t *b
|
|||
.quadhd_io_num = -1,
|
||||
.max_transfer_sz = bus_conf->max_transfer_sz,
|
||||
};
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0))
|
||||
esp_err_t ret = spi_bus_initialize(host_id, &buscfg, SPI_DMA_CH_AUTO);
|
||||
#else
|
||||
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
|
||||
SPI_BUS_CHECK(ESP_OK == ret, "spi bus create failed", NULL);
|
||||
s_spi_bus[index].host_id = host_id;
|
||||
memcpy(&s_spi_bus[index].conf, &buscfg, sizeof(spi_bus_config_t));
|
||||
|
|
@ -199,7 +203,7 @@ esp_err_t spi_bus_transfer_bytes(spi_bus_device_handle_t dev_handle, const uint8
|
|||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
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"
|
||||
INCLUDE_DIRS include
|
||||
PRIV_REQUIRES esp_adc_cal)
|
||||
REQUIRES driver
|
||||
PRIV_REQUIRES ${PRIVREQ})
|
||||
|
|
|
|||
17
components/button/README.md
Normal file
17
components/button/README.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# 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
|
||||
|
|
@ -31,11 +31,7 @@ static const char *TAG = "adc button";
|
|||
#define DEFAULT_VREF 1100
|
||||
#define NO_OF_SAMPLES CONFIG_ADC_BUTTON_SAMPLE_TIMES //Multisampling
|
||||
|
||||
#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_WIDTH ADC_WIDTH_MAX-1
|
||||
#define ADC_BUTTON_ATTEN ADC_ATTEN_DB_11
|
||||
#define ADC_BUTTON_ADC_UNIT ADC_UNIT_1
|
||||
#define ADC_BUTTON_MAX_CHANNEL CONFIG_ADC_BUTTON_MAX_CHANNEL
|
||||
|
|
|
|||
5
components/button/idf_component.yml
Normal file
5
components/button/idf_component.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
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"
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (* button_cb_t)(void *);
|
||||
typedef void (* button_cb_t)(void *, void *);
|
||||
typedef void *button_handle_t;
|
||||
|
||||
/**
|
||||
|
|
@ -87,12 +87,13 @@ esp_err_t iot_button_delete(button_handle_t btn_handle);
|
|||
* @param btn_handle A button handle to register
|
||||
* @param event Button event
|
||||
* @param cb Callback function.
|
||||
* @param usr_data user data
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - 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);
|
||||
esp_err_t iot_button_register_cb(button_handle_t btn_handle, button_event_t event, button_cb_t cb, void *usr_data);
|
||||
|
||||
/**
|
||||
* @brief Unregister the button event callback function.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ typedef struct Button {
|
|||
uint8_t debounce_cnt: 3;
|
||||
uint8_t active_level: 1;
|
||||
uint8_t button_level: 1;
|
||||
uint8_t (*hal_button_Level)(void *usr_data);
|
||||
uint8_t (*hal_button_Level)(void *hardware_data);
|
||||
void *hardware_data;
|
||||
void *usr_data;
|
||||
button_type_t type;
|
||||
button_cb_t cb[BUTTON_EVENT_MAX];
|
||||
|
|
@ -56,14 +57,14 @@ static bool g_is_timer_running = false;
|
|||
#define SHORT_TICKS (CONFIG_BUTTON_SHORT_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)
|
||||
#define CALL_EVENT_CB(ev) if(btn->cb[ev])btn->cb[ev](btn, btn->usr_data)
|
||||
|
||||
/**
|
||||
* @brief Button driver core function, driver state machine.
|
||||
*/
|
||||
static void button_handler(button_dev_t *btn)
|
||||
{
|
||||
uint8_t read_gpio_level = btn->hal_button_Level(btn->usr_data);
|
||||
uint8_t read_gpio_level = btn->hal_button_Level(btn->hardware_data);
|
||||
|
||||
/** ticks counter working.. */
|
||||
if ((btn->state) > 0) {
|
||||
|
|
@ -163,13 +164,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 *usr_data), void *usr_data)
|
||||
static button_dev_t *button_create_com(uint8_t active_level, uint8_t (*hal_get_key_state)(void *hardware_data), void *hardware_data)
|
||||
{
|
||||
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));
|
||||
BTN_CHECK(NULL != btn, "Button memory alloc failed", NULL);
|
||||
btn->usr_data = usr_data;
|
||||
btn->hardware_data = hardware_data;
|
||||
btn->event = BUTTON_NONE_PRESS;
|
||||
btn->active_level = active_level;
|
||||
btn->hal_button_Level = hal_get_key_state;
|
||||
|
|
@ -259,10 +260,10 @@ esp_err_t iot_button_delete(button_handle_t btn_handle)
|
|||
button_dev_t *btn = (button_dev_t *)btn_handle;
|
||||
switch (btn->type) {
|
||||
case BUTTON_TYPE_GPIO:
|
||||
ret = button_gpio_deinit((int)(btn->usr_data));
|
||||
ret = button_gpio_deinit((int)(btn->hardware_data));
|
||||
break;
|
||||
case BUTTON_TYPE_ADC:
|
||||
ret = button_adc_deinit(ADC_BUTTON_SPLIT_CHANNEL(btn->usr_data), ADC_BUTTON_SPLIT_INDEX(btn->usr_data));
|
||||
ret = button_adc_deinit(ADC_BUTTON_SPLIT_CHANNEL(btn->hardware_data), ADC_BUTTON_SPLIT_INDEX(btn->hardware_data));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -272,12 +273,13 @@ esp_err_t iot_button_delete(button_handle_t btn_handle)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t iot_button_register_cb(button_handle_t btn_handle, button_event_t event, button_cb_t cb)
|
||||
esp_err_t iot_button_register_cb(button_handle_t btn_handle, button_event_t event, button_cb_t cb, void *usr_data)
|
||||
{
|
||||
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);
|
||||
button_dev_t *btn = (button_dev_t *) btn_handle;
|
||||
btn->cb[event] = cb;
|
||||
btn->usr_data = usr_data;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
202
components/button/license.txt
Normal file
202
components/button/license.txt
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
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.
|
||||
|
|
@ -1,15 +1,18 @@
|
|||
|
||||
set(SCREEN_DIR "controller_driver/ili9341"
|
||||
"controller_driver/ili9342"
|
||||
"controller_driver/st7789"
|
||||
"controller_driver/st7796"
|
||||
"controller_driver/nt35510"
|
||||
"controller_driver/ili9806"
|
||||
"controller_driver/ili9486"
|
||||
"controller_driver/ili9488"
|
||||
"controller_driver/ssd1351"
|
||||
"controller_driver/rm68120"
|
||||
"controller_driver/ssd1306"
|
||||
"controller_driver/ssd1307"
|
||||
"controller_driver/ssd1322"
|
||||
"controller_driver/ssd1963"
|
||||
)
|
||||
|
||||
idf_component_register(SRC_DIRS "${SCREEN_DIR}" "screen_utility" "interface_driver" "."
|
||||
|
|
|
|||
|
|
@ -4,12 +4,18 @@ menu "LCD Drivers"
|
|||
config LCD_DRIVER_SCREEN_CONTROLLER_ILI9341
|
||||
bool "ILI9341"
|
||||
default y
|
||||
config LCD_DRIVER_SCREEN_CONTROLLER_ILI9342
|
||||
bool "ILI9342"
|
||||
default y
|
||||
config LCD_DRIVER_SCREEN_CONTROLLER_ILI9486
|
||||
bool "ILI9486"
|
||||
default n
|
||||
config LCD_DRIVER_SCREEN_CONTROLLER_ILI9806
|
||||
bool "ILI9806"
|
||||
default n
|
||||
config LCD_DRIVER_SCREEN_CONTROLLER_ILI9488
|
||||
bool "ILI9488"
|
||||
default n
|
||||
config LCD_DRIVER_SCREEN_CONTROLLER_NT35510
|
||||
bool "NT35510"
|
||||
default n
|
||||
|
|
@ -19,6 +25,9 @@ menu "LCD Drivers"
|
|||
config LCD_DRIVER_SCREEN_CONTROLLER_SSD1351
|
||||
bool "SSD1351"
|
||||
default n
|
||||
config LCD_DRIVER_SCREEN_CONTROLLER_SSD1963
|
||||
bool "SSD1963"
|
||||
default n
|
||||
config LCD_DRIVER_SCREEN_CONTROLLER_ST7789
|
||||
bool "ST7789"
|
||||
default n
|
||||
|
|
@ -37,4 +46,4 @@ menu "LCD Drivers"
|
|||
default n
|
||||
endmenu
|
||||
|
||||
endmenu
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -5,16 +5,19 @@
|
|||
|
||||
|
||||
SCREEN_DIR = controller_driver/ili9341 \
|
||||
controller_driver/st7789 \
|
||||
controller_driver/st7796 \
|
||||
controller_driver/nt35510 \
|
||||
controller_driver/ili9806 \
|
||||
controller_driver/ili9486 \
|
||||
controller_driver/ssd1351 \
|
||||
controller_driver/rm68120 \
|
||||
controller_driver/ssd1306 \
|
||||
controller_driver/ssd1307 \
|
||||
controller_driver/ssd1322
|
||||
controller_driver/ili9342 \
|
||||
controller_driver/st7789 \
|
||||
controller_driver/st7796 \
|
||||
controller_driver/nt35510 \
|
||||
controller_driver/ili9806 \
|
||||
controller_driver/ili9486 \
|
||||
controller_driver/ili9488 \
|
||||
controller_driver/ssd1351 \
|
||||
controller_driver/rm68120 \
|
||||
controller_driver/ssd1306 \
|
||||
controller_driver/ssd1307 \
|
||||
controller_driver/ssd1322 \
|
||||
controller_driver/ssd1963
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := . iface_driver $(SCREEN_DIR) screen_utility
|
||||
COMPONENT_SRCDIRS := . iface_driver $(SCREEN_DIR) screen_utility
|
||||
COMPONENT_ADD_INCLUDEDIRS := . interface_driver $(SCREEN_DIR) screen_utility
|
||||
COMPONENT_SRCDIRS := . interface_driver $(SCREEN_DIR) screen_utility
|
||||
|
|
|
|||
|
|
@ -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->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->interface_drv->write_cmd && \
|
||||
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 && \
|
||||
|
|
|
|||
394
components/display/screen/controller_driver/ili9342/ili9342.c
Normal file
394
components/display/screen/controller_driver/ili9342/ili9342.c
Normal file
|
|
@ -0,0 +1,394 @@
|
|||
// 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;
|
||||
}
|
||||
134
components/display/screen/controller_driver/ili9342/ili9342.h
Normal file
134
components/display/screen/controller_driver/ili9342/ili9342.h
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
// 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
|
||||
|
|
@ -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->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->interface_drv->write_cmd && \
|
||||
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 && \
|
||||
|
|
|
|||
401
components/display/screen/controller_driver/ili9488/ili9488.c
Normal file
401
components/display/screen/controller_driver/ili9488/ili9488.c
Normal file
|
|
@ -0,0 +1,401 @@
|
|||
// 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);
|
||||
}
|
||||
138
components/display/screen/controller_driver/ili9488/ili9488.h
Normal file
138
components/display/screen/controller_driver/ili9488/ili9488.h
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
// 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
|
||||
|
|
@ -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->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->interface_drv->write_cmd && \
|
||||
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 && \
|
||||
|
|
|
|||
|
|
@ -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->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->interface_drv->write_cmd && \
|
||||
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 && \
|
||||
|
|
@ -176,7 +176,7 @@ esp_err_t lcd_nt35510_set_rotation(scr_dir_t dir)
|
|||
default: break;
|
||||
}
|
||||
ESP_LOGI(TAG, "MADCTL=0x%x", reg_data);
|
||||
ret = LCD_WRITE_REG(NT35510_MADCTL, reg_data);
|
||||
ret = LCD_WRITE_REG_16B(NT35510_MADCTL, reg_data);
|
||||
LCD_CHECK(ESP_OK == ret, "Set screen rotate failed", ESP_FAIL);
|
||||
g_lcd_handle.dir = dir;
|
||||
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;
|
||||
scr_utility_apply_offset(&g_lcd_handle, NT35510_RESOLUTION_HOR, NT35510_RESOLUTION_VER, &x0, &y0, &x1, &y1);
|
||||
|
||||
ret |= LCD_WRITE_REG(NT35510_CASET, x0 >> 8);
|
||||
ret |= LCD_WRITE_REG(NT35510_CASET + 1, x0 & 0xff);
|
||||
ret |= LCD_WRITE_REG(NT35510_CASET + 2, x1 >> 8);
|
||||
ret |= LCD_WRITE_REG(NT35510_CASET + 3, x1 & 0xff);
|
||||
ret |= LCD_WRITE_REG(NT35510_RASET, y0 >> 8);
|
||||
ret |= LCD_WRITE_REG(NT35510_RASET + 1, y0 & 0xff);
|
||||
ret |= LCD_WRITE_REG(NT35510_RASET + 2, y1 >> 8);
|
||||
ret |= LCD_WRITE_REG(NT35510_RASET + 3, y1 & 0xff);
|
||||
ret |= LCD_WRITE_REG_16B(NT35510_CASET, x0 >> 8);
|
||||
ret |= LCD_WRITE_REG_16B(NT35510_CASET + 1, x0 & 0xff);
|
||||
ret |= LCD_WRITE_REG_16B(NT35510_CASET + 2, x1 >> 8);
|
||||
ret |= LCD_WRITE_REG_16B(NT35510_CASET + 3, x1 & 0xff);
|
||||
ret |= LCD_WRITE_REG_16B(NT35510_RASET, y0 >> 8);
|
||||
ret |= LCD_WRITE_REG_16B(NT35510_RASET + 1, y0 & 0xff);
|
||||
ret |= LCD_WRITE_REG_16B(NT35510_RASET + 2, y1 >> 8);
|
||||
ret |= LCD_WRITE_REG_16B(NT35510_RASET + 3, y1 & 0xff);
|
||||
|
||||
ret |= LCD_WRITE_CMD(NT35510_RAMWR);
|
||||
ret |= LCD_WRITE_CMD_16B(NT35510_RAMWR);
|
||||
LCD_CHECK(ESP_OK == ret, "Set window failed", ESP_FAIL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
|
@ -253,387 +253,426 @@ 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)
|
||||
{
|
||||
LCD_WRITE_CMD(0x0100); // Software Reset
|
||||
// Software Reset
|
||||
LCD_WRITE_CMD_16B(0x0100);
|
||||
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);
|
||||
|
||||
LCD_WRITE_REG(0xbc01, 0x0086);
|
||||
LCD_WRITE_REG(0xbc02, 0x006a);
|
||||
LCD_WRITE_REG(0xbd01, 0x0086);
|
||||
LCD_WRITE_REG(0xbd02, 0x006a);
|
||||
LCD_WRITE_REG(0xbe01, 0x0067);
|
||||
// Partial mode on
|
||||
LCD_WRITE_CMD_16B(0x1200);
|
||||
|
||||
LCD_WRITE_REG(0xd100, 0x0000);
|
||||
LCD_WRITE_REG(0xd101, 0x005d);
|
||||
LCD_WRITE_REG(0xd102, 0x0000);
|
||||
LCD_WRITE_REG(0xd103, 0x006b);
|
||||
LCD_WRITE_REG(0xd104, 0x0000);
|
||||
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);
|
||||
// Enable manufacturer command set, select page 1
|
||||
LCD_WRITE_REG_16B(0xf000, 0x0055);
|
||||
LCD_WRITE_REG_16B(0xf001, 0x00aa);
|
||||
LCD_WRITE_REG_16B(0xf002, 0x0052);
|
||||
LCD_WRITE_REG_16B(0xf003, 0x0008);
|
||||
LCD_WRITE_REG_16B(0xf004, 0x0001);
|
||||
|
||||
LCD_WRITE_REG(0xd200, 0x0000);
|
||||
LCD_WRITE_REG(0xd201, 0x005d);
|
||||
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 positive gamma divider)
|
||||
LCD_WRITE_REG_16B(0xbc01, 0x0086);
|
||||
LCD_WRITE_REG_16B(0xbc02, 0x006a);
|
||||
|
||||
LCD_WRITE_REG(0xd300, 0x0000);
|
||||
LCD_WRITE_REG(0xd301, 0x005d);
|
||||
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);
|
||||
// VGML and VGSP voltages (regulator output voltage VGMP/VGSP for negative gamma divider)
|
||||
LCD_WRITE_REG_16B(0xbd01, 0x0086);
|
||||
LCD_WRITE_REG_16B(0xbd02, 0x006a);
|
||||
|
||||
LCD_WRITE_REG(0xd400, 0x0000);
|
||||
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);
|
||||
// VCOM Offset Voltage
|
||||
LCD_WRITE_REG_16B(0xbe01, 0x0067);
|
||||
|
||||
LCD_WRITE_REG(0xd500, 0x0000);
|
||||
LCD_WRITE_REG(0xd501, 0x005d);
|
||||
LCD_WRITE_REG(0xd502, 0x0000);
|
||||
LCD_WRITE_REG(0xd503, 0x006b);
|
||||
LCD_WRITE_REG(0xd504, 0x0000);
|
||||
LCD_WRITE_REG(0xd505, 0x0084);
|
||||
LCD_WRITE_REG(0xd506, 0x0000);
|
||||
LCD_WRITE_REG(0xd507, 0x009c);
|
||||
LCD_WRITE_REG(0xd508, 0x0000);
|
||||
LCD_WRITE_REG(0xd509, 0x00b1);
|
||||
LCD_WRITE_REG(0xd50a, 0x0000);
|
||||
LCD_WRITE_REG(0xd50b, 0x00D9);
|
||||
LCD_WRITE_REG(0xd50c, 0x0000);
|
||||
LCD_WRITE_REG(0xd50d, 0x00fd);
|
||||
LCD_WRITE_REG(0xd50e, 0x0001);
|
||||
LCD_WRITE_REG(0xd50f, 0x0038);
|
||||
LCD_WRITE_REG(0xd510, 0x0001);
|
||||
LCD_WRITE_REG(0xd511, 0x0068);
|
||||
LCD_WRITE_REG(0xd512, 0x0001);
|
||||
LCD_WRITE_REG(0xd513, 0x00b9);
|
||||
LCD_WRITE_REG(0xd514, 0x0001);
|
||||
LCD_WRITE_REG(0xd515, 0x00fb);
|
||||
LCD_WRITE_REG(0xd516, 0x0002);
|
||||
LCD_WRITE_REG(0xd517, 0x0063);
|
||||
LCD_WRITE_REG(0xd518, 0x0002);
|
||||
LCD_WRITE_REG(0xd519, 0x00b9);
|
||||
LCD_WRITE_REG(0xd51a, 0x0002);
|
||||
LCD_WRITE_REG(0xd51b, 0x00bb);
|
||||
LCD_WRITE_REG(0xd51c, 0x0003);
|
||||
LCD_WRITE_REG(0xd51d, 0x0003);
|
||||
LCD_WRITE_REG(0xd51e, 0x0003);
|
||||
LCD_WRITE_REG(0xd51f, 0x0046);
|
||||
LCD_WRITE_REG(0xd520, 0x0003);
|
||||
LCD_WRITE_REG(0xd521, 0x0069);
|
||||
LCD_WRITE_REG(0xd522, 0x0003);
|
||||
LCD_WRITE_REG(0xd523, 0x008f);
|
||||
LCD_WRITE_REG(0xd524, 0x0003);
|
||||
LCD_WRITE_REG(0xd525, 0x00a4);
|
||||
LCD_WRITE_REG(0xd526, 0x0003);
|
||||
LCD_WRITE_REG(0xd527, 0x00b9);
|
||||
LCD_WRITE_REG(0xd528, 0x0003);
|
||||
LCD_WRITE_REG(0xd529, 0x00c7);
|
||||
LCD_WRITE_REG(0xd52a, 0x0003);
|
||||
LCD_WRITE_REG(0xd52b, 0x00c9);
|
||||
LCD_WRITE_REG(0xd52c, 0x0003);
|
||||
LCD_WRITE_REG(0xd52d, 0x00cb);
|
||||
LCD_WRITE_REG(0xd52e, 0x0003);
|
||||
LCD_WRITE_REG(0xd52f, 0x00cb);
|
||||
LCD_WRITE_REG(0xd530, 0x0003);
|
||||
LCD_WRITE_REG(0xd531, 0x00cb);
|
||||
LCD_WRITE_REG(0xd532, 0x0003);
|
||||
LCD_WRITE_REG(0xd533, 0x00cc);
|
||||
// Gamma 2.2 Correction for Red (Positive)
|
||||
LCD_WRITE_REG_16B(0xd100, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd101, 0x005d);
|
||||
LCD_WRITE_REG_16B(0xd102, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd103, 0x006b);
|
||||
LCD_WRITE_REG_16B(0xd104, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd105, 0x0084);
|
||||
LCD_WRITE_REG_16B(0xd106, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd107, 0x009c);
|
||||
LCD_WRITE_REG_16B(0xd108, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd109, 0x00b1);
|
||||
LCD_WRITE_REG_16B(0xd10a, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd10b, 0x00d9);
|
||||
LCD_WRITE_REG_16B(0xd10c, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd10d, 0x00fd);
|
||||
LCD_WRITE_REG_16B(0xd10e, 0x0001);
|
||||
LCD_WRITE_REG_16B(0xd10f, 0x0038);
|
||||
LCD_WRITE_REG_16B(0xd110, 0x0001);
|
||||
LCD_WRITE_REG_16B(0xd111, 0x0068);
|
||||
LCD_WRITE_REG_16B(0xd112, 0x0001);
|
||||
LCD_WRITE_REG_16B(0xd113, 0x00b9);
|
||||
LCD_WRITE_REG_16B(0xd114, 0x0001);
|
||||
LCD_WRITE_REG_16B(0xd115, 0x00fb);
|
||||
LCD_WRITE_REG_16B(0xd116, 0x0002);
|
||||
LCD_WRITE_REG_16B(0xd117, 0x0063);
|
||||
LCD_WRITE_REG_16B(0xd118, 0x0002);
|
||||
LCD_WRITE_REG_16B(0xd119, 0x00b9);
|
||||
LCD_WRITE_REG_16B(0xd11a, 0x0002);
|
||||
LCD_WRITE_REG_16B(0xd11b, 0x00bb);
|
||||
LCD_WRITE_REG_16B(0xd11c, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd11d, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd11e, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd11f, 0x0046);
|
||||
LCD_WRITE_REG_16B(0xd120, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd121, 0x0069);
|
||||
LCD_WRITE_REG_16B(0xd122, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd123, 0x008f);
|
||||
LCD_WRITE_REG_16B(0xd124, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd125, 0x00a4);
|
||||
LCD_WRITE_REG_16B(0xd126, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd127, 0x00b9);
|
||||
LCD_WRITE_REG_16B(0xd128, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd129, 0x00c7);
|
||||
LCD_WRITE_REG_16B(0xd12a, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd12b, 0x00c9);
|
||||
LCD_WRITE_REG_16B(0xd12c, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd12d, 0x00cb);
|
||||
LCD_WRITE_REG_16B(0xd12e, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd12f, 0x00cb);
|
||||
LCD_WRITE_REG_16B(0xd130, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd131, 0x00cb);
|
||||
LCD_WRITE_REG_16B(0xd132, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd133, 0x00cc);
|
||||
|
||||
LCD_WRITE_REG(0xd600, 0x0000);
|
||||
LCD_WRITE_REG(0xd601, 0x005d);
|
||||
LCD_WRITE_REG(0xd602, 0x0000);
|
||||
LCD_WRITE_REG(0xd603, 0x006b);
|
||||
LCD_WRITE_REG(0xd604, 0x0000);
|
||||
LCD_WRITE_REG(0xd605, 0x0084);
|
||||
LCD_WRITE_REG(0xd606, 0x0000);
|
||||
LCD_WRITE_REG(0xd607, 0x009c);
|
||||
LCD_WRITE_REG(0xd608, 0x0000);
|
||||
LCD_WRITE_REG(0xd609, 0x00b1);
|
||||
LCD_WRITE_REG(0xd60a, 0x0000);
|
||||
LCD_WRITE_REG(0xd60b, 0x00d9);
|
||||
LCD_WRITE_REG(0xd60c, 0x0000);
|
||||
LCD_WRITE_REG(0xd60d, 0x00fd);
|
||||
LCD_WRITE_REG(0xd60e, 0x0001);
|
||||
LCD_WRITE_REG(0xd60f, 0x0038);
|
||||
LCD_WRITE_REG(0xd610, 0x0001);
|
||||
LCD_WRITE_REG(0xd611, 0x0068);
|
||||
LCD_WRITE_REG(0xd612, 0x0001);
|
||||
LCD_WRITE_REG(0xd613, 0x00b9);
|
||||
LCD_WRITE_REG(0xd614, 0x0001);
|
||||
LCD_WRITE_REG(0xd615, 0x00fb);
|
||||
LCD_WRITE_REG(0xd616, 0x0002);
|
||||
LCD_WRITE_REG(0xd617, 0x0063);
|
||||
LCD_WRITE_REG(0xd618, 0x0002);
|
||||
LCD_WRITE_REG(0xd619, 0x00b9);
|
||||
LCD_WRITE_REG(0xd61a, 0x0002);
|
||||
LCD_WRITE_REG(0xd61b, 0x00bb);
|
||||
LCD_WRITE_REG(0xd61c, 0x0003);
|
||||
LCD_WRITE_REG(0xd61d, 0x0003);
|
||||
LCD_WRITE_REG(0xd61e, 0x0003);
|
||||
LCD_WRITE_REG(0xd61f, 0x0046);
|
||||
LCD_WRITE_REG(0xd620, 0x0003);
|
||||
LCD_WRITE_REG(0xd621, 0x0069);
|
||||
LCD_WRITE_REG(0xd622, 0x0003);
|
||||
LCD_WRITE_REG(0xd623, 0x008f);
|
||||
LCD_WRITE_REG(0xd624, 0x0003);
|
||||
LCD_WRITE_REG(0xd625, 0x00a4);
|
||||
LCD_WRITE_REG(0xd626, 0x0003);
|
||||
LCD_WRITE_REG(0xd627, 0x00b9);
|
||||
LCD_WRITE_REG(0xd628, 0x0003);
|
||||
LCD_WRITE_REG(0xd629, 0x00c7);
|
||||
LCD_WRITE_REG(0xd62a, 0x0003);
|
||||
LCD_WRITE_REG(0xd62b, 0x00c9);
|
||||
LCD_WRITE_REG(0xd62c, 0x0003);
|
||||
LCD_WRITE_REG(0xd62d, 0x00cb);
|
||||
LCD_WRITE_REG(0xd62e, 0x0003);
|
||||
LCD_WRITE_REG(0xd62f, 0x00cb);
|
||||
LCD_WRITE_REG(0xd630, 0x0003);
|
||||
LCD_WRITE_REG(0xd631, 0x00cb);
|
||||
LCD_WRITE_REG(0xd632, 0x0003);
|
||||
LCD_WRITE_REG(0xd633, 0x00cc);
|
||||
// Gamma 2.2 Correction for Green (Positive)
|
||||
LCD_WRITE_REG_16B(0xd200, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd201, 0x005d);
|
||||
LCD_WRITE_REG_16B(0xd202, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd203, 0x006b);
|
||||
LCD_WRITE_REG_16B(0xd204, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd205, 0x0084);
|
||||
LCD_WRITE_REG_16B(0xd206, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd207, 0x009c);
|
||||
LCD_WRITE_REG_16B(0xd208, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd209, 0x00b1);
|
||||
LCD_WRITE_REG_16B(0xd20a, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd20b, 0x00d9);
|
||||
LCD_WRITE_REG_16B(0xd20c, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd20d, 0x00fd);
|
||||
LCD_WRITE_REG_16B(0xd20e, 0x0001);
|
||||
LCD_WRITE_REG_16B(0xd20f, 0x0038);
|
||||
LCD_WRITE_REG_16B(0xd210, 0x0001);
|
||||
LCD_WRITE_REG_16B(0xd211, 0x0068);
|
||||
LCD_WRITE_REG_16B(0xd212, 0x0001);
|
||||
LCD_WRITE_REG_16B(0xd213, 0x00b9);
|
||||
LCD_WRITE_REG_16B(0xd214, 0x0001);
|
||||
LCD_WRITE_REG_16B(0xd215, 0x00fb);
|
||||
LCD_WRITE_REG_16B(0xd216, 0x0002);
|
||||
LCD_WRITE_REG_16B(0xd217, 0x0063);
|
||||
LCD_WRITE_REG_16B(0xd218, 0x0002);
|
||||
LCD_WRITE_REG_16B(0xd219, 0x00b9);
|
||||
LCD_WRITE_REG_16B(0xd21a, 0x0002);
|
||||
LCD_WRITE_REG_16B(0xd21b, 0x00bb);
|
||||
LCD_WRITE_REG_16B(0xd21c, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd21d, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd21e, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd21f, 0x0046);
|
||||
LCD_WRITE_REG_16B(0xd220, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd221, 0x0069);
|
||||
LCD_WRITE_REG_16B(0xd222, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd223, 0x008f);
|
||||
LCD_WRITE_REG_16B(0xd224, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd225, 0x00a4);
|
||||
LCD_WRITE_REG_16B(0xd226, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd227, 0x00b9);
|
||||
LCD_WRITE_REG_16B(0xd228, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd229, 0x00c7);
|
||||
LCD_WRITE_REG_16B(0xd22a, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd22b, 0x00c9);
|
||||
LCD_WRITE_REG_16B(0xd22c, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd22d, 0x00cb);
|
||||
LCD_WRITE_REG_16B(0xd22e, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd22f, 0x00cb);
|
||||
LCD_WRITE_REG_16B(0xd230, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd231, 0x00cb);
|
||||
LCD_WRITE_REG_16B(0xd232, 0x0003);
|
||||
LCD_WRITE_REG_16B(0xd233, 0x00cc);
|
||||
|
||||
LCD_WRITE_REG(0xba00, 0x0024);
|
||||
LCD_WRITE_REG(0xba01, 0x0024);
|
||||
LCD_WRITE_REG(0xba02, 0x0024);
|
||||
// Gamma 2.2 Correction for Blue (Positive)
|
||||
LCD_WRITE_REG_16B(0xd300, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd301, 0x005d);
|
||||
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);
|
||||
|
||||
LCD_WRITE_REG(0xb900, 0x0024);
|
||||
LCD_WRITE_REG(0xb901, 0x0024);
|
||||
LCD_WRITE_REG(0xb902, 0x0024);
|
||||
// Gamma 2.2 Correction for Red (Negative)
|
||||
LCD_WRITE_REG_16B(0xd400, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd401, 0x005d);
|
||||
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);
|
||||
|
||||
LCD_WRITE_REG(0xf000, 0x0055);
|
||||
LCD_WRITE_REG(0xf001, 0x00aa);
|
||||
LCD_WRITE_REG(0xf002, 0x0052);
|
||||
LCD_WRITE_REG(0xf003, 0x0008);
|
||||
LCD_WRITE_REG(0xf004, 0x0000);
|
||||
// Gamma 2.2 Correction for Green (Negative)
|
||||
LCD_WRITE_REG_16B(0xd500, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd501, 0x005d);
|
||||
LCD_WRITE_REG_16B(0xd502, 0x0000);
|
||||
LCD_WRITE_REG_16B(0xd503, 0x006b);
|
||||
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);
|
||||
|
||||
LCD_WRITE_REG(0xb100, 0x00cc);
|
||||
LCD_WRITE_REG(0xB500, 0x0050);
|
||||
// Gamma 2.2 Correction for Blue (Negative)
|
||||
LCD_WRITE_REG_16B(0xd600, 0x0000);
|
||||
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);
|
||||
|
||||
LCD_WRITE_REG(0xbc00, 0x0005);
|
||||
LCD_WRITE_REG(0xbc01, 0x0005);
|
||||
LCD_WRITE_REG(0xbc02, 0x0005);
|
||||
// BT5 Power Control for VGLX
|
||||
LCD_WRITE_REG_16B(0xba00, 0x0024);
|
||||
LCD_WRITE_REG_16B(0xba01, 0x0024);
|
||||
LCD_WRITE_REG_16B(0xba02, 0x0024);
|
||||
|
||||
LCD_WRITE_REG(0xb800, 0x0001);
|
||||
LCD_WRITE_REG(0xb801, 0x0003);
|
||||
LCD_WRITE_REG(0xb802, 0x0003);
|
||||
LCD_WRITE_REG(0xb803, 0x0003);
|
||||
// BT4 Power Control for VGH
|
||||
LCD_WRITE_REG_16B(0xb900, 0x0024);
|
||||
LCD_WRITE_REG_16B(0xb901, 0x0024);
|
||||
LCD_WRITE_REG_16B(0xb902, 0x0024);
|
||||
|
||||
LCD_WRITE_REG(0xbd02, 0x0007);
|
||||
LCD_WRITE_REG(0xbd03, 0x0031);
|
||||
LCD_WRITE_REG(0xbe02, 0x0007);
|
||||
LCD_WRITE_REG(0xbe03, 0x0031);
|
||||
LCD_WRITE_REG(0xbf02, 0x0007);
|
||||
LCD_WRITE_REG(0xbf03, 0x0031);
|
||||
// Enable manufacturer command set, select page 0
|
||||
LCD_WRITE_REG_16B(0xf000, 0x0055);
|
||||
LCD_WRITE_REG_16B(0xf001, 0x00aa);
|
||||
LCD_WRITE_REG_16B(0xf002, 0x0052);
|
||||
LCD_WRITE_REG_16B(0xf003, 0x0008);
|
||||
LCD_WRITE_REG_16B(0xf004, 0x0000);
|
||||
|
||||
LCD_WRITE_REG(0xff00, 0x00aa);
|
||||
LCD_WRITE_REG(0xff01, 0x0055);
|
||||
LCD_WRITE_REG(0xff02, 0x0025);
|
||||
LCD_WRITE_REG(0xff03, 0x0001);
|
||||
// Display Option Control
|
||||
LCD_WRITE_REG_16B(0xb100, 0x00cc);
|
||||
|
||||
LCD_WRITE_REG(0xf304, 0x0011);
|
||||
LCD_WRITE_REG(0xf306, 0x0010);
|
||||
LCD_WRITE_REG(0xf308, 0x0000);
|
||||
// Display Resolution Control
|
||||
LCD_WRITE_REG_16B(0xB500, 0x0050); // 480RGB X 800
|
||||
|
||||
// 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
|
||||
LCD_WRITE_CMD(0x1100);
|
||||
LCD_WRITE_CMD_16B(0x1100);
|
||||
|
||||
// Write continue
|
||||
LCD_WRITE_CMD(0x2C00);
|
||||
LCD_WRITE_CMD_16B(0x2C00);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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->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->interface_drv->write_cmd && \
|
||||
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 && \
|
||||
|
|
@ -176,7 +176,7 @@ esp_err_t lcd_rm68120_set_rotation(scr_dir_t dir)
|
|||
default: break;
|
||||
}
|
||||
ESP_LOGI(TAG, "MADCTL=0x%x", reg_data);
|
||||
ret = LCD_WRITE_REG(RM68120_MADCTL, reg_data);
|
||||
ret = LCD_WRITE_REG_16B(RM68120_MADCTL, reg_data);
|
||||
LCD_CHECK(ESP_OK == ret, "Set screen rotate failed", ESP_FAIL);
|
||||
g_lcd_handle.dir = dir;
|
||||
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;
|
||||
scr_utility_apply_offset(&g_lcd_handle, RM68120_RESOLUTION_HOR, RM68120_RESOLUTION_VER, &x0, &y0, &x1, &y1);
|
||||
|
||||
ret |= LCD_WRITE_REG(RM68120_CASET, x0 >> 8);
|
||||
ret |= LCD_WRITE_REG(RM68120_CASET + 1, x0 & 0xff);
|
||||
ret |= LCD_WRITE_REG(RM68120_CASET + 2, x1 >> 8);
|
||||
ret |= LCD_WRITE_REG(RM68120_CASET + 3, x1 & 0xff);
|
||||
ret |= LCD_WRITE_REG(RM68120_RASET, y0 >> 8);
|
||||
ret |= LCD_WRITE_REG(RM68120_RASET + 1, y0 & 0xff);
|
||||
ret |= LCD_WRITE_REG(RM68120_RASET + 2, y1 >> 8);
|
||||
ret |= LCD_WRITE_REG(RM68120_RASET + 3, y1 & 0xff);
|
||||
ret |= LCD_WRITE_REG_16B(RM68120_CASET, x0 >> 8);
|
||||
ret |= LCD_WRITE_REG_16B(RM68120_CASET + 1, x0 & 0xff);
|
||||
ret |= LCD_WRITE_REG_16B(RM68120_CASET + 2, x1 >> 8);
|
||||
ret |= LCD_WRITE_REG_16B(RM68120_CASET + 3, x1 & 0xff);
|
||||
ret |= LCD_WRITE_REG_16B(RM68120_RASET, y0 >> 8);
|
||||
ret |= LCD_WRITE_REG_16B(RM68120_RASET + 1, y0 & 0xff);
|
||||
ret |= LCD_WRITE_REG_16B(RM68120_RASET + 2, y1 >> 8);
|
||||
ret |= LCD_WRITE_REG_16B(RM68120_RASET + 3, y1 & 0xff);
|
||||
|
||||
ret |= LCD_WRITE_CMD(RM68120_RAMWR);
|
||||
ret |= LCD_WRITE_CMD_16B(RM68120_RAMWR);
|
||||
LCD_CHECK(ESP_OK == ret, "Set window failed", ESP_FAIL);
|
||||
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)
|
||||
{
|
||||
LCD_WRITE_CMD(0x0100); // Software Reset
|
||||
LCD_WRITE_CMD_16B(0x0100); // Software Reset
|
||||
vTaskDelay(10 / portTICK_RATE_MS);
|
||||
LCD_WRITE_REG(0xF000, 0x55);
|
||||
LCD_WRITE_REG(0xF001, 0xAA);
|
||||
LCD_WRITE_REG(0xF002, 0x52);
|
||||
LCD_WRITE_REG(0xF003, 0x08);
|
||||
LCD_WRITE_REG(0xF004, 0x01);
|
||||
LCD_WRITE_REG_16B(0xF000, 0x55);
|
||||
LCD_WRITE_REG_16B(0xF001, 0xAA);
|
||||
LCD_WRITE_REG_16B(0xF002, 0x52);
|
||||
LCD_WRITE_REG_16B(0xF003, 0x08);
|
||||
LCD_WRITE_REG_16B(0xF004, 0x01);
|
||||
|
||||
//GAMMA SETING RED
|
||||
LCD_WRITE_REG(0xD100, 0x00);
|
||||
LCD_WRITE_REG(0xD101, 0x00);
|
||||
LCD_WRITE_REG(0xD102, 0x1b);
|
||||
LCD_WRITE_REG(0xD103, 0x44);
|
||||
LCD_WRITE_REG(0xD104, 0x62);
|
||||
LCD_WRITE_REG(0xD105, 0x00);
|
||||
LCD_WRITE_REG(0xD106, 0x7b);
|
||||
LCD_WRITE_REG(0xD107, 0xa1);
|
||||
LCD_WRITE_REG(0xD108, 0xc0);
|
||||
LCD_WRITE_REG(0xD109, 0xee);
|
||||
LCD_WRITE_REG(0xD10A, 0x55);
|
||||
LCD_WRITE_REG(0xD10B, 0x10);
|
||||
LCD_WRITE_REG(0xD10C, 0x2c);
|
||||
LCD_WRITE_REG(0xD10D, 0x43);
|
||||
LCD_WRITE_REG(0xD10E, 0x57);
|
||||
LCD_WRITE_REG(0xD10F, 0x55);
|
||||
LCD_WRITE_REG(0xD110, 0x68);
|
||||
LCD_WRITE_REG(0xD111, 0x78);
|
||||
LCD_WRITE_REG(0xD112, 0x87);
|
||||
LCD_WRITE_REG(0xD113, 0x94);
|
||||
LCD_WRITE_REG(0xD114, 0x55);
|
||||
LCD_WRITE_REG(0xD115, 0xa0);
|
||||
LCD_WRITE_REG(0xD116, 0xac);
|
||||
LCD_WRITE_REG(0xD117, 0xb6);
|
||||
LCD_WRITE_REG(0xD118, 0xc1);
|
||||
LCD_WRITE_REG(0xD119, 0x55);
|
||||
LCD_WRITE_REG(0xD11A, 0xcb);
|
||||
LCD_WRITE_REG(0xD11B, 0xcd);
|
||||
LCD_WRITE_REG(0xD11C, 0xd6);
|
||||
LCD_WRITE_REG(0xD11D, 0xdf);
|
||||
LCD_WRITE_REG(0xD11E, 0x95);
|
||||
LCD_WRITE_REG(0xD11F, 0xe8);
|
||||
LCD_WRITE_REG(0xD120, 0xf1);
|
||||
LCD_WRITE_REG(0xD121, 0xfa);
|
||||
LCD_WRITE_REG(0xD122, 0x02);
|
||||
LCD_WRITE_REG(0xD123, 0xaa);
|
||||
LCD_WRITE_REG(0xD124, 0x0b);
|
||||
LCD_WRITE_REG(0xD125, 0x13);
|
||||
LCD_WRITE_REG(0xD126, 0x1d);
|
||||
LCD_WRITE_REG(0xD127, 0x26);
|
||||
LCD_WRITE_REG(0xD128, 0xaa);
|
||||
LCD_WRITE_REG(0xD129, 0x30);
|
||||
LCD_WRITE_REG(0xD12A, 0x3c);
|
||||
LCD_WRITE_REG(0xD12B, 0x4A);
|
||||
LCD_WRITE_REG(0xD12C, 0x63);
|
||||
LCD_WRITE_REG(0xD12D, 0xea);
|
||||
LCD_WRITE_REG(0xD12E, 0x79);
|
||||
LCD_WRITE_REG(0xD12F, 0xa6);
|
||||
LCD_WRITE_REG(0xD130, 0xd0);
|
||||
LCD_WRITE_REG(0xD131, 0x20);
|
||||
LCD_WRITE_REG(0xD132, 0x0f);
|
||||
LCD_WRITE_REG(0xD133, 0x8e);
|
||||
LCD_WRITE_REG(0xD134, 0xff);
|
||||
LCD_WRITE_REG_16B(0xD100, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD101, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD102, 0x1b);
|
||||
LCD_WRITE_REG_16B(0xD103, 0x44);
|
||||
LCD_WRITE_REG_16B(0xD104, 0x62);
|
||||
LCD_WRITE_REG_16B(0xD105, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD106, 0x7b);
|
||||
LCD_WRITE_REG_16B(0xD107, 0xa1);
|
||||
LCD_WRITE_REG_16B(0xD108, 0xc0);
|
||||
LCD_WRITE_REG_16B(0xD109, 0xee);
|
||||
LCD_WRITE_REG_16B(0xD10A, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD10B, 0x10);
|
||||
LCD_WRITE_REG_16B(0xD10C, 0x2c);
|
||||
LCD_WRITE_REG_16B(0xD10D, 0x43);
|
||||
LCD_WRITE_REG_16B(0xD10E, 0x57);
|
||||
LCD_WRITE_REG_16B(0xD10F, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD110, 0x68);
|
||||
LCD_WRITE_REG_16B(0xD111, 0x78);
|
||||
LCD_WRITE_REG_16B(0xD112, 0x87);
|
||||
LCD_WRITE_REG_16B(0xD113, 0x94);
|
||||
LCD_WRITE_REG_16B(0xD114, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD115, 0xa0);
|
||||
LCD_WRITE_REG_16B(0xD116, 0xac);
|
||||
LCD_WRITE_REG_16B(0xD117, 0xb6);
|
||||
LCD_WRITE_REG_16B(0xD118, 0xc1);
|
||||
LCD_WRITE_REG_16B(0xD119, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD11A, 0xcb);
|
||||
LCD_WRITE_REG_16B(0xD11B, 0xcd);
|
||||
LCD_WRITE_REG_16B(0xD11C, 0xd6);
|
||||
LCD_WRITE_REG_16B(0xD11D, 0xdf);
|
||||
LCD_WRITE_REG_16B(0xD11E, 0x95);
|
||||
LCD_WRITE_REG_16B(0xD11F, 0xe8);
|
||||
LCD_WRITE_REG_16B(0xD120, 0xf1);
|
||||
LCD_WRITE_REG_16B(0xD121, 0xfa);
|
||||
LCD_WRITE_REG_16B(0xD122, 0x02);
|
||||
LCD_WRITE_REG_16B(0xD123, 0xaa);
|
||||
LCD_WRITE_REG_16B(0xD124, 0x0b);
|
||||
LCD_WRITE_REG_16B(0xD125, 0x13);
|
||||
LCD_WRITE_REG_16B(0xD126, 0x1d);
|
||||
LCD_WRITE_REG_16B(0xD127, 0x26);
|
||||
LCD_WRITE_REG_16B(0xD128, 0xaa);
|
||||
LCD_WRITE_REG_16B(0xD129, 0x30);
|
||||
LCD_WRITE_REG_16B(0xD12A, 0x3c);
|
||||
LCD_WRITE_REG_16B(0xD12B, 0x4A);
|
||||
LCD_WRITE_REG_16B(0xD12C, 0x63);
|
||||
LCD_WRITE_REG_16B(0xD12D, 0xea);
|
||||
LCD_WRITE_REG_16B(0xD12E, 0x79);
|
||||
LCD_WRITE_REG_16B(0xD12F, 0xa6);
|
||||
LCD_WRITE_REG_16B(0xD130, 0xd0);
|
||||
LCD_WRITE_REG_16B(0xD131, 0x20);
|
||||
LCD_WRITE_REG_16B(0xD132, 0x0f);
|
||||
LCD_WRITE_REG_16B(0xD133, 0x8e);
|
||||
LCD_WRITE_REG_16B(0xD134, 0xff);
|
||||
//GAMMA SETING GREEN
|
||||
LCD_WRITE_REG(0xD200, 0x00);
|
||||
LCD_WRITE_REG(0xD201, 0x00);
|
||||
LCD_WRITE_REG(0xD202, 0x1b);
|
||||
LCD_WRITE_REG(0xD203, 0x44);
|
||||
LCD_WRITE_REG(0xD204, 0x62);
|
||||
LCD_WRITE_REG(0xD205, 0x00);
|
||||
LCD_WRITE_REG(0xD206, 0x7b);
|
||||
LCD_WRITE_REG(0xD207, 0xa1);
|
||||
LCD_WRITE_REG(0xD208, 0xc0);
|
||||
LCD_WRITE_REG(0xD209, 0xee);
|
||||
LCD_WRITE_REG(0xD20A, 0x55);
|
||||
LCD_WRITE_REG(0xD20B, 0x10);
|
||||
LCD_WRITE_REG(0xD20C, 0x2c);
|
||||
LCD_WRITE_REG(0xD20D, 0x43);
|
||||
LCD_WRITE_REG(0xD20E, 0x57);
|
||||
LCD_WRITE_REG(0xD20F, 0x55);
|
||||
LCD_WRITE_REG(0xD210, 0x68);
|
||||
LCD_WRITE_REG(0xD211, 0x78);
|
||||
LCD_WRITE_REG(0xD212, 0x87);
|
||||
LCD_WRITE_REG(0xD213, 0x94);
|
||||
LCD_WRITE_REG(0xD214, 0x55);
|
||||
LCD_WRITE_REG(0xD215, 0xa0);
|
||||
LCD_WRITE_REG(0xD216, 0xac);
|
||||
LCD_WRITE_REG(0xD217, 0xb6);
|
||||
LCD_WRITE_REG(0xD218, 0xc1);
|
||||
LCD_WRITE_REG(0xD219, 0x55);
|
||||
LCD_WRITE_REG(0xD21A, 0xcb);
|
||||
LCD_WRITE_REG(0xD21B, 0xcd);
|
||||
LCD_WRITE_REG(0xD21C, 0xd6);
|
||||
LCD_WRITE_REG(0xD21D, 0xdf);
|
||||
LCD_WRITE_REG(0xD21E, 0x95);
|
||||
LCD_WRITE_REG(0xD21F, 0xe8);
|
||||
LCD_WRITE_REG(0xD220, 0xf1);
|
||||
LCD_WRITE_REG(0xD221, 0xfa);
|
||||
LCD_WRITE_REG(0xD222, 0x02);
|
||||
LCD_WRITE_REG(0xD223, 0xaa);
|
||||
LCD_WRITE_REG(0xD224, 0x0b);
|
||||
LCD_WRITE_REG(0xD225, 0x13);
|
||||
LCD_WRITE_REG(0xD226, 0x1d);
|
||||
LCD_WRITE_REG(0xD227, 0x26);
|
||||
LCD_WRITE_REG(0xD228, 0xaa);
|
||||
LCD_WRITE_REG(0xD229, 0x30);
|
||||
LCD_WRITE_REG(0xD22A, 0x3c);
|
||||
LCD_WRITE_REG(0xD22B, 0x4a);
|
||||
LCD_WRITE_REG(0xD22C, 0x63);
|
||||
LCD_WRITE_REG(0xD22D, 0xea);
|
||||
LCD_WRITE_REG(0xD22E, 0x79);
|
||||
LCD_WRITE_REG(0xD22F, 0xa6);
|
||||
LCD_WRITE_REG(0xD230, 0xd0);
|
||||
LCD_WRITE_REG(0xD231, 0x20);
|
||||
LCD_WRITE_REG(0xD232, 0x0f);
|
||||
LCD_WRITE_REG(0xD233, 0x8e);
|
||||
LCD_WRITE_REG(0xD234, 0xff);
|
||||
LCD_WRITE_REG_16B(0xD200, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD201, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD202, 0x1b);
|
||||
LCD_WRITE_REG_16B(0xD203, 0x44);
|
||||
LCD_WRITE_REG_16B(0xD204, 0x62);
|
||||
LCD_WRITE_REG_16B(0xD205, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD206, 0x7b);
|
||||
LCD_WRITE_REG_16B(0xD207, 0xa1);
|
||||
LCD_WRITE_REG_16B(0xD208, 0xc0);
|
||||
LCD_WRITE_REG_16B(0xD209, 0xee);
|
||||
LCD_WRITE_REG_16B(0xD20A, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD20B, 0x10);
|
||||
LCD_WRITE_REG_16B(0xD20C, 0x2c);
|
||||
LCD_WRITE_REG_16B(0xD20D, 0x43);
|
||||
LCD_WRITE_REG_16B(0xD20E, 0x57);
|
||||
LCD_WRITE_REG_16B(0xD20F, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD210, 0x68);
|
||||
LCD_WRITE_REG_16B(0xD211, 0x78);
|
||||
LCD_WRITE_REG_16B(0xD212, 0x87);
|
||||
LCD_WRITE_REG_16B(0xD213, 0x94);
|
||||
LCD_WRITE_REG_16B(0xD214, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD215, 0xa0);
|
||||
LCD_WRITE_REG_16B(0xD216, 0xac);
|
||||
LCD_WRITE_REG_16B(0xD217, 0xb6);
|
||||
LCD_WRITE_REG_16B(0xD218, 0xc1);
|
||||
LCD_WRITE_REG_16B(0xD219, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD21A, 0xcb);
|
||||
LCD_WRITE_REG_16B(0xD21B, 0xcd);
|
||||
LCD_WRITE_REG_16B(0xD21C, 0xd6);
|
||||
LCD_WRITE_REG_16B(0xD21D, 0xdf);
|
||||
LCD_WRITE_REG_16B(0xD21E, 0x95);
|
||||
LCD_WRITE_REG_16B(0xD21F, 0xe8);
|
||||
LCD_WRITE_REG_16B(0xD220, 0xf1);
|
||||
LCD_WRITE_REG_16B(0xD221, 0xfa);
|
||||
LCD_WRITE_REG_16B(0xD222, 0x02);
|
||||
LCD_WRITE_REG_16B(0xD223, 0xaa);
|
||||
LCD_WRITE_REG_16B(0xD224, 0x0b);
|
||||
LCD_WRITE_REG_16B(0xD225, 0x13);
|
||||
LCD_WRITE_REG_16B(0xD226, 0x1d);
|
||||
LCD_WRITE_REG_16B(0xD227, 0x26);
|
||||
LCD_WRITE_REG_16B(0xD228, 0xaa);
|
||||
LCD_WRITE_REG_16B(0xD229, 0x30);
|
||||
LCD_WRITE_REG_16B(0xD22A, 0x3c);
|
||||
LCD_WRITE_REG_16B(0xD22B, 0x4a);
|
||||
LCD_WRITE_REG_16B(0xD22C, 0x63);
|
||||
LCD_WRITE_REG_16B(0xD22D, 0xea);
|
||||
LCD_WRITE_REG_16B(0xD22E, 0x79);
|
||||
LCD_WRITE_REG_16B(0xD22F, 0xa6);
|
||||
LCD_WRITE_REG_16B(0xD230, 0xd0);
|
||||
LCD_WRITE_REG_16B(0xD231, 0x20);
|
||||
LCD_WRITE_REG_16B(0xD232, 0x0f);
|
||||
LCD_WRITE_REG_16B(0xD233, 0x8e);
|
||||
LCD_WRITE_REG_16B(0xD234, 0xff);
|
||||
|
||||
//GAMMA SETING BLUE
|
||||
LCD_WRITE_REG(0xD300, 0x00);
|
||||
LCD_WRITE_REG(0xD301, 0x00);
|
||||
LCD_WRITE_REG(0xD302, 0x1b);
|
||||
LCD_WRITE_REG(0xD303, 0x44);
|
||||
LCD_WRITE_REG(0xD304, 0x62);
|
||||
LCD_WRITE_REG(0xD305, 0x00);
|
||||
LCD_WRITE_REG(0xD306, 0x7b);
|
||||
LCD_WRITE_REG(0xD307, 0xa1);
|
||||
LCD_WRITE_REG(0xD308, 0xc0);
|
||||
LCD_WRITE_REG(0xD309, 0xee);
|
||||
LCD_WRITE_REG(0xD30A, 0x55);
|
||||
LCD_WRITE_REG(0xD30B, 0x10);
|
||||
LCD_WRITE_REG(0xD30C, 0x2c);
|
||||
LCD_WRITE_REG(0xD30D, 0x43);
|
||||
LCD_WRITE_REG(0xD30E, 0x57);
|
||||
LCD_WRITE_REG(0xD30F, 0x55);
|
||||
LCD_WRITE_REG(0xD310, 0x68);
|
||||
LCD_WRITE_REG(0xD311, 0x78);
|
||||
LCD_WRITE_REG(0xD312, 0x87);
|
||||
LCD_WRITE_REG(0xD313, 0x94);
|
||||
LCD_WRITE_REG(0xD314, 0x55);
|
||||
LCD_WRITE_REG(0xD315, 0xa0);
|
||||
LCD_WRITE_REG(0xD316, 0xac);
|
||||
LCD_WRITE_REG(0xD317, 0xb6);
|
||||
LCD_WRITE_REG(0xD318, 0xc1);
|
||||
LCD_WRITE_REG(0xD319, 0x55);
|
||||
LCD_WRITE_REG(0xD31A, 0xcb);
|
||||
LCD_WRITE_REG(0xD31B, 0xcd);
|
||||
LCD_WRITE_REG(0xD31C, 0xd6);
|
||||
LCD_WRITE_REG(0xD31D, 0xdf);
|
||||
LCD_WRITE_REG(0xD31E, 0x95);
|
||||
LCD_WRITE_REG(0xD31F, 0xe8);
|
||||
LCD_WRITE_REG(0xD320, 0xf1);
|
||||
LCD_WRITE_REG(0xD321, 0xfa);
|
||||
LCD_WRITE_REG(0xD322, 0x02);
|
||||
LCD_WRITE_REG(0xD323, 0xaa);
|
||||
LCD_WRITE_REG(0xD324, 0x0b);
|
||||
LCD_WRITE_REG(0xD325, 0x13);
|
||||
LCD_WRITE_REG(0xD326, 0x1d);
|
||||
LCD_WRITE_REG(0xD327, 0x26);
|
||||
LCD_WRITE_REG(0xD328, 0xaa);
|
||||
LCD_WRITE_REG(0xD329, 0x30);
|
||||
LCD_WRITE_REG(0xD32A, 0x3c);
|
||||
LCD_WRITE_REG(0xD32B, 0x4A);
|
||||
LCD_WRITE_REG(0xD32C, 0x63);
|
||||
LCD_WRITE_REG(0xD32D, 0xea);
|
||||
LCD_WRITE_REG(0xD32E, 0x79);
|
||||
LCD_WRITE_REG(0xD32F, 0xa6);
|
||||
LCD_WRITE_REG(0xD330, 0xd0);
|
||||
LCD_WRITE_REG(0xD331, 0x20);
|
||||
LCD_WRITE_REG(0xD332, 0x0f);
|
||||
LCD_WRITE_REG(0xD333, 0x8e);
|
||||
LCD_WRITE_REG(0xD334, 0xff);
|
||||
LCD_WRITE_REG_16B(0xD300, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD301, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD302, 0x1b);
|
||||
LCD_WRITE_REG_16B(0xD303, 0x44);
|
||||
LCD_WRITE_REG_16B(0xD304, 0x62);
|
||||
LCD_WRITE_REG_16B(0xD305, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD306, 0x7b);
|
||||
LCD_WRITE_REG_16B(0xD307, 0xa1);
|
||||
LCD_WRITE_REG_16B(0xD308, 0xc0);
|
||||
LCD_WRITE_REG_16B(0xD309, 0xee);
|
||||
LCD_WRITE_REG_16B(0xD30A, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD30B, 0x10);
|
||||
LCD_WRITE_REG_16B(0xD30C, 0x2c);
|
||||
LCD_WRITE_REG_16B(0xD30D, 0x43);
|
||||
LCD_WRITE_REG_16B(0xD30E, 0x57);
|
||||
LCD_WRITE_REG_16B(0xD30F, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD310, 0x68);
|
||||
LCD_WRITE_REG_16B(0xD311, 0x78);
|
||||
LCD_WRITE_REG_16B(0xD312, 0x87);
|
||||
LCD_WRITE_REG_16B(0xD313, 0x94);
|
||||
LCD_WRITE_REG_16B(0xD314, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD315, 0xa0);
|
||||
LCD_WRITE_REG_16B(0xD316, 0xac);
|
||||
LCD_WRITE_REG_16B(0xD317, 0xb6);
|
||||
LCD_WRITE_REG_16B(0xD318, 0xc1);
|
||||
LCD_WRITE_REG_16B(0xD319, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD31A, 0xcb);
|
||||
LCD_WRITE_REG_16B(0xD31B, 0xcd);
|
||||
LCD_WRITE_REG_16B(0xD31C, 0xd6);
|
||||
LCD_WRITE_REG_16B(0xD31D, 0xdf);
|
||||
LCD_WRITE_REG_16B(0xD31E, 0x95);
|
||||
LCD_WRITE_REG_16B(0xD31F, 0xe8);
|
||||
LCD_WRITE_REG_16B(0xD320, 0xf1);
|
||||
LCD_WRITE_REG_16B(0xD321, 0xfa);
|
||||
LCD_WRITE_REG_16B(0xD322, 0x02);
|
||||
LCD_WRITE_REG_16B(0xD323, 0xaa);
|
||||
LCD_WRITE_REG_16B(0xD324, 0x0b);
|
||||
LCD_WRITE_REG_16B(0xD325, 0x13);
|
||||
LCD_WRITE_REG_16B(0xD326, 0x1d);
|
||||
LCD_WRITE_REG_16B(0xD327, 0x26);
|
||||
LCD_WRITE_REG_16B(0xD328, 0xaa);
|
||||
LCD_WRITE_REG_16B(0xD329, 0x30);
|
||||
LCD_WRITE_REG_16B(0xD32A, 0x3c);
|
||||
LCD_WRITE_REG_16B(0xD32B, 0x4A);
|
||||
LCD_WRITE_REG_16B(0xD32C, 0x63);
|
||||
LCD_WRITE_REG_16B(0xD32D, 0xea);
|
||||
LCD_WRITE_REG_16B(0xD32E, 0x79);
|
||||
LCD_WRITE_REG_16B(0xD32F, 0xa6);
|
||||
LCD_WRITE_REG_16B(0xD330, 0xd0);
|
||||
LCD_WRITE_REG_16B(0xD331, 0x20);
|
||||
LCD_WRITE_REG_16B(0xD332, 0x0f);
|
||||
LCD_WRITE_REG_16B(0xD333, 0x8e);
|
||||
LCD_WRITE_REG_16B(0xD334, 0xff);
|
||||
|
||||
|
||||
//GAMMA SETING RED
|
||||
LCD_WRITE_REG(0xD400, 0x00);
|
||||
LCD_WRITE_REG(0xD401, 0x00);
|
||||
LCD_WRITE_REG(0xD402, 0x1b);
|
||||
LCD_WRITE_REG(0xD403, 0x44);
|
||||
LCD_WRITE_REG(0xD404, 0x62);
|
||||
LCD_WRITE_REG(0xD405, 0x00);
|
||||
LCD_WRITE_REG(0xD406, 0x7b);
|
||||
LCD_WRITE_REG(0xD407, 0xa1);
|
||||
LCD_WRITE_REG(0xD408, 0xc0);
|
||||
LCD_WRITE_REG(0xD409, 0xee);
|
||||
LCD_WRITE_REG(0xD40A, 0x55);
|
||||
LCD_WRITE_REG(0xD40B, 0x10);
|
||||
LCD_WRITE_REG(0xD40C, 0x2c);
|
||||
LCD_WRITE_REG(0xD40D, 0x43);
|
||||
LCD_WRITE_REG(0xD40E, 0x57);
|
||||
LCD_WRITE_REG(0xD40F, 0x55);
|
||||
LCD_WRITE_REG(0xD410, 0x68);
|
||||
LCD_WRITE_REG(0xD411, 0x78);
|
||||
LCD_WRITE_REG(0xD412, 0x87);
|
||||
LCD_WRITE_REG(0xD413, 0x94);
|
||||
LCD_WRITE_REG(0xD414, 0x55);
|
||||
LCD_WRITE_REG(0xD415, 0xa0);
|
||||
LCD_WRITE_REG(0xD416, 0xac);
|
||||
LCD_WRITE_REG(0xD417, 0xb6);
|
||||
LCD_WRITE_REG(0xD418, 0xc1);
|
||||
LCD_WRITE_REG(0xD419, 0x55);
|
||||
LCD_WRITE_REG(0xD41A, 0xcb);
|
||||
LCD_WRITE_REG(0xD41B, 0xcd);
|
||||
LCD_WRITE_REG(0xD41C, 0xd6);
|
||||
LCD_WRITE_REG(0xD41D, 0xdf);
|
||||
LCD_WRITE_REG(0xD41E, 0x95);
|
||||
LCD_WRITE_REG(0xD41F, 0xe8);
|
||||
LCD_WRITE_REG(0xD420, 0xf1);
|
||||
LCD_WRITE_REG(0xD421, 0xfa);
|
||||
LCD_WRITE_REG(0xD422, 0x02);
|
||||
LCD_WRITE_REG(0xD423, 0xaa);
|
||||
LCD_WRITE_REG(0xD424, 0x0b);
|
||||
LCD_WRITE_REG(0xD425, 0x13);
|
||||
LCD_WRITE_REG(0xD426, 0x1d);
|
||||
LCD_WRITE_REG(0xD427, 0x26);
|
||||
LCD_WRITE_REG(0xD428, 0xaa);
|
||||
LCD_WRITE_REG(0xD429, 0x30);
|
||||
LCD_WRITE_REG(0xD42A, 0x3c);
|
||||
LCD_WRITE_REG(0xD42B, 0x4A);
|
||||
LCD_WRITE_REG(0xD42C, 0x63);
|
||||
LCD_WRITE_REG(0xD42D, 0xea);
|
||||
LCD_WRITE_REG(0xD42E, 0x79);
|
||||
LCD_WRITE_REG(0xD42F, 0xa6);
|
||||
LCD_WRITE_REG(0xD430, 0xd0);
|
||||
LCD_WRITE_REG(0xD431, 0x20);
|
||||
LCD_WRITE_REG(0xD432, 0x0f);
|
||||
LCD_WRITE_REG(0xD433, 0x8e);
|
||||
LCD_WRITE_REG(0xD434, 0xff);
|
||||
LCD_WRITE_REG_16B(0xD400, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD401, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD402, 0x1b);
|
||||
LCD_WRITE_REG_16B(0xD403, 0x44);
|
||||
LCD_WRITE_REG_16B(0xD404, 0x62);
|
||||
LCD_WRITE_REG_16B(0xD405, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD406, 0x7b);
|
||||
LCD_WRITE_REG_16B(0xD407, 0xa1);
|
||||
LCD_WRITE_REG_16B(0xD408, 0xc0);
|
||||
LCD_WRITE_REG_16B(0xD409, 0xee);
|
||||
LCD_WRITE_REG_16B(0xD40A, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD40B, 0x10);
|
||||
LCD_WRITE_REG_16B(0xD40C, 0x2c);
|
||||
LCD_WRITE_REG_16B(0xD40D, 0x43);
|
||||
LCD_WRITE_REG_16B(0xD40E, 0x57);
|
||||
LCD_WRITE_REG_16B(0xD40F, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD410, 0x68);
|
||||
LCD_WRITE_REG_16B(0xD411, 0x78);
|
||||
LCD_WRITE_REG_16B(0xD412, 0x87);
|
||||
LCD_WRITE_REG_16B(0xD413, 0x94);
|
||||
LCD_WRITE_REG_16B(0xD414, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD415, 0xa0);
|
||||
LCD_WRITE_REG_16B(0xD416, 0xac);
|
||||
LCD_WRITE_REG_16B(0xD417, 0xb6);
|
||||
LCD_WRITE_REG_16B(0xD418, 0xc1);
|
||||
LCD_WRITE_REG_16B(0xD419, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD41A, 0xcb);
|
||||
LCD_WRITE_REG_16B(0xD41B, 0xcd);
|
||||
LCD_WRITE_REG_16B(0xD41C, 0xd6);
|
||||
LCD_WRITE_REG_16B(0xD41D, 0xdf);
|
||||
LCD_WRITE_REG_16B(0xD41E, 0x95);
|
||||
LCD_WRITE_REG_16B(0xD41F, 0xe8);
|
||||
LCD_WRITE_REG_16B(0xD420, 0xf1);
|
||||
LCD_WRITE_REG_16B(0xD421, 0xfa);
|
||||
LCD_WRITE_REG_16B(0xD422, 0x02);
|
||||
LCD_WRITE_REG_16B(0xD423, 0xaa);
|
||||
LCD_WRITE_REG_16B(0xD424, 0x0b);
|
||||
LCD_WRITE_REG_16B(0xD425, 0x13);
|
||||
LCD_WRITE_REG_16B(0xD426, 0x1d);
|
||||
LCD_WRITE_REG_16B(0xD427, 0x26);
|
||||
LCD_WRITE_REG_16B(0xD428, 0xaa);
|
||||
LCD_WRITE_REG_16B(0xD429, 0x30);
|
||||
LCD_WRITE_REG_16B(0xD42A, 0x3c);
|
||||
LCD_WRITE_REG_16B(0xD42B, 0x4A);
|
||||
LCD_WRITE_REG_16B(0xD42C, 0x63);
|
||||
LCD_WRITE_REG_16B(0xD42D, 0xea);
|
||||
LCD_WRITE_REG_16B(0xD42E, 0x79);
|
||||
LCD_WRITE_REG_16B(0xD42F, 0xa6);
|
||||
LCD_WRITE_REG_16B(0xD430, 0xd0);
|
||||
LCD_WRITE_REG_16B(0xD431, 0x20);
|
||||
LCD_WRITE_REG_16B(0xD432, 0x0f);
|
||||
LCD_WRITE_REG_16B(0xD433, 0x8e);
|
||||
LCD_WRITE_REG_16B(0xD434, 0xff);
|
||||
|
||||
//GAMMA SETING GREEN
|
||||
LCD_WRITE_REG(0xD500, 0x00);
|
||||
LCD_WRITE_REG(0xD501, 0x00);
|
||||
LCD_WRITE_REG(0xD502, 0x1b);
|
||||
LCD_WRITE_REG(0xD503, 0x44);
|
||||
LCD_WRITE_REG(0xD504, 0x62);
|
||||
LCD_WRITE_REG(0xD505, 0x00);
|
||||
LCD_WRITE_REG(0xD506, 0x7b);
|
||||
LCD_WRITE_REG(0xD507, 0xa1);
|
||||
LCD_WRITE_REG(0xD508, 0xc0);
|
||||
LCD_WRITE_REG(0xD509, 0xee);
|
||||
LCD_WRITE_REG(0xD50A, 0x55);
|
||||
LCD_WRITE_REG(0xD50B, 0x10);
|
||||
LCD_WRITE_REG(0xD50C, 0x2c);
|
||||
LCD_WRITE_REG(0xD50D, 0x43);
|
||||
LCD_WRITE_REG(0xD50E, 0x57);
|
||||
LCD_WRITE_REG(0xD50F, 0x55);
|
||||
LCD_WRITE_REG(0xD510, 0x68);
|
||||
LCD_WRITE_REG(0xD511, 0x78);
|
||||
LCD_WRITE_REG(0xD512, 0x87);
|
||||
LCD_WRITE_REG(0xD513, 0x94);
|
||||
LCD_WRITE_REG(0xD514, 0x55);
|
||||
LCD_WRITE_REG(0xD515, 0xa0);
|
||||
LCD_WRITE_REG(0xD516, 0xac);
|
||||
LCD_WRITE_REG(0xD517, 0xb6);
|
||||
LCD_WRITE_REG(0xD518, 0xc1);
|
||||
LCD_WRITE_REG(0xD519, 0x55);
|
||||
LCD_WRITE_REG(0xD51A, 0xcb);
|
||||
LCD_WRITE_REG(0xD51B, 0xcd);
|
||||
LCD_WRITE_REG(0xD51C, 0xd6);
|
||||
LCD_WRITE_REG(0xD51D, 0xdf);
|
||||
LCD_WRITE_REG(0xD51E, 0x95);
|
||||
LCD_WRITE_REG(0xD51F, 0xe8);
|
||||
LCD_WRITE_REG(0xD520, 0xf1);
|
||||
LCD_WRITE_REG(0xD521, 0xfa);
|
||||
LCD_WRITE_REG(0xD522, 0x02);
|
||||
LCD_WRITE_REG(0xD523, 0xaa);
|
||||
LCD_WRITE_REG(0xD524, 0x0b);
|
||||
LCD_WRITE_REG(0xD525, 0x13);
|
||||
LCD_WRITE_REG(0xD526, 0x1d);
|
||||
LCD_WRITE_REG(0xD527, 0x26);
|
||||
LCD_WRITE_REG(0xD528, 0xaa);
|
||||
LCD_WRITE_REG(0xD529, 0x30);
|
||||
LCD_WRITE_REG(0xD52A, 0x3c);
|
||||
LCD_WRITE_REG(0xD52B, 0x4a);
|
||||
LCD_WRITE_REG(0xD52C, 0x63);
|
||||
LCD_WRITE_REG(0xD52D, 0xea);
|
||||
LCD_WRITE_REG(0xD52E, 0x79);
|
||||
LCD_WRITE_REG(0xD52F, 0xa6);
|
||||
LCD_WRITE_REG(0xD530, 0xd0);
|
||||
LCD_WRITE_REG(0xD531, 0x20);
|
||||
LCD_WRITE_REG(0xD532, 0x0f);
|
||||
LCD_WRITE_REG(0xD533, 0x8e);
|
||||
LCD_WRITE_REG(0xD534, 0xff);
|
||||
LCD_WRITE_REG_16B(0xD500, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD501, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD502, 0x1b);
|
||||
LCD_WRITE_REG_16B(0xD503, 0x44);
|
||||
LCD_WRITE_REG_16B(0xD504, 0x62);
|
||||
LCD_WRITE_REG_16B(0xD505, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD506, 0x7b);
|
||||
LCD_WRITE_REG_16B(0xD507, 0xa1);
|
||||
LCD_WRITE_REG_16B(0xD508, 0xc0);
|
||||
LCD_WRITE_REG_16B(0xD509, 0xee);
|
||||
LCD_WRITE_REG_16B(0xD50A, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD50B, 0x10);
|
||||
LCD_WRITE_REG_16B(0xD50C, 0x2c);
|
||||
LCD_WRITE_REG_16B(0xD50D, 0x43);
|
||||
LCD_WRITE_REG_16B(0xD50E, 0x57);
|
||||
LCD_WRITE_REG_16B(0xD50F, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD510, 0x68);
|
||||
LCD_WRITE_REG_16B(0xD511, 0x78);
|
||||
LCD_WRITE_REG_16B(0xD512, 0x87);
|
||||
LCD_WRITE_REG_16B(0xD513, 0x94);
|
||||
LCD_WRITE_REG_16B(0xD514, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD515, 0xa0);
|
||||
LCD_WRITE_REG_16B(0xD516, 0xac);
|
||||
LCD_WRITE_REG_16B(0xD517, 0xb6);
|
||||
LCD_WRITE_REG_16B(0xD518, 0xc1);
|
||||
LCD_WRITE_REG_16B(0xD519, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD51A, 0xcb);
|
||||
LCD_WRITE_REG_16B(0xD51B, 0xcd);
|
||||
LCD_WRITE_REG_16B(0xD51C, 0xd6);
|
||||
LCD_WRITE_REG_16B(0xD51D, 0xdf);
|
||||
LCD_WRITE_REG_16B(0xD51E, 0x95);
|
||||
LCD_WRITE_REG_16B(0xD51F, 0xe8);
|
||||
LCD_WRITE_REG_16B(0xD520, 0xf1);
|
||||
LCD_WRITE_REG_16B(0xD521, 0xfa);
|
||||
LCD_WRITE_REG_16B(0xD522, 0x02);
|
||||
LCD_WRITE_REG_16B(0xD523, 0xaa);
|
||||
LCD_WRITE_REG_16B(0xD524, 0x0b);
|
||||
LCD_WRITE_REG_16B(0xD525, 0x13);
|
||||
LCD_WRITE_REG_16B(0xD526, 0x1d);
|
||||
LCD_WRITE_REG_16B(0xD527, 0x26);
|
||||
LCD_WRITE_REG_16B(0xD528, 0xaa);
|
||||
LCD_WRITE_REG_16B(0xD529, 0x30);
|
||||
LCD_WRITE_REG_16B(0xD52A, 0x3c);
|
||||
LCD_WRITE_REG_16B(0xD52B, 0x4a);
|
||||
LCD_WRITE_REG_16B(0xD52C, 0x63);
|
||||
LCD_WRITE_REG_16B(0xD52D, 0xea);
|
||||
LCD_WRITE_REG_16B(0xD52E, 0x79);
|
||||
LCD_WRITE_REG_16B(0xD52F, 0xa6);
|
||||
LCD_WRITE_REG_16B(0xD530, 0xd0);
|
||||
LCD_WRITE_REG_16B(0xD531, 0x20);
|
||||
LCD_WRITE_REG_16B(0xD532, 0x0f);
|
||||
LCD_WRITE_REG_16B(0xD533, 0x8e);
|
||||
LCD_WRITE_REG_16B(0xD534, 0xff);
|
||||
|
||||
//GAMMA SETING BLUE
|
||||
LCD_WRITE_REG(0xD600, 0x00);
|
||||
LCD_WRITE_REG(0xD601, 0x00);
|
||||
LCD_WRITE_REG(0xD602, 0x1b);
|
||||
LCD_WRITE_REG(0xD603, 0x44);
|
||||
LCD_WRITE_REG(0xD604, 0x62);
|
||||
LCD_WRITE_REG(0xD605, 0x00);
|
||||
LCD_WRITE_REG(0xD606, 0x7b);
|
||||
LCD_WRITE_REG(0xD607, 0xa1);
|
||||
LCD_WRITE_REG(0xD608, 0xc0);
|
||||
LCD_WRITE_REG(0xD609, 0xee);
|
||||
LCD_WRITE_REG(0xD60A, 0x55);
|
||||
LCD_WRITE_REG(0xD60B, 0x10);
|
||||
LCD_WRITE_REG(0xD60C, 0x2c);
|
||||
LCD_WRITE_REG(0xD60D, 0x43);
|
||||
LCD_WRITE_REG(0xD60E, 0x57);
|
||||
LCD_WRITE_REG(0xD60F, 0x55);
|
||||
LCD_WRITE_REG(0xD610, 0x68);
|
||||
LCD_WRITE_REG(0xD611, 0x78);
|
||||
LCD_WRITE_REG(0xD612, 0x87);
|
||||
LCD_WRITE_REG(0xD613, 0x94);
|
||||
LCD_WRITE_REG(0xD614, 0x55);
|
||||
LCD_WRITE_REG(0xD615, 0xa0);
|
||||
LCD_WRITE_REG(0xD616, 0xac);
|
||||
LCD_WRITE_REG(0xD617, 0xb6);
|
||||
LCD_WRITE_REG(0xD618, 0xc1);
|
||||
LCD_WRITE_REG(0xD619, 0x55);
|
||||
LCD_WRITE_REG(0xD61A, 0xcb);
|
||||
LCD_WRITE_REG(0xD61B, 0xcd);
|
||||
LCD_WRITE_REG(0xD61C, 0xd6);
|
||||
LCD_WRITE_REG(0xD61D, 0xdf);
|
||||
LCD_WRITE_REG(0xD61E, 0x95);
|
||||
LCD_WRITE_REG(0xD61F, 0xe8);
|
||||
LCD_WRITE_REG(0xD620, 0xf1);
|
||||
LCD_WRITE_REG(0xD621, 0xfa);
|
||||
LCD_WRITE_REG(0xD622, 0x02);
|
||||
LCD_WRITE_REG(0xD623, 0xaa);
|
||||
LCD_WRITE_REG(0xD624, 0x0b);
|
||||
LCD_WRITE_REG(0xD625, 0x13);
|
||||
LCD_WRITE_REG(0xD626, 0x1d);
|
||||
LCD_WRITE_REG(0xD627, 0x26);
|
||||
LCD_WRITE_REG(0xD628, 0xaa);
|
||||
LCD_WRITE_REG(0xD629, 0x30);
|
||||
LCD_WRITE_REG(0xD62A, 0x3c);
|
||||
LCD_WRITE_REG(0xD62B, 0x4A);
|
||||
LCD_WRITE_REG(0xD62C, 0x63);
|
||||
LCD_WRITE_REG(0xD62D, 0xea);
|
||||
LCD_WRITE_REG(0xD62E, 0x79);
|
||||
LCD_WRITE_REG(0xD62F, 0xa6);
|
||||
LCD_WRITE_REG(0xD630, 0xd0);
|
||||
LCD_WRITE_REG(0xD631, 0x20);
|
||||
LCD_WRITE_REG(0xD632, 0x0f);
|
||||
LCD_WRITE_REG(0xD633, 0x8e);
|
||||
LCD_WRITE_REG(0xD634, 0xff);
|
||||
LCD_WRITE_REG_16B(0xD600, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD601, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD602, 0x1b);
|
||||
LCD_WRITE_REG_16B(0xD603, 0x44);
|
||||
LCD_WRITE_REG_16B(0xD604, 0x62);
|
||||
LCD_WRITE_REG_16B(0xD605, 0x00);
|
||||
LCD_WRITE_REG_16B(0xD606, 0x7b);
|
||||
LCD_WRITE_REG_16B(0xD607, 0xa1);
|
||||
LCD_WRITE_REG_16B(0xD608, 0xc0);
|
||||
LCD_WRITE_REG_16B(0xD609, 0xee);
|
||||
LCD_WRITE_REG_16B(0xD60A, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD60B, 0x10);
|
||||
LCD_WRITE_REG_16B(0xD60C, 0x2c);
|
||||
LCD_WRITE_REG_16B(0xD60D, 0x43);
|
||||
LCD_WRITE_REG_16B(0xD60E, 0x57);
|
||||
LCD_WRITE_REG_16B(0xD60F, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD610, 0x68);
|
||||
LCD_WRITE_REG_16B(0xD611, 0x78);
|
||||
LCD_WRITE_REG_16B(0xD612, 0x87);
|
||||
LCD_WRITE_REG_16B(0xD613, 0x94);
|
||||
LCD_WRITE_REG_16B(0xD614, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD615, 0xa0);
|
||||
LCD_WRITE_REG_16B(0xD616, 0xac);
|
||||
LCD_WRITE_REG_16B(0xD617, 0xb6);
|
||||
LCD_WRITE_REG_16B(0xD618, 0xc1);
|
||||
LCD_WRITE_REG_16B(0xD619, 0x55);
|
||||
LCD_WRITE_REG_16B(0xD61A, 0xcb);
|
||||
LCD_WRITE_REG_16B(0xD61B, 0xcd);
|
||||
LCD_WRITE_REG_16B(0xD61C, 0xd6);
|
||||
LCD_WRITE_REG_16B(0xD61D, 0xdf);
|
||||
LCD_WRITE_REG_16B(0xD61E, 0x95);
|
||||
LCD_WRITE_REG_16B(0xD61F, 0xe8);
|
||||
LCD_WRITE_REG_16B(0xD620, 0xf1);
|
||||
LCD_WRITE_REG_16B(0xD621, 0xfa);
|
||||
LCD_WRITE_REG_16B(0xD622, 0x02);
|
||||
LCD_WRITE_REG_16B(0xD623, 0xaa);
|
||||
LCD_WRITE_REG_16B(0xD624, 0x0b);
|
||||
LCD_WRITE_REG_16B(0xD625, 0x13);
|
||||
LCD_WRITE_REG_16B(0xD626, 0x1d);
|
||||
LCD_WRITE_REG_16B(0xD627, 0x26);
|
||||
LCD_WRITE_REG_16B(0xD628, 0xaa);
|
||||
LCD_WRITE_REG_16B(0xD629, 0x30);
|
||||
LCD_WRITE_REG_16B(0xD62A, 0x3c);
|
||||
LCD_WRITE_REG_16B(0xD62B, 0x4A);
|
||||
LCD_WRITE_REG_16B(0xD62C, 0x63);
|
||||
LCD_WRITE_REG_16B(0xD62D, 0xea);
|
||||
LCD_WRITE_REG_16B(0xD62E, 0x79);
|
||||
LCD_WRITE_REG_16B(0xD62F, 0xa6);
|
||||
LCD_WRITE_REG_16B(0xD630, 0xd0);
|
||||
LCD_WRITE_REG_16B(0xD631, 0x20);
|
||||
LCD_WRITE_REG_16B(0xD632, 0x0f);
|
||||
LCD_WRITE_REG_16B(0xD633, 0x8e);
|
||||
LCD_WRITE_REG_16B(0xD634, 0xff);
|
||||
|
||||
//AVDD VOLTAGE SETTING
|
||||
LCD_WRITE_REG(0xB000, 0x05);
|
||||
LCD_WRITE_REG(0xB001, 0x05);
|
||||
LCD_WRITE_REG(0xB002, 0x05);
|
||||
LCD_WRITE_REG_16B(0xB000, 0x05);
|
||||
LCD_WRITE_REG_16B(0xB001, 0x05);
|
||||
LCD_WRITE_REG_16B(0xB002, 0x05);
|
||||
//AVEE VOLTAGE SETTING
|
||||
LCD_WRITE_REG(0xB100, 0x05);
|
||||
LCD_WRITE_REG(0xB101, 0x05);
|
||||
LCD_WRITE_REG(0xB102, 0x05);
|
||||
LCD_WRITE_REG_16B(0xB100, 0x05);
|
||||
LCD_WRITE_REG_16B(0xB101, 0x05);
|
||||
LCD_WRITE_REG_16B(0xB102, 0x05);
|
||||
|
||||
//AVDD Boosting
|
||||
LCD_WRITE_REG(0xB600, 0x34);
|
||||
LCD_WRITE_REG(0xB601, 0x34);
|
||||
LCD_WRITE_REG(0xB603, 0x34);
|
||||
LCD_WRITE_REG_16B(0xB600, 0x34);
|
||||
LCD_WRITE_REG_16B(0xB601, 0x34);
|
||||
LCD_WRITE_REG_16B(0xB603, 0x34);
|
||||
//AVEE Boosting
|
||||
LCD_WRITE_REG(0xB700, 0x24);
|
||||
LCD_WRITE_REG(0xB701, 0x24);
|
||||
LCD_WRITE_REG(0xB702, 0x24);
|
||||
LCD_WRITE_REG_16B(0xB700, 0x24);
|
||||
LCD_WRITE_REG_16B(0xB701, 0x24);
|
||||
LCD_WRITE_REG_16B(0xB702, 0x24);
|
||||
//VCL Boosting
|
||||
LCD_WRITE_REG(0xB800, 0x24);
|
||||
LCD_WRITE_REG(0xB801, 0x24);
|
||||
LCD_WRITE_REG(0xB802, 0x24);
|
||||
LCD_WRITE_REG_16B(0xB800, 0x24);
|
||||
LCD_WRITE_REG_16B(0xB801, 0x24);
|
||||
LCD_WRITE_REG_16B(0xB802, 0x24);
|
||||
//VGLX VOLTAGE SETTING
|
||||
LCD_WRITE_REG(0xBA00, 0x14);
|
||||
LCD_WRITE_REG(0xBA01, 0x14);
|
||||
LCD_WRITE_REG(0xBA02, 0x14);
|
||||
LCD_WRITE_REG_16B(0xBA00, 0x14);
|
||||
LCD_WRITE_REG_16B(0xBA01, 0x14);
|
||||
LCD_WRITE_REG_16B(0xBA02, 0x14);
|
||||
//VCL Boosting
|
||||
LCD_WRITE_REG(0xB900, 0x24);
|
||||
LCD_WRITE_REG(0xB901, 0x24);
|
||||
LCD_WRITE_REG(0xB902, 0x24);
|
||||
LCD_WRITE_REG_16B(0xB900, 0x24);
|
||||
LCD_WRITE_REG_16B(0xB901, 0x24);
|
||||
LCD_WRITE_REG_16B(0xB902, 0x24);
|
||||
//Gamma Voltage
|
||||
LCD_WRITE_REG(0xBc00, 0x00);
|
||||
LCD_WRITE_REG(0xBc01, 0xa0);//vgmp=5.0
|
||||
LCD_WRITE_REG(0xBc02, 0x00);
|
||||
LCD_WRITE_REG(0xBd00, 0x00);
|
||||
LCD_WRITE_REG(0xBd01, 0xa0);//vgmn=5.0
|
||||
LCD_WRITE_REG(0xBd02, 0x00);
|
||||
LCD_WRITE_REG_16B(0xBc00, 0x00);
|
||||
LCD_WRITE_REG_16B(0xBc01, 0xa0);//vgmp=5.0
|
||||
LCD_WRITE_REG_16B(0xBc02, 0x00);
|
||||
LCD_WRITE_REG_16B(0xBd00, 0x00);
|
||||
LCD_WRITE_REG_16B(0xBd01, 0xa0);//vgmn=5.0
|
||||
LCD_WRITE_REG_16B(0xBd02, 0x00);
|
||||
//VCOM Setting
|
||||
LCD_WRITE_REG(0xBe01, 0x3d);//3
|
||||
LCD_WRITE_REG_16B(0xBe01, 0x3d);//3
|
||||
//ENABLE PAGE 0
|
||||
LCD_WRITE_REG(0xF000, 0x55);
|
||||
LCD_WRITE_REG(0xF001, 0xAA);
|
||||
LCD_WRITE_REG(0xF002, 0x52);
|
||||
LCD_WRITE_REG(0xF003, 0x08);
|
||||
LCD_WRITE_REG(0xF004, 0x00);
|
||||
LCD_WRITE_REG_16B(0xF000, 0x55);
|
||||
LCD_WRITE_REG_16B(0xF001, 0xAA);
|
||||
LCD_WRITE_REG_16B(0xF002, 0x52);
|
||||
LCD_WRITE_REG_16B(0xF003, 0x08);
|
||||
LCD_WRITE_REG_16B(0xF004, 0x00);
|
||||
//Vivid Color Function Control
|
||||
LCD_WRITE_REG(0xB400, 0x10);
|
||||
LCD_WRITE_REG_16B(0xB400, 0x10);
|
||||
//Z-INVERSION
|
||||
LCD_WRITE_REG(0xBC00, 0x05);
|
||||
LCD_WRITE_REG(0xBC01, 0x05);
|
||||
LCD_WRITE_REG(0xBC02, 0x05);
|
||||
LCD_WRITE_REG_16B(0xBC00, 0x05);
|
||||
LCD_WRITE_REG_16B(0xBC01, 0x05);
|
||||
LCD_WRITE_REG_16B(0xBC02, 0x05);
|
||||
|
||||
//*************** add on 20111021**********************//
|
||||
LCD_WRITE_REG(0xB700, 0x22);//GATE EQ CONTROL
|
||||
LCD_WRITE_REG(0xB701, 0x22);//GATE EQ CONTROL
|
||||
LCD_WRITE_REG(0xC80B, 0x2A);//DISPLAY TIMING CONTROL
|
||||
LCD_WRITE_REG(0xC80C, 0x2A);//DISPLAY TIMING CONTROL
|
||||
LCD_WRITE_REG(0xC80F, 0x2A);//DISPLAY TIMING CONTROL
|
||||
LCD_WRITE_REG(0xC810, 0x2A);//DISPLAY TIMING CONTROL
|
||||
LCD_WRITE_REG_16B(0xB700, 0x22);//GATE EQ CONTROL
|
||||
LCD_WRITE_REG_16B(0xB701, 0x22);//GATE EQ CONTROL
|
||||
LCD_WRITE_REG_16B(0xC80B, 0x2A);//DISPLAY TIMING CONTROL
|
||||
LCD_WRITE_REG_16B(0xC80C, 0x2A);//DISPLAY TIMING CONTROL
|
||||
LCD_WRITE_REG_16B(0xC80F, 0x2A);//DISPLAY TIMING CONTROL
|
||||
LCD_WRITE_REG_16B(0xC810, 0x2A);//DISPLAY TIMING CONTROL
|
||||
//*************** add on 20111021**********************//
|
||||
//PWM_ENH_OE =1
|
||||
LCD_WRITE_REG(0xd000, 0x01);
|
||||
LCD_WRITE_REG_16B(0xd000, 0x01);
|
||||
//DM_SEL =1
|
||||
LCD_WRITE_REG(0xb300, 0x10);
|
||||
LCD_WRITE_REG_16B(0xb300, 0x10);
|
||||
//VBPDA=07h
|
||||
LCD_WRITE_REG(0xBd02, 0x07);
|
||||
LCD_WRITE_REG_16B(0xBd02, 0x07);
|
||||
//VBPDb=07h
|
||||
LCD_WRITE_REG(0xBe02, 0x07);
|
||||
LCD_WRITE_REG_16B(0xBe02, 0x07);
|
||||
//VBPDc=07h
|
||||
LCD_WRITE_REG(0xBf02, 0x07);
|
||||
LCD_WRITE_REG_16B(0xBf02, 0x07);
|
||||
//ENABLE PAGE 2
|
||||
LCD_WRITE_REG(0xF000, 0x55);
|
||||
LCD_WRITE_REG(0xF001, 0xAA);
|
||||
LCD_WRITE_REG(0xF002, 0x52);
|
||||
LCD_WRITE_REG(0xF003, 0x08);
|
||||
LCD_WRITE_REG(0xF004, 0x02);
|
||||
LCD_WRITE_REG_16B(0xF000, 0x55);
|
||||
LCD_WRITE_REG_16B(0xF001, 0xAA);
|
||||
LCD_WRITE_REG_16B(0xF002, 0x52);
|
||||
LCD_WRITE_REG_16B(0xF003, 0x08);
|
||||
LCD_WRITE_REG_16B(0xF004, 0x02);
|
||||
//SDREG0 =0
|
||||
LCD_WRITE_REG(0xc301, 0xa9);
|
||||
LCD_WRITE_REG_16B(0xc301, 0xa9);
|
||||
//DS=14
|
||||
LCD_WRITE_REG(0xfe01, 0x94);
|
||||
LCD_WRITE_REG_16B(0xfe01, 0x94);
|
||||
//OSC =60h
|
||||
LCD_WRITE_REG(0xf600, 0x60);
|
||||
LCD_WRITE_REG_16B(0xf600, 0x60);
|
||||
//TE ON
|
||||
LCD_WRITE_REG(0x3500, 0x00);
|
||||
LCD_WRITE_REG_16B(0x3500, 0x00);
|
||||
//SLEEP OUT
|
||||
LCD_WRITE_CMD(0x1100);
|
||||
LCD_WRITE_CMD_16B(0x1100);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
//DISPLY ON
|
||||
LCD_WRITE_CMD(0x2900);
|
||||
LCD_WRITE_CMD_16B(0x2900);
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
|
||||
LCD_WRITE_REG(0x3A00, 0x55);
|
||||
LCD_WRITE_REG(0x3600, 0xA3);
|
||||
LCD_WRITE_REG_16B(0x3A00, 0x55);
|
||||
LCD_WRITE_REG_16B(0x3600, 0xA3);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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->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->interface_drv->write_cmd && \
|
||||
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 && \
|
||||
|
|
|
|||
345
components/display/screen/controller_driver/ssd1963/ssd1963.c
Normal file
345
components/display/screen/controller_driver/ssd1963/ssd1963.c
Normal file
|
|
@ -0,0 +1,345 @@
|
|||
// 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
|
||||
|
||||
}
|
||||
123
components/display/screen/controller_driver/ssd1963/ssd1963.h
Normal file
123
components/display/screen/controller_driver/ssd1963/ssd1963.h
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
// 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
|
||||
|
|
@ -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->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->interface_drv->write_cmd && \
|
||||
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 && \
|
||||
|
|
|
|||
|
|
@ -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->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->interface_drv->write_cmd && \
|
||||
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 && \
|
||||
|
|
|
|||
|
|
@ -28,6 +28,11 @@ static const char *TAG = "screen interface";
|
|||
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 ----------------------*/
|
||||
typedef struct {
|
||||
i2s_lcd_handle_t i2s_lcd_handle;
|
||||
|
|
@ -40,10 +45,10 @@ static esp_err_t _i2s_lcd_write_data(void *handle, uint16_t data)
|
|||
return i2s_lcd_write_data(interface_i2s->i2s_lcd_handle, data);
|
||||
}
|
||||
|
||||
static esp_err_t _i2s_lcd_write_cmd(void *handle, uint16_t cmd)
|
||||
static esp_err_t _i2s_lcd_write_command(void *handle, const uint8_t *cmd, uint32_t length)
|
||||
{
|
||||
interface_i2s_handle_t *interface_i2s = __containerof(handle, interface_i2s_handle_t, interface_drv);
|
||||
return i2s_lcd_write_cmd(interface_i2s->i2s_lcd_handle, cmd);
|
||||
return i2s_lcd_write_command(interface_i2s->i2s_lcd_handle, cmd, length);
|
||||
}
|
||||
|
||||
static esp_err_t _i2s_lcd_write(void *handle, const uint8_t *data, uint32_t length)
|
||||
|
|
@ -68,6 +73,7 @@ static esp_err_t _i2s_lcd_release(void *handle)
|
|||
interface_i2s_handle_t *interface_i2s = __containerof(handle, interface_i2s_handle_t, interface_drv);
|
||||
return i2s_lcd_release(interface_i2s->i2s_lcd_handle);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**--------------------- I2C interface driver ----------------------*/
|
||||
#define SSD1306_WRITE_CMD 0x00
|
||||
|
|
@ -110,10 +116,11 @@ static esp_err_t i2c_lcd_write_byte(i2c_bus_device_handle_t i2c_dev, uint8_t ctr
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t i2c_lcd_write_cmd(void *handle, uint16_t cmd)
|
||||
static esp_err_t i2c_lcd_write_command(void *handle, const uint8_t *cmd, uint32_t length)
|
||||
{
|
||||
(void)length;// TODO: In most cases, the length is 1
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -162,7 +169,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)
|
||||
{
|
||||
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_cs) || cfg->pin_num_cs == -1, "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);
|
||||
|
||||
//Initialize non-SPI GPIOs
|
||||
|
|
@ -204,13 +211,12 @@ 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);
|
||||
}
|
||||
|
||||
static esp_err_t spi_lcd_driver_write_cmd(void *handle, uint16_t value)
|
||||
static esp_err_t spi_lcd_driver_write_command(void *handle, const uint8_t *cmd, uint32_t length)
|
||||
{
|
||||
interface_spi_handle_t *interface_spi = __containerof(handle, interface_spi_handle_t, interface_drv);
|
||||
esp_err_t ret;
|
||||
gpio_set_level(interface_spi->pin_num_dc, LCD_CMD_LEV);
|
||||
uint8_t data = value;
|
||||
ret = _lcd_spi_rw(interface_spi->spi_wr_dev, &data, NULL, 1);
|
||||
ret = _lcd_spi_rw(interface_spi->spi_wr_dev, cmd, NULL, length);
|
||||
gpio_set_level(interface_spi->pin_num_dc, LCD_DATA_LEV);
|
||||
LCD_IFACE_CHECK(ESP_OK == ret, "Send cmd failed", ESP_FAIL);
|
||||
return ESP_OK;
|
||||
|
|
@ -278,6 +284,7 @@ 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);
|
||||
|
||||
switch (type) {
|
||||
#ifdef SOC_SUPPORT_8080_IFACE
|
||||
case SCREEN_IFACE_8080: {
|
||||
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);
|
||||
|
|
@ -289,7 +296,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.write_cmd = _i2s_lcd_write_cmd;
|
||||
interface_i2s->interface_drv.write_command = _i2s_lcd_write_command;
|
||||
interface_i2s->interface_drv.write_data = _i2s_lcd_write_data;
|
||||
interface_i2s->interface_drv.write = _i2s_lcd_write;
|
||||
interface_i2s->interface_drv.read = _i2s_lcd_read;
|
||||
|
|
@ -298,6 +305,7 @@ esp_err_t scr_interface_create(scr_interface_type_t type, void *config, scr_inte
|
|||
|
||||
*out_driver = &interface_i2s->interface_drv;
|
||||
} break;
|
||||
#endif
|
||||
case SCREEN_IFACE_SPI: {
|
||||
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);
|
||||
|
|
@ -309,7 +317,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.write_cmd = spi_lcd_driver_write_cmd;
|
||||
interface_spi->interface_drv.write_command = spi_lcd_driver_write_command;
|
||||
interface_spi->interface_drv.write_data = spi_lcd_driver_write_data;
|
||||
interface_spi->interface_drv.write = spi_lcd_driver_write;
|
||||
interface_spi->interface_drv.read = spi_lcd_driver_read;
|
||||
|
|
@ -330,7 +338,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.write_cmd = i2c_lcd_write_cmd;
|
||||
interface_i2c->interface_drv.write_command = i2c_lcd_write_command;
|
||||
interface_i2c->interface_drv.write_data = i2c_lcd_write_data;
|
||||
interface_i2c->interface_drv.write = i2c_lcd_write;
|
||||
interface_i2c->interface_drv.read = i2c_lcd_read;
|
||||
|
|
@ -352,11 +360,13 @@ 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);
|
||||
|
||||
switch (driver->type) {
|
||||
#ifdef SOC_SUPPORT_8080_IFACE
|
||||
case SCREEN_IFACE_8080: {
|
||||
interface_i2s_handle_t *interface_i2s = __containerof(driver, interface_i2s_handle_t, interface_drv);
|
||||
i2s_lcd_driver_deinit(interface_i2s->i2s_lcd_handle);
|
||||
heap_caps_free(interface_i2s);
|
||||
} break;
|
||||
#endif
|
||||
case SCREEN_IFACE_SPI: {
|
||||
interface_spi_handle_t *interface_spi = __containerof(driver, interface_spi_handle_t, interface_drv);
|
||||
spi_lcd_driver_deinit(interface_spi);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ typedef enum {
|
|||
*/
|
||||
typedef struct {
|
||||
scr_interface_type_t type; /*!< Interface bus type, see scr_interface_type_t struct */
|
||||
esp_err_t (*write_cmd)(void *handle, uint16_t cmd); /*!< Function to write a command */
|
||||
esp_err_t (*write_command)(void *handle, const uint8_t *cmd, uint32_t length); /*!< Function to write command */
|
||||
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 (*read)(void *handle, uint8_t *data, uint32_t length); /*!< Function to read a block data */
|
||||
|
|
|
|||
|
|
@ -31,12 +31,18 @@ static const char *TAG = "screen driver";
|
|||
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9341
|
||||
extern scr_driver_t lcd_ili9341_default_driver;
|
||||
#endif
|
||||
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9342
|
||||
extern scr_driver_t lcd_ili9342_default_driver;
|
||||
#endif
|
||||
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9486
|
||||
extern scr_driver_t lcd_ili9486_default_driver;
|
||||
#endif
|
||||
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9806
|
||||
extern scr_driver_t lcd_ili9806_default_driver;
|
||||
#endif
|
||||
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ILI9488
|
||||
extern scr_driver_t lcd_ili9488_default_driver;
|
||||
#endif
|
||||
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_NT35510
|
||||
extern scr_driver_t lcd_nt35510_default_driver;
|
||||
#endif
|
||||
|
|
@ -46,6 +52,9 @@ extern scr_driver_t lcd_rm68120_default_driver;
|
|||
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_SSD1351
|
||||
extern scr_driver_t lcd_ssd1351_default_driver;
|
||||
#endif
|
||||
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_SSD1963
|
||||
extern scr_driver_t lcd_ssd1963_default_driver;
|
||||
#endif
|
||||
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_ST7789
|
||||
extern scr_driver_t lcd_st7789_default_driver;
|
||||
#endif
|
||||
|
|
@ -76,6 +85,11 @@ esp_err_t scr_find_driver(scr_controller_t controller, scr_driver_t *out_screen)
|
|||
*out_screen = lcd_ili9341_default_driver;
|
||||
break;
|
||||
#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
|
||||
case SCREEN_CONTROLLER_ILI9806:
|
||||
*out_screen = lcd_ili9806_default_driver;
|
||||
|
|
@ -86,6 +100,11 @@ esp_err_t scr_find_driver(scr_controller_t controller, scr_driver_t *out_screen)
|
|||
*out_screen = lcd_ili9486_default_driver;
|
||||
break;
|
||||
#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
|
||||
case SCREEN_CONTROLLER_NT35510:
|
||||
*out_screen = lcd_nt35510_default_driver;
|
||||
|
|
@ -111,6 +130,11 @@ esp_err_t scr_find_driver(scr_controller_t controller, scr_driver_t *out_screen)
|
|||
*out_screen = lcd_ssd1351_default_driver;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_SSD1963
|
||||
case SCREEN_CONTROLLER_SSD1963:
|
||||
*out_screen = lcd_ssd1963_default_driver;
|
||||
break;
|
||||
#endif
|
||||
|
||||
/**< Monochrome screen */
|
||||
#ifdef CONFIG_LCD_DRIVER_SCREEN_CONTROLLER_SSD1306
|
||||
|
|
|
|||
|
|
@ -126,13 +126,16 @@ typedef enum {
|
|||
typedef enum {
|
||||
/* color screen */
|
||||
SCREEN_CONTROLLER_ILI9341,
|
||||
SCREEN_CONTROLLER_ILI9342,
|
||||
SCREEN_CONTROLLER_ILI9806,
|
||||
SCREEN_CONTROLLER_ILI9486,
|
||||
SCREEN_CONTROLLER_ILI9488,
|
||||
SCREEN_CONTROLLER_NT35510,
|
||||
SCREEN_CONTROLLER_RM68120,
|
||||
SCREEN_CONTROLLER_ST7789,
|
||||
SCREEN_CONTROLLER_ST7796,
|
||||
SCREEN_CONTROLLER_SSD1351,
|
||||
SCREEN_CONTROLLER_SSD1963,
|
||||
|
||||
/* monochrome screen */
|
||||
SCREEN_CONTROLLER_SSD1306,
|
||||
|
|
|
|||
|
|
@ -19,15 +19,40 @@
|
|||
extern "C" {
|
||||
#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 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_COMMAND(data, length) g_lcd_handle.interface_drv->write_command(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_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)
|
||||
|
||||
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;
|
||||
ret = LCD_WRITE_CMD(cmd);
|
||||
|
|
@ -39,6 +64,18 @@ static inline esp_err_t LCD_WRITE_REG(uint16_t cmd, uint16_t data)
|
|||
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
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -406,6 +406,34 @@ TEST_CASE("Screen RM68210 8080 test", "[screen][iot]")
|
|||
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]")
|
||||
{
|
||||
scr_driver_t lcd;
|
||||
|
|
|
|||
|
|
@ -92,28 +92,33 @@ 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(NULL != font, "Font pointer invalid");
|
||||
int i, j;
|
||||
int x0 = x;
|
||||
uint16_t char_size = font->Height * (font->Width / 8 + (font->Width % 8 ? 1 : 0));
|
||||
unsigned int char_offset = (ascii_char - ' ') * char_size;
|
||||
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++) {
|
||||
uint8_t temp = ptr[j];
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (temp & 0x80) {
|
||||
g_lcd.draw_pixel(x, y, g_point_color);
|
||||
} else {
|
||||
g_lcd.draw_pixel(x, y, g_back_color);
|
||||
buf[ox + (font->Width * oy)] = g_point_color;
|
||||
}
|
||||
temp <<= 1;
|
||||
x++;
|
||||
if ((x - x0) == font->Width) {
|
||||
x = x0;
|
||||
y++;
|
||||
ox++;
|
||||
if (ox == font->Width) {
|
||||
ox = 0;
|
||||
oy++;
|
||||
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)
|
||||
|
|
@ -149,7 +154,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(NULL != font, "Font pointer invalid");
|
||||
char buf[10]={0};
|
||||
char buf[10] = {0};
|
||||
int8_t num_len;
|
||||
|
||||
itoa(num, buf, 10);
|
||||
|
|
@ -196,7 +201,7 @@ void painter_draw_line(int x1, int y1, int x2, int y2, uint16_t color)
|
|||
uint16_t t;
|
||||
int xerr = 0, yerr = 0, delta_x, delta_y, distance;
|
||||
int incx, incy, uRow, uCol;
|
||||
delta_x = x2 - x1;
|
||||
delta_x = x2 - x1;
|
||||
delta_y = y2 - y1;
|
||||
uRow = x1;
|
||||
uCol = y1;
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ esp_err_t touch_calibration_run(const scr_driver_t *screen,
|
|||
calibrate_error = 0;
|
||||
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);
|
||||
show_prompt_with_dir(30, h/2, "Successful", &Font16, COLOR_BLUE, old_dir);
|
||||
show_prompt_with_dir((w/2)-(Font16.Width*5), (h/2)+Font16.Height, "Successful", &Font16, COLOR_BLUE, old_dir);
|
||||
touch_save_calibration(&g_caldata, sizeof(Calibration_t));
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
file(GLOB_RECURSE srcs lvgl/src/*.c)
|
||||
|
||||
list(APPEND srcs "lvgl_gui.c"
|
||||
"lvgl_adapter.c")
|
||||
list(APPEND srcs "lvgl_gui.c")
|
||||
|
||||
set(incdirs "."
|
||||
"lvgl"
|
||||
|
|
@ -10,6 +9,6 @@ set(incdirs "."
|
|||
"lvgl/src")
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS "${incdirs}"
|
||||
REQUIRES screen touch_panel)
|
||||
REQUIRES screen touch_panel esp_timer)
|
||||
|
||||
target_compile_definitions(${COMPONENT_LIB} INTERFACE LV_CONF_INCLUDE_SIMPLE=1)
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
[[中文]](../../../documents/hmi_solution/littlevgl/littlevgl_guide_cn.md)/[[EN]]((../../../documents/hmi_solution/littlevgl/littlevgl_guide_en.md))
|
||||
|
|
@ -1,17 +1,16 @@
|
|||
#ifndef _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
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "lv_conf.h"
|
||||
#include "lvgl.h"
|
||||
#include "lvgl_adapter.h"
|
||||
|
||||
/**
|
||||
* @brief Initialize lvgl and register driver to lvgl
|
||||
*
|
||||
|
|
@ -26,9 +25,22 @@ extern "C"
|
|||
*/
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _COM_GUI_LVGL_H */
|
||||
#endif /* _COM_GUI_LVGL_H */
|
||||
|
|
|
|||
|
|
@ -1,146 +0,0 @@
|
|||
// 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 interface,Initialize 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;
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
#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 */
|
||||
|
|
@ -14,75 +14,156 @@
|
|||
|
||||
/* FreeRTOS includes */
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_log.h"
|
||||
/* LVGL includes */
|
||||
#include "esp_timer.h"
|
||||
#include "lvgl_gui.h"
|
||||
|
||||
static const char *TAG = "lvgl_gui";
|
||||
|
||||
typedef struct {
|
||||
scr_driver_t *lcd_drv;
|
||||
touch_panel_driver_t *touch_drv;
|
||||
} lvgl_drv_t;
|
||||
|
||||
// wait for execute lv_task_handler and lv_tick_inc to avoid some widget don't refresh.
|
||||
#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);
|
||||
}
|
||||
#define ESP_GOTO_ON_FALSE(a, err_code, goto_tag, log_tag, format, ...) do { \
|
||||
if (unlikely(!(a))) { \
|
||||
ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \
|
||||
ret = err_code; \
|
||||
goto goto_tag; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Creates a semaphore to handle concurrent call to lvgl stuff
|
||||
* If you wish to call *any* lvgl function from other threads/tasks
|
||||
* you should lock on the very same semaphore! */
|
||||
static SemaphoreHandle_t xGuiSemaphore = NULL;
|
||||
static void gui_task(void *args)
|
||||
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)
|
||||
{
|
||||
esp_err_t ret;
|
||||
lvgl_drv_t *lvgl_driver = (lvgl_drv_t *)args;
|
||||
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);
|
||||
|
||||
/* Initialize LittlevGL */
|
||||
lv_init();
|
||||
/* IMPORTANT!!!
|
||||
* Inform the graphics library that you are ready with the flushing*/
|
||||
lv_disp_flush_ready(drv);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
#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;
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
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_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);
|
||||
ESP_LOGI(TAG, "Alloc memory total size: %u Byte", BUFFER_NUMBER * PIXEL_TO_SIZE(alloc_pixel));
|
||||
|
||||
xGuiSemaphore = xSemaphoreCreateMutex();
|
||||
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 interface,Initialize 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)
|
||||
{
|
||||
ESP_LOGI(TAG, "Start to run LVGL");
|
||||
|
||||
while (1) {
|
||||
/* Delay 1 tick (assumes FreeRTOS tick is 10ms */
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
|
||||
/* Try to take the semaphore, call lvgl related function on success */
|
||||
|
|
@ -95,27 +176,66 @@ static void gui_task(void *args)
|
|||
|
||||
esp_err_t lvgl_init(scr_driver_t *lcd_drv, touch_panel_driver_t *touch_drv)
|
||||
{
|
||||
/* If you want to use a task to create the graphic, you NEED to create a Pinned task
|
||||
* 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);
|
||||
esp_err_t ret;
|
||||
esp_timer_handle_t tick_timer = NULL;
|
||||
|
||||
static lvgl_drv_t lvgl_driver;
|
||||
lvgl_driver.lcd_drv = lcd_drv;
|
||||
lvgl_driver.touch_drv = touch_drv;
|
||||
/* Initialize LittlevGL */
|
||||
lv_init();
|
||||
|
||||
xTaskCreatePinnedToCore(gui_task, "lv gui", 1024 * 8, &lvgl_driver, 5, NULL, chip_info.cores - 1);
|
||||
/* Display interface */
|
||||
ret = lvgl_display_init(lcd_drv);
|
||||
ESP_GOTO_ON_FALSE(ESP_OK == ret, ESP_FAIL, err, TAG, "lvgl display initialize failed");
|
||||
|
||||
uint16_t timeout = 20;
|
||||
while (NULL == xGuiSemaphore) {
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
timeout--;
|
||||
if (0 == timeout) {
|
||||
ESP_LOGW(TAG, "GUI Task Start Timeout");
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
#if defined(CONFIG_LVGL_DRIVER_TOUCH_SCREEN_ENABLE)
|
||||
if (NULL != touch_drv) {
|
||||
/* Input device interface */
|
||||
ret = lvgl_indev_init(touch_drv);
|
||||
ESP_GOTO_ON_FALSE(ESP_OK == ret, ESP_FAIL, err, TAG, "lvgl indev initialize failed");
|
||||
}
|
||||
#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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
idf_component_register(SRCS "led_indicator.c"
|
||||
INCLUDE_DIRS include)
|
||||
INCLUDE_DIRS include
|
||||
REQUIRES driver)
|
||||
|
|
@ -255,7 +255,6 @@ 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)
|
||||
{
|
||||
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
|
||||
{
|
||||
if (p_led_indicator->p_blink_steps[index] != LED_BLINK_STOP)
|
||||
|
|
@ -271,7 +270,7 @@ static void _blink_list_switch(_led_indicator_t *p_led_indicator)
|
|||
*
|
||||
* @param xTimer handle of the timmer instance
|
||||
*/
|
||||
static void _blink_list_runner(xTimerHandle xTimer)
|
||||
static void _blink_list_runner(TimerHandle_t xTimer)
|
||||
{
|
||||
_led_indicator_t * p_led_indicator = (_led_indicator_t *)pvTimerGetTimerID(xTimer);
|
||||
bool leave = false;
|
||||
|
|
@ -287,9 +286,9 @@ static void _blink_list_runner(xTimerHandle xTimer)
|
|||
|
||||
p_led_indicator->p_blink_steps[active_blink] += 1;
|
||||
|
||||
if (pdFALSE == xSemaphoreTake(p_led_indicator->mutex, (100 / portTICK_RATE_MS))) {
|
||||
if (pdFALSE == xSemaphoreTake(p_led_indicator->mutex, pdMS_TO_TICKS(100))) {
|
||||
ESP_LOGW(TAG, "blinks runner blockTime expired, try repairing...");
|
||||
xTimerChangePeriod(p_led_indicator->h_timer, (100 / portTICK_RATE_MS), 0);
|
||||
xTimerChangePeriod(p_led_indicator->h_timer, pdMS_TO_TICKS(100), 0);
|
||||
xTimerStart(p_led_indicator->h_timer, 0);
|
||||
break;
|
||||
}
|
||||
|
|
@ -308,7 +307,7 @@ static void _blink_list_runner(xTimerHandle xTimer)
|
|||
_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)
|
||||
break;
|
||||
xTimerChangePeriod(p_led_indicator->h_timer, (p_blink_step->hold_time_ms / portTICK_RATE_MS), 0);
|
||||
xTimerChangePeriod(p_led_indicator->h_timer, pdMS_TO_TICKS(p_blink_step->hold_time_ms), 0);
|
||||
xTimerStart(p_led_indicator->h_timer, 0);
|
||||
leave=true;
|
||||
break;
|
||||
|
|
@ -327,13 +326,13 @@ led_indicator_handle_t led_indicator_create(int io_num, const led_indicator_conf
|
|||
char timmer_name[16] = {'\0'};
|
||||
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_CHECK(p_led_indicator != NULL, "calloc memory failed", NULL);
|
||||
LED_INDICATOR_CHECK(p_led_indicator != NULL, "calloc indicator memory failed", NULL);
|
||||
p_led_indicator->off_level = config->off_level;
|
||||
p_led_indicator->io_num = io_num;
|
||||
p_led_indicator->mode = config->mode;
|
||||
p_led_indicator->active_blink = NULL_ACTIVE_BLINK;
|
||||
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 memory failed 2", cleanup_indicator);
|
||||
LED_INDICATOR_CHECK_GOTO(p_led_indicator->p_blink_steps != NULL, "calloc blink_steps memory failed", cleanup_indicator);
|
||||
p_led_indicator->mutex = xSemaphoreCreateMutex();
|
||||
LED_INDICATOR_CHECK_GOTO(p_led_indicator->mutex != NULL, "create mutex failed", cleanup_indicator_blinkstep);
|
||||
|
||||
|
|
@ -347,7 +346,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);
|
||||
LED_INDICATOR_CHECK_GOTO(ininted != false, "init led gpio failed", cleanup_all);
|
||||
p_led_indicator->h_timer = xTimerCreate(timmer_name, (100 / portTICK_RATE_MS), pdFALSE, (void *)p_led_indicator, _blink_list_runner);
|
||||
p_led_indicator->h_timer = xTimerCreate(timmer_name, (pdMS_TO_TICKS(100)), pdFALSE, (void *)p_led_indicator, _blink_list_runner);
|
||||
LED_INDICATOR_CHECK_GOTO(p_led_indicator->h_timer != NULL, "led timmer create failed", cleanup_all);
|
||||
}
|
||||
break;
|
||||
|
|
@ -440,6 +439,10 @@ 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;
|
||||
_blink_list_switch(p_led_indicator); //stop and swith to next blink steps
|
||||
xSemaphoreGive(p_led_indicator->mutex);
|
||||
_blink_list_runner(p_led_indicator->h_timer);
|
||||
|
||||
if(p_led_indicator->active_blink == blink_type) { //re-run from first step
|
||||
_blink_list_runner(p_led_indicator->h_timer);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
idf_component_register(SRCS "light.c"
|
||||
INCLUDE_DIRS include)
|
||||
INCLUDE_DIRS include
|
||||
REQUIRES driver)
|
||||
|
|
@ -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;
|
||||
POINT_ASSERT(TAG, light_handle);
|
||||
IOT_CHECK(TAG, channel_idx < light->channel_num, FAIL);
|
||||
IOT_CHECK(TAG, channel_idx < light->channel_num, ESP_FAIL);
|
||||
if (light->channel_group[channel_idx] != NULL) {
|
||||
ESP_LOGE(TAG, "this channel index has been registered");
|
||||
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;
|
||||
POINT_ASSERT(TAG, light_handle);
|
||||
IOT_CHECK(TAG, channel_id < light->channel_num, FAIL);
|
||||
IOT_CHECK(TAG, channel_id < light->channel_num, ESP_FAIL);
|
||||
POINT_ASSERT(TAG, light->channel_group[channel_id]);
|
||||
light_channel_t* l_chn = light->channel_group[channel_id];
|
||||
if (l_chn->breath_period != breath_period_ms) {
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
idf_component_register(SRCS "iot_servo.c"
|
||||
INCLUDE_DIRS include)
|
||||
INCLUDE_DIRS include
|
||||
REQUIRES driver)
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
idf_component_register(SRCS "sht3x.c"
|
||||
INCLUDE_DIRS include
|
||||
REQUIRES bus)
|
||||
REQUIRES bus esp_timer)
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
#include "i2c_bus.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_timer.h"
|
||||
#include "sht3x.h"
|
||||
|
||||
typedef struct {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#include "esp_log.h"
|
||||
#include "mpu6050.h"
|
||||
|
||||
static const char *TAG = "MPU6050";
|
||||
|
||||
#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
|
||||
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */
|
||||
|
|
@ -330,6 +329,7 @@ esp_err_t mpu6050_complimentory_filter(mpu6050_handle_t sensor, mpu6050_acce_val
|
|||
/***sensors hal interface****/
|
||||
#ifdef CONFIG_SENSOR_IMU_INCLUDED_MPU6050
|
||||
|
||||
static const char *TAG = "MPU6050";
|
||||
static mpu6050_handle_t mpu6050 = NULL;
|
||||
static bool is_init = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,4 +9,4 @@ list(APPEND requires bh1750 veml6040 veml6075)
|
|||
|
||||
idf_component_register(SRC_DIRS "." "hal"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES "${requires}")
|
||||
REQUIRES "${requires}" "esp_timer")
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
#include <sys/queue.h>
|
||||
#include "esp_log.h"
|
||||
#include "iot_sensor_hub.h"
|
||||
#include "esp_timer.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
|
|
|||
BIN
docs/_static/camera-workflow.png
vendored
Normal file
BIN
docs/_static/camera-workflow.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
4
docs/en/_templates/layout.html
Normal file
4
docs/en/_templates/layout.html
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{% extends '!layout.html' %}
|
||||
{% block comments %}
|
||||
<p style="text-align:center"><a href="https://www.espressif.com/en/company/documents/documentation_feedback?docId=5602§ions={{ title|striptags|e }} ({{ pagename }})&version={{ release }} ({{ version }})">Provide feedback about this document</a></p>
|
||||
{% endblock %}
|
||||
|
|
@ -2,6 +2,10 @@ PWM Audio
|
|||
==============
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
================== =========== =============== =============== =============
|
||||
Supported Socs ESP32 ESP32-S2 ESP32-S3 ESP32-C3
|
||||
================== =========== =============== =============== =============
|
||||
|
||||
The PWM audio function uses the internal LEDC peripheral in ESP32 to generate PWM audio, which does not need an external audio Codec chip. This is mainly used for cost-sensitive applications with low audio quality requirements.
|
||||
|
||||
Features
|
||||
|
|
|
|||
|
|
@ -217,9 +217,9 @@ Initialize the Screen
|
|||
|
||||
/** Find screen driver for ILI9806 */
|
||||
ret = scr_find_driver(SCREEN_CONTROLLER_ILI9806, &g_lcd);
|
||||
if (ESP_OK != ret) {
|
||||
return;
|
||||
if (ESP_OK != ret) {
|
||||
ESP_LOGE(TAG, "screen find failed");
|
||||
return;
|
||||
}
|
||||
|
||||
/** Configure screen controller */
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
# This is a list of python packages used to generate documentation. This file is used with pip:
|
||||
# pip install --user -r requirements.txt
|
||||
#
|
||||
setuptools<58
|
||||
sphinx==2.3.1
|
||||
breathe==4.14.1
|
||||
sphinx-rtd-theme
|
||||
sphinx-notfound-page
|
||||
sphinx-rtd-theme==1.0.0
|
||||
sphinx-notfound-page==0.7.1
|
||||
sphinxcontrib-blockdiag==2.0.0
|
||||
sphinxcontrib-seqdiag==2.0.0
|
||||
sphinxcontrib-actdiag==2.0.0
|
||||
sphinxcontrib-nwdiag==2.0.0
|
||||
sphinxcontrib-wavedrom==2.0.0
|
||||
nwdiag==2.0.0
|
||||
recommonmark
|
||||
future>=0.16.0 # for ../tools/gen_esp_err_to_name.py
|
||||
recommonmark==0.7.0
|
||||
future==0.16.0 # for ../tools/gen_esp_err_to_name.py
|
||||
|
|
|
|||
1
docs/setuptools.requirements.txt
Executable file
1
docs/setuptools.requirements.txt
Executable file
|
|
@ -0,0 +1 @@
|
|||
setuptools<58
|
||||
4
docs/zh_CN/_templates/layout.html
Normal file
4
docs/zh_CN/_templates/layout.html
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{% extends '!layout.html' %}
|
||||
{% block comments %}
|
||||
<p style="text-align:center"><a href="https://www.espressif.com/zh-hans/company/documents/documentation_feedback?docId=5603§ions={{ title|striptags|e }} ({{ pagename }})&version={{ release }} ({{ version }})">提供有关此文档的反馈</a></p>
|
||||
{% endblock %}
|
||||
|
|
@ -2,8 +2,11 @@ PWM 音频
|
|||
==============
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
PWM 音频功能使用 ESP32 内部的 LEDC 外设产生 PWM 播放音频,无需使用外部的音频 Codec 芯片,适用于对音质要求不高而对成本敏感的应用。
|
||||
================== =========== =============== =============== =============
|
||||
支持的芯片 ESP32 ESP32-S2 ESP32-S3 ESP32-C3
|
||||
================== =========== =============== =============== =============
|
||||
|
||||
PWM 音频功能使用 ESP32 内部的 LEDC 外设产生 PWM 播放音频,无需使用外部的音频 Codec 芯片,适用于对音质要求不高而对成本敏感的应用。
|
||||
|
||||
特性
|
||||
------
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
+------------+----------------+------------+
|
||||
| ILI9486 | 320 x 480 | Color |
|
||||
+------------+----------------+------------+
|
||||
| ILI9488 | 320 x 480 | Color |
|
||||
+------------+----------------+------------+
|
||||
| ILI9341 | 240 x 320 | Color |
|
||||
+------------+----------------+------------+
|
||||
| ST7789 | 240 x 320 | Color |
|
||||
|
|
@ -29,6 +31,8 @@
|
|||
+------------+----------------+------------+
|
||||
| SSD1322 | 480 x 128 | Gray |
|
||||
+------------+----------------+------------+
|
||||
| SSD1963 | 480 x 864 | Color |
|
||||
+------------+----------------+------------+
|
||||
|
||||
.. note:: 8080 接口通过 ESP32 I2S 的 LCD 模式实现,故下文中有时也称之为 ``I2S 接口``。
|
||||
|
||||
|
|
@ -216,9 +220,9 @@ BPP < 8 时,一个字节映射到了多个像素,因此无法直接地控制
|
|||
|
||||
/** Find screen driver for ILI9806 */
|
||||
ret = scr_find_driver(SCREEN_CONTROLLER_ILI9806, &g_lcd);
|
||||
if (ESP_OK != ret) {
|
||||
return;
|
||||
if (ESP_OK != ret) {
|
||||
ESP_LOGE(TAG, "screen find failed");
|
||||
return;
|
||||
}
|
||||
|
||||
/** Configure screen controller */
|
||||
|
|
|
|||
|
|
@ -6,23 +6,24 @@ This example will show how to configure and operate the LEDC peripheral to play
|
|||
|
||||
### Hardware Required
|
||||
|
||||
* A development board with ESP32 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.)
|
||||
* A development board with ESP32, ESP32-S2, ESP32-S3 or ESP32-C3 SoC (e.g., ESP32-DevKitC, ESP-S2-Saola, ESP32-S3-DevKitC-1, etc.)
|
||||
* A USB cable for power supply and programming
|
||||
|
||||
The following is the hardware connection:
|
||||
|
||||
|hardware|GPIO|
|
||||
|SoC|GPIO|
|
||||
|:---:|:---:|
|
||||
|speaker(R)|GPIO25|
|
||||
|speaker(L)|GPIO26|
|
||||
|ESP32|speaker(R) ----- GPIO25<br />speaker(L) ------- GPIO26|
|
||||
|ESP32S2|speaker(R) ----- GPIO1<br />speaker(L) ------- GPIO2|
|
||||
|ESP32S3|speaker(R) ----- GPIO1<br />speaker(L) ------- GPIO2|
|
||||
|ESP32C3|speaker(R) ----- GPIO1<br />speaker(L) ------- GPIO2|
|
||||
|
||||
If you have ESP32-LCDKit board, just plug the speakers into the socket on the board.
|
||||
|
||||
If you only have ESP32-DevKitC board, connect two speakers to gpio of ESP32 directly, as shown in the figure below. The volume of this connection will sound small.
|
||||
You can connect two speakers to gpio of the SoC directly, as shown in the figure below. The volume of this connection will sound small.
|
||||
|
||||
```
|
||||
47R
|
||||
GPIO25 +----/\/\/\----+
|
||||
GPIOX +----/\/\/\----+
|
||||
|
|
||||
| /|
|
||||
+-+ | Speaker
|
||||
|
|
@ -33,7 +34,7 @@ GPIO25 +----/\/\/\----+
|
|||
+--------------+ GND
|
||||
|
||||
47R
|
||||
GPIO26 +----/\/\/\----+
|
||||
GPIOX +----/\/\/\----+
|
||||
|
|
||||
| /|
|
||||
+-+ | Speaker
|
||||
|
|
|
|||
|
|
@ -40,6 +40,22 @@ static char **g_file_list = NULL;
|
|||
static uint16_t g_file_num = 0;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define GPIO_AUDIO_OUTPUT_L 25
|
||||
#define GPIO_AUDIO_OUTPUT_R 26
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2
|
||||
#define GPIO_AUDIO_OUTPUT_L 1
|
||||
#define GPIO_AUDIO_OUTPUT_R 2
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S3
|
||||
#define GPIO_AUDIO_OUTPUT_L 1
|
||||
#define GPIO_AUDIO_OUTPUT_R 2
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32C3
|
||||
#define GPIO_AUDIO_OUTPUT_L 1
|
||||
#define GPIO_AUDIO_OUTPUT_R 2
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
static esp_err_t play_wav(const char *filepath)
|
||||
{
|
||||
FILE *fd = NULL;
|
||||
|
|
@ -121,9 +137,9 @@ void app_main()
|
|||
|
||||
pwm_audio_config_t pac;
|
||||
pac.duty_resolution = LEDC_TIMER_10_BIT;
|
||||
pac.gpio_num_left = 25;
|
||||
pac.gpio_num_left = GPIO_AUDIO_OUTPUT_L;
|
||||
pac.ledc_channel_left = LEDC_CHANNEL_0;
|
||||
pac.gpio_num_right = 26;
|
||||
pac.gpio_num_right = GPIO_AUDIO_OUTPUT_R;
|
||||
pac.ledc_channel_right = LEDC_CHANNEL_1;
|
||||
pac.ledc_timer_sel = LEDC_TIMER_0;
|
||||
pac.tg_num = TIMER_GROUP_0;
|
||||
|
|
|
|||
|
|
@ -26,16 +26,16 @@
|
|||
#include "sdmmc_cmd.h"
|
||||
#include "file_manager.h"
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#include "driver/sdmmc_host.h"
|
||||
#endif
|
||||
|
||||
static const char *TAG = "file manager";
|
||||
|
||||
static const char *partition_label = "audio";
|
||||
|
||||
#define FLN_MAX CONFIG_FATFS_MAX_LFN
|
||||
|
||||
#ifdef CONFIG_STORAGE_SDCARD
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#include "driver/sdmmc_host.h"
|
||||
#endif
|
||||
// #define USE_SPI_MODE /* To enable SPI mode, uncomment this line*/
|
||||
|
||||
// ESP32-S2 doesn't have an SD Host peripheral, always use SPI:
|
||||
|
|
@ -147,6 +147,7 @@ esp_err_t fm_sdcard_init(void)
|
|||
sdmmc_card_print_info(stdout, card);
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t fm_spiffs_init(void)
|
||||
{
|
||||
|
|
|
|||
83
examples/camera/README.md
Normal file
83
examples/camera/README.md
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
# Camera Examples
|
||||
|
||||
This directory contains a range of example [esp32-camera](https://github.com/espressif/esp32-camera) projects.
|
||||
See the [README.md](../../README.md) file in the upper level directory for more information about examples.
|
||||
|
||||
## Camera driver workflow
|
||||

|
||||
|
||||
The camera sensor transmits data to ESP32 device through DVP(parallel digital video port) interface. When initializing the camera, some `frame_buffer` will be allocated to store the data transmitted by the camera sensor. Once the camera is initialized, it starts working immediately, and the application can call `esp_camera_fb_get()` to get image data. After the application has applied the image data, the `frame_buffer` can be reused by calling `esp_camera_fb_return()`.
|
||||
|
||||
## Example Layout
|
||||
* `basic` demonstrates basic usage of `ESP32-camera driver`.
|
||||
* `pic_server` introduces how to control the action of taking pictures, and view the pictures immediately on the web page.
|
||||
* `test_framerate` introduces how to evaluate the speed of the camera sensor and how to improve the speed of the camera sensor.
|
||||
* `video_stream_server` demonstrates how to implement a video stream HTTP server on ESP32.
|
||||
|
||||
### More
|
||||
* [ESP-WHO](https://github.com/espressif/esp-who) is an image processing development platform based on Espressif chips. It contains development examples that may be applied in practical applications.
|
||||
* [USB_camera_examples](https://github.com/espressif/esp-iot-solution/tree/usb/add_usb_solutions/examples/usb/host) Contains some examples of using USB cameras.
|
||||
|
||||
## API Reference
|
||||
|
||||
The APIs included in the [esp32-camera](https://github.com/espressif/esp32-camera) are described below.
|
||||
### Header File
|
||||
- [esp32-camera/driver/include/esp_camera.h](https://github.com/espressif/esp32-camera/blob/master/driver/include/esp_camera.h)
|
||||
#### Functions
|
||||
- `esp_err_t esp_camera_init(const camera_config_t* config)`
|
||||
Initialize the camera driver.
|
||||
|
||||
- `esp_err_t esp_camera_deinit()`
|
||||
Deinitialize the camera driver.
|
||||
|
||||
- `camera_fb_t* esp_camera_fb_get()`
|
||||
Obtain pointer to a frame buffer.
|
||||
|
||||
- `void esp_camera_fb_return(camera_fb_t * fb)`
|
||||
Return the frame buffer to be reused again.
|
||||
|
||||
- `sensor_t * esp_camera_sensor_get()`
|
||||
Get a pointer to the image sensor control structure.
|
||||
|
||||
- `esp_err_t esp_camera_save_to_nvs(const char *key)`
|
||||
Save camera settings to non-volatile-storage (NVS).
|
||||
|
||||
- `esp_err_t esp_camera_load_from_nvs(const char *key)`
|
||||
Load camera settings from non-volatile-storage (NVS).
|
||||
### Header File
|
||||
- [esp32-camera/driver/include/sensor.h](https://github.com/espressif/esp32-camera/blob/master/driver/include/sensor.h)
|
||||
#### Functions
|
||||
- `camera_sensor_info_t *esp_camera_sensor_get_info(sensor_id_t *id)`
|
||||
Get the camera sensor information.
|
||||
### Header File
|
||||
- [esp32-camera/conversions/include/img_converters.h](https://github.com/espressif/esp32-camera/blob/master/conversions/include/img_converters.h)
|
||||
#### Functions
|
||||
- `bool fmt2jpg_cb(uint8_t *src, size_t src_len, uint16_t width, uint16_t height, pixformat_t format, uint8_t quality, jpg_out_cb cb, void * arg)`
|
||||
Convert image buffer to JPEG.
|
||||
|
||||
- `bool frame2jpg_cb(camera_fb_t * fb, uint8_t quality, jpg_out_cb cb, void * arg)`
|
||||
Convert camera frame buffer to JPEG.
|
||||
|
||||
- `bool fmt2jpg(uint8_t *src, size_t src_len, uint16_t width, uint16_t height, pixformat_t format, uint8_t quality, uint8_t ** out, size_t * out_len)`
|
||||
Convert image buffer to JPEG buffer.
|
||||
|
||||
- `bool fmt2bmp(uint8_t *src, size_t src_len, uint16_t width, uint16_t height, pixformat_t format, uint8_t ** out, size_t * out_len)`
|
||||
Convert image buffer to BMP buffer.
|
||||
|
||||
- `bool frame2bmp(camera_fb_t * fb, uint8_t ** out, size_t * out_len)`
|
||||
Convert camera frame buffer to BMP buffer.
|
||||
|
||||
- `bool frame2bmp(camera_fb_t * fb, uint8_t ** out, size_t * out_len)`
|
||||
Convert camera frame buffer to BMP buffer.
|
||||
|
||||
- `bool fmt2rgb888(const uint8_t *src_buf, size_t src_len, pixformat_t format, uint8_t * rgb_buf)`
|
||||
Convert image buffer to RGB888 buffer.
|
||||
|
||||
- `bool jpg2rgb565(const uint8_t *src, size_t src_len, uint8_t * out, jpg_scale_t scale)`
|
||||
Convert image buffer to RGB565 buffer.
|
||||
|
||||
### Header File
|
||||
- [esp32-camera/conversions/include/esp_jpg_decode.h](https://github.com/espressif/esp32-camera/blob/master/conversions/include/esp_jpg_decode.h)
|
||||
#### Functions
|
||||
- `esp_err_t esp_jpg_decode(size_t len, jpg_scale_t scale, jpg_reader_cb reader, jpg_writer_cb writer, void * arg)`
|
||||
JPEG scaling function.
|
||||
18
examples/camera/basic/CMakeLists.txt
Normal file
18
examples/camera/basic/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
#If IOT_SOLUTION_PATH is not defined, use relative path as default value
|
||||
if(NOT DEFINED ENV{IOT_SOLUTION_PATH})
|
||||
get_filename_component(IOT_SOLUTION_PATH "${CMAKE_SOURCE_DIR}/../../.." ABSOLUTE)
|
||||
set(ENV{IOT_SOLUTION_PATH} ${IOT_SOLUTION_PATH})
|
||||
message(WARNING "Can't detect IOT_SOLUTION_PATH in your environment, we infer it is $ENV{IOT_SOLUTION_PATH}")
|
||||
endif()
|
||||
|
||||
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IOT_SOLUTION_PATH}/examples/camera/camera_components/camera_example_common" "$ENV{IOT_SOLUTION_PATH}/examples/camera/camera_components/esp32-camera")
|
||||
|
||||
include($ENV{IOT_SOLUTION_PATH}/component.cmake)
|
||||
|
||||
add_compile_options(-fdiagnostics-color=always)
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(camera_basic_example)
|
||||
55
examples/camera/basic/README.md
Normal file
55
examples/camera/basic/README.md
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
| Supported Targets | ESP32 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- |
|
||||
|
||||
# Camera Basic Example
|
||||
|
||||
This example demonstrates how to initialize the camera sensor and then get the data captured by the sensor.
|
||||
|
||||
See the [README.md](../README.md) file in the upper level [camera](../) directory for more information about examples.
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware Required
|
||||
|
||||
* A development board with camera module (e.g., ESP-EYE, ESP32-S2-Kaluga-1, ESP32-S3-EYE, etc.)
|
||||
* A USB cable for power supply and programming
|
||||
|
||||
### Configure the project
|
||||
|
||||
```
|
||||
idf.py menuconfig
|
||||
```
|
||||
* Open the project configuration menu (`idf.py menuconfig -> Camera Pin Configuration`) to configure camera pins.
|
||||
|
||||
### Build and Flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output:
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(Replace PORT with the name of the serial port to use.)
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example Output
|
||||
```
|
||||
I (325) camera: Detected OV2640 camera
|
||||
I (325) camera: Camera PID=0x26 VER=0x42 MIDL=0x7f MIDH=0xa2
|
||||
I (504) s2 ll_cam: node_size: 3840, nodes_per_line: 1, lines_per_node: 6
|
||||
I (504) s2 ll_cam: dma_half_buffer_min: 3840, dma_half_buffer: 15360, lines_per_half_buffer: 24, dma_buffer_size: 30720
|
||||
I (512) cam_hal: buffer_size: 30720, half_buffer_size: 15360, node_buffer_size: 3840, node_cnt: 8, total_cnt: 10
|
||||
I (522) cam_hal: Allocating 153600 Byte frame buffer in PSRAM
|
||||
I (529) cam_hal: Allocating 153600 Byte frame buffer in PSRAM
|
||||
I (535) cam_hal: cam config ok
|
||||
I (539) ov2640: Set PLL: clk_2x: 1, clk_div: 3, pclk_auto: 1, pclk_div: 8
|
||||
I (714) example:take_picture: Taking picture...
|
||||
I (855) example:take_picture: Picture taken! Its size was: 153600 bytes
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
* If the log shows "gpio: gpio_intr_disable(176): GPIO number error", then you probably need to check the configuration of camera pins, which you can find in the project configuration menu (`idf.py menuconfig`): Component config -> Camera Pin Config.
|
||||
* If the initialization of the camera sensor fails. Please check the initialization parameters and pin configuration of your camera sensor.
|
||||
3
examples/camera/basic/main/CMakeLists.txt
Normal file
3
examples/camera/basic/main/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
idf_component_register(SRC_DIRS .
|
||||
PRIV_INCLUDE_DIRS .
|
||||
PRIV_REQUIRES nvs_flash esp32-camera camera_example_common)
|
||||
5
examples/camera/basic/main/component.mk
Normal file
5
examples/camera/basic/main/component.mk
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
||||
118
examples/camera/basic/main/take_picture.c
Normal file
118
examples/camera/basic/main/take_picture.c
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/* Camera basic example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <esp_log.h>
|
||||
#include <esp_system.h>
|
||||
#include <nvs_flash.h>
|
||||
#include <sys/param.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include "esp_camera.h"
|
||||
#include "camera_pin.h"
|
||||
|
||||
static bool auto_jpeg_support = false; // whether the camera sensor support compression or JPEG encode
|
||||
static const char *TAG = "example:take_picture";
|
||||
|
||||
static esp_err_t init_camera(uint32_t xclk_freq_hz, pixformat_t pixel_format, framesize_t frame_size, uint8_t fb_count)
|
||||
{
|
||||
camera_config_t camera_config = {
|
||||
.pin_pwdn = CAMERA_PIN_PWDN,
|
||||
.pin_reset = CAMERA_PIN_RESET,
|
||||
.pin_xclk = CAMERA_PIN_XCLK,
|
||||
.pin_sscb_sda = CAMERA_PIN_SIOD,
|
||||
.pin_sscb_scl = CAMERA_PIN_SIOC,
|
||||
|
||||
.pin_d7 = CAMERA_PIN_D7,
|
||||
.pin_d6 = CAMERA_PIN_D6,
|
||||
.pin_d5 = CAMERA_PIN_D5,
|
||||
.pin_d4 = CAMERA_PIN_D4,
|
||||
.pin_d3 = CAMERA_PIN_D3,
|
||||
.pin_d2 = CAMERA_PIN_D2,
|
||||
.pin_d1 = CAMERA_PIN_D1,
|
||||
.pin_d0 = CAMERA_PIN_D0,
|
||||
.pin_vsync = CAMERA_PIN_VSYNC,
|
||||
.pin_href = CAMERA_PIN_HREF,
|
||||
.pin_pclk = CAMERA_PIN_PCLK,
|
||||
|
||||
// EXPERIMENTAL: Set to 16MHz on ESP32-S2 or ESP32-S3 to enable EDMA mode.
|
||||
.xclk_freq_hz = xclk_freq_hz,
|
||||
.ledc_timer = LEDC_TIMER_0, // This is only valid on ESP32/ESP32-S2. ESP32-S3 use LCD_CAM interface.
|
||||
.ledc_channel = LEDC_CHANNEL_0,
|
||||
|
||||
.pixel_format = pixel_format, // YUV422,GRAYSCALE,RGB565,JPEG
|
||||
.frame_size = frame_size, // QQVGA-UXGA, sizes above QVGA are not been recommended when not JPEG format.
|
||||
|
||||
.jpeg_quality = 30, // 0-63, used only with JPEG format.
|
||||
.fb_count = fb_count, // For ESP32/ESP32-S2, if more than one, i2s runs in continuous mode.
|
||||
.grab_mode = CAMERA_GRAB_WHEN_EMPTY,
|
||||
.fb_location = CAMERA_FB_IN_PSRAM
|
||||
};
|
||||
|
||||
// initialize the camera sensor
|
||||
esp_err_t ret = esp_camera_init(&camera_config);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get the sensor object, and then use some of its functions to adjust the parameters when taking a photo.
|
||||
// Note: Do not call functions that set resolution, set picture format and PLL clock,
|
||||
// If you need to reset the appeal parameters, please reinitialize the sensor.
|
||||
sensor_t *s = esp_camera_sensor_get();
|
||||
s->set_vflip(s, 1); // flip it back
|
||||
// initial sensors are flipped vertically and colors are a bit saturated
|
||||
if (s->id.PID == OV3660_PID) {
|
||||
s->set_brightness(s, 1); // up the blightness just a bit
|
||||
s->set_saturation(s, -2); // lower the saturation
|
||||
}
|
||||
|
||||
if (s->id.PID == OV3660_PID || s->id.PID == OV2640_PID) {
|
||||
s->set_vflip(s, 1); // flip it back
|
||||
} else if (s->id.PID == GC0308_PID) {
|
||||
s->set_hmirror(s, 0);
|
||||
} else if (s->id.PID == GC032A_PID) {
|
||||
s->set_vflip(s, 1);
|
||||
}
|
||||
|
||||
// Get the basic information of the sensor.
|
||||
camera_sensor_info_t *s_info = esp_camera_sensor_get_info(&(s->id));
|
||||
|
||||
if (ESP_OK == ret && PIXFORMAT_JPEG == pixel_format && s_info->support_jpeg == true) {
|
||||
auto_jpeg_support = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void app_main()
|
||||
{
|
||||
if (ESP_OK != init_camera(10 * 1000000, PIXFORMAT_RGB565, FRAMESIZE_QVGA, 2)) {
|
||||
ESP_LOGE(TAG, "init camrea sensor fail");
|
||||
return;
|
||||
}
|
||||
|
||||
// take a picture every two seconds and print the size of the picture.
|
||||
while (1) {
|
||||
ESP_LOGI(TAG, "Taking picture...");
|
||||
camera_fb_t *pic = esp_camera_fb_get();
|
||||
|
||||
if(pic){
|
||||
// use pic->buf to access the image
|
||||
ESP_LOGI(TAG, "Picture taken! Its size was: %zu bytes", pic->len);
|
||||
// To enable the frame buffer can be reused again.
|
||||
// Note: If you don't call fb_return(), the next time you call fb_get() you may get
|
||||
// an error "Failed to get the frame on time!"because there is no frame buffer space available.
|
||||
esp_camera_fb_return(pic);
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
}
|
||||
}
|
||||
2
examples/camera/basic/sdkconfig.ci
Normal file
2
examples/camera/basic/sdkconfig.ci
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
CONFIG_SPIRAM_SUPPORT=n
|
||||
CONFIG_ESP32S2_SPIRAM_SUPPORT=n
|
||||
24
examples/camera/basic/sdkconfig.defaults
Normal file
24
examples/camera/basic/sdkconfig.defaults
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
|
||||
CONFIG_ESP32S2_DEFAULT_CPU_FREQ_240=y
|
||||
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
|
||||
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
||||
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
|
||||
CONFIG_SPIRAM_SUPPORT=y
|
||||
CONFIG_ESP32_SPIRAM_SUPPORT=y
|
||||
CONFIG_ESP32S2_SPIRAM_SUPPORT=y
|
||||
CONFIG_ESP32S3_SPIRAM_SUPPORT=y
|
||||
CONFIG_SPIRAM_MODE_OCT=y
|
||||
CONFIG_SPIRAM_SPEED_80M=y
|
||||
CONFIG_SPIRAM_MEMTEST=n
|
||||
|
||||
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=1580
|
||||
CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536
|
||||
|
||||
CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=y
|
||||
CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON=y
|
||||
CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS=y
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
idf_component_register(INCLUDE_DIRS "include")
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
menu "Camera Pin Configuration"
|
||||
|
||||
choice CAMERA_MODULE
|
||||
bool "Select Camera Pinout"
|
||||
default CAMERA_MODULE_WROVER_KIT
|
||||
help
|
||||
Select Camera Pinout.
|
||||
|
||||
config CAMERA_MODULE_WROVER_KIT
|
||||
bool "WROVER-KIT With OV2640 Module"
|
||||
config CAMERA_MODULE_ESP_EYE
|
||||
bool "ESP-EYE DevKit"
|
||||
config CAMERA_MODULE_ESP_S2_KALUGA
|
||||
bool "ESP32-S2-Kaluga-1 V1.3"
|
||||
config CAMERA_MODULE_ESP_S3_EYE
|
||||
bool "ESP-S3-EYE DevKit"
|
||||
config CAMERA_MODEL_ESP32_CAM_BOARD
|
||||
bool "ESP32 Camera Development Board"
|
||||
config CAMERA_MODULE_M5STACK_PSRAM
|
||||
bool "M5Stack Camera With PSRAM"
|
||||
config CAMERA_MODULE_M5STACK_WIDE
|
||||
bool "M5Stack Camera F (Wide)"
|
||||
config CAMERA_MODULE_AI_THINKER
|
||||
bool "ESP32-CAM by AI-Thinker"
|
||||
config CAMERA_MODULE_CUSTOM
|
||||
bool "Custom Camera Pinout"
|
||||
endchoice
|
||||
|
||||
config CAMERA_PIN_PWDN
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "Power Down pin"
|
||||
range -1 33
|
||||
default -1
|
||||
help
|
||||
Select Power Down pin or -1 for unmanaged.
|
||||
|
||||
config CAMERA_PIN_RESET
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "Reset pin"
|
||||
range -1 33
|
||||
default -1
|
||||
help
|
||||
Select Camera Reset pin or -1 for software reset.
|
||||
|
||||
config CAMERA_PIN_XCLK
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "XCLK pin"
|
||||
range 0 33
|
||||
default 21
|
||||
help
|
||||
Select Camera XCLK pin.
|
||||
|
||||
config CAMERA_PIN_SIOD
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "SIOD pin"
|
||||
range 0 33
|
||||
default 26
|
||||
help
|
||||
Select Camera SIOD pin.
|
||||
|
||||
config CAMERA_PIN_SIOC
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "SIOC pin"
|
||||
range 0 33
|
||||
default 27
|
||||
help
|
||||
Select Camera SIOC pin.
|
||||
|
||||
config CAMERA_PIN_VSYNC
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "VSYNC pin"
|
||||
range 0 39
|
||||
default 25
|
||||
help
|
||||
Select Camera VSYNC pin.
|
||||
|
||||
config CAMERA_PIN_HREF
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "HREF pin"
|
||||
range 0 39
|
||||
default 23
|
||||
help
|
||||
Select Camera HREF pin.
|
||||
|
||||
config CAMERA_PIN_PCLK
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "PCLK pin"
|
||||
range 0 39
|
||||
default 25
|
||||
help
|
||||
Select Camera PCLK pin.
|
||||
|
||||
config CAMERA_PIN_Y2
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "Y2 pin"
|
||||
range 0 39
|
||||
default 4
|
||||
help
|
||||
Select Camera Y2 pin.
|
||||
|
||||
config CAMERA_PIN_Y3
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "Y3 pin"
|
||||
range 0 39
|
||||
default 5
|
||||
help
|
||||
Select Camera Y3 pin.
|
||||
|
||||
config CAMERA_PIN_Y4
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "Y4 pin"
|
||||
range 0 39
|
||||
default 18
|
||||
help
|
||||
Select Camera Y4 pin.
|
||||
|
||||
config CAMERA_PIN_Y5
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "Y5 pin"
|
||||
range 0 39
|
||||
default 19
|
||||
help
|
||||
Select Camera Y5 pin.
|
||||
|
||||
config CAMERA_PIN_Y6
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "Y6 pin"
|
||||
range 0 39
|
||||
default 36
|
||||
help
|
||||
Select Camera Y6 pin.
|
||||
|
||||
config CAMERA_PIN_Y7
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "Y7 pin"
|
||||
range 0 39
|
||||
default 39
|
||||
help
|
||||
Select Camera Y7 pin.
|
||||
|
||||
config CAMERA_PIN_Y8
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "Y8 pin"
|
||||
range 0 39
|
||||
default 34
|
||||
help
|
||||
Select Camera Y8 pin.
|
||||
|
||||
config CAMERA_PIN_Y9
|
||||
depends on CAMERA_MODULE_CUSTOM
|
||||
int "Y9 pin"
|
||||
range 0 39
|
||||
default 35
|
||||
help
|
||||
Select Camera Y9 pin.
|
||||
endmenu
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Camera Example Common
|
||||
|
||||
This directory contains component that is common for esp32-camera examples. The component defines camera pins used by different development boards.
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_CAMERA_MODULE_WROVER_KIT
|
||||
#define CAMERA_MODULE_NAME "Wrover Kit"
|
||||
#define CAMERA_PIN_PWDN -1
|
||||
#define CAMERA_PIN_RESET -1
|
||||
#define CAMERA_PIN_XCLK 21
|
||||
#define CAMERA_PIN_SIOD 26
|
||||
#define CAMERA_PIN_SIOC 27
|
||||
|
||||
#define CAMERA_PIN_D7 35
|
||||
#define CAMERA_PIN_D6 34
|
||||
#define CAMERA_PIN_D5 39
|
||||
#define CAMERA_PIN_D4 36
|
||||
#define CAMERA_PIN_D3 19
|
||||
#define CAMERA_PIN_D2 18
|
||||
#define CAMERA_PIN_D1 5
|
||||
#define CAMERA_PIN_D0 4
|
||||
#define CAMERA_PIN_VSYNC 25
|
||||
#define CAMERA_PIN_HREF 23
|
||||
#define CAMERA_PIN_PCLK 22
|
||||
|
||||
#elif CONFIG_CAMERA_MODULE_ESP_EYE
|
||||
#define CAMERA_MODULE_NAME "ESP-EYE"
|
||||
#define CAMERA_PIN_PWDN -1
|
||||
#define CAMERA_PIN_RESET -1
|
||||
#define CAMERA_PIN_XCLK 4
|
||||
#define CAMERA_PIN_SIOD 18
|
||||
#define CAMERA_PIN_SIOC 23
|
||||
|
||||
#define CAMERA_PIN_D7 36
|
||||
#define CAMERA_PIN_D6 37
|
||||
#define CAMERA_PIN_D5 38
|
||||
#define CAMERA_PIN_D4 39
|
||||
#define CAMERA_PIN_D3 35
|
||||
#define CAMERA_PIN_D2 14
|
||||
#define CAMERA_PIN_D1 13
|
||||
#define CAMERA_PIN_D0 34
|
||||
#define CAMERA_PIN_VSYNC 5
|
||||
#define CAMERA_PIN_HREF 27
|
||||
#define CAMERA_PIN_PCLK 25
|
||||
|
||||
#elif CONFIG_CAMERA_MODULE_ESP_S2_KALUGA
|
||||
#define CAMERA_MODULE_NAME "ESP-S2-KALUGA"
|
||||
#define CAMERA_PIN_PWDN -1
|
||||
#define CAMERA_PIN_RESET -1
|
||||
#define CAMERA_PIN_XCLK 1
|
||||
#define CAMERA_PIN_SIOD 8
|
||||
#define CAMERA_PIN_SIOC 7
|
||||
|
||||
#define CAMERA_PIN_D7 38
|
||||
#define CAMERA_PIN_D6 21
|
||||
#define CAMERA_PIN_D5 40
|
||||
#define CAMERA_PIN_D4 39
|
||||
#define CAMERA_PIN_D3 42
|
||||
#define CAMERA_PIN_D2 41
|
||||
#define CAMERA_PIN_D1 37
|
||||
#define CAMERA_PIN_D0 36
|
||||
#define CAMERA_PIN_VSYNC 2
|
||||
#define CAMERA_PIN_HREF 3
|
||||
#define CAMERA_PIN_PCLK 33
|
||||
|
||||
#elif CONFIG_CAMERA_MODULE_ESP_S3_EYE
|
||||
#define CAMERA_MODULE_NAME "ESP-S3-EYE"
|
||||
#define CAMERA_PIN_PWDN -1
|
||||
#define CAMERA_PIN_RESET -1
|
||||
|
||||
#define CAMERA_PIN_VSYNC 6
|
||||
#define CAMERA_PIN_HREF 7
|
||||
#define CAMERA_PIN_PCLK 13
|
||||
#define CAMERA_PIN_XCLK 15
|
||||
|
||||
#define CAMERA_PIN_SIOD 4
|
||||
#define CAMERA_PIN_SIOC 5
|
||||
|
||||
#define CAMERA_PIN_D0 11
|
||||
#define CAMERA_PIN_D1 9
|
||||
#define CAMERA_PIN_D2 8
|
||||
#define CAMERA_PIN_D3 10
|
||||
#define CAMERA_PIN_D4 12
|
||||
#define CAMERA_PIN_D5 18
|
||||
#define CAMERA_PIN_D6 17
|
||||
#define CAMERA_PIN_D7 16
|
||||
|
||||
#elif CONFIG_CAMERA_MODEL_ESP32_CAM_BOARD
|
||||
#define CAMERA_MODULE_NAME "ESP-DEVCAM"
|
||||
#define CAMERA_PIN_PWDN 32
|
||||
#define CAMERA_PIN_RESET 33
|
||||
|
||||
#define CAMERA_PIN_XCLK 4
|
||||
#define CAMERA_PIN_SIOD 18
|
||||
#define CAMERA_PIN_SIOC 23
|
||||
|
||||
#define CAMERA_PIN_D7 36
|
||||
#define CAMERA_PIN_D6 19
|
||||
#define CAMERA_PIN_D5 21
|
||||
#define CAMERA_PIN_D4 39
|
||||
#define CAMERA_PIN_D3 35
|
||||
#define CAMERA_PIN_D2 14
|
||||
#define CAMERA_PIN_D1 13
|
||||
#define CAMERA_PIN_D0 34
|
||||
#define CAMERA_PIN_VSYNC 5
|
||||
#define CAMERA_PIN_HREF 27
|
||||
#define CAMERA_PIN_PCLK 25
|
||||
|
||||
#elif CONFIG_CAMERA_MODULE_M5STACK_PSRAM
|
||||
#define CAMERA_MODULE_NAME "M5STACK-PSRAM"
|
||||
#define CAMERA_PIN_PWDN -1
|
||||
#define CAMERA_PIN_RESET 15
|
||||
|
||||
#define CAMERA_PIN_XCLK 27
|
||||
#define CAMERA_PIN_SIOD 25
|
||||
#define CAMERA_PIN_SIOC 23
|
||||
|
||||
#define CAMERA_PIN_D7 19
|
||||
#define CAMERA_PIN_D6 36
|
||||
#define CAMERA_PIN_D5 18
|
||||
#define CAMERA_PIN_D4 39
|
||||
#define CAMERA_PIN_D3 5
|
||||
#define CAMERA_PIN_D2 34
|
||||
#define CAMERA_PIN_D1 35
|
||||
#define CAMERA_PIN_D0 32
|
||||
#define CAMERA_PIN_VSYNC 22
|
||||
#define CAMERA_PIN_HREF 26
|
||||
#define CAMERA_PIN_PCLK 21
|
||||
|
||||
#elif CONFIG_CAMERA_MODULE_M5STACK_WIDE
|
||||
#define CAMERA_MODULE_NAME "M5STACK-WIDE"
|
||||
#define CAMERA_PIN_PWDN -1
|
||||
#define CAMERA_PIN_RESET 15
|
||||
#define CAMERA_PIN_XCLK 27
|
||||
#define CAMERA_PIN_SIOD 22
|
||||
#define CAMERA_PIN_SIOC 23
|
||||
|
||||
#define CAMERA_PIN_D7 19
|
||||
#define CAMERA_PIN_D6 36
|
||||
#define CAMERA_PIN_D5 18
|
||||
#define CAMERA_PIN_D4 39
|
||||
#define CAMERA_PIN_D3 5
|
||||
#define CAMERA_PIN_D2 34
|
||||
#define CAMERA_PIN_D1 35
|
||||
#define CAMERA_PIN_D0 32
|
||||
#define CAMERA_PIN_VSYNC 25
|
||||
#define CAMERA_PIN_HREF 26
|
||||
#define CAMERA_PIN_PCLK 21
|
||||
|
||||
#elif CONFIG_CAMERA_MODULE_AI_THINKER
|
||||
#define CAMERA_MODULE_NAME "AI-THINKER"
|
||||
#define CAMERA_PIN_PWDN 32
|
||||
#define CAMERA_PIN_RESET -1
|
||||
#define CAMERA_PIN_XCLK 0
|
||||
#define CAMERA_PIN_SIOD 26
|
||||
#define CAMERA_PIN_SIOC 27
|
||||
|
||||
#define CAMERA_PIN_D7 35
|
||||
#define CAMERA_PIN_D6 34
|
||||
#define CAMERA_PIN_D5 39
|
||||
#define CAMERA_PIN_D4 36
|
||||
#define CAMERA_PIN_D3 21
|
||||
#define CAMERA_PIN_D2 19
|
||||
#define CAMERA_PIN_D1 18
|
||||
#define CAMERA_PIN_D0 5
|
||||
#define CAMERA_PIN_VSYNC 25
|
||||
#define CAMERA_PIN_HREF 23
|
||||
#define CAMERA_PIN_PCLK 22
|
||||
|
||||
#elif CONFIG_CAMERA_MODULE_CUSTOM
|
||||
#define CAMERA_MODULE_NAME "CUSTOM"
|
||||
#define CAMERA_PIN_PWDN CONFIG_CAMERA_PIN_PWDN
|
||||
#define CAMERA_PIN_RESET CONFIG_CAMERA_PIN_RESET
|
||||
#define CAMERA_PIN_XCLK CONFIG_CAMERA_PIN_XCLK
|
||||
#define CAMERA_PIN_SIOD CONFIG_CAMERA_PIN_SIOD
|
||||
#define CAMERA_PIN_SIOC CONFIG_CAMERA_PIN_SIOC
|
||||
|
||||
#define CAMERA_PIN_D7 CONFIG_CAMERA_PIN_Y9
|
||||
#define CAMERA_PIN_D6 CONFIG_CAMERA_PIN_Y8
|
||||
#define CAMERA_PIN_D5 CONFIG_CAMERA_PIN_Y7
|
||||
#define CAMERA_PIN_D4 CONFIG_CAMERA_PIN_Y6
|
||||
#define CAMERA_PIN_D3 CONFIG_CAMERA_PIN_Y5
|
||||
#define CAMERA_PIN_D2 CONFIG_CAMERA_PIN_Y4
|
||||
#define CAMERA_PIN_D1 CONFIG_CAMERA_PIN_Y3
|
||||
#define CAMERA_PIN_D0 CONFIG_CAMERA_PIN_Y2
|
||||
#define CAMERA_PIN_VSYNC CONFIG_CAMERA_PIN_VSYNC
|
||||
#define CAMERA_PIN_HREF CONFIG_CAMERA_PIN_HREF
|
||||
#define CAMERA_PIN_PCLK CONFIG_CAMERA_PIN_PCLK
|
||||
#endif
|
||||
1
examples/camera/camera_components/esp32-camera
Submodule
1
examples/camera/camera_components/esp32-camera
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 1ac48e5397ee22a59a18a314c4acf44c23dfe946
|
||||
16
examples/camera/pic_server/CMakeLists.txt
Normal file
16
examples/camera/pic_server/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
#If IOT_SOLUTION_PATH is not defined, use relative path as default value
|
||||
if(NOT DEFINED ENV{IOT_SOLUTION_PATH})
|
||||
get_filename_component(IOT_SOLUTION_PATH "${CMAKE_SOURCE_DIR}/../../.." ABSOLUTE)
|
||||
set(ENV{IOT_SOLUTION_PATH} ${IOT_SOLUTION_PATH})
|
||||
message(WARNING "Can't detect IOT_SOLUTION_PATH in your environment, we infer it is $ENV{IOT_SOLUTION_PATH}")
|
||||
endif()
|
||||
|
||||
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IOT_SOLUTION_PATH}/examples/camera/camera_components/camera_example_common" "$ENV{IOT_SOLUTION_PATH}/examples/camera/camera_components/esp32-camera")
|
||||
include($ENV{IOT_SOLUTION_PATH}/component.cmake)
|
||||
# add_compile_options(-fdiagnostics-color=always)
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(camera_pic_server)
|
||||
53
examples/camera/pic_server/README.md
Normal file
53
examples/camera/pic_server/README.md
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
| Supported Targets | ESP32 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- |
|
||||
|
||||
# ESP Camera Picture Server
|
||||
|
||||
The example starts a web server on a local network. You can use a browser to access this server to view pictures.
|
||||
|
||||
See the [README.md](../README.md) file in the upper level [camera](../) directory for more information about examples.
|
||||
|
||||
## How to use the example
|
||||
|
||||
|
||||
### Hardware Required
|
||||
|
||||
* A development board with camera module (e.g., ESP-EYE, ESP32-S2-Kaluga-1, ESP32-S3-EYE, etc.)
|
||||
* A USB cable for power supply and programming
|
||||
|
||||
### Configure the project
|
||||
|
||||
step1: chose your taget chip.
|
||||
|
||||
````
|
||||
idf.py menuconfig -> Camera Pin Configuration
|
||||
````
|
||||
|
||||
step2: Configure your wifi.
|
||||
|
||||
```
|
||||
idf.py menuconfig -> Example Connection Configuration
|
||||
```
|
||||
|
||||
step3: Configure the camera.
|
||||
|
||||
```
|
||||
idf.py menuconfig -> component config -> Camera Configuration
|
||||
```
|
||||
|
||||
step 4: Launch and monitor
|
||||
Flash the program and launch IDF Monitor:
|
||||
|
||||
```bash
|
||||
idf.py flash monitor
|
||||
```
|
||||
|
||||
step 5: Test the example interactively on a web browser (assuming IP is 192.168.43.130):
|
||||
|
||||
open path `http://192.168.43.130/pic` to see an HTML web page on the server.
|
||||
|
||||
step 6: Click the refresh button to get next picture on the HTML web page.
|
||||
|
||||
## Troubleshooting
|
||||
* If the log shows "gpio: gpio_intr_disable(176): GPIO number error", then you probably need to check the configuration of camera pins, which you can find in the project configuration menu (`idf.py menuconfig`): Component config -> Camera Pin Config.
|
||||
* If the initialization of the camera sensor fails. Please check the initialization parameters and pin configuration of your camera sensor.
|
||||
3
examples/camera/pic_server/main/CMakeLists.txt
Normal file
3
examples/camera/pic_server/main/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
idf_component_register(SRC_DIRS .
|
||||
PRIV_INCLUDE_DIRS .
|
||||
PRIV_REQUIRES esp32-camera nvs_flash esp_http_server camera_example_common)
|
||||
50
examples/camera/pic_server/main/Kconfig.projbuild
Normal file
50
examples/camera/pic_server/main/Kconfig.projbuild
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
menu "Example Connection Configuration"
|
||||
|
||||
config ESP_WIFI_SSID
|
||||
string "WiFi STA SSID"
|
||||
default ""
|
||||
help
|
||||
WiFi SSID (network name) to connect to or empty for Off.
|
||||
|
||||
config ESP_WIFI_PASSWORD
|
||||
string "WiFi STA Password"
|
||||
default ""
|
||||
help
|
||||
WiFi Password if WEP/WPA/WPA2 or empty if Open.
|
||||
|
||||
config ESP_WIFI_AP_SSID
|
||||
string "WiFi AP SSID"
|
||||
default "ESP32-Camera"
|
||||
help
|
||||
AP SSID (network name) to create or empty for Off.
|
||||
|
||||
config ESP_WIFI_AP_PASSWORD
|
||||
string "WiFi AP Password"
|
||||
default ""
|
||||
help
|
||||
AP password for WPA2 or empty for Open.
|
||||
|
||||
config MAX_STA_CONN
|
||||
int "Maximal STA connections"
|
||||
default 1
|
||||
help
|
||||
Max number of the STA connects to AP.
|
||||
|
||||
config ESP_WIFI_AP_CHANNEL
|
||||
string "WiFi AP Channel"
|
||||
default ""
|
||||
help
|
||||
AP channel for better connection performance.
|
||||
|
||||
config SERVER_IP
|
||||
string "WiFi AP IP Address"
|
||||
default "192.168.4.1"
|
||||
help
|
||||
IP address that the ESP will assign to it's AP interface. You can use this IP to connect to the camera after flashing.
|
||||
|
||||
config ESP_MAXIMUM_RETRY
|
||||
int "Maximum retry"
|
||||
default 5
|
||||
help
|
||||
Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent.
|
||||
endmenu
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue