diff --git a/bsp/esp32_s3_touch_lcd_1_85C_V2/CMakeLists.txt b/bsp/esp32_s3_touch_lcd_1_85C_V2/CMakeLists.txt new file mode 100644 index 00000000..96220bae --- /dev/null +++ b/bsp/esp32_s3_touch_lcd_1_85C_V2/CMakeLists.txt @@ -0,0 +1,7 @@ +idf_component_register( + SRCS "esp32_s3_touch_lcd_1_85C_V2.c" ${SRC_VER} + INCLUDE_DIRS "include" "include/bsp" + PRIV_INCLUDE_DIRS "priv_include" + REQUIRES fatfs esp_driver_i2c esp_driver_gpio esp_lcd pcf85063a esp_io_expander_tca9554 + PRIV_REQUIRES esp_timer spiffs esp_psram +) \ No newline at end of file diff --git a/bsp/esp32_s3_touch_lcd_1_85C_V2/Kconfig b/bsp/esp32_s3_touch_lcd_1_85C_V2/Kconfig new file mode 100644 index 00000000..c50f9500 --- /dev/null +++ b/bsp/esp32_s3_touch_lcd_1_85C_V2/Kconfig @@ -0,0 +1,96 @@ +menu "Board Support Package" + + config BSP_ERROR_CHECK + bool "Enable error check in BSP" + default y + help + Error check assert the application before returning the error code. + + menu "I2C" + config BSP_I2C_NUM + int "I2C peripheral index" + default 0 + range 0 1 + help + ESP32-S2 has two I2C peripherals, pick the one you want to use. + + config BSP_I2C_FAST_MODE + bool "Enable I2C fast mode" + default y + help + I2C has two speed modes: normal (100kHz) and fast (400kHz). + + config BSP_I2C_CLK_SPEED_HZ + int + default 400000 if BSP_I2C_FAST_MODE + default 100000 + endmenu + + menu "SPIFFS - Virtual File System" + config BSP_SPIFFS_FORMAT_ON_MOUNT_FAIL + bool "Format SPIFFS if mounting fails" + default n + help + Format SPIFFS if it fails to mount the filesystem. + + config BSP_SPIFFS_MOUNT_POINT + string "SPIFFS mount point" + default "/spiffs" + help + Mount point of SPIFFS in the Virtual File System. + + config BSP_SPIFFS_PARTITION_LABEL + string "Partition label of SPIFFS" + default "storage" + help + Partition label which stores SPIFFS. + + config BSP_SPIFFS_MAX_FILES + int "Maximum files that could be open at the same time" + default 2 + help + Supported max files for SPIFFS in the Virtual File System. + endmenu + + menu "uSD card - Virtual File System" + config BSP_SD_FORMAT_ON_MOUNT_FAIL + bool "Format uSD card if mounting fails" + default n + help + The SDMMC host will format (FAT) the uSD card if it fails to mount the filesystem. + + config BSP_SD_MOUNT_POINT + string "uSD card mount point" + default "/sdcard" + help + Mount point of the uSD card in the Virtual File System + + endmenu + menu "Display" + config BSP_LCD_TRANS_QUEUE_DEPTH + int "Set The depth of the SPI transmission task queue for the SPI screen" + default 2 + range 1 10 + help + Cache the SPI screen instruction/pixel data transmission tasks, implement asynchronous non-blocking screen refreshing, and the CPU can execute other logic after submitting the task. + config BSP_LCD_TE_RESISTANT + bool "Enable tear resistance function" + default n + help + Tearing effect avoidance mode + config BSP_DISPLAY_BRIGHTNESS_LEDC_CH + int "LEDC channel index" + default 1 + range 0 7 + help + LEDC channel is used to generate PWM signal that controls display brightness. + Set LEDC index that should be used. + endmenu + + config BSP_I2S_NUM + int "I2S peripheral index" + default 1 + range 0 1 + help + ESP32S3 has two I2S peripherals, pick the one you want to use. +endmenu diff --git a/bsp/esp32_s3_touch_lcd_1_85C_V2/LICENSE b/bsp/esp32_s3_touch_lcd_1_85C_V2/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/bsp/esp32_s3_touch_lcd_1_85C_V2/LICENSE @@ -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. diff --git a/bsp/esp32_s3_touch_lcd_1_85C_V2/README.md b/bsp/esp32_s3_touch_lcd_1_85C_V2/README.md new file mode 100644 index 00000000..f3ebb884 --- /dev/null +++ b/bsp/esp32_s3_touch_lcd_1_85C_V2/README.md @@ -0,0 +1,9 @@ +# BSP: Waveshare ESP32-S3-TOUCH-LCD-1.85C-V2 + +[![Component Registry](https://components.espressif.com/components/waveshare/esp32_s3_cam_ovxxxx/badge.svg)](https://components.espressif.com/components/waveshare/esp32_s3_cam_ovxxxx) + +ESP32-S3-TOUCH-LCD-1.85C-V2 is a camera development board designed by waveshare electronics. + +| HW version | BSP Version | +|:-------------------------------------------------------------:| :---------: | +| [V1.0](http://www.waveshare.com/wiki/ESP32-S3-TOUCH-LCD-1.85C-V2) | ^1 | \ No newline at end of file diff --git a/bsp/esp32_s3_touch_lcd_1_85C_V2/esp32_s3_touch_lcd_1_85C_V2.c b/bsp/esp32_s3_touch_lcd_1_85C_V2/esp32_s3_touch_lcd_1_85C_V2.c new file mode 100644 index 00000000..a88cdc4f --- /dev/null +++ b/bsp/esp32_s3_touch_lcd_1_85C_V2/esp32_s3_touch_lcd_1_85C_V2.c @@ -0,0 +1,1248 @@ +#include +#include +#include +#include "dirent.h" +#include "driver/gpio.h" +#include "driver/spi_master.h" +#include "driver/ledc.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_lcd_panel_io.h" +#include "esp_lcd_panel_vendor.h" +#include "esp_lcd_panel_ops.h" +#include "esp_spiffs.h" +#include "esp_vfs_fat.h" + +#include "bsp/esp-bsp.h" +#include "bsp/display.h" +#include "bsp/touch.h" +#include "bsp_err_check.h" + +#include "esp_lcd_st77916.h" +#include "esp_lcd_touch_cst816s.h" +#include "esp_codec_dev_defaults.h" +#include "iot_button.h" + +static const char *TAG = "esp32_s3_touch_lcd_1_85C_V2"; + +/** + * @brief I2C handle for BSP usage + * + * In IDF v5.4 you can call i2c_master_get_bus_handle(BSP_I2C_NUM, i2c_master_bus_handle_t *ret_handle) + * from #include "esp_private/i2c_platform.h" to get this handle + * + * For IDF 5.2 and 5.3 you must call bsp_i2c_get_handle() + */ +static i2c_master_bus_handle_t i2c_handle = NULL; +static bool i2c_initialized = false; +static sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler +static esp_lcd_touch_handle_t tp; // LCD touch handle +static esp_lcd_panel_handle_t panel_handle = NULL; // LCD panel handle +static esp_lcd_panel_io_handle_t io_handle = NULL; +#if (BSP_CONFIG_NO_GRAPHIC_LIB == 0) +static lv_indev_t *disp_indev = NULL; +static lv_display_t *disp_drv = NULL; +#endif // (BSP_CONFIG_NO_GRAPHIC_LIB == 0) +static uint8_t brightness; +static i2s_chan_handle_t i2s_tx_chan = NULL; +static i2s_chan_handle_t i2s_rx_chan = NULL; +static const audio_codec_data_if_t *i2s_data_if = NULL; /* Codec data interface */ +static esp_io_expander_handle_t io_expander_handle = NULL; // IO expander tca9554 handle + +#define LCD_OPCODE_READ_CMD (0x0BULL) +#define LCD_LEDC_CH CONFIG_BSP_DISPLAY_BRIGHTNESS_LEDC_CH + +/* Can be used for i2s_std_gpio_config_t and/or i2s_std_config_t initialization */ +#define BSP_ES7210_CODEC_ADDR ES7210_CODEC_DEFAULT_ADDR +#define BSP_I2S_GPIO_CFG \ + { \ + .mclk = BSP_I2S_MCLK, \ + .bclk = BSP_I2S_SCLK, \ + .ws = BSP_I2S_LCLK, \ + .dout = BSP_I2S_DOUT, \ + .din = BSP_I2S_DSIN, \ + .invert_flags = { \ + .mclk_inv = false, \ + .bclk_inv = false, \ + .ws_inv = false, \ + }, \ + } + +/* This configuration is used by default in bsp_audio_init() */ +#define BSP_I2S_DUPLEX_MONO_CFG(_sample_rate) \ + { \ + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(_sample_rate), \ + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO), \ + .gpio_cfg = BSP_I2S_GPIO_CFG, \ + } + + static const st77916_lcd_init_cmd_t vendor_specific_init_version_1[] = { + {0xF0, (uint8_t []){0x28}, 1, 0}, + {0xF2, (uint8_t []){0x28}, 1, 0}, + {0x7C, (uint8_t []){0xD1}, 1, 0}, + {0x83, (uint8_t []){0xE0}, 1, 0}, + {0x84, (uint8_t []){0x61}, 1, 0}, + {0xF2, (uint8_t []){0x82}, 1, 0}, + {0xF0, (uint8_t []){0x00}, 1, 0}, + {0xF0, (uint8_t []){0x01}, 1, 0}, + {0xF1, (uint8_t []){0x01}, 1, 0}, + {0xB0, (uint8_t []){0x49}, 1, 0}, + {0xB1, (uint8_t []){0x4A}, 1, 0}, + {0xB2, (uint8_t []){0x1F}, 1, 0}, + {0xB4, (uint8_t []){0x46}, 1, 0}, + {0xB5, (uint8_t []){0x34}, 1, 0}, + {0xB6, (uint8_t []){0xD5}, 1, 0}, + {0xB7, (uint8_t []){0x30}, 1, 0}, + {0xB8, (uint8_t []){0x04}, 1, 0}, + {0xBA, (uint8_t []){0x00}, 1, 0}, + {0xBB, (uint8_t []){0x08}, 1, 0}, + {0xBC, (uint8_t []){0x08}, 1, 0}, + {0xBD, (uint8_t []){0x00}, 1, 0}, + {0xC0, (uint8_t []){0x80}, 1, 0}, + {0xC1, (uint8_t []){0x10}, 1, 0}, + {0xC2, (uint8_t []){0x37}, 1, 0}, + {0xC3, (uint8_t []){0x80}, 1, 0}, + {0xC4, (uint8_t []){0x10}, 1, 0}, + {0xC5, (uint8_t []){0x37}, 1, 0}, + {0xC6, (uint8_t []){0xA9}, 1, 0}, + {0xC7, (uint8_t []){0x41}, 1, 0}, + {0xC8, (uint8_t []){0x01}, 1, 0}, + {0xC9, (uint8_t []){0xA9}, 1, 0}, + {0xCA, (uint8_t []){0x41}, 1, 0}, + {0xCB, (uint8_t []){0x01}, 1, 0}, + {0xD0, (uint8_t []){0x91}, 1, 0}, + {0xD1, (uint8_t []){0x68}, 1, 0}, + {0xD2, (uint8_t []){0x68}, 1, 0}, + {0xF5, (uint8_t []){0x00, 0xA5}, 2, 0}, + // {0xDD, (uint8_t []){0x35}, 1, 0}, + // {0xDE, (uint8_t []){0x35}, 1, 0}, + // {0xDD, (uint8_t []){0x3F}, 1, 0}, + // {0xDE, (uint8_t []){0x3F}, 1, 0}, + {0xF1, (uint8_t []){0x10}, 1, 0}, + {0xF0, (uint8_t []){0x00}, 1, 0}, + {0xF0, (uint8_t []){0x02}, 1, 0}, + {0xE0, (uint8_t []){0x70, 0x09, 0x12, 0x0C, 0x0B, 0x27, 0x38, 0x54, 0x4E, 0x19, 0x15, 0x15, 0x2C, 0x2F}, 14, 0}, + {0xE1, (uint8_t []){0x70, 0x08, 0x11, 0x0C, 0x0B, 0x27, 0x38, 0x43, 0x4C, 0x18, 0x14, 0x14, 0x2B, 0x2D}, 14, 0}, + // {0xE0, (uint8_t []){0xF0, 0x0E, 0x15, 0x0B, 0x0B, 0x07, 0x3C, 0x44, 0x51, 0x38, 0x15, 0x15, 0x32, 0x36}, 14, 0}, + // {0xE1, (uint8_t []){0xF0, 0x0D, 0x15, 0x0A, 0x0A, 0x26, 0x3B, 0x43, 0x50, 0x37, 0x14, 0x15, 0x31, 0x36}, 14, 0}, + {0xF0, (uint8_t []){0x10}, 1, 0}, + {0xF3, (uint8_t []){0x10}, 1, 0}, + {0xE0, (uint8_t []){0x08}, 1, 0}, + {0xE1, (uint8_t []){0x00}, 1, 0}, + {0xE2, (uint8_t []){0x0B}, 1, 0}, + {0xE3, (uint8_t []){0x00}, 1, 0}, + {0xE4, (uint8_t []){0xE0}, 1, 0}, + {0xE5, (uint8_t []){0x06}, 1, 0}, + {0xE6, (uint8_t []){0x21}, 1, 0}, + {0xE7, (uint8_t []){0x00}, 1, 0}, + {0xE8, (uint8_t []){0x05}, 1, 0}, + {0xE9, (uint8_t []){0x82}, 1, 0}, + {0xEA, (uint8_t []){0xDF}, 1, 0}, + {0xEB, (uint8_t []){0x89}, 1, 0}, + {0xEC, (uint8_t []){0x20}, 1, 0}, + {0xED, (uint8_t []){0x14}, 1, 0}, + {0xEE, (uint8_t []){0xFF}, 1, 0}, + {0xEF, (uint8_t []){0x00}, 1, 0}, + {0xF8, (uint8_t []){0xFF}, 1, 0}, + {0xF9, (uint8_t []){0x00}, 1, 0}, + {0xFA, (uint8_t []){0x00}, 1, 0}, + {0xFB, (uint8_t []){0x30}, 1, 0}, + {0xFC, (uint8_t []){0x00}, 1, 0}, + {0xFD, (uint8_t []){0x00}, 1, 0}, + {0xFE, (uint8_t []){0x00}, 1, 0}, + {0xFF, (uint8_t []){0x00}, 1, 0}, + {0x60, (uint8_t []){0x42}, 1, 0}, + {0x61, (uint8_t []){0xE0}, 1, 0}, + {0x62, (uint8_t []){0x40}, 1, 0}, + {0x63, (uint8_t []){0x40}, 1, 0}, + {0x64, (uint8_t []){0x02}, 1, 0}, + {0x65, (uint8_t []){0x00}, 1, 0}, + {0x66, (uint8_t []){0x40}, 1, 0}, + {0x67, (uint8_t []){0x03}, 1, 0}, + {0x68, (uint8_t []){0x00}, 1, 0}, + {0x69, (uint8_t []){0x00}, 1, 0}, + {0x6A, (uint8_t []){0x00}, 1, 0}, + {0x6B, (uint8_t []){0x00}, 1, 0}, + {0x70, (uint8_t []){0x42}, 1, 0}, + {0x71, (uint8_t []){0xE0}, 1, 0}, + {0x72, (uint8_t []){0x40}, 1, 0}, + {0x73, (uint8_t []){0x40}, 1, 0}, + {0x74, (uint8_t []){0x02}, 1, 0}, + {0x75, (uint8_t []){0x00}, 1, 0}, + {0x76, (uint8_t []){0x40}, 1, 0}, + {0x77, (uint8_t []){0x03}, 1, 0}, + {0x78, (uint8_t []){0x00}, 1, 0}, + {0x79, (uint8_t []){0x00}, 1, 0}, + {0x7A, (uint8_t []){0x00}, 1, 0}, + {0x7B, (uint8_t []){0x00}, 1, 0}, + // {0x80, (uint8_t []){0x38}, 1, 0}, + {0x80, (uint8_t []){0x38}, 1, 0}, + {0x81, (uint8_t []){0x00}, 1, 0}, + // {0x82, (uint8_t []){0x04}, 1, 0}, + {0x82, (uint8_t []){0x04}, 1, 0}, + {0x83, (uint8_t []){0x02}, 1, 0}, + // {0x84, (uint8_t []){0xDC}, 1, 0}, + {0x84, (uint8_t []){0xDC}, 1, 0}, + {0x85, (uint8_t []){0x00}, 1, 0}, + {0x86, (uint8_t []){0x00}, 1, 0}, + {0x87, (uint8_t []){0x00}, 1, 0}, + // {0x88, (uint8_t []){0x38}, 1, 0}, + {0x88, (uint8_t []){0x38}, 1, 0}, + {0x89, (uint8_t []){0x00}, 1, 0}, + // {0x8A, (uint8_t []){0x06}, 1, 0}, + {0x8A, (uint8_t []){0x06}, 1, 0}, + {0x8B, (uint8_t []){0x02}, 1, 0}, + // {0x8C, (uint8_t []){0xDE}, 1, 0}, + {0x8C, (uint8_t []){0xDE}, 1, 0}, + {0x8D, (uint8_t []){0x00}, 1, 0}, + {0x8E, (uint8_t []){0x00}, 1, 0}, + {0x8F, (uint8_t []){0x00}, 1, 0}, + // {0x90, (uint8_t []){0x38}, 1, 0}, + {0x90, (uint8_t []){0x38}, 1, 0}, + {0x91, (uint8_t []){0x00}, 1, 0}, + // {0x92, (uint8_t []){0x08}, 1, 0}, + {0x92, (uint8_t []){0x08}, 1, 0}, + {0x93, (uint8_t []){0x02}, 1, 0}, + // {0x94, (uint8_t []){0xE0}, 1, 0}, + {0x94, (uint8_t []){0xE0}, 1, 0}, + {0x95, (uint8_t []){0x00}, 1, 0}, + {0x96, (uint8_t []){0x00}, 1, 0}, + {0x97, (uint8_t []){0x00}, 1, 0}, + // {0x98, (uint8_t []){0x38}, 1, 0}, + {0x98, (uint8_t []){0x38}, 1, 0}, + {0x99, (uint8_t []){0x00}, 1, 0}, + // {0x9A, (uint8_t []){0x0A}, 1, 0}, + {0x9A, (uint8_t []){0x0A}, 1, 0}, + {0x9B, (uint8_t []){0x02}, 1, 0}, + // {0x9C, (uint8_t []){0xE2}, 1, 0}, + {0x9C, (uint8_t []){0xE2}, 1, 0}, + {0x9D, (uint8_t []){0x00}, 1, 0}, + {0x9E, (uint8_t []){0x00}, 1, 0}, + {0x9F, (uint8_t []){0x00}, 1, 0}, + // {0xA0, (uint8_t []){0x38}, 1, 0}, + {0xA0, (uint8_t []){0x38}, 1, 0}, + {0xA1, (uint8_t []){0x00}, 1, 0}, + // {0xA2, (uint8_t []){0x03}, 1, 0}, + {0xA2, (uint8_t []){0x03}, 1, 0}, + {0xA3, (uint8_t []){0x02}, 1, 0}, + // {0xA4, (uint8_t []){0xDB}, 1, 0}, + {0xA4, (uint8_t []){0xDB}, 1, 0}, + {0xA5, (uint8_t []){0x00}, 1, 0}, + {0xA6, (uint8_t []){0x00}, 1, 0}, + {0xA7, (uint8_t []){0x00}, 1, 0}, + // {0xA8, (uint8_t []){0x38}, 1, 0}, + {0xA8, (uint8_t []){0x38}, 1, 0}, + {0xA9, (uint8_t []){0x00}, 1, 0}, + // {0xAA, (uint8_t []){0x05}, 1, 0}, + {0xAA, (uint8_t []){0x05}, 1, 0}, + {0xAB, (uint8_t []){0x02}, 1, 0}, + // {0xAC, (uint8_t []){0xDD}, 1, 0}, + {0xAC, (uint8_t []){0xDD}, 1, 0}, + {0xAD, (uint8_t []){0x00}, 1, 0}, + {0xAE, (uint8_t []){0x00}, 1, 0}, + {0xAF, (uint8_t []){0x00}, 1, 0}, + // {0xB0, (uint8_t []){0x38}, 1, 0}, + {0xB0, (uint8_t []){0x38}, 1, 0}, + {0xB1, (uint8_t []){0x00}, 1, 0}, + // {0xB2, (uint8_t []){0x07}, 1, 0}, + {0xB2, (uint8_t []){0x07}, 1, 0}, + {0xB3, (uint8_t []){0x02}, 1, 0}, + // {0xB4, (uint8_t []){0xDF}, 1, 0}, + {0xB4, (uint8_t []){0xDF}, 1, 0}, + {0xB5, (uint8_t []){0x00}, 1, 0}, + {0xB6, (uint8_t []){0x00}, 1, 0}, + {0xB7, (uint8_t []){0x00}, 1, 0}, + // {0xB8, (uint8_t []){0x38}, 1, 0}, + {0xB8, (uint8_t []){0x38}, 1, 0}, + {0xB9, (uint8_t []){0x00}, 1, 0}, + // {0xBA, (uint8_t []){0x09}, 1, 0}, + {0xBA, (uint8_t []){0x09}, 1, 0}, + {0xBB, (uint8_t []){0x02}, 1, 0}, + // {0xBC, (uint8_t []){0xE1}, 1, 0}, + {0xBC, (uint8_t []){0xE1}, 1, 0}, + {0xBD, (uint8_t []){0x00}, 1, 0}, + {0xBE, (uint8_t []){0x00}, 1, 0}, + {0xBF, (uint8_t []){0x00}, 1, 0}, + // {0xC0, (uint8_t []){0x22}, 1, 0}, + {0xC0, (uint8_t []){0x22}, 1, 0}, + {0xC1, (uint8_t []){0xAA}, 1, 0}, + {0xC2, (uint8_t []){0x65}, 1, 0}, + {0xC3, (uint8_t []){0x74}, 1, 0}, + {0xC4, (uint8_t []){0x47}, 1, 0}, + {0xC5, (uint8_t []){0x56}, 1, 0}, + {0xC6, (uint8_t []){0x00}, 1, 0}, + {0xC7, (uint8_t []){0x88}, 1, 0}, + {0xC8, (uint8_t []){0x99}, 1, 0}, + {0xC9, (uint8_t []){0x33}, 1, 0}, + // {0xD0, (uint8_t []){0x11}, 1, 0}, + {0xD0, (uint8_t []){0x11}, 1, 0}, + {0xD1, (uint8_t []){0xAA}, 1, 0}, + {0xD2, (uint8_t []){0x65}, 1, 0}, + {0xD3, (uint8_t []){0x74}, 1, 0}, + {0xD4, (uint8_t []){0x47}, 1, 0}, + {0xD5, (uint8_t []){0x56}, 1, 0}, + {0xD6, (uint8_t []){0x00}, 1, 0}, + {0xD7, (uint8_t []){0x88}, 1, 0}, + {0xD8, (uint8_t []){0x99}, 1, 0}, + {0xD9, (uint8_t []){0x33}, 1, 0}, + {0xF3, (uint8_t []){0x01}, 1, 0}, + {0xF0, (uint8_t []){0x00}, 1, 0}, + // {0x3A, (uint8_t []){0x55}, 1, 0}, + {0x35, (uint8_t []){0x00}, 1, 0}, + {0x21, (uint8_t []){0x00}, 0, 0}, + {0x11, (uint8_t []){0x00}, 0, 120}, + {0x29, (uint8_t []){0x00}, 0, 0}, +}; +static const st77916_lcd_init_cmd_t vendor_specific_init_version_2[] = { + {0xF0, (uint8_t []){0x28}, 1, 0}, + {0xF2, (uint8_t []){0x28}, 1, 0}, + {0x73, (uint8_t []){0xF0}, 1, 0}, + {0x7C, (uint8_t []){0xD1}, 1, 0}, + {0x83, (uint8_t []){0xE0}, 1, 0}, + {0x84, (uint8_t []){0x61}, 1, 0}, + {0xF2, (uint8_t []){0x82}, 1, 0}, + {0xF0, (uint8_t []){0x00}, 1, 0}, + {0xF0, (uint8_t []){0x01}, 1, 0}, + {0xF1, (uint8_t []){0x01}, 1, 0}, + {0xB0, (uint8_t []){0x56}, 1, 0}, + {0xB1, (uint8_t []){0x4D}, 1, 0}, + {0xB2, (uint8_t []){0x24}, 1, 0}, + {0xB4, (uint8_t []){0x87}, 1, 0}, + {0xB5, (uint8_t []){0x44}, 1, 0}, + {0xB6, (uint8_t []){0x8B}, 1, 0}, + {0xB7, (uint8_t []){0x40}, 1, 0}, + {0xB8, (uint8_t []){0x86}, 1, 0}, + {0xBA, (uint8_t []){0x00}, 1, 0}, + {0xBB, (uint8_t []){0x08}, 1, 0}, + {0xBC, (uint8_t []){0x08}, 1, 0}, + {0xBD, (uint8_t []){0x00}, 1, 0}, + {0xC0, (uint8_t []){0x80}, 1, 0}, + {0xC1, (uint8_t []){0x10}, 1, 0}, + {0xC2, (uint8_t []){0x37}, 1, 0}, + {0xC3, (uint8_t []){0x80}, 1, 0}, + {0xC4, (uint8_t []){0x10}, 1, 0}, + {0xC5, (uint8_t []){0x37}, 1, 0}, + {0xC6, (uint8_t []){0xA9}, 1, 0}, + {0xC7, (uint8_t []){0x41}, 1, 0}, + {0xC8, (uint8_t []){0x01}, 1, 0}, + {0xC9, (uint8_t []){0xA9}, 1, 0}, + {0xCA, (uint8_t []){0x41}, 1, 0}, + {0xCB, (uint8_t []){0x01}, 1, 0}, + {0xD0, (uint8_t []){0x91}, 1, 0}, + {0xD1, (uint8_t []){0x68}, 1, 0}, + {0xD2, (uint8_t []){0x68}, 1, 0}, + {0xF5, (uint8_t []){0x00, 0xA5}, 2, 0}, + {0xDD, (uint8_t []){0x4F}, 1, 0}, + {0xDE, (uint8_t []){0x4F}, 1, 0}, + {0xF1, (uint8_t []){0x10}, 1, 0}, + {0xF0, (uint8_t []){0x00}, 1, 0}, + {0xF0, (uint8_t []){0x02}, 1, 0}, + {0xE0, (uint8_t []){0xF0, 0x0A, 0x10, 0x09, 0x09, 0x36, 0x35, 0x33, 0x4A, 0x29, 0x15, 0x15, 0x2E, 0x34}, 14, 0}, + {0xE1, (uint8_t []){0xF0, 0x0A, 0x0F, 0x08, 0x08, 0x05, 0x34, 0x33, 0x4A, 0x39, 0x15, 0x15, 0x2D, 0x33}, 14, 0}, + {0xF0, (uint8_t []){0x10}, 1, 0}, + {0xF3, (uint8_t []){0x10}, 1, 0}, + {0xE0, (uint8_t []){0x07}, 1, 0}, + {0xE1, (uint8_t []){0x00}, 1, 0}, + {0xE2, (uint8_t []){0x00}, 1, 0}, + {0xE3, (uint8_t []){0x00}, 1, 0}, + {0xE4, (uint8_t []){0xE0}, 1, 0}, + {0xE5, (uint8_t []){0x06}, 1, 0}, + {0xE6, (uint8_t []){0x21}, 1, 0}, + {0xE7, (uint8_t []){0x01}, 1, 0}, + {0xE8, (uint8_t []){0x05}, 1, 0}, + {0xE9, (uint8_t []){0x02}, 1, 0}, + {0xEA, (uint8_t []){0xDA}, 1, 0}, + {0xEB, (uint8_t []){0x00}, 1, 0}, + {0xEC, (uint8_t []){0x00}, 1, 0}, + {0xED, (uint8_t []){0x0F}, 1, 0}, + {0xEE, (uint8_t []){0x00}, 1, 0}, + {0xEF, (uint8_t []){0x00}, 1, 0}, + {0xF8, (uint8_t []){0x00}, 1, 0}, + {0xF9, (uint8_t []){0x00}, 1, 0}, + {0xFA, (uint8_t []){0x00}, 1, 0}, + {0xFB, (uint8_t []){0x00}, 1, 0}, + {0xFC, (uint8_t []){0x00}, 1, 0}, + {0xFD, (uint8_t []){0x00}, 1, 0}, + {0xFE, (uint8_t []){0x00}, 1, 0}, + {0xFF, (uint8_t []){0x00}, 1, 0}, + {0x60, (uint8_t []){0x40}, 1, 0}, + {0x61, (uint8_t []){0x04}, 1, 0}, + {0x62, (uint8_t []){0x00}, 1, 0}, + {0x63, (uint8_t []){0x42}, 1, 0}, + {0x64, (uint8_t []){0xD9}, 1, 0}, + {0x65, (uint8_t []){0x00}, 1, 0}, + {0x66, (uint8_t []){0x00}, 1, 0}, + {0x67, (uint8_t []){0x00}, 1, 0}, + {0x68, (uint8_t []){0x00}, 1, 0}, + {0x69, (uint8_t []){0x00}, 1, 0}, + {0x6A, (uint8_t []){0x00}, 1, 0}, + {0x6B, (uint8_t []){0x00}, 1, 0}, + {0x70, (uint8_t []){0x40}, 1, 0}, + {0x71, (uint8_t []){0x03}, 1, 0}, + {0x72, (uint8_t []){0x00}, 1, 0}, + {0x73, (uint8_t []){0x42}, 1, 0}, + {0x74, (uint8_t []){0xD8}, 1, 0}, + {0x75, (uint8_t []){0x00}, 1, 0}, + {0x76, (uint8_t []){0x00}, 1, 0}, + {0x77, (uint8_t []){0x00}, 1, 0}, + {0x78, (uint8_t []){0x00}, 1, 0}, + {0x79, (uint8_t []){0x00}, 1, 0}, + {0x7A, (uint8_t []){0x00}, 1, 0}, + {0x7B, (uint8_t []){0x00}, 1, 0}, + {0x80, (uint8_t []){0x48}, 1, 0}, + {0x81, (uint8_t []){0x00}, 1, 0}, + {0x82, (uint8_t []){0x06}, 1, 0}, + {0x83, (uint8_t []){0x02}, 1, 0}, + {0x84, (uint8_t []){0xD6}, 1, 0}, + {0x85, (uint8_t []){0x04}, 1, 0}, + {0x86, (uint8_t []){0x00}, 1, 0}, + {0x87, (uint8_t []){0x00}, 1, 0}, + {0x88, (uint8_t []){0x48}, 1, 0}, + {0x89, (uint8_t []){0x00}, 1, 0}, + {0x8A, (uint8_t []){0x08}, 1, 0}, + {0x8B, (uint8_t []){0x02}, 1, 0}, + {0x8C, (uint8_t []){0xD8}, 1, 0}, + {0x8D, (uint8_t []){0x04}, 1, 0}, + {0x8E, (uint8_t []){0x00}, 1, 0}, + {0x8F, (uint8_t []){0x00}, 1, 0}, + {0x90, (uint8_t []){0x48}, 1, 0}, + {0x91, (uint8_t []){0x00}, 1, 0}, + {0x92, (uint8_t []){0x0A}, 1, 0}, + {0x93, (uint8_t []){0x02}, 1, 0}, + {0x94, (uint8_t []){0xDA}, 1, 0}, + {0x95, (uint8_t []){0x04}, 1, 0}, + {0x96, (uint8_t []){0x00}, 1, 0}, + {0x97, (uint8_t []){0x00}, 1, 0}, + {0x98, (uint8_t []){0x48}, 1, 0}, + {0x99, (uint8_t []){0x00}, 1, 0}, + {0x9A, (uint8_t []){0x0C}, 1, 0}, + {0x9B, (uint8_t []){0x02}, 1, 0}, + {0x9C, (uint8_t []){0xDC}, 1, 0}, + {0x9D, (uint8_t []){0x04}, 1, 0}, + {0x9E, (uint8_t []){0x00}, 1, 0}, + {0x9F, (uint8_t []){0x00}, 1, 0}, + {0xA0, (uint8_t []){0x48}, 1, 0}, + {0xA1, (uint8_t []){0x00}, 1, 0}, + {0xA2, (uint8_t []){0x05}, 1, 0}, + {0xA3, (uint8_t []){0x02}, 1, 0}, + {0xA4, (uint8_t []){0xD5}, 1, 0}, + {0xA5, (uint8_t []){0x04}, 1, 0}, + {0xA6, (uint8_t []){0x00}, 1, 0}, + {0xA7, (uint8_t []){0x00}, 1, 0}, + {0xA8, (uint8_t []){0x48}, 1, 0}, + {0xA9, (uint8_t []){0x00}, 1, 0}, + {0xAA, (uint8_t []){0x07}, 1, 0}, + {0xAB, (uint8_t []){0x02}, 1, 0}, + {0xAC, (uint8_t []){0xD7}, 1, 0}, + {0xAD, (uint8_t []){0x04}, 1, 0}, + {0xAE, (uint8_t []){0x00}, 1, 0}, + {0xAF, (uint8_t []){0x00}, 1, 0}, + {0xB0, (uint8_t []){0x48}, 1, 0}, + {0xB1, (uint8_t []){0x00}, 1, 0}, + {0xB2, (uint8_t []){0x09}, 1, 0}, + {0xB3, (uint8_t []){0x02}, 1, 0}, + {0xB4, (uint8_t []){0xD9}, 1, 0}, + {0xB5, (uint8_t []){0x04}, 1, 0}, + {0xB6, (uint8_t []){0x00}, 1, 0}, + {0xB7, (uint8_t []){0x00}, 1, 0}, + + {0xB8, (uint8_t []){0x48}, 1, 0}, + {0xB9, (uint8_t []){0x00}, 1, 0}, + {0xBA, (uint8_t []){0x0B}, 1, 0}, + {0xBB, (uint8_t []){0x02}, 1, 0}, + {0xBC, (uint8_t []){0xDB}, 1, 0}, + {0xBD, (uint8_t []){0x04}, 1, 0}, + {0xBE, (uint8_t []){0x00}, 1, 0}, + {0xBF, (uint8_t []){0x00}, 1, 0}, + {0xC0, (uint8_t []){0x10}, 1, 0}, + {0xC1, (uint8_t []){0x47}, 1, 0}, + {0xC2, (uint8_t []){0x56}, 1, 0}, + {0xC3, (uint8_t []){0x65}, 1, 0}, + {0xC4, (uint8_t []){0x74}, 1, 0}, + {0xC5, (uint8_t []){0x88}, 1, 0}, + {0xC6, (uint8_t []){0x99}, 1, 0}, + {0xC7, (uint8_t []){0x01}, 1, 0}, + {0xC8, (uint8_t []){0xBB}, 1, 0}, + {0xC9, (uint8_t []){0xAA}, 1, 0}, + {0xD0, (uint8_t []){0x10}, 1, 0}, + {0xD1, (uint8_t []){0x47}, 1, 0}, + {0xD2, (uint8_t []){0x56}, 1, 0}, + {0xD3, (uint8_t []){0x65}, 1, 0}, + {0xD4, (uint8_t []){0x74}, 1, 0}, + {0xD5, (uint8_t []){0x88}, 1, 0}, + {0xD6, (uint8_t []){0x99}, 1, 0}, + {0xD7, (uint8_t []){0x01}, 1, 0}, + {0xD8, (uint8_t []){0xBB}, 1, 0}, + {0xD9, (uint8_t []){0xAA}, 1, 0}, + {0xF3, (uint8_t []){0x01}, 1, 0}, + {0xF0, (uint8_t []){0x00}, 1, 0}, + {0x35, (uint8_t []){0x00}, 1, 0}, + {0x21, (uint8_t []){0x00}, 1, 0}, + {0x11, (uint8_t []){0x00}, 1, 120}, + {0x29, (uint8_t []){0x00}, 1, 0}, +}; + +esp_err_t bsp_i2c_init(void) +{ + /* I2C was initialized before */ + if (i2c_initialized) + { + return ESP_OK; + } + + i2c_master_bus_config_t i2c_bus_conf = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .sda_io_num = BSP_I2C_SDA, + .scl_io_num = BSP_I2C_SCL, + .i2c_port = BSP_I2C_NUM, + }; + BSP_ERROR_CHECK_RETURN_ERR(i2c_new_master_bus(&i2c_bus_conf, &i2c_handle)); + + i2c_initialized = true; + + return ESP_OK; +} + +esp_err_t bsp_i2c_deinit(void) +{ + BSP_ERROR_CHECK_RETURN_ERR(i2c_del_master_bus(i2c_handle)); + i2c_initialized = false; + return ESP_OK; +} + +i2c_master_bus_handle_t bsp_i2c_get_handle(void) +{ + bsp_i2c_init(); + return i2c_handle; +} + +sdmmc_card_t *bsp_sdcard_get_handle(void) +{ + return bsp_sdcard; +} + +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + + sdmmc_host_t host_config = SDMMC_HOST_DEFAULT(); + + memcpy(config, &host_config, sizeof(sdmmc_host_t)); +} + +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_host_t)); + ESP_LOGE(TAG, "SD card SPI mode is not supported by HW!"); +} + +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdmmc_slot_config_t)); + + config->clk = BSP_SD_CLK; + config->cmd = BSP_SD_CMD; + config->d0 = BSP_SD_D0; + config->d1 = GPIO_NUM_NC; + config->d2 = GPIO_NUM_NC; + config->d3 = GPIO_NUM_NC; + config->d4 = GPIO_NUM_NC; + config->d5 = GPIO_NUM_NC; + config->d6 = GPIO_NUM_NC; + config->d7 = GPIO_NUM_NC; + config->cd = SDMMC_SLOT_NO_CD; + config->wp = SDMMC_SLOT_NO_WP; + config->width = 1; + config->flags = 0; +} + +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config) +{ + assert(config); + memset(config, 0, sizeof(sdspi_device_config_t)); + ESP_LOGE(TAG, "SD card SPI mode is not supported by HW!"); +} + +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg) +{ + sdmmc_host_t sdhost = {0}; + sdmmc_slot_config_t sdslot = {0}; + const esp_vfs_fat_sdmmc_mount_config_t mount_config = { +#ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL + .format_if_mount_failed = true, +#else + .format_if_mount_failed = false, +#endif + .max_files = 5, + .allocation_unit_size = 16 * 1024 + }; + assert(cfg); + + if (!cfg->mount) { + cfg->mount = &mount_config; + } + + if (!cfg->host) { + bsp_sdcard_get_sdmmc_host(SDMMC_HOST_SLOT_0, &sdhost); + cfg->host = &sdhost; + } + + if (!cfg->slot.sdmmc) { + bsp_sdcard_sdmmc_get_slot(SDMMC_HOST_SLOT_0, &sdslot); + cfg->slot.sdmmc = &sdslot; + } + +#if !CONFIG_FATFS_LONG_FILENAMES + ESP_LOGW(TAG, "Warning: Long filenames on SD card are disabled in menuconfig!"); +#endif + + return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, cfg->host, cfg->slot.sdmmc, cfg->mount, &bsp_sdcard); +} + +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg) +{ + ESP_LOGE(TAG, "SD card SPI mode is not supported by HW!"); + return ESP_ERR_NOT_SUPPORTED; +} + +esp_err_t bsp_sdcard_mount(void) +{ + bsp_sdcard_cfg_t cfg = {0}; + return bsp_sdcard_sdmmc_mount(&cfg); +} + +esp_err_t bsp_sdcard_unmount(void) +{ + esp_err_t ret = ESP_OK; + + ret |= esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); + bsp_sdcard = NULL; + + return ret; +} + +esp_err_t bsp_audio_init(const i2s_std_config_t *i2s_config) +{ + esp_err_t ret = ESP_FAIL; + if (i2s_tx_chan && i2s_rx_chan) { + /* Audio was initialized before */ + return ESP_OK; + } + + /* Setup I2S peripheral */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(CONFIG_BSP_I2S_NUM, I2S_ROLE_MASTER); + chan_cfg.auto_clear = true; // Auto clear the legacy data in the DMA buffer + BSP_ERROR_CHECK_RETURN_ERR(i2s_new_channel(&chan_cfg, &i2s_tx_chan, &i2s_rx_chan)); + + /* Setup I2S channels */ + const i2s_std_config_t std_cfg_default = BSP_I2S_DUPLEX_MONO_CFG(22050); + const i2s_std_config_t *p_i2s_cfg = &std_cfg_default; + if (i2s_config != NULL) { + p_i2s_cfg = i2s_config; + } + + if (i2s_tx_chan != NULL) { + ESP_GOTO_ON_ERROR(i2s_channel_init_std_mode(i2s_tx_chan, p_i2s_cfg), err, TAG, "I2S channel initialization failed"); + ESP_GOTO_ON_ERROR(i2s_channel_enable(i2s_tx_chan), err, TAG, "I2S enabling failed"); + } + if (i2s_rx_chan != NULL) { + ESP_GOTO_ON_ERROR(i2s_channel_init_std_mode(i2s_rx_chan, p_i2s_cfg), err, TAG, "I2S channel initialization failed"); + ESP_GOTO_ON_ERROR(i2s_channel_enable(i2s_rx_chan), err, TAG, "I2S enabling failed"); + } + + audio_codec_i2s_cfg_t i2s_cfg = { + .port = CONFIG_BSP_I2S_NUM, + .rx_handle = i2s_rx_chan, + .tx_handle = i2s_tx_chan, + }; + i2s_data_if = audio_codec_new_i2s_data(&i2s_cfg); + BSP_NULL_CHECK_GOTO(i2s_data_if, err); + + return ESP_OK; + +err: + if (i2s_tx_chan) { + i2s_del_channel(i2s_tx_chan); + } + if (i2s_rx_chan) { + i2s_del_channel(i2s_rx_chan); + } + + return ret; +} + +const audio_codec_data_if_t *bsp_audio_get_codec_itf(void) +{ + return i2s_data_if; +} + +esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void) +{ + const audio_codec_data_if_t *i2s_data_if = bsp_audio_get_codec_itf(); + if (i2s_data_if == NULL) { + /* Initilize I2C */ + BSP_ERROR_CHECK_RETURN_NULL(bsp_i2c_init()); + /* Configure I2S peripheral and Power Amplifier */ + BSP_ERROR_CHECK_RETURN_NULL(bsp_audio_init(NULL)); + i2s_data_if = bsp_audio_get_codec_itf(); + } + assert(i2s_data_if); + + const audio_codec_gpio_if_t *gpio_if = audio_codec_new_gpio(); + + audio_codec_i2c_cfg_t i2c_cfg = { + .port = BSP_I2C_NUM, + .addr = ES8311_CODEC_DEFAULT_ADDR, + .bus_handle = i2c_handle, + }; + const audio_codec_ctrl_if_t *i2c_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg); + BSP_NULL_CHECK(i2c_ctrl_if, NULL); + + esp_codec_dev_hw_gain_t gain = { + .pa_voltage = 5.0, + .codec_dac_voltage = 3.3, + }; + + es8311_codec_cfg_t es8311_cfg = { + .ctrl_if = i2c_ctrl_if, + .gpio_if = gpio_if, + .codec_mode = ESP_CODEC_DEV_WORK_MODE_DAC, + .pa_pin = BSP_POWER_AMP_IO, + .pa_reverted = false, + .master_mode = false, + .use_mclk = true, + .digital_mic = false, + .invert_mclk = false, + .invert_sclk = false, + .hw_gain = gain, + }; + const audio_codec_if_t *es8311_dev = es8311_codec_new(&es8311_cfg); + BSP_NULL_CHECK(es8311_dev, NULL); + + esp_codec_dev_cfg_t codec_dev_cfg = { + .dev_type = ESP_CODEC_DEV_TYPE_OUT, + .codec_if = es8311_dev, + .data_if = i2s_data_if, + }; + return esp_codec_dev_new(&codec_dev_cfg); +} + +esp_codec_dev_handle_t bsp_audio_codec_microphone_init(void) +{ + const audio_codec_data_if_t *i2s_data_if = bsp_audio_get_codec_itf(); + if (i2s_data_if == NULL) { + /* Initilize I2C */ + BSP_ERROR_CHECK_RETURN_NULL(bsp_i2c_init()); + /* Configure I2S peripheral and Power Amplifier */ + BSP_ERROR_CHECK_RETURN_NULL(bsp_audio_init(NULL)); + i2s_data_if = bsp_audio_get_codec_itf(); + } + assert(i2s_data_if); + + audio_codec_i2c_cfg_t i2c_cfg = { + .port = BSP_I2C_NUM, + .addr = BSP_ES7210_CODEC_ADDR, + .bus_handle = i2c_handle, + }; + const audio_codec_ctrl_if_t *i2c_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg); + BSP_NULL_CHECK(i2c_ctrl_if, NULL); + + es7210_codec_cfg_t es7210_cfg = { + .ctrl_if = i2c_ctrl_if, + }; + const audio_codec_if_t *es7210_dev = es7210_codec_new(&es7210_cfg); + BSP_NULL_CHECK(es7210_dev, NULL); + + esp_codec_dev_cfg_t codec_es7210_dev_cfg = { + .dev_type = ESP_CODEC_DEV_TYPE_IN, + .codec_if = es7210_dev, + .data_if = i2s_data_if, + }; + return esp_codec_dev_new(&codec_es7210_dev_cfg); +} + +esp_err_t bsp_display_new(const bsp_display_config_t *config, esp_lcd_panel_handle_t *ret_panel, esp_lcd_panel_io_handle_t *ret_io) +{ + // reset lcd + gpio_config_t ioconf = { + .pin_bit_mask = 1ULL << BSP_LCD_RST, + .mode = GPIO_MODE_OUTPUT, + .pull_up_en = GPIO_PULLUP_DISABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_DISABLE, + }; + gpio_config(&ioconf); + + gpio_set_level(BSP_LCD_RST,0); + vTaskDelay(pdMS_TO_TICKS(10)); + gpio_set_level(BSP_LCD_RST,1); + vTaskDelay(pdMS_TO_TICKS(10)); + + esp_err_t ret = ESP_OK; + + ESP_LOGD(TAG, "Initialize QSPI bus"); + const spi_bus_config_t buscfg = { + .data0_io_num = BSP_LCD_DATA0, + .data1_io_num = BSP_LCD_DATA1, + .sclk_io_num = BSP_LCD_PCLK, + .data2_io_num = BSP_LCD_DATA2, + .data3_io_num = BSP_LCD_DATA3, + .data4_io_num = -1, + .data5_io_num = -1, + .data6_io_num = -1, + .data7_io_num = -1, + .max_transfer_sz = 0, + .flags = SPICOMMON_BUSFLAG_QUAD, + .intr_flags = 0, + }; + ESP_RETURN_ON_ERROR(spi_bus_initialize(BSP_LCD_SPI_NUM, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI init failed"); + + ESP_LOGD(TAG, "Install panel IO"); + esp_lcd_panel_io_spi_config_t io_config ={ + .cs_gpio_num = BSP_LCD_CS, + .dc_gpio_num = -1, + .spi_mode = 0, + .pclk_hz = 3 * 1000 * 1000, + .trans_queue_depth = CONFIG_BSP_LCD_TRANS_QUEUE_DEPTH, + .on_color_trans_done = NULL, + .user_ctx = NULL, + .lcd_cmd_bits = 32, + .lcd_param_bits = 8, + .flags = { + .dc_low_on_data = 0, + .octal_mode = 0, + .quad_mode = 1, + .sio_mode = 0, + .lsb_first = 0, + .cs_high_active = 0, + }, + }; + ESP_GOTO_ON_ERROR(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)BSP_LCD_SPI_NUM, &io_config, ret_io), err, TAG, "New panel IO failed"); + + + printf("Install LCD driver of st77916\r\n"); + st77916_vendor_config_t vendor_config={ + .flags = { + .use_qspi_interface = 1, + }, + }; + + + /*----------------- Read the screen version and select initialization parameters based on the version -----------------*/ + //read id + int lcd_cmd = 0x04; + uint8_t register_data[4]; + size_t param_size = sizeof(register_data); + lcd_cmd &= 0xff; + lcd_cmd <<= 8; + lcd_cmd |= LCD_OPCODE_READ_CMD << 24; // Use the read opcode instead of write + ret = esp_lcd_panel_io_rx_param(*ret_io, lcd_cmd, register_data, param_size); + if (ret == ESP_OK) { + printf("Register 0x04 data: %02x %02x %02x %02x\n", register_data[0], register_data[1], register_data[2], register_data[3]); + } else { + printf("Failed to read register 0x04, error code: %d\n", ret); + } + + // reconfig spi bus + io_config.pclk_hz = 80*1000*1000; + ESP_RETURN_ON_ERROR(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)BSP_LCD_SPI_NUM, &io_config, ret_io), TAG, "New panel IO failed"); + + // Check register values and configure accordingly + if (register_data[0] == 0x00 && register_data[1] == 0x7F && register_data[2] == 0x7F && register_data[3] == 0x7F) { + vendor_config.init_cmds = vendor_specific_init_version_1; + vendor_config.init_cmds_size = sizeof(vendor_specific_init_version_1) / sizeof(st77916_lcd_init_cmd_t); + printf("Vendor-specific initialization for case 1.\n"); + } + else if (register_data[0] == 0x00 && register_data[1] == 0x02 && register_data[2] == 0x7F && register_data[3] == 0x7F) { + vendor_config.init_cmds = vendor_specific_init_version_2; + vendor_config.init_cmds_size = sizeof(vendor_specific_init_version_2) / sizeof(st77916_lcd_init_cmd_t); + printf("Vendor-specific initialization for case 2.\n"); + } + /*-----------------------------------------------------------------------------------------------------------------------*/ + + esp_lcd_panel_dev_config_t panel_config={ + .reset_gpio_num = BSP_LCD_RST, + .rgb_ele_order = BSP_LCD_COLOR_SPACE, + .bits_per_pixel = BSP_LCD_BITS_PER_PIXEL, + .flags = { + .reset_active_high = 0, + }, + .vendor_config = (void *) &vendor_config, + }; + esp_lcd_new_panel_st77916(*ret_io, &panel_config, ret_panel); + + esp_lcd_panel_reset(*ret_panel); + esp_lcd_panel_init(*ret_panel); + esp_lcd_panel_disp_on_off(*ret_panel, true); + + //esp_lcd_panel_swap_xy(*ret_panel, true); + //esp_lcd_panel_mirror(*ret_panel,true,false); + return ret; + +err: + if (*ret_panel) { + esp_lcd_panel_del(*ret_panel); + } + if (*ret_io) { + esp_lcd_panel_io_del(*ret_io); + } + spi_bus_free(BSP_LCD_SPI_NUM); + return ret; +} + +esp_err_t bsp_touch_new(const bsp_display_cfg_t *cfg, esp_lcd_touch_handle_t *ret_touch) +{ + assert(cfg != NULL); + /* Initilize I2C */ + BSP_ERROR_CHECK_RETURN_ERR(bsp_i2c_init()); + + + i2c_master_bus_handle_t i2c_handle = NULL; + i2c_master_get_bus_handle(BSP_I2C_NUM, &i2c_handle); + + /* Initialize touch HW */ + const esp_lcd_touch_config_t tp_cfg = { + .x_max = BSP_LCD_H_RES, + .y_max = BSP_LCD_V_RES, + .rst_gpio_num = BSP_LCD_TOUCH_RST, + .int_gpio_num = BSP_LCD_TOUCH_INT, + .levels = { + .reset = 0, + .interrupt = 0, + }, + .flags = { + .swap_xy = cfg->touch_flags.swap_xy, + .mirror_x = cfg->touch_flags.mirror_x, + .mirror_y = cfg->touch_flags.mirror_y, + }, + }; + + esp_lcd_panel_io_handle_t tp_io_handle = NULL; + esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_CST816S_CONFIG(); + tp_io_config.scl_speed_hz = CONFIG_BSP_I2C_CLK_SPEED_HZ; + esp_lcd_new_panel_io_i2c((i2c_master_bus_handle_t)i2c_handle, &tp_io_config, &tp_io_handle); + return esp_lcd_touch_new_i2c_cst816s(tp_io_handle, &tp_cfg, ret_touch); +} + + +#if (BSP_CONFIG_NO_GRAPHIC_LIB == 0) +static lv_display_t *bsp_display_lcd_init(const bsp_display_cfg_t *cfg) +{ + assert(cfg != NULL); + + bsp_display_config_t disp_config = {0}; + BSP_ERROR_CHECK_RETURN_NULL(bsp_display_new(&disp_config, &panel_handle, &io_handle)); + + ESP_LOGD(TAG, "Add LCD screen"); + #if CONFIG_BSP_LCD_TE_RESISTANT + esp_lv_adapter_display_config_t disp_cfg = + ESP_LV_ADAPTER_DISPLAY_SPI_WITH_PSRAM_TE_DEFAULT_CONFIG( + panel_handle, + io_handle, + BSP_LCD_H_RES, BSP_LCD_V_RES, + ESP_LV_ADAPTER_ROTATE_0, + BSP_LCD_TE, + 80 * 1000 * 1000, + 4, + BSP_LCD_BITS_PER_PIXEL + + ); + #else + esp_lv_adapter_display_config_t disp_cfg = { + .panel = panel_handle, + .panel_io = io_handle, + .profile = { + .interface = ESP_LV_ADAPTER_PANEL_IF_OTHER, + .rotation = cfg->rotation, + .hor_res = BSP_LCD_H_RES, + .ver_res = BSP_LCD_V_RES, + .buffer_height = 50, + .use_psram = true, + .enable_ppa_accel = false, + .require_double_buffer = true, + }, + .tear_avoid_mode = cfg->tear_avoid_mode, + }; + #endif + + + + + lv_display_t *disp = esp_lv_adapter_register_display(&disp_cfg); + if (!disp) + { + return NULL; + } + + return disp; +} + +static lv_indev_t *bsp_display_indev_init(const bsp_display_cfg_t *cfg, lv_display_t *disp) +{ + assert(cfg != NULL); + BSP_ERROR_CHECK_RETURN_NULL(bsp_touch_new(cfg, &tp)); + assert(tp); + + const esp_lv_adapter_touch_config_t touch_cfg = ESP_LV_ADAPTER_TOUCH_DEFAULT_CONFIG(disp, tp); + + return esp_lv_adapter_register_touch(&touch_cfg); +} +#endif // (BSP_CONFIG_NO_GRAPHIC_LIB == 0) + + +esp_io_expander_handle_t bsp_io_expander_init(void) +{ + bsp_i2c_init(); + + esp_err_t ret = esp_io_expander_new_i2c_tca9554(i2c_handle, ESP_IO_EXPANDER_I2C_TCA9554_ADDRESS_000, &io_expander_handle); + if (ret != ESP_OK ) + { + ESP_LOGE(TAG, "Failed to initialize TCA9554 IO Expander"); + return NULL; + } + + esp_io_expander_set_dir(io_expander_handle, IO_EXPANDER_PIN_NUM_0 | IO_EXPANDER_PIN_NUM_1, IO_EXPANDER_OUTPUT); + + esp_io_expander_set_level(io_expander_handle, IO_EXPANDER_PIN_NUM_0 | IO_EXPANDER_PIN_NUM_1, 0); + vTaskDelay(pdMS_TO_TICKS(10)); + esp_io_expander_set_level(io_expander_handle, IO_EXPANDER_PIN_NUM_0 | IO_EXPANDER_PIN_NUM_1, 1); + + + return io_expander_handle; +} + +esp_err_t bsp_display_brightness_init(void) +{ + const ledc_channel_config_t LCD_backlight_channel = { + .gpio_num = BSP_LCD_BACKLIGHT, + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = LCD_LEDC_CH, + .intr_type = LEDC_INTR_DISABLE, + .timer_sel = 1, + .duty = 0, + .hpoint = 0 + }; + const ledc_timer_config_t LCD_backlight_timer = { + .speed_mode = LEDC_LOW_SPEED_MODE, + .duty_resolution = LEDC_TIMER_10_BIT, + .timer_num = 1, + .freq_hz = 5000, + .clk_cfg = LEDC_AUTO_CLK + }; + + BSP_ERROR_CHECK_RETURN_ERR(ledc_timer_config(&LCD_backlight_timer)); + BSP_ERROR_CHECK_RETURN_ERR(ledc_channel_config(&LCD_backlight_channel)); + + return ESP_OK; +} + +esp_err_t bsp_display_brightness_set(int brightness_percent) +{ + if (brightness_percent > 100) { + brightness_percent = 100; + } else if (brightness_percent < 0) { + brightness_percent = 0; + } + + int flipped_brightness = brightness_percent; + + brightness = (uint8_t)flipped_brightness; + + ESP_LOGI(TAG, "Setting flipped LCD backlight: %d%% (original: %d%%)", flipped_brightness, brightness_percent); + + uint32_t duty_cycle = (1023 * flipped_brightness) / 100; + BSP_ERROR_CHECK_RETURN_ERR(ledc_set_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH, duty_cycle)); + BSP_ERROR_CHECK_RETURN_ERR(ledc_update_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH)); + return ESP_OK; +} + +int bsp_display_brightness_get(void) +{ + if (disp_drv == NULL) + { + ESP_LOGE(TAG, "disp_drv is not initialized"); + return -1; + } + + return brightness * 100 / 255; +} + +esp_err_t bsp_display_backlight_off(void) +{ + ESP_LOGI(TAG, "Backlight off"); + return bsp_display_brightness_set(0); +} + +esp_err_t bsp_display_backlight_on(void) +{ + ESP_LOGI(TAG, "Backlight on"); + return bsp_display_brightness_set(100); +} + +#if (BSP_CONFIG_NO_GRAPHIC_LIB == 0) + +lv_display_t *bsp_display_start(void) +{ + bsp_display_cfg_t cfg = { + .lv_adapter_cfg = ESP_LV_ADAPTER_DEFAULT_CONFIG(), + .rotation = ESP_LV_ADAPTER_ROTATE_0, + .tear_avoid_mode = ESP_LV_ADAPTER_TEAR_AVOID_MODE_NONE, + .touch_flags = { + .swap_xy = 0, + .mirror_x = 0, + .mirror_y = 0}}; + return bsp_display_start_with_config(&cfg); +} + +lv_display_t *bsp_display_start_with_config(bsp_display_cfg_t *cfg) +{ + lv_display_t *disp; + + assert(cfg != NULL); + BSP_ERROR_CHECK_RETURN_NULL(esp_lv_adapter_init(&cfg->lv_adapter_cfg)); + + BSP_NULL_CHECK(disp = bsp_display_lcd_init(cfg), NULL); + + BSP_NULL_CHECK(disp_indev = bsp_display_indev_init(cfg, disp), NULL); + + BSP_ERROR_CHECK_RETURN_NULL(bsp_display_brightness_init()); + + ESP_ERROR_CHECK(esp_lv_adapter_start()); + + disp_drv = disp; + return disp; +} + + +lv_display_t *bsp_display_get_disp_dev(void) +{ + return disp_drv; +} + +lv_indev_t *bsp_display_get_input_dev(void) +{ + return disp_indev; +} + +esp_err_t bsp_display_lock(int32_t timeout_ms) +{ + return esp_lv_adapter_lock(timeout_ms); +} + +void bsp_display_unlock(void) +{ + esp_lv_adapter_unlock(); +} + +#endif // (BSP_CONFIG_NO_GRAPHIC_LIB == 0) + +esp_err_t bsp_spiffs_mount(void) +{ + esp_vfs_spiffs_conf_t conf = { + .base_path = CONFIG_BSP_SPIFFS_MOUNT_POINT, + .partition_label = CONFIG_BSP_SPIFFS_PARTITION_LABEL, + .max_files = CONFIG_BSP_SPIFFS_MAX_FILES, +#ifdef CONFIG_BSP_SPIFFS_FORMAT_ON_MOUNT_FAIL + .format_if_mount_failed = true, +#else + .format_if_mount_failed = false, +#endif + }; + + esp_err_t ret_val = esp_vfs_spiffs_register(&conf); + + BSP_ERROR_CHECK_RETURN_ERR(ret_val); + + size_t total = 0, used = 0; + ret_val = esp_spiffs_info(conf.partition_label, &total, &used); + if (ret_val != ESP_OK) { + ESP_LOGE(TAG, "Failed to get SPIFFS partition information (%s)", esp_err_to_name(ret_val)); + } else { + ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used); + } + + return ret_val; +} + +esp_err_t bsp_spiffs_unmount(void) +{ + return esp_vfs_spiffs_unregister(CONFIG_BSP_SPIFFS_PARTITION_LABEL); +} + +/** + * @brief A universal function to retrieve a list of files with specific extensions in a designated directory + * + * @param dir_path path (example "/sdcard") + * @param extension target extension (example ".jpg", ".avi", ".png") + * @param out + * @return esp_err_t + */ +esp_err_t get_file_list_by_ext(const char *dir_path, const char *extension, generic_file_list_t *out) +{ + if (!dir_path || !extension || !out) { + return ESP_ERR_INVALID_ARG; + } + + out->list = NULL; + out->count = 0; + + DIR *dir = opendir(dir_path); + if (!dir) { + return ESP_FAIL; + } + + struct dirent *entry; + int count = 0; + + while ((entry = readdir(dir)) != NULL) { + if (entry->d_type == DT_REG) { + char *ext = strrchr(entry->d_name, '.'); + if (ext && strcasecmp(ext, extension) == 0) { + count++; + } + } + } + + if (count == 0) { + closedir(dir); + return ESP_ERR_NOT_FOUND; + } + + char **list = (char **)malloc(sizeof(char *) * count); + if (!list) { + closedir(dir); + return ESP_ERR_NO_MEM; + } + + rewinddir(dir); + int idx = 0; + + while ((entry = readdir(dir)) != NULL) { + if (entry->d_type == DT_REG) { + char *ext = strrchr(entry->d_name, '.'); + if (ext && strcasecmp(ext, extension) == 0) { + + size_t len = strlen(dir_path) + strlen(entry->d_name) + 2; + char *full_path = (char *)malloc(len); + if (!full_path) { + + for (int i = 0; i < idx; i++) free(list[i]); + free(list); + closedir(dir); + return ESP_ERR_NO_MEM; + } + snprintf(full_path, len, "%s/%s", dir_path, entry->d_name); + list[idx++] = full_path; + } + } + } + + closedir(dir); + out->list = list; + out->count = idx; + return ESP_OK; +} + diff --git a/bsp/esp32_s3_touch_lcd_1_85C_V2/idf_component.yml b/bsp/esp32_s3_touch_lcd_1_85C_V2/idf_component.yml new file mode 100644 index 00000000..e73ad7ea --- /dev/null +++ b/bsp/esp32_s3_touch_lcd_1_85C_V2/idf_component.yml @@ -0,0 +1,23 @@ +dependencies: + esp_codec_dev: + public: true + version: ~1.5 + espressif/button: ^4.1.4 + espressif/esp_lcd_touch_cst816s: ^1.1.0 + espressif/esp_lvgl_adapter: + public: true + version: ^0.3.* + idf: '>=5.3' + lvgl/lvgl: '>=8,<10' + espressif/esp_lcd_st77916: ^2.0.1 + waveshare/pcf85063a: ^1.0.1 + espressif/esp_io_expander_tca9554: ^2.0.3 + +description: Board Support Package (BSP) for Waveshare ESP32-S3-TOUCH-LCD-1.85C-V2 +repository: git://github.com/waveshareteam/Waveshare-ESP32-components.git +tags: +- bsp +targets: +- esp32s3 +url: https://github.com/waveshareteam/Waveshare-ESP32-components +version: 1.0.0 diff --git a/bsp/esp32_s3_touch_lcd_1_85C_V2/include/bsp/config.h b/bsp/esp32_s3_touch_lcd_1_85C_V2/include/bsp/config.h new file mode 100644 index 00000000..927f8149 --- /dev/null +++ b/bsp/esp32_s3_touch_lcd_1_85C_V2/include/bsp/config.h @@ -0,0 +1,10 @@ +#pragma once + +/************************************************************************************************** + * BSP configuration + **************************************************************************************************/ +// By default, this BSP is shipped with LVGL graphical library. Enabling this option will exclude it. +// If you want to use BSP without LVGL, select BSP version with 'noglib' suffix. +#if !defined(BSP_CONFIG_NO_GRAPHIC_LIB) // Check if the symbol is not coming from compiler definitions (-D...) +#define BSP_CONFIG_NO_GRAPHIC_LIB (0) +#endif diff --git a/bsp/esp32_s3_touch_lcd_1_85C_V2/include/bsp/display.h b/bsp/esp32_s3_touch_lcd_1_85C_V2/include/bsp/display.h new file mode 100644 index 00000000..0cbdb190 --- /dev/null +++ b/bsp/esp32_s3_touch_lcd_1_85C_V2/include/bsp/display.h @@ -0,0 +1,109 @@ +/* + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief BSP LCD + * + * This file offers API for basic LCD control. + * It is useful for users who want to use the LCD without the default Graphical Library LVGL. + * + * For standard LCD initialization with LVGL graphical library, you can call all-in-one function bsp_display_start(). + */ + +#pragma once +#include "esp_lcd_types.h" + +/** @defgroup g04_display Display and Touch + * @brief Display BSP API + * @{ + */ + +/* LCD color formats */ +#define ESP_LCD_COLOR_FORMAT_RGB565 (1) +#define ESP_LCD_COLOR_FORMAT_RGB888 (2) + +/* LCD display color format */ +#define BSP_LCD_COLOR_FORMAT (ESP_LCD_COLOR_FORMAT_RGB565) +/* LCD display color bytes endianess */ +#define BSP_LCD_BIGENDIAN (1) +/* LCD display color bits */ +#define BSP_LCD_BITS_PER_PIXEL (16) +/* LCD display color space */ +#define BSP_LCD_COLOR_SPACE (LCD_RGB_ELEMENT_ORDER_RGB) +/* LCD definition */ +#define BSP_LCD_H_RES (360) +#define BSP_LCD_V_RES (360) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief BSP display configuration structure + * + */ +typedef struct { + int max_transfer_sz; /*!< Maximum transfer size, in bytes. */ +} bsp_display_config_t; + +/** + * @brief Create new display panel + * + * For maximum flexibility, this function performs only reset and initialization of the display. + * You must turn on the display explicitly by calling esp_lcd_panel_disp_on_off(). + * The display's backlight is not turned on either. You can use bsp_display_backlight_on/off(), + * bsp_display_brightness_set() (on supported boards) or implement your own backlight control. + * + * If you want to free resources allocated by this function, you can use esp_lcd API, ie.: + * + * \code{.c} + * esp_lcd_panel_del(panel); + * esp_lcd_panel_io_del(io); + * spi_bus_free(spi_num_from_configuration); + * \endcode + * + * @param[in] config display configuration + * @param[out] ret_panel esp_lcd panel handle + * @param[out] ret_io esp_lcd IO handle + * @return + * - ESP_OK On successa + * - Else esp_lcd failure + */ +esp_err_t bsp_display_new(const bsp_display_config_t *config, esp_lcd_panel_handle_t *ret_panel, esp_lcd_panel_io_handle_t *ret_io); + +/** + * @brief Turn on display backlight + * + * Backlight is controlled with IO expander TCA9554. + * + * @return + * - ESP_OK On success + * - Else Failure to initialize IO expander or set backlight level + */ +esp_err_t bsp_display_backlight_on(void); + +/** + * @brief Turn off display backlight + * + * Backlight is controlled with IO expander TCA9554. + * + * @return + * - ESP_OK On success + * - Else Failure to initialize IO expander or set backlight level + */ +esp_err_t bsp_display_backlight_off(void); + +/* Brightness functions are not implemented on this board. + These functions are here to provide consistent API with other Board Support Packages */ +esp_err_t bsp_display_brightness_init(void); +esp_err_t bsp_display_brightness_set(int brightness_percent); + +#ifdef __cplusplus +} +#endif + +/** @} */ // end of display diff --git a/bsp/esp32_s3_touch_lcd_1_85C_V2/include/bsp/esp-bsp.h b/bsp/esp32_s3_touch_lcd_1_85C_V2/include/bsp/esp-bsp.h new file mode 100644 index 00000000..f24344af --- /dev/null +++ b/bsp/esp32_s3_touch_lcd_1_85C_V2/include/bsp/esp-bsp.h @@ -0,0 +1,2 @@ +#pragma once +#include "bsp/esp32_s3_touch_lcd_1_85C_V2.h" diff --git a/bsp/esp32_s3_touch_lcd_1_85C_V2/include/bsp/esp32_s3_touch_lcd_1_85C_V2.h b/bsp/esp32_s3_touch_lcd_1_85C_V2/include/bsp/esp32_s3_touch_lcd_1_85C_V2.h new file mode 100644 index 00000000..9ea59751 --- /dev/null +++ b/bsp/esp32_s3_touch_lcd_1_85C_V2/include/bsp/esp32_s3_touch_lcd_1_85C_V2.h @@ -0,0 +1,540 @@ +/* + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief ESP BSP: ESP32-S3-TOUCH-LCD-1.85C-V2 + */ + +#pragma once + +#include "sdkconfig.h" +#include "driver/gpio.h" +#include "driver/i2s_std.h" +#include "driver/sdmmc_host.h" +#include "driver/sdspi_host.h" +#include "driver/i2c_master.h" +#include "esp_vfs_fat.h" +#include "driver/i2c_master.h" +#include "iot_button.h" +#include "esp_codec_dev.h" +#include "bsp/config.h" +#include "bsp/display.h" +#include "button_gpio.h" +#include "esp_io_expander_tca9554.h" + +#if (BSP_CONFIG_NO_GRAPHIC_LIB == 0) +#include "lvgl.h" +#include "esp_lv_adapter.h" +#endif // BSP_CONFIG_NO_GRAPHIC_LIB == 0 + +/************************************************************************************************** + * BSP Board Name + **************************************************************************************************/ + +/** @defgroup boardname Board Name + * @brief BSP Board Name + * @{ + */ +#define ESP32-S3-TOUCH-LCD-1_85C-v2 +/** @} */ // end of boardname + +/************************************************************************************************** + * BSP Capabilities + **************************************************************************************************/ + +/** @defgroup capabilities Capabilities + * @brief BSP Capabilities + * @{ + */ +#define BSP_CAPS_DISPLAY 1 +#define BSP_CAPS_TOUCH 1 +#define BSP_CAPS_BUTTONS 1 +#define BSP_CAPS_AUDIO 1 +#define BSP_CAPS_AUDIO_SPEAKER 1 +#define BSP_CAPS_AUDIO_MIC 1 +#define BSP_CAPS_LED 0 +#define BSP_CAPS_SDCARD 1 +#define BSP_CAPS_IMU 0 +#define BSP_CAPS_CAMERA 0 +/** @} */ // end of capabilities + +/************************************************************************************************** + * Board pinout + **************************************************************************************************/ + +/** @defgroup g01_i2c I2C + * @brief I2C BSP API + * @{ + */ +#define BSP_I2C_SCL (GPIO_NUM_10) +#define BSP_I2C_SDA (GPIO_NUM_11) +/** @} */ // end of i2c + +/** @defgroup g03_audio Audio + * @brief Audio BSP API + * @{ + */ +#define BSP_I2S_SCLK (GPIO_NUM_48) +#define BSP_I2S_MCLK (GPIO_NUM_2) +#define BSP_I2S_LCLK (GPIO_NUM_38) +#define BSP_I2S_DOUT (GPIO_NUM_47) +#define BSP_I2S_DSIN (GPIO_NUM_39) +#define BSP_POWER_AMP_IO (GPIO_NUM_15) +/** @} */ // end of audio + +/** @defgroup g04_display Display and Touch + * @brief Display BSP API + * @{ + */ + +#define BSP_LCD_CS (GPIO_NUM_21) +#define BSP_LCD_PCLK (GPIO_NUM_40) +#define BSP_LCD_DATA0 (GPIO_NUM_46) +#define BSP_LCD_DATA1 (GPIO_NUM_45) +#define BSP_LCD_DATA2 (GPIO_NUM_42) +#define BSP_LCD_DATA3 (GPIO_NUM_41) +#define BSP_LCD_BACKLIGHT (GPIO_NUM_5) +#define BSP_LCD_TE (GPIO_NUM_18) + +#define BSP_LCD_RST (GPIO_NUM_NC) +#define BSP_LCD_TOUCH_RST (GPIO_NUM_NC) +#define BSP_LCD_TOUCH_INT (GPIO_NUM_4) +/** @} */ // end of display + +/** @defgroup g02_storage SD Card and SPIFFS + * @brief SPIFFS and SD card BSP API + * @{ + */ +/* uSD card MMC */ +#define BSP_SD_CLK (GPIO_NUM_14) +#define BSP_SD_CMD (GPIO_NUM_17) +#define BSP_SD_D0 (GPIO_NUM_16) +#define BSP_SD_D1 (GPIO_NUM_NC) +#define BSP_SD_D2 (GPIO_NUM_NC) +#define BSP_SD_D3 (GPIO_NUM_NC) +/** @} */ // end of storage + +/** @defgroup g05_buttons Buttons + * @brief Buttons BSP API + * @{ + */ +#define BSP_BUTTONS_IO_0 (GPIO_NUM_0) +/** @} */ // end of buttons + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize all buttons + * + * Returned button handlers must be used with espressif/button component API + * + * @note For LCD panel button which is defined as BSP_BUTTON_MAIN, bsp_display_start should + * be called before call this function. + * + * @param[out] btn_array Output button array + * @param[out] btn_cnt Number of button handlers saved to btn_array, can be NULL + * @param[in] btn_array_size Size of output button array. Must be at least BSP_BUTTON_NUM + * @return + * - ESP_OK All buttons initialized + * - ESP_ERR_INVALID_ARG btn_array is too small or NULL + * - ESP_FAIL Underlaying iot_button_create failed + */ +//esp_err_t bsp_iot_button_create(button_handle_t btn_array[], int *btn_cnt, int btn_array_size); + +/** @} */ // end of buttons + +/** \addtogroup g03_audio + * @{ + */ + +/************************************************************************************************** + * + * I2S audio interface + * + * There are two devices connected to the I2S peripheral: + * - Codec ES8311 for output (playback) path + * - ADC ES7210 for input (recording) path + * + * For speaker initialization use bsp_audio_codec_speaker_init() which is inside initialize I2S with bsp_audio_init(). + * For microphone initialization use bsp_audio_codec_microphone_init() which is inside initialize I2S with bsp_audio_init(). + * After speaker or microphone initialization, use functions from esp_codec_dev for play/record audio. + * Example audio play: + * \code{.c} + * esp_codec_dev_set_out_vol(spk_codec_dev, DEFAULT_VOLUME); + * esp_codec_dev_open(spk_codec_dev, &fs); + * esp_codec_dev_write(spk_codec_dev, wav_bytes, wav_bytes_len); + * esp_codec_dev_close(spk_codec_dev); + * \endcode + **************************************************************************************************/ + +/** + * @brief Init audio + * + * @note There is no deinit audio function. Users can free audio resources by calling i2s_del_channel() + * @param[in] i2s_config I2S configuration. Pass NULL to use default values (Mono, duplex, 16bit, 22050 Hz) + * @return + * - ESP_OK On success + * - ESP_ERR_NOT_SUPPORTED The communication mode is not supported on the current chip + * - ESP_ERR_INVALID_ARG NULL pointer or invalid configuration + * - ESP_ERR_NOT_FOUND No available I2S channel found + * - ESP_ERR_NO_MEM No memory for storing the channel information + * - ESP_ERR_INVALID_STATE This channel has not initialized or already started + */ +esp_err_t bsp_audio_init(const i2s_std_config_t *i2s_config); + +/** + * @brief Get codec I2S interface (initialized in bsp_audio_init) + * + * @return + * - Pointer to codec I2S interface handle or NULL when error occurred + */ +const audio_codec_data_if_t *bsp_audio_get_codec_itf(void); + +/** + * @brief Initialize speaker codec device + * + * @return Pointer to codec device handle or NULL when error occurred + */ +esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void); + +/** + * @brief Initialize microphone codec device + * + * @return Pointer to codec device handle or NULL when error occurred + */ +esp_codec_dev_handle_t bsp_audio_codec_microphone_init(void); + +/** @} */ // end of audio + +/** \addtogroup g01_i2c + * @{ + */ + +/************************************************************************************************** + * + * I2C interface + * + * There are multiple devices connected to I2C peripheral: + * - Codec ES8311 (configuration only) + * - ADC ES7210 (configuration only) + * - LCD Touch controller + * - IO Expander TCA9554 + * - Camera + **************************************************************************************************/ +#define BSP_I2C_NUM CONFIG_BSP_I2C_NUM + +/** + * @brief Init I2C driver + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG I2C parameter error + * - ESP_FAIL I2C driver installation error + * + */ +esp_err_t bsp_i2c_init(void); + +/** + * @brief Deinit I2C driver and free its resources + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG I2C parameter error + * + */ +esp_err_t bsp_i2c_deinit(void); + +/** + * @brief Get I2C driver handle + * + * @return + * - I2C handle + */ +i2c_master_bus_handle_t bsp_i2c_get_handle(void); + +/** @} */ // end of i2c + +/** \addtogroup g02_storage + * @{ + */ + +/************************************************************************************************** + * + * SPIFFS + * + * After mounting the SPIFFS, it can be accessed with stdio functions ie.: + * \code{.c} + * FILE* f = fopen(BSP_SPIFFS_MOUNT_POINT"/hello.txt", "w"); + * fprintf(f, "Hello World!\n"); + * fclose(f); + * \endcode + **************************************************************************************************/ +#define BSP_SPIFFS_MOUNT_POINT CONFIG_BSP_SPIFFS_MOUNT_POINT + +/** + * @brief Mount SPIFFS to virtual file system + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_spiffs_register was already called + * - ESP_ERR_NO_MEM if memory can not be allocated + * - ESP_FAIL if partition can not be mounted + * - other error codes + */ +esp_err_t bsp_spiffs_mount(void); + +/** + * @brief Unmount SPIFFS from virtual file system + * + * @return + * - ESP_OK on success + * - ESP_ERR_NOT_FOUND if the partition table does not contain SPIFFS partition with given label + * - ESP_ERR_INVALID_STATE if esp_vfs_spiffs_unregister was already called + * - ESP_ERR_NO_MEM if memory can not be allocated + * - ESP_FAIL if partition can not be mounted + * - other error codes + */ +esp_err_t bsp_spiffs_unmount(void); + +/************************************************************************************************** + * + * uSD card + * + * After mounting the uSD card, it can be accessed with stdio functions ie.: + * \code{.c} + * FILE* f = fopen(BSP_MOUNT_POINT"/hello.txt", "w"); + * fprintf(f, "Hello %s!\n", bsp_sdcard->cid.name); + * fclose(f); + * \endcode + **************************************************************************************************/ +#define BSP_SD_MOUNT_POINT CONFIG_BSP_SD_MOUNT_POINT + +/** + * @brief BSP SD card configuration structure + */ +typedef struct { + const esp_vfs_fat_sdmmc_mount_config_t *mount; + sdmmc_host_t *host; + union { + const sdmmc_slot_config_t *sdmmc; + const sdspi_device_config_t *sdspi; + } slot; +} bsp_sdcard_cfg_t; + +/** + * @brief Mount microSD card to virtual file system + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_mount(void); + +/** + * @brief Unmount microSD card from virtual file system + * + * @return + * - ESP_OK on success + * - ESP_ERR_NOT_FOUND if the partition table does not contain FATFS partition with given label + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_spiflash_mount was already called + * - ESP_ERR_NO_MEM if memory can not be allocated + * - ESP_FAIL if partition can not be mounted + * - other error codes from wear levelling library, SPI flash driver, or FATFS drivers + */ +esp_err_t bsp_sdcard_unmount(void); + +/** + * @brief Get SD card handle + * + * @return SD card handle + */ +sdmmc_card_t *bsp_sdcard_get_handle(void); + +/** + * @brief Get SD card MMC host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdmmc_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card SPI host config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_get_sdspi_host(const int slot, sdmmc_host_t *config); + +/** + * @brief Get SD card MMC slot config + * + * @param slot SD card slot + * @param config Structure which will be filled + */ +void bsp_sdcard_sdmmc_get_slot(const int slot, sdmmc_slot_config_t *config); + +/** + * @brief Get SD card SPI slot config + * + * @param spi_host SPI host ID + * @param config Structure which will be filled + */ +void bsp_sdcard_sdspi_get_slot(const spi_host_device_t spi_host, sdspi_device_config_t *config); + +/** + * @brief Mount microSD card to virtual file system (MMC mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdmmc_mount(bsp_sdcard_cfg_t *cfg); + +/** + * @brief Mount microSD card to virtual file system (SPI mode) + * + * @param cfg SD card configuration + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called + * - ESP_ERR_NO_MEM if memory cannot be allocated + * - ESP_FAIL if partition cannot be mounted + * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers + */ +esp_err_t bsp_sdcard_sdspi_mount(bsp_sdcard_cfg_t *cfg); + +typedef struct { + char **list; + int count; +} generic_file_list_t; + +esp_err_t get_file_list_by_ext(const char *dir_path, const char *extension, generic_file_list_t *out); + +/** @} */ // end of storage + + +/** + * @brief Init IO expander chip TCA9554 + * + * @note If the device was already initialized, users can also use it to get handle. + * @note This function will be called in `bsp_display_start()` when using LCD sub-board 2 with the resolution of 480x480. + * @note This function will be called in `bsp_audio_init()`. + * + * @return Pointer to device handle or NULL when error occurred + */ +esp_io_expander_handle_t bsp_io_expander_init(void); + +/** \addtogroup g04_display + * @{ + */ + +/************************************************************************************************** + * + * LCD interface + * + * Board is shipped with 2.4inch ILI9341 display controller. + * It features 16-bit colors, 320x240 resolution and capacitive touch controller. + * + * LVGL is used as graphics library. LVGL is NOT thread safe, therefore the user must take LVGL mutex + * by calling bsp_display_lock() before calling and LVGL API (lv_...) and then give the mutex with + * bsp_display_unlock(). + * + * Display's backlight must be enabled explicitly by calling bsp_display_backlight_on() + **************************************************************************************************/ +#define BSP_LCD_PIXEL_CLOCK_HZ (80 * 1000 * 1000) +#define BSP_LCD_SPI_NUM (SPI2_HOST) + +#if (BSP_CONFIG_NO_GRAPHIC_LIB == 0) + +/** + * @brief BSP display configuration structure + */ +typedef struct { + esp_lv_adapter_config_t lv_adapter_cfg; + esp_lv_adapter_rotation_t rotation; + esp_lv_adapter_tear_avoid_mode_t tear_avoid_mode; + struct { + unsigned int swap_xy; /*!< Swap X and Y after read coordinates */ + unsigned int mirror_x; /*!< Mirror X after read coordinates */ + unsigned int mirror_y; /*!< Mirror Y after read coordinates */ + } touch_flags; +} bsp_display_cfg_t; + +/** + * @brief Initialize display + * + * This function initializes SPI, display controller and starts LVGL handling task. + * LCD backlight must be enabled separately by calling bsp_display_brightness_set() + * + * @return Pointer to LVGL display or NULL when error occurred + */ +lv_display_t *bsp_display_start(void); + +/** + * @brief Initialize display + * + * This function initializes SPI, display controller and starts LVGL handling task. + * LCD backlight must be enabled separately by calling bsp_display_brightness_set() + * + * @param cfg display configuration + * + * @return Pointer to LVGL display or NULL when error occurred + */ +lv_display_t *bsp_display_start_with_config(bsp_display_cfg_t *cfg); + +/** + * @brief Get pointer to display device + * + * @note The LVGL display device is initialized in bsp_display_start() function. + * + * @return Pointer to LVGL display device or NULL when not initialized + */ +lv_display_t *bsp_display_get_disp_dev(void); + +/** + * @brief Get pointer to input device (touch, buttons, ...) + * + * @note The LVGL input device is initialized in bsp_display_start() function. + * + * @return Pointer to LVGL input device or NULL when not initialized + */ +lv_indev_t *bsp_display_get_input_dev(void); + +/** + * @brief Take LVGL mutex + * + * @param timeout_ms Timeout in [ms]. 0 will block indefinitely. + * @return true Mutex was taken + * @return false Mutex was NOT taken + */ +esp_err_t bsp_display_lock(int32_t timeout_ms); + +/** + * @brief Give LVGL mutex + * + */ +void bsp_display_unlock(void); +#endif // BSP_CONFIG_NO_GRAPHIC_LIB == 0 + + + +#ifdef __cplusplus +} +#endif + diff --git a/bsp/esp32_s3_touch_lcd_1_85C_V2/include/bsp/touch.h b/bsp/esp32_s3_touch_lcd_1_85C_V2/include/bsp/touch.h new file mode 100644 index 00000000..4113d9d8 --- /dev/null +++ b/bsp/esp32_s3_touch_lcd_1_85C_V2/include/bsp/touch.h @@ -0,0 +1,35 @@ +#pragma once +#include "esp_lcd_touch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief BSP touch configuration structure + * + */ +typedef struct { + void *dummy; /*!< Prepared for future use. */ +} bsp_touch_config_t; + +/** + * @brief Create new touchscreen + * + * If you want to free resources allocated by this function, you can use esp_lcd_touch API, ie.: + * + * \code{.c} + * esp_lcd_touch_del(tp); + * \endcode + * + * @param[in] config touch configuration + * @param[out] ret_touch esp_lcd_touch touchscreen handle + * @return + * - ESP_OK On success + * - Else esp_lcd_touch failure + */ +esp_err_t bsp_touch_new(const bsp_display_cfg_t *cfg, esp_lcd_touch_handle_t *ret_touch); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/bsp/esp32_s3_touch_lcd_1_85C_V2/priv_include/bsp_err_check.h b/bsp/esp32_s3_touch_lcd_1_85C_V2/priv_include/bsp_err_check.h new file mode 100644 index 00000000..82f35971 --- /dev/null +++ b/bsp/esp32_s3_touch_lcd_1_85C_V2/priv_include/bsp_err_check.h @@ -0,0 +1,52 @@ +#pragma once + +#include "esp_check.h" +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Assert on error, if selected in menuconfig. Otherwise return error code. */ +#if CONFIG_BSP_ERROR_CHECK +#define BSP_ERROR_CHECK_RETURN_ERR(x) ESP_ERROR_CHECK(x) +#define BSP_ERROR_CHECK_RETURN_NULL(x) ESP_ERROR_CHECK(x) +#define BSP_ERROR_CHECK(x, ret) ESP_ERROR_CHECK(x) +#define BSP_NULL_CHECK(x, ret) assert(x) +#define BSP_NULL_CHECK_GOTO(x, goto_tag) assert(x) +#else +#define BSP_ERROR_CHECK_RETURN_ERR(x) do { \ + esp_err_t err_rc_ = (x); \ + if (unlikely(err_rc_ != ESP_OK)) { \ + return err_rc_; \ + } \ + } while(0) + +#define BSP_ERROR_CHECK_RETURN_NULL(x) do { \ + if (unlikely((x) != ESP_OK)) { \ + return NULL; \ + } \ + } while(0) + +#define BSP_NULL_CHECK(x, ret) do { \ + if ((x) == NULL) { \ + return ret; \ + } \ + } while(0) + +#define BSP_ERROR_CHECK(x, ret) do { \ + if (unlikely((x) != ESP_OK)) { \ + return ret; \ + } \ + } while(0) + +#define BSP_NULL_CHECK_GOTO(x, goto_tag) do { \ + if ((x) == NULL) { \ + goto goto_tag; \ + } \ + } while(0) +#endif + +#ifdef __cplusplus +} +#endif \ No newline at end of file