diff --git a/.github/workflows/upload_component.yml b/.github/workflows/upload_component.yml index b8985005..924661a2 100644 --- a/.github/workflows/upload_component.yml +++ b/.github/workflows/upload_component.yml @@ -17,7 +17,7 @@ jobs: uses: espressif/upload-components-ci-action@v1 with: directories: > - bsp/esp32_azure_iot_kit;bsp/esp32_s2_kaluga_kit;bsp/esp_wrover_kit;bsp/esp-box;bsp/esp32_s3_usb_otg;bsp/esp32_s3_eye;bsp/esp32_s3_lcd_ev_board;bsp/esp32_s3_korvo_2;bsp/esp-box-lite;bsp/esp32_lyrat;bsp/esp32_c3_lcdkit;bsp/esp-box-3;bsp/esp_bsp_generic;bsp/esp32_s3_korvo_1;bsp/esp32_p4_function_ev_board;bsp/m5stack_core_s3;bsp/m5dial;bsp/m5stack_core_2; + bsp/esp32_azure_iot_kit;bsp/esp32_s2_kaluga_kit;bsp/esp_wrover_kit;bsp/esp-box;bsp/esp32_s3_usb_otg;bsp/esp32_s3_eye;bsp/esp32_s3_lcd_ev_board;bsp/esp32_s3_korvo_2;bsp/esp-box-lite;bsp/esp32_lyrat;bsp/esp32_c3_lcdkit;bsp/esp-box-3;bsp/esp_bsp_generic;bsp/esp32_s3_korvo_1;bsp/esp32_p4_function_ev_board;bsp/m5stack_core_s3;bsp/m5dial;bsp/m5stack_core_2;bsp/esp_bsp_devkit; components/bh1750;components/ds18b20;components/es8311;components/es7210;components/fbm320;components/hts221;components/mag3110;components/mpu6050;components/esp_lvgl_port;components/icm42670; components/lcd_touch/esp_lcd_touch;components/lcd_touch/esp_lcd_touch_ft5x06;components/lcd_touch/esp_lcd_touch_gt911;components/lcd_touch/esp_lcd_touch_tt21100;components/lcd_touch/esp_lcd_touch_gt1151;components/lcd_touch/esp_lcd_touch_cst816s; components/lcd/esp_lcd_gc9a01;components/lcd/esp_lcd_ili9341;components/lcd/esp_lcd_ra8875;components/lcd_touch/esp_lcd_touch_stmpe610;components/lcd/esp_lcd_sh1107;components/lcd/esp_lcd_st7796;components/lcd/esp_lcd_gc9503;components/lcd/esp_lcd_ssd1681;components/lcd/esp_lcd_ili9881c; diff --git a/bsp/esp_bsp_devkit/CMakeLists.txt b/bsp/esp_bsp_devkit/CMakeLists.txt new file mode 100644 index 00000000..9bd1dabe --- /dev/null +++ b/bsp/esp_bsp_devkit/CMakeLists.txt @@ -0,0 +1,8 @@ +file(GLOB_RECURSE SRCS src/*.c) + +idf_component_register( + SRCS ${SRCS} + INCLUDE_DIRS "include" + PRIV_INCLUDE_DIRS "priv_include" + REQUIRES driver spiffs fatfs +) diff --git a/bsp/esp_bsp_devkit/Kconfig b/bsp/esp_bsp_devkit/Kconfig new file mode 100644 index 00000000..904f07e4 --- /dev/null +++ b/bsp/esp_bsp_devkit/Kconfig @@ -0,0 +1,770 @@ +menu "Board Support Package (generic)" + + 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" + menu "Pins" + config BSP_I2C_GPIO_SCL + int "I2C GPIO SCL" + default -1 + range -1 ENV_GPIO_OUT_RANGE_MAX + help + The GPIO pin for I2C SCL. + config BSP_I2C_GPIO_SDA + int "I2C GPIO SDA" + default -1 + range -1 ENV_GPIO_OUT_RANGE_MAX + help + The GPIO pin for I2C SDA. + endmenu + config BSP_I2C_NUM + int "I2C peripheral index" + default 1 + range 0 1 + help + ESP32 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 "Buttons" + config BSP_BUTTONS_NUM + int + prompt "Number of buttons in BSP" + default 2 + range 0 5 + + menu "Button 1" + depends on BSP_BUTTONS_NUM > 0 + choice BSP_BUTTON_1_TYPE + prompt "Button type" + default BSP_BUTTON_1_TYPE_GPIO + help + Select a button type GPIO or ADC + + config BSP_BUTTON_1_TYPE_GPIO + bool "GPIO Button" + config BSP_BUTTON_1_TYPE_ADC + bool "ADC Button" + endchoice + + config BSP_BUTTON_1_GPIO + depends on BSP_BUTTON_1_TYPE_GPIO + int + prompt "Button 1 GPIO" + default 0 + range -1 ENV_GPIO_IN_RANGE_MAX + help + The GPIO pin for button 1. + config BSP_BUTTON_1_LEVEL + depends on BSP_BUTTON_1_TYPE_GPIO + int + prompt "Button 1 Active Level" + default 0 + range 0 1 + help + The active level for button 1. + + config BSP_BUTTON_1_ADC_UNIT + depends on BSP_BUTTON_1_TYPE_ADC + int "Button 1 ADC Unit" + default 1 + range 0 1 + help + The ADC unit for button 1. + + config BSP_BUTTON_1_ADC_CHANNEL + depends on BSP_BUTTON_1_TYPE_ADC + int "Button 1 ADC Channel" + default 0 + range 0 9 + help + The ADC channel for button 1. + + config BSP_BUTTON_1_ADC_VALUE + depends on BSP_BUTTON_1_TYPE_ADC + int "Button 1 ADC Value" + default 2000 + range 0 2500 + help + The ADC middle value for button 1. + endmenu + + menu "Button 2" + depends on BSP_BUTTONS_NUM > 1 + choice + prompt "Button type" + default BSP_BUTTON_2_TYPE_GPIO + help + Select a button type GPIO or ADC + + config BSP_BUTTON_2_TYPE_GPIO + bool "GPIO Button" + config BSP_BUTTON_2_TYPE_ADC + bool "ADC Button" + endchoice + + config BSP_BUTTON_2_GPIO + depends on BSP_BUTTON_2_TYPE_GPIO + int "Button 2 GPIO" + default -1 + range -1 ENV_GPIO_IN_RANGE_MAX + help + The GPIO pin for button 2. + + config BSP_BUTTON_2_LEVEL + depends on BSP_BUTTON_2_TYPE_GPIO + int "Button 2 Active Level" + default 0 + range 0 1 + help + The active level for button 2. + + config BSP_BUTTON_2_ADC_UNIT + depends on BSP_BUTTON_2_TYPE_ADC + int "Button 2 ADC Unit" + default 1 + range 0 1 + help + The ADC unit for button 2. + + config BSP_BUTTON_2_ADC_CHANNEL + depends on BSP_BUTTON_2_TYPE_ADC + int "Button 2 ADC Channel" + default 0 + range 0 9 + help + The ADC channel for button 2. + + config BSP_BUTTON_2_ADC_VALUE + depends on BSP_BUTTON_2_TYPE_ADC + int "Button 2 ADC Value" + default 2000 + range 0 2500 + help + The ADC middle value for button 2. + endmenu + + menu "Button 3" + depends on BSP_BUTTONS_NUM > 2 + choice + prompt "Button type" + default BSP_BUTTON_3_TYPE_GPIO + help + Select a button type GPIO or ADC + + config BSP_BUTTON_3_TYPE_GPIO + bool "GPIO Button" + config BSP_BUTTON_3_TYPE_ADC + bool "ADC Button" + endchoice + + config BSP_BUTTON_3_GPIO + depends on BSP_BUTTON_3_TYPE_GPIO + int "Button 3 GPIO" + default -1 + range -1 ENV_GPIO_IN_RANGE_MAX + help + The GPIO pin for button 3. + + config BSP_BUTTON_3_LEVEL + depends on BSP_BUTTON_3_TYPE_GPIO + int "Button 3 Active Level" + default 0 + range 0 1 + help + The active level for button 3. + + config BSP_BUTTON_3_ADC_UNIT + depends on BSP_BUTTON_3_TYPE_ADC + int "Button 3 ADC Unit" + default 1 + range 0 1 + help + The ADC unit for button 3. + + config BSP_BUTTON_3_ADC_CHANNEL + depends on BSP_BUTTON_3_TYPE_ADC + int "Button 3 ADC Channel" + default 0 + range 0 9 + help + The ADC channel for button 3. + + config BSP_BUTTON_3_ADC_VALUE + depends on BSP_BUTTON_3_TYPE_ADC + int "Button 3 ADC Value" + default 2000 + range 0 2500 + help + The ADC middle value for button 3. + endmenu + + menu "Button 4" + depends on BSP_BUTTONS_NUM > 3 + choice + prompt "Button type" + default BSP_BUTTON_4_TYPE_GPIO + help + Select a button type GPIO or ADC + + config BSP_BUTTON_4_TYPE_GPIO + bool "GPIO Button" + config BSP_BUTTON_4_TYPE_ADC + bool "ADC Button" + endchoice + + config BSP_BUTTON_4_GPIO + depends on BSP_BUTTON_4_TYPE_GPIO + int "Button 4 GPIO" + default -1 + range -1 ENV_GPIO_IN_RANGE_MAX + help + The GPIO pin for button 4. + + config BSP_BUTTON_4_LEVEL + depends on BSP_BUTTON_4_TYPE_GPIO + int "Button 4 Active Level" + default 0 + range 0 1 + help + The active level for button 4. + + config BSP_BUTTON_4_ADC_UNIT + depends on BSP_BUTTON_4_TYPE_ADC + int "Button 4 ADC Unit" + default 1 + range 0 1 + help + The ADC unit for button 4. + + config BSP_BUTTON_4_ADC_CHANNEL + depends on BSP_BUTTON_4_TYPE_ADC + int "Button 4 ADC Channel" + default 0 + range 0 9 + help + The ADC channel for button 4. + + config BSP_BUTTON_4_ADC_VALUE + depends on BSP_BUTTON_4_TYPE_ADC + int "Button 4 ADC Value" + default 2000 + range 0 2500 + help + The ADC middle value for button 4. + endmenu + + menu "Button 5" + depends on BSP_BUTTONS_NUM > 4 + choice + prompt "Button type" + default BSP_BUTTON_5_TYPE_GPIO + help + Select a button type GPIO or ADC + + config BSP_BUTTON_5_TYPE_GPIO + bool "GPIO Button" + config BSP_BUTTON_5_TYPE_ADC + bool "ADC Button" + endchoice + + config BSP_BUTTON_5_GPIO + depends on BSP_BUTTON_5_TYPE_GPIO + int "Button 5 GPIO" + default -1 + range -1 ENV_GPIO_IN_RANGE_MAX + help + The GPIO pin for button 5. + + config BSP_BUTTON_5_LEVEL + depends on BSP_BUTTON_5_TYPE_GPIO + int "Button 5 Active Level" + default 0 + range 0 1 + help + The active level for button 5. + + config BSP_BUTTON_5_ADC_UNIT + depends on BSP_BUTTON_5_TYPE_ADC + int "Button 5 ADC Unit" + default 1 + range 0 1 + help + The ADC unit for button 5. + + config BSP_BUTTON_5_ADC_CHANNEL + depends on BSP_BUTTON_5_TYPE_ADC + int "Button 5 ADC Channel" + default 0 + range 0 9 + help + The ADC channel for button 5. + + config BSP_BUTTON_5_ADC_VALUE + depends on BSP_BUTTON_5_TYPE_ADC + int "Button 5 ADC Value" + default 2000 + range 0 2500 + help + The ADC middle value for button 5. + endmenu + endmenu + + + menu "LEDs" + choice + prompt "LED type" + default BSP_LED_TYPE_GPIO + help + Select a LED type GPIO or Adressable RGB + config BSP_LED_TYPE_GPIO + bool "GPIO LED" + config BSP_LED_TYPE_RGB_CLASSIC + bool "Classic RGB LED" + config BSP_LED_TYPE_RGB + bool "Adressable RGB LED" + endchoice + + if BSP_LED_TYPE_GPIO + config ENV_MAX_LEDS + int + default 5 + endif + if BSP_LED_TYPE_RGB_CLASSIC || BSP_LED_TYPE_RGB + config ENV_MAX_LEDS + int + default 1 + endif + + config BSP_LEDS_NUM + int + prompt "Number of LEDs in BSP" + default 1 + range 0 ENV_MAX_LEDS + + config BSP_LED_RGB_GPIO + depends on BSP_LED_TYPE_RGB && BSP_LEDS_NUM > 0 + int + prompt "Adressable RGB LED GPIO" + default 48 + range -1 ENV_GPIO_OUT_RANGE_MAX + help + The GPIO pin for adressable LEDs. + + config BSP_LED_RGB_CLASSIC_LEVEL + depends on BSP_LED_TYPE_RGB_CLASSIC && BSP_LEDS_NUM > 0 + int + prompt "Classic RGB LED Active Level" + default 0 + range 0 1 + help + The active level for classic RGB LED. + + config BSP_LED_RGB_RED_GPIO + depends on BSP_LED_TYPE_RGB_CLASSIC && BSP_LEDS_NUM > 0 + int + prompt "Classic RGB LED red GPIO" + default -1 + range -1 ENV_GPIO_OUT_RANGE_MAX + help + The GPIO pin for red color RGB LED. + + config BSP_LED_RGB_GREEN_GPIO + depends on BSP_LED_TYPE_RGB_CLASSIC && BSP_LEDS_NUM > 0 + int + prompt "Classic RGB LED green GPIO" + default -1 + range -1 ENV_GPIO_OUT_RANGE_MAX + help + The GPIO pin for green color RGB LED. + + config BSP_LED_RGB_BLUE_GPIO + depends on BSP_LED_TYPE_RGB_CLASSIC && BSP_LEDS_NUM > 0 + int + prompt "Classic RGB LED blue GPIO" + default -1 + range -1 ENV_GPIO_OUT_RANGE_MAX + help + The GPIO pin for blue color RGB LED. + + config BSP_ESP_IDF_VERSION + string + default "$ESP_IDF_VERSION" + + choice BSP_LED_RGB_BACKEND + depends on BSP_LED_TYPE_RGB && BSP_LEDS_NUM > 0 + prompt "Adressable RGB LED backend peripheral" + default BSP_LED_RGB_BACKEND_RMT + default BSP_LED_RGB_BACKEND_SPI + help + Select the backend peripheral to drive the LED strip. + + config BSP_LED_RGB_BACKEND_RMT + bool "RMT" + if BSP_ESP_IDF_VERSION>="5.0" + config BSP_LED_RGB_BACKEND_SPI + bool "SPI" + endif + endchoice + + menu "LED 1" + depends on BSP_LEDS_NUM > 0 && BSP_LED_TYPE_GPIO + + config BSP_LED_1_GPIO + int + prompt "LED 1 GPIO" + default 0 + range -1 ENV_GPIO_OUT_RANGE_MAX + help + The GPIO pin for LED 1. + + config BSP_LED_1_LEVEL + int + prompt "LED 1 Active Level" + default 1 + range 0 1 + help + The active level for LED 1. + endmenu + + menu "LED 2" + depends on BSP_LEDS_NUM > 1 && BSP_LED_TYPE_GPIO + + config BSP_LED_2_GPIO + int + prompt "LED 2 GPIO" + default 0 + range -1 ENV_GPIO_OUT_RANGE_MAX + help + The GPIO pin for LED 2. + config BSP_LED_2_LEVEL + int + prompt "LED 2 Active Level" + default 1 + range 0 1 + help + The active level for LED 2. + endmenu + + menu "LED 3" + depends on BSP_LEDS_NUM > 2 && BSP_LED_TYPE_GPIO + + config BSP_LED_3_GPIO + int + prompt "LED 3 GPIO" + default 0 + range -1 ENV_GPIO_OUT_RANGE_MAX + help + The GPIO pin for LED 3. + config BSP_LED_3_LEVEL + int + prompt "LED 3 Active Level" + default 1 + range 0 1 + help + The active level for LED 3. + endmenu + + menu "LED 4" + depends on BSP_LEDS_NUM > 3 && BSP_LED_TYPE_GPIO + + config BSP_LED_4_GPIO + int + prompt "LED 4 GPIO" + default 0 + range -1 ENV_GPIO_OUT_RANGE_MAX + help + The GPIO pin for LED 4. + config BSP_LED_4_LEVEL + int + prompt "LED 4 Active Level" + default 1 + range 0 1 + help + The active level for LED 4. + endmenu + + menu "LED 5" + depends on BSP_LEDS_NUM > 4 && BSP_LED_TYPE_GPIO + + config BSP_LED_5_GPIO + int + prompt "LED 5 GPIO" + default 0 + range -1 ENV_GPIO_OUT_RANGE_MAX + help + The GPIO pin for LED 5. + config BSP_LED_5_LEVEL + int + prompt "LED 5 Active Level" + default 1 + range 0 1 + help + The active level for LED 5. + endmenu + + endmenu + + menu "uSD card - Virtual File System" + menu "Pins" + depends on (IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4) + config BSP_SD_CLK + int "uSD GPIO CLK" + default -1 + range -1 ENV_GPIO_IN_RANGE_MAX + help + The GPIO pin for uSD CLK. + config BSP_SD_CMD + int "uSD GPIO CMD" + default -1 + range -1 ENV_GPIO_IN_RANGE_MAX + help + The GPIO pin for uSD CMD. + config BSP_SD_D0 + int "uSD GPIO D0" + default -1 + range -1 ENV_GPIO_IN_RANGE_MAX + help + The GPIO pin for uSD D0. + config BSP_SD_D1 + int "uSD GPIO D1" + default -1 + range -1 ENV_GPIO_IN_RANGE_MAX + help + The GPIO pin for uSD D1. + config BSP_SD_D2 + int "uSD GPIO D2" + default -1 + range -1 ENV_GPIO_IN_RANGE_MAX + help + The GPIO pin for uSD D2. + config BSP_SD_D3 + int "uSD GPIO D3" + default -1 + range -1 ENV_GPIO_IN_RANGE_MAX + help + The GPIO pin for uSD D3. + + endmenu + 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 + + config BSP_SD_MAX_FILES + int "Max files supported for SD VFS" + default 2 + help + Supported max files for SD in the Virtual File System. + + 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 "Max files supported for SPIFFS VFS" + default 2 + help + Supported max files for SPIFFS in the Virtual File System. + endmenu + + + # TARGET CONFIGURATION + + if IDF_TARGET_ESP32 + config ENV_GPIO_RANGE_MIN + int + default 0 + + config ENV_GPIO_RANGE_MAX + int + default 39 + + config ENV_GPIO_IN_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + + config ENV_GPIO_OUT_RANGE_MAX + int + default 33 + endif + if IDF_TARGET_ESP32C2 + config ENV_GPIO_RANGE_MIN + int + default 0 + + config ENV_GPIO_RANGE_MAX + int + default 18 + # GPIOs 19/20 are always used by UART in examples + + config ENV_GPIO_IN_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + + config ENV_GPIO_OUT_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + endif + if IDF_TARGET_ESP32C3 + config ENV_GPIO_RANGE_MIN + int + default 0 + + config ENV_GPIO_RANGE_MAX + int + default 19 + # GPIOs 20/21 are always used by UART in examples + + config ENV_GPIO_IN_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + + config ENV_GPIO_OUT_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + endif + if IDF_TARGET_ESP32C6 + config ENV_GPIO_RANGE_MIN + int + default 0 + + config ENV_GPIO_RANGE_MAX + int + default 30 + # GPIOs 16/17 are always used by UART in examples + + config ENV_GPIO_IN_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + + config ENV_GPIO_OUT_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + endif + if IDF_TARGET_ESP32H2 + config ENV_GPIO_RANGE_MIN + int + default 0 + + config ENV_GPIO_RANGE_MAX + int + default 27 + # GPIOs 23/24 are always used by UART in examples + + config ENV_GPIO_IN_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + + config ENV_GPIO_OUT_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + endif + if IDF_TARGET_ESP32P4 + config ENV_GPIO_RANGE_MIN + int + default 0 + + config ENV_GPIO_RANGE_MAX + int + default 56 + + config ENV_GPIO_IN_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + + config ENV_GPIO_OUT_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + endif + if IDF_TARGET_ESP32S2 + config ENV_GPIO_RANGE_MIN + int + default 0 + + config ENV_GPIO_RANGE_MAX + int + default 46 + + config ENV_GPIO_IN_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + + config ENV_GPIO_OUT_RANGE_MAX + int + default 45 + endif + if IDF_TARGET_ESP32S3 + config ENV_GPIO_RANGE_MIN + int + default 0 + + config ENV_GPIO_RANGE_MAX + int + default 48 + + config ENV_GPIO_IN_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + + config ENV_GPIO_OUT_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + endif + if IDF_TARGET_LINUX + config ENV_GPIO_RANGE_MIN + int + default 0 + + config ENV_GPIO_RANGE_MAX + int + default 0 + + config ENV_GPIO_IN_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + + config ENV_GPIO_OUT_RANGE_MAX + int + default ENV_GPIO_RANGE_MAX + endif + +endmenu diff --git a/bsp/esp_bsp_devkit/LICENSE b/bsp/esp_bsp_devkit/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/bsp/esp_bsp_devkit/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/esp_bsp_devkit/README.md b/bsp/esp_bsp_devkit/README.md new file mode 100644 index 00000000..44d6f259 --- /dev/null +++ b/bsp/esp_bsp_devkit/README.md @@ -0,0 +1,160 @@ +# BSP: DevKit + +[![Component Registry](https://components.espressif.com/components/espressif/esp_bsp_devkit/badge.svg)](https://components.espressif.com/components/espressif/esp_bsp_devkit) + +### Overview + +This is a generic BSP, which is configurable from `menuconfig`. The generic BSP can provide consistent API for simple boards, such as Espressif's DevKit-C and DevKit-M boards. Predefined settings for selected DevKits are in [generic_button_led](examples/generic_button_led). + +**Supported features:** +- I2C +- SPIFFS +- SD card +- Buttons +- LEDs + +# Build with predefined configuration + +Predefined configurations are saved in [generic_button_led](examples/generic_button_led) example. + +``` + idf.py -p COM4 -D "SDKCONFIG_DEFAULTS=sdkconfig.esp32_s3_devkitc_1" flash monitor +``` + +# Example usage + +## I2C + +1. Set GPIOs for I2C in `menuconfig` + - `BSP_I2C_GPIO_SCL` + - `BSP_I2C_GPIO_SDA` + +2. Set I2C number in `menuconfig` + - `BSP_I2C_NUM` + +Example code: +``` + /* Initialization */ + bsp_i2c_init(); + + /* Example I2C write with BSP_I2C_NUM */ + i2c_master_write_to_device(BSP_I2C_NUM, 0x10, value, sizeof(value), 1000 / portTICK_PERIOD_MS); + + ... + + bsp_i2c_deinit(); +``` +**Note:** The BSP automatically initialize I2C, when need it for some component (LCD touch, audio, etc.) + +## SPIFFS + +Example code: +``` + /* Mount SPIFFS partition */ + bsp_spiffs_mount(); + + /* Use file system read/write with BSP_SPIFFS_MOUNT_POINT */ + FILE *in = fopen(BSP_SD_MOUNT_POINT"/text.txt", "rb"); + + ... + + bsp_spiffs_unmount(); +``` + +## SD card + +Example code: +``` + /* Mount SD card partition */ + bsp_sdcard_mount(); + + /* Use file system read/write with BSP_SD_MOUNT_POINT */ + FILE *in = fopen(BSP_SD_MOUNT_POINT"/text.txt", "rb"); + + ... + + bsp_sdcard_unmount(); +``` + +**Note:** This API is available only in MCUs, which have SD MMC peripheral. + +## Buttons + +1. Set count of buttons in `menuconfig` + - `BSP_BUTTONS_NUM` (max 5) + +2. Set button type and other values by type for each button in `menuconfig` + - `BSP_BUTTON_x_TYPE` + - `BSP_BUTTON_x_GPIO` (for GPIO button) + - `BSP_BUTTON_x_LEVEL` (for GPIO button) + - `BSP_BUTTON_x_ADC_CHANNEL` (for ADC button) + - `BSP_BUTTON_x_ADC_VALUE` (for ADC button) + +Example code: +``` + /* Button callback */ + static void btn_handler(void *button_handle, void *usr_data) + { + int button_pressed = (int)usr_data; + + ESP_LOGI(TAG, "Button pressed: %d", button_pressed); + } + + /* Initialize all buttons and register callback for them */ + button_handle_t btns[BSP_BUTTON_NUM]; + ESP_ERROR_CHECK(bsp_iot_button_create(btns, NULL, BSP_BUTTON_NUM)); + for (int i = 0; i < BSP_BUTTON_NUM; i++) { + ESP_ERROR_CHECK(iot_button_register_cb(btns[i], BUTTON_PRESS_DOWN, btn_handler, (void *) i)); + } +``` +For button handling is used component [iot_button](https://components.espressif.com/components/espressif/button). For more information, please look into guide for this component. + +## LEDS + +1. Set count of LEDs in `menuconfig` + - `BSP_LEDS_NUM` (max 5) + +2. Set type for all LEDs in `menuconfig` + - `BSP_LED_TYPE` (GPIO / Adressable RGB LED / Classic RGB) + +3. For GPIO LEDs set pin and level for each LED in `menuconfig` + - `BSP_LED_x_GPIO` + - `BSP_LED_x_LEVEL` + +3. For addressable RBG LEDs set pin and peripheral in `menuconfig` + - `BSP_LED_RGB_GPIO` + - `BSP_LED_RGB_BACKEND` + +3. For classic RBG LEDs set pins for all colors and level in `menuconfig` + - `BSP_LED_RGB_RED_GPIO` + - `BSP_LED_RGB_GREEN_GPIO` + - `BSP_LED_RGB_BLUE_GPIO` + - `BSP_LED_RGB_CLASSIC_LEVEL` + +Example code: +``` + /* Initialize all LEDs */ + led_indicator_handle_t leds[BSP_LED_NUM]; + ESP_ERROR_CHECK(bsp_led_indicator_create(leds, NULL, BSP_LED_NUM)); + + /* Set LED color for first LED (only for addressable RGB LEDs) */ + led_indicator_set_rgb(leds[0], SET_IRGB(0, 0x00, 0x64, 0x64)); + + /* Start effect for each LED (predefined: BSP_LED_ON, BSP_LED_OFF, BSP_LED_BLINK_FAST, BSP_LED_BLINK_SLOW, BSP_LED_BREATHE_FAST, BSP_LED_BREATHE_SLOW) */ + led_indicator_start(leds[0], BSP_LED_BREATHE_SLOW); +``` +For LEDs handling is used component [led_indicator](https://components.espressif.com/components/espressif/led_indicator) with [led_strip](https://components.espressif.com/components/espressif/led_strip) component. For more information, please look into guides for these components. + + + +### Capabilities and dependencies +| Capability | Available | Component | Version | +|-------------|------------------|--------------------------------------------------------------------------------|----------| +| BUTTONS |:heavy_check_mark:|[espressif/button](https://components.espressif.com/components/espressif/button)|>=2.5,<4.0| +| LEDS |:heavy_check_mark:| | | +| AUDIO | :x: | | | +|AUDIO_SPEAKER| :x: | | | +| AUDIO_MIC | :x: | | | +| SDCARD | :x: | | | +| IMU | :x: | | | + diff --git a/bsp/esp_bsp_devkit/idf_component.yml b/bsp/esp_bsp_devkit/idf_component.yml new file mode 100644 index 00000000..e8150dd6 --- /dev/null +++ b/bsp/esp_bsp_devkit/idf_component.yml @@ -0,0 +1,21 @@ + +version: "1.0.0" +description: DevKit Board Support Package (BSP) +url: https://github.com/espressif/esp-bsp/tree/master/bsp/esp_bsp_devkit + +tags: + - bsp + +dependencies: + idf: ">=4.4.2" + + button: + version: ">=2.5,<4.0" + public: true + + led_indicator: + version: "^0.9" + public: true + +examples: + - path: ../../examples/generic_button_led diff --git a/bsp/esp_bsp_devkit/include/bsp/esp-bsp.h b/bsp/esp_bsp_devkit/include/bsp/esp-bsp.h new file mode 100644 index 00000000..cfcb6e66 --- /dev/null +++ b/bsp/esp_bsp_devkit/include/bsp/esp-bsp.h @@ -0,0 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "bsp/esp_bsp_devkit.h" diff --git a/bsp/esp_bsp_devkit/include/bsp/esp_bsp_devkit.h b/bsp/esp_bsp_devkit/include/bsp/esp_bsp_devkit.h new file mode 100644 index 00000000..73d7df4b --- /dev/null +++ b/bsp/esp_bsp_devkit/include/bsp/esp_bsp_devkit.h @@ -0,0 +1,292 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief ESP BSP: Generic + */ + +#pragma once + +#include "sdkconfig.h" +#include "driver/gpio.h" +#include "driver/i2c.h" +#include "driver/sdmmc_host.h" +#include "iot_button.h" +#include "led_indicator.h" + +/************************************************************************************************** + * BSP Capabilities + **************************************************************************************************/ + +#if CONFIG_BSP_BUTTONS_NUM > 0 +#define BSP_CAPS_BUTTONS 1 +#endif +#if CONFIG_BSP_LEDS_NUM > 0 +#define BSP_CAPS_LEDS 1 +#endif +#define BSP_CAPS_AUDIO 0 +#define BSP_CAPS_AUDIO_SPEAKER 0 +#define BSP_CAPS_AUDIO_MIC 0 +#define BSP_CAPS_SDCARD 0 +#define BSP_CAPS_IMU 0 + +/************************************************************************************************** + * Pinout + **************************************************************************************************/ +/* I2C */ +#define BSP_I2C_SCL (CONFIG_BSP_I2C_GPIO_SCL) +#define BSP_I2C_SDA (CONFIG_BSP_I2C_GPIO_SDA) + +/* SD card */ +#define BSP_SD_CMD (CONFIG_BSP_SD_CMD) +#define BSP_SD_CLK (CONFIG_BSP_SD_CLK) +#define BSP_SD_D0 (CONFIG_BSP_SD_D0) +#define BSP_SD_D1 (CONFIG_BSP_SD_D1) +#define BSP_SD_D2 (CONFIG_BSP_SD_D2) +#define BSP_SD_D3 (CONFIG_BSP_SD_D3) + +/* Buttons */ +#define BSP_BUTTON_1_IO (CONFIG_BSP_BUTTON_1_GPIO) +#define BSP_BUTTON_2_IO (CONFIG_BSP_BUTTON_2_GPIO) +#define BSP_BUTTON_3_IO (CONFIG_BSP_BUTTON_3_GPIO) +#define BSP_BUTTON_4_IO (CONFIG_BSP_BUTTON_4_GPIO) +#define BSP_BUTTON_5_IO (CONFIG_BSP_BUTTON_5_GPIO) + +/* Leds */ +#define BSP_LED_1_IO (CONFIG_BSP_LED_1_GPIO) +#define BSP_LED_2_IO (CONFIG_BSP_LED_2_GPIO) +#define BSP_LED_3_IO (CONFIG_BSP_LED_3_GPIO) +#define BSP_LED_4_IO (CONFIG_BSP_LED_4_GPIO) +#define BSP_LED_5_IO (CONFIG_BSP_LED_5_GPIO) + +/* Buttons */ +typedef enum { +#if CONFIG_BSP_BUTTONS_NUM > 0 + BSP_BUTTON_1, +#endif +#if CONFIG_BSP_BUTTONS_NUM > 1 + BSP_BUTTON_2, +#endif +#if CONFIG_BSP_BUTTONS_NUM > 2 + BSP_BUTTON_3, +#endif +#if CONFIG_BSP_BUTTONS_NUM > 3 + BSP_BUTTON_4, +#endif +#if CONFIG_BSP_BUTTONS_NUM > 4 + BSP_BUTTON_5, +#endif + BSP_BUTTON_NUM +} bsp_button_t; + +/* Leds */ +typedef enum { +#if CONFIG_BSP_LEDS_NUM > 0 + BSP_LED_1, +#endif +#if CONFIG_BSP_LEDS_NUM > 1 + BSP_LED_2, +#endif +#if CONFIG_BSP_LEDS_NUM > 2 + BSP_LED_3, +#endif +#if CONFIG_BSP_LEDS_NUM > 3 + BSP_LED_4, +#endif +#if CONFIG_BSP_LEDS_NUM > 4 + BSP_LED_5, +#endif + BSP_LED_NUM +} bsp_led_t; + +/* Default LED effects */ +enum { + BSP_LED_ON, + BSP_LED_OFF, + BSP_LED_BLINK_FAST, + BSP_LED_BLINK_SLOW, + BSP_LED_BREATHE_FAST, + BSP_LED_BREATHE_SLOW, + BSP_LED_MAX, +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + * + * I2C interface + * + **************************************************************************************************/ +#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); + +/************************************************************************************************** + * + * 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 + +#if SOC_SDMMC_HOST_SUPPORTED +extern sdmmc_card_t *bsp_sdcard; +#endif + +/** + * @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); + +/************************************************************************************************** + * + * Button + * + **************************************************************************************************/ + +/** + * @brief Initialize all buttons + * + * Returned button handlers must be used with espressif/button component API + * + * @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); + +/************************************************************************************************** + * + * LEDs + * + **************************************************************************************************/ + +/** + * @brief Initialize all LEDs + * + * @param[out] led_array Output LED array + * @param[out] led_cnt Number of LED handlers saved to led_array, can be NULL + * @param[in] led_array_size Size of output LED array. Must be at least BSP_LED_NUM + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t bsp_led_indicator_create(led_indicator_handle_t led_array[], int *led_cnt, int led_array_size); + +/** + * @brief Turn LED on/off + * + * @param handle led handle + * @param on Switch LED on/off + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t bsp_led_set(led_indicator_handle_t handle, const bool on); + +/** + * @brief Set LED temperature + * + * @param handle led handle + * @param temperature Color temperature of LED + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t bsp_led_set_temperature(led_indicator_handle_t handle, const uint16_t temperature); + +#ifdef __cplusplus +} +#endif diff --git a/bsp/esp_bsp_devkit/priv_include/bsp_err_check.h b/bsp/esp_bsp_devkit/priv_include/bsp_err_check.h new file mode 100644 index 00000000..cf2f36eb --- /dev/null +++ b/bsp/esp_bsp_devkit/priv_include/bsp_err_check.h @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#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 diff --git a/bsp/esp_bsp_devkit/src/esp_bsp_devkit.c b/bsp/esp_bsp_devkit/src/esp_bsp_devkit.c new file mode 100644 index 00000000..6c8e14be --- /dev/null +++ b/bsp/esp_bsp_devkit/src/esp_bsp_devkit.c @@ -0,0 +1,441 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "driver/gpio.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_spiffs.h" +#include "esp_vfs_fat.h" + +#include "bsp/esp_bsp_devkit.h" +#include "bsp_err_check.h" + +static const char *TAG = "BSP-devkit"; + +sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler +static bool i2c_initialized = false; +extern blink_step_t const *bsp_led_blink_defaults_lists[]; + +static const button_config_t bsp_button_config[] = { +#if CONFIG_BSP_BUTTONS_NUM > 0 +#if CONFIG_BSP_BUTTON_1_TYPE_GPIO + { + .type = BUTTON_TYPE_GPIO, + .gpio_button_config.gpio_num = BSP_BUTTON_1_IO, + .gpio_button_config.active_level = CONFIG_BSP_BUTTON_1_LEVEL, + }, +#elif CONFIG_BSP_BUTTON_1_TYPE_ADC + { + .type = BUTTON_TYPE_ADC, + .adc_button_config.adc_channel = CONFIG_BSP_BUTTON_1_ADC_CHANNEL, + .adc_button_config.button_index = BSP_BUTTON_1, + .adc_button_config.min = (CONFIG_BSP_BUTTON_1_ADC_VALUE - 100), + .adc_button_config.max = (CONFIG_BSP_BUTTON_1_ADC_VALUE + 100) + }, +#endif // CONFIG_BSP_BUTTON_1_TYPE_x +#endif // CONFIG_BSP_BUTTONS_NUM >= 0 + +#if CONFIG_BSP_BUTTONS_NUM > 1 +#if CONFIG_BSP_BUTTON_2_TYPE_GPIO + { + .type = BUTTON_TYPE_GPIO, + .gpio_button_config.gpio_num = BSP_BUTTON_2_IO, + .gpio_button_config.active_level = CONFIG_BSP_BUTTON_2_LEVEL, + }, + +#elif CONFIG_BSP_BUTTON_2_TYPE_ADC + { + .type = BUTTON_TYPE_ADC, + .adc_button_config.adc_channel = CONFIG_BSP_BUTTON_2_ADC_CHANNEL, + .adc_button_config.button_index = BSP_BUTTON_2, + .adc_button_config.min = (CONFIG_BSP_BUTTON_2_ADC_VALUE - 100), + .adc_button_config.max = (CONFIG_BSP_BUTTON_2_ADC_VALUE + 100) + }, +#endif // CONFIG_BSP_BUTTON_2_TYPE_x +#endif // CONFIG_BSP_BUTTONS_NUM >= 1 + +#if CONFIG_BSP_BUTTONS_NUM > 2 +#if CONFIG_BSP_BUTTON_3_TYPE_GPIO + { + .type = BUTTON_TYPE_GPIO, + .gpio_button_config.gpio_num = BSP_BUTTON_3_IO, + .gpio_button_config.active_level = CONFIG_BSP_BUTTON_3_LEVEL, + }, + +#elif CONFIG_BSP_BUTTON_3_TYPE_ADC + { + .type = BUTTON_TYPE_ADC, + .adc_button_config.adc_channel = CONFIG_BSP_BUTTON_3_ADC_CHANNEL, + .adc_button_config.button_index = BSP_BUTTON_3, + .adc_button_config.min = (CONFIG_BSP_BUTTON_3_ADC_VALUE - 100), + .adc_button_config.max = (CONFIG_BSP_BUTTON_3_ADC_VALUE + 100) + }, +#endif // CONFIG_BSP_BUTTON_3_TYPE_x +#endif // CONFIG_BSP_BUTTONS_NUM >= 2 + +#if CONFIG_BSP_BUTTONS_NUM > 3 +#if CONFIG_BSP_BUTTON_4_TYPE_GPIO + { + .type = BUTTON_TYPE_GPIO, + .gpio_button_config.gpio_num = BSP_BUTTON_4_IO, + .gpio_button_config.active_level = CONFIG_BSP_BUTTON_4_LEVEL, + }, + +#elif CONFIG_BSP_BUTTON_4_TYPE_ADC + { + .type = BUTTON_TYPE_ADC, + .adc_button_config.adc_channel = CONFIG_BSP_BUTTON_4_ADC_CHANNEL, + .adc_button_config.button_index = BSP_BUTTON_4, + .adc_button_config.min = (CONFIG_BSP_BUTTON_4_ADC_VALUE - 100), + .adc_button_config.max = (CONFIG_BSP_BUTTON_4_ADC_VALUE + 100) + }, +#endif // CONFIG_BSP_BUTTON_4_TYPE_x +#endif // CONFIG_BSP_BUTTONS_NUM >= 3 + +#if CONFIG_BSP_BUTTONS_NUM > 4 +#if CONFIG_BSP_BUTTON_5_TYPE_GPIO + { + .type = BUTTON_TYPE_GPIO, + .gpio_button_config.gpio_num = BSP_BUTTON_5_IO, + .gpio_button_config.active_level = CONFIG_BSP_BUTTON_5_LEVEL, + }, + +#elif CONFIG_BSP_BUTTON_5_TYPE_ADC + { + .type = BUTTON_TYPE_ADC, + .adc_button_config.adc_channel = CONFIG_BSP_BUTTON_5_ADC_CHANNEL, + .adc_button_config.button_index = BSP_BUTTON_5, + .adc_button_config.min = (CONFIG_BSP_BUTTON_5_ADC_VALUE - 100), + .adc_button_config.max = (CONFIG_BSP_BUTTON_5_ADC_VALUE + 100) + } +#endif // CONFIG_BSP_BUTTON_5_TYPE_x +#endif // CONFIG_BSP_BUTTONS_NUM >= 4 +}; + +#if CONFIG_BSP_LED_TYPE_GPIO +static led_indicator_gpio_config_t bsp_leds_gpio_config[] = { + { +#if CONFIG_BSP_LED_1_LEVEL && CONFIG_BSP_LED_1_GPIO + .is_active_level_high = CONFIG_BSP_LED_1_LEVEL, + .gpio_num = CONFIG_BSP_LED_1_GPIO, +#endif + }, + { +#if CONFIG_BSP_LED_2_LEVEL && CONFIG_BSP_LED_2_GPIO + .is_active_level_high = CONFIG_BSP_LED_2_LEVEL, + .gpio_num = CONFIG_BSP_LED_2_GPIO, +#endif + }, + { +#if CONFIG_BSP_LED_3_LEVEL && CONFIG_BSP_LED_3_GPIO + .is_active_level_high = CONFIG_BSP_LED_3_LEVEL, + .gpio_num = CONFIG_BSP_LED_3_GPIO, +#endif + }, + { +#if CONFIG_BSP_LED_4_LEVEL && CONFIG_BSP_LED_4_GPIO + .is_active_level_high = CONFIG_BSP_LED_4_LEVEL, + .gpio_num = CONFIG_BSP_LED_4_GPIO, +#endif + }, + { +#if CONFIG_BSP_LED_5_LEVEL && CONFIG_BSP_LED_5_GPIO + .is_active_level_high = CONFIG_BSP_LED_5_LEVEL, + .gpio_num = CONFIG_BSP_LED_5_GPIO, +#endif + } +}; +#endif // CONFIG_BSP_LED_TYPE_GPIO + +#if CONFIG_BSP_LED_TYPE_RGB && CONFIG_BSP_LEDS_NUM > 0 +static const led_strip_config_t bsp_leds_rgb_strip_config = { + .strip_gpio_num = CONFIG_BSP_LED_RGB_GPIO, // The GPIO that connected to the LED strip's data line + .max_leds = BSP_LED_NUM, // The number of LEDs in the strip, + .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip + .led_model = LED_MODEL_WS2812, // LED strip model + .flags.invert_out = false, // whether to invert the output signal +}; + +#if CONFIG_BSP_LED_RGB_BACKEND_RMT +static const led_strip_rmt_config_t bsp_leds_rgb_rmt_config = { +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) + .rmt_channel = 0, +#else + .clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption + .resolution_hz = 10 * 1000 * 1000, // RMT counter clock frequency = 10MHz + .flags.with_dma = false, // DMA feature is available on ESP target like ESP32-S3 +#endif +}; +#elif CONFIG_BSP_LED_RGB_BACKEND_SPI +static led_strip_spi_config_t bsp_leds_rgb_spi_config = { + .spi_bus = SPI2_HOST, + .flags.with_dma = true, +}; +#else +#error "unsupported LED strip backend" +#endif + +static led_indicator_strips_config_t bsp_leds_rgb_config = { + .led_strip_cfg = bsp_leds_rgb_strip_config, +#if CONFIG_BSP_LED_RGB_BACKEND_RMT + .led_strip_driver = LED_STRIP_RMT, + .led_strip_rmt_cfg = bsp_leds_rgb_rmt_config, +#elif CONFIG_BSP_LED_RGB_BACKEND_SPI + .led_strip_driver = LED_STRIP_SPI, + .led_strip_spi_cfg = bsp_leds_rgb_spi_config, +#endif +}; + +#elif CONFIG_BSP_LED_TYPE_RGB_CLASSIC && CONFIG_BSP_LEDS_NUM > 0 // CONFIG_BSP_LED_TYPE_RGB_CLASSIC + +static led_indicator_rgb_config_t bsp_leds_rgb_config = { + .is_active_level_high = CONFIG_BSP_LED_RGB_CLASSIC_LEVEL, + .timer_num = LEDC_TIMER_0, + .red_gpio_num = CONFIG_BSP_LED_RGB_RED_GPIO, + .green_gpio_num = CONFIG_BSP_LED_RGB_GREEN_GPIO, + .blue_gpio_num = CONFIG_BSP_LED_RGB_BLUE_GPIO, + .red_channel = LEDC_CHANNEL_0, + .green_channel = LEDC_CHANNEL_1, + .blue_channel = LEDC_CHANNEL_2, +}; + +#endif // CONFIG_BSP_LED_TYPE_RGB + +static const led_indicator_config_t bsp_leds_config[BSP_LED_NUM] = { +#if CONFIG_BSP_LED_TYPE_RGB + { + .mode = LED_STRIPS_MODE, + .led_indicator_strips_config = &bsp_leds_rgb_config, + .blink_lists = bsp_led_blink_defaults_lists, + .blink_list_num = BSP_LED_MAX, + }, +#elif CONFIG_BSP_LED_TYPE_RGB_CLASSIC + { + .mode = LED_RGB_MODE, + .led_indicator_rgb_config = &bsp_leds_rgb_config, + .blink_lists = bsp_led_blink_defaults_lists, + .blink_list_num = BSP_LED_MAX, + }, +#elif CONFIG_BSP_LED_TYPE_GPIO + +#if CONFIG_BSP_LEDS_NUM > 0 + { + .mode = LED_GPIO_MODE, + .led_indicator_gpio_config = &bsp_leds_gpio_config[0], + .blink_lists = bsp_led_blink_defaults_lists, + .blink_list_num = BSP_LED_MAX, + }, +#endif // CONFIG_BSP_LEDS_NUM > 0 +#if CONFIG_BSP_LEDS_NUM > 1 + { + .mode = LED_GPIO_MODE, + .led_indicator_gpio_config = &bsp_leds_gpio_config[1], + .blink_lists = bsp_led_blink_defaults_lists, + .blink_list_num = BSP_LED_MAX, + }, +#endif // CONFIG_BSP_LEDS_NUM > 1 +#if CONFIG_BSP_LEDS_NUM > 2 + { + .mode = LED_GPIO_MODE, + .led_indicator_gpio_config = &bsp_leds_gpio_config[2], + .blink_lists = bsp_led_blink_defaults_lists, + .blink_list_num = BSP_LED_MAX, + }, +#endif // CONFIG_BSP_LEDS_NUM > 2 +#if CONFIG_BSP_LEDS_NUM > 3 + { + .mode = LED_GPIO_MODE, + .led_indicator_gpio_config = &bsp_leds_gpio_config[3], + .blink_lists = bsp_led_blink_defaults_lists, + .blink_list_num = BSP_LED_MAX, + }, +#endif // CONFIG_BSP_LEDS_NUM > 3 +#if CONFIG_BSP_LEDS_NUM > 4 + { + .mode = LED_GPIO_MODE, + .led_indicator_gpio_config = &bsp_leds_gpio_config[4], + .blink_lists = bsp_led_blink_defaults_lists, + .blink_list_num = BSP_LED_MAX, + }, +#endif // CONFIG_BSP_LEDS_NUM > 4 +#endif // CONFIG_BSP_LED_TYPE_RGB/CONFIG_BSP_LED_TYPE_GPIO +}; + +esp_err_t bsp_i2c_init(void) +{ + /* I2C was initialized before */ + if (i2c_initialized) { + return ESP_OK; + } + + const i2c_config_t i2c_conf = { + .mode = I2C_MODE_MASTER, + .sda_io_num = BSP_I2C_SDA, + .sda_pullup_en = GPIO_PULLUP_DISABLE, + .scl_io_num = BSP_I2C_SCL, + .scl_pullup_en = GPIO_PULLUP_DISABLE, + .master.clk_speed = CONFIG_BSP_I2C_CLK_SPEED_HZ + }; + BSP_ERROR_CHECK_RETURN_ERR(i2c_param_config(BSP_I2C_NUM, &i2c_conf)); + BSP_ERROR_CHECK_RETURN_ERR(i2c_driver_install(BSP_I2C_NUM, i2c_conf.mode, 0, 0, 0)); + + i2c_initialized = true; + + return ESP_OK; +} + +esp_err_t bsp_i2c_deinit(void) +{ + BSP_ERROR_CHECK_RETURN_ERR(i2c_driver_delete(BSP_I2C_NUM)); + i2c_initialized = false; + return ESP_OK; +} + +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); +} + +esp_err_t bsp_sdcard_mount(void) +{ +#if SOC_SDMMC_HOST_SUPPORTED + 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 = CONFIG_BSP_SD_MAX_FILES, + .allocation_unit_size = 16 * 1024 + }; + + const sdmmc_host_t host = SDMMC_HOST_DEFAULT(); + const sdmmc_slot_config_t slot_config = { +#if SOC_SDMMC_USE_GPIO_MATRIX + .clk = BSP_SD_CLK, + .cmd = BSP_SD_CMD, + .d0 = BSP_SD_D0, + .d1 = BSP_SD_D1, + .d2 = BSP_SD_D2, + .d3 = BSP_SD_D3, + .d4 = GPIO_NUM_NC, + .d5 = GPIO_NUM_NC, + .d6 = GPIO_NUM_NC, + .d7 = GPIO_NUM_NC, +#endif + .cd = SDMMC_SLOT_NO_CD, + .wp = SDMMC_SLOT_NO_WP, + .width = 1, + .flags = 0, + }; + + return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, &host, &slot_config, &mount_config, &bsp_sdcard); +#else + return ESP_OK; +#endif // SOC_SDMMC_HOST_SUPPORTED +} + +esp_err_t bsp_sdcard_unmount(void) +{ +#if SOC_SDMMC_HOST_SUPPORTED + return esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); +#else + return ESP_OK; +#endif // SOC_SDMMC_HOST_SUPPORTED +} + +esp_err_t bsp_iot_button_create(button_handle_t btn_array[], int *btn_cnt, int btn_array_size) +{ + esp_err_t ret = ESP_OK; + if ((btn_array_size < BSP_BUTTON_NUM) || + (btn_array == NULL)) { + return ESP_ERR_INVALID_ARG; + } + + if (btn_cnt) { + *btn_cnt = 0; + } + for (int i = 0; i < BSP_BUTTON_NUM; i++) { + btn_array[i] = iot_button_create(&bsp_button_config[i]); + if (btn_array[i] == NULL) { + ret = ESP_FAIL; + break; + } + if (btn_cnt) { + (*btn_cnt)++; + } + } + return ret; +} + +esp_err_t bsp_led_indicator_create(led_indicator_handle_t led_array[], int *led_cnt, int led_array_size) +{ + esp_err_t ret = ESP_OK; + if ((led_array_size < BSP_LED_NUM) || + (led_array == NULL)) { + return ESP_ERR_INVALID_ARG; + } + + if (led_cnt) { + *led_cnt = 0; + } + for (int i = 0; i < BSP_LED_NUM; i++) { + led_array[i] = led_indicator_create(&bsp_leds_config[i]); + if (led_array[i] == NULL) { + ret = ESP_FAIL; + break; + } + if (led_cnt) { + (*led_cnt)++; + } + } + return ret; +} + +esp_err_t bsp_led_set(led_indicator_handle_t handle, const bool on) +{ + if (on) { + led_indicator_start(handle, BSP_LED_ON); + } else { + led_indicator_start(handle, BSP_LED_OFF); + } + + return ESP_OK; +} + +esp_err_t bsp_led_set_temperature(led_indicator_handle_t handle, const uint16_t temperature) +{ + return led_indicator_set_color_temperature(handle, temperature); +} diff --git a/bsp/esp_bsp_devkit/src/led_blink_defaults.c b/bsp/esp_bsp_devkit/src/led_blink_defaults.c new file mode 100644 index 00000000..7f25d125 --- /dev/null +++ b/bsp/esp_bsp_devkit/src/led_blink_defaults.c @@ -0,0 +1,83 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "led_indicator.h" +#include "bsp/esp-bsp.h" + +/*********************************** Config Blink List ***********************************/ +/** + * @brief LED on + * + */ +static const blink_step_t bsp_led_on[] = { + {LED_BLINK_HOLD, LED_STATE_ON, 0}, + {LED_BLINK_STOP, 0, 0}, +}; + +/** + * @brief LED off + * + */ +static const blink_step_t bsp_led_off[] = { + {LED_BLINK_HOLD, LED_STATE_OFF, 0}, + {LED_BLINK_STOP, 0, 0}, +}; + +/** + * @brief LED blink fast + * + */ +static const blink_step_t bsp_led_blink_fast[] = { + {LED_BLINK_HOLD, LED_STATE_ON, 500}, + {LED_BLINK_HOLD, LED_STATE_OFF, 500}, + {LED_BLINK_LOOP, 0, 0}, +}; + +/** + * @brief LED blink slow + * + */ +static const blink_step_t bsp_led_blink_slow[] = { + {LED_BLINK_HOLD, LED_STATE_ON, 1000}, + {LED_BLINK_HOLD, LED_STATE_OFF, 1000}, + {LED_BLINK_LOOP, 0, 0}, +}; + +/** + * @brief LED breathe fast + * + */ +static const blink_step_t bsp_led_breathe_fast[] = { + {LED_BLINK_BREATHE, LED_STATE_ON, 500}, + {LED_BLINK_HOLD, LED_STATE_ON, 500}, + {LED_BLINK_BREATHE, LED_STATE_OFF, 500}, + {LED_BLINK_HOLD, LED_STATE_OFF, 500}, + {LED_BLINK_LOOP, 0, 0}, +}; + +/** + * @brief LED breathe slow + * + */ +static const blink_step_t bsp_led_breathe_slow[] = { + {LED_BLINK_BREATHE, LED_STATE_OFF, 2000}, + {LED_BLINK_BREATHE, LED_STATE_ON, 2000}, + {LED_BLINK_LOOP, 0, 0}, +}; + +/** + * @brief LED blink lists + * + */ +blink_step_t const *bsp_led_blink_defaults_lists[] = { + [BSP_LED_ON] = bsp_led_on, + [BSP_LED_OFF] = bsp_led_off, + [BSP_LED_BLINK_FAST] = bsp_led_blink_fast, + [BSP_LED_BLINK_SLOW] = bsp_led_blink_slow, + [BSP_LED_BREATHE_FAST] = bsp_led_breathe_fast, + [BSP_LED_BREATHE_SLOW] = bsp_led_breathe_slow, + [BSP_LED_MAX] = NULL, +}; diff --git a/examples/bsp_ext.py b/examples/bsp_ext.py index c135cea2..78d2b52f 100644 --- a/examples/bsp_ext.py +++ b/examples/bsp_ext.py @@ -56,6 +56,7 @@ def set_bsp_callback(action: str, ctx: Context, args: PropertyDict, **kwargs: st 'esp-box-3', 'esp32_c3_lcdkit', 'esp_bsp_generic', + 'esp_bsp_devkit', 'esp32_s3_korvo_1', 'esp32_p4_function_ev_board', 'm5stack_core_s3',