From 660c77e2c393f0096532be580e66b104ef9f3eae Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 19 Apr 2023 17:51:06 +0200 Subject: [PATCH 1/4] nanocoap: implement extended tokens (RFC 8974) --- sys/include/net/nanocoap.h | 58 ++++++++++++++++++- sys/net/application_layer/nanocoap/nanocoap.c | 35 +++++++++-- 2 files changed, 86 insertions(+), 7 deletions(-) diff --git a/sys/include/net/nanocoap.h b/sys/include/net/nanocoap.h index 73f51fe8ffbe..6682b7bf6cd8 100644 --- a/sys/include/net/nanocoap.h +++ b/sys/include/net/nanocoap.h @@ -91,6 +91,7 @@ #include "byteorder.h" #include "iolist.h" #include "net/coap.h" +#include "modules.h" #else #include "coap.h" #include @@ -494,15 +495,37 @@ static inline unsigned coap_get_id(const coap_pkt_t *pkt) /** * @brief Get a message's token length [in byte] * + * If the `nanocoap_token_ext` module is enabled, this will include + * the extended token length. + * * @param[in] pkt CoAP packet * * @returns length of token in the given message (0-8 byte) */ static inline unsigned coap_get_token_len(const coap_pkt_t *pkt) { - return (pkt->hdr->ver_t_tkl & 0xf); + uint8_t tkl = pkt->hdr->ver_t_tkl & 0xf; + + if (!IS_USED(MODULE_NANOCOAP_TOKEN_EXT)) { + return tkl; + } + + void *ext = pkt->hdr + 1; + switch (tkl) { + case 13: + return tkl + *(uint8_t *)ext; + case 14: + return tkl + 255 + byteorder_bebuftohs(ext); + case 15: + assert(0); + /* fall-through */ + default: + return tkl; + } } +static inline uint8_t *coap_hdr_data_ptr(const coap_hdr_t *hdr); + /** * @brief Get pointer to a message's token * @@ -512,7 +535,7 @@ static inline unsigned coap_get_token_len(const coap_pkt_t *pkt) */ static inline void *coap_get_token(const coap_pkt_t *pkt) { - return (uint8_t*)pkt->hdr + sizeof(coap_hdr_t); + return coap_hdr_data_ptr(pkt->hdr); } /** @@ -568,6 +591,35 @@ static inline unsigned coap_get_ver(const coap_pkt_t *pkt) return (pkt->hdr->ver_t_tkl & 0x60) >> 6; } +/** + * @brief Get the size of the extended Token length field + * (RFC 8974) + * + * @note This requires the `nanocoap_token_ext` module to be enabled + * + * @param[in] hdr CoAP header + * + * @returns number of bytes used for extended token length + */ +static inline uint8_t coap_hdr_tkl_ext_len(const coap_hdr_t *hdr) +{ + if (!IS_USED(MODULE_NANOCOAP_TOKEN_EXT)) { + return 0; + } + + switch (hdr->ver_t_tkl & 0xf) { + case 13: + return 1; + case 14: + return 2; + case 15: + assert(0); + /* fall-through */ + default: + return 0; + } +} + /** * @brief Get the start of data after the header * @@ -577,7 +629,7 @@ static inline unsigned coap_get_ver(const coap_pkt_t *pkt) */ static inline uint8_t *coap_hdr_data_ptr(const coap_hdr_t *hdr) { - return ((uint8_t *)hdr) + sizeof(coap_hdr_t); + return ((uint8_t *)hdr) + sizeof(coap_hdr_t) + coap_hdr_tkl_ext_len(hdr); } /** diff --git a/sys/net/application_layer/nanocoap/nanocoap.c b/sys/net/application_layer/nanocoap/nanocoap.c index f768ffd8d49c..d66be640bdc7 100644 --- a/sys/net/application_layer/nanocoap/nanocoap.c +++ b/sys/net/application_layer/nanocoap/nanocoap.c @@ -80,7 +80,13 @@ int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len) return -EBADMSG; } - if (coap_get_token_len(pkt) > COAP_TOKEN_LENGTH_MAX) { + if (IS_USED(MODULE_NANOCOAP_TOKEN_EXT)) { + if ((pkt->hdr->ver_t_tkl & 0xf) == 15) { + DEBUG("nanocoap: token length is reserved value 15," + "invalid for extended token length field.\n"); + return -EBADMSG; + } + } else if (coap_get_token_len(pkt) > COAP_TOKEN_LENGTH_MAX) { DEBUG("nanocoap: token length invalid\n"); return -EBADMSG; } @@ -555,18 +561,39 @@ ssize_t coap_build_reply(coap_pkt_t *pkt, unsigned code, ssize_t coap_build_hdr(coap_hdr_t *hdr, unsigned type, uint8_t *token, size_t token_len, unsigned code, uint16_t id) { assert(!(type & ~0x3)); - assert(!(token_len & ~0x1f)); + + uint16_t tkl_ext; + uint8_t tkl_ext_len, tkl; + + if (token_len > 268 && IS_USED(MODULE_NANOCOAP_TOKEN_EXT)) { + tkl_ext_len = 2; + tkl_ext = htons(token_len - 269); /* 269 = 255 + 14 */ + tkl = 14; + } + else if (token_len > 12 && IS_USED(MODULE_NANOCOAP_TOKEN_EXT)) { + tkl_ext_len = 1; + tkl_ext = token_len - 13; + tkl = 13; + } + else { + tkl = token_len; + tkl_ext_len = 0; + } memset(hdr, 0, sizeof(coap_hdr_t)); - hdr->ver_t_tkl = (COAP_V1 << 6) | (type << 4) | token_len; + hdr->ver_t_tkl = (COAP_V1 << 6) | (type << 4) | tkl; hdr->code = code; hdr->id = htons(id); + if (tkl_ext_len) { + memcpy(hdr + 1, &tkl_ext, tkl_ext_len); + } + if (token_len) { memcpy(coap_hdr_data_ptr(hdr), token, token_len); } - return sizeof(coap_hdr_t) + token_len; + return sizeof(coap_hdr_t) + token_len + tkl_ext_len; } void coap_pkt_init(coap_pkt_t *pkt, uint8_t *buf, size_t len, size_t header_len) From c01c470e8fc5313b45abbe70570cc2667f4f6a63 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 19 Apr 2023 17:51:29 +0200 Subject: [PATCH 2/4] tests/unittests: nanocoap: add test for extended token --- .../unittests/tests-nanocoap/Makefile.include | 1 + .../unittests/tests-nanocoap/tests-nanocoap.c | 65 +++++++++++++++++-- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/tests/unittests/tests-nanocoap/Makefile.include b/tests/unittests/tests-nanocoap/Makefile.include index cd6b8172a754..2b94b4ef2eff 100644 --- a/tests/unittests/tests-nanocoap/Makefile.include +++ b/tests/unittests/tests-nanocoap/Makefile.include @@ -1 +1,2 @@ USEMODULE += nanocoap +USEMODULE += nanocoap_token_ext diff --git a/tests/unittests/tests-nanocoap/tests-nanocoap.c b/tests/unittests/tests-nanocoap/tests-nanocoap.c index b3c2888eda38..75f5cb14377e 100644 --- a/tests/unittests/tests-nanocoap/tests-nanocoap.c +++ b/tests/unittests/tests-nanocoap/tests-nanocoap.c @@ -1035,13 +1035,13 @@ static void test_nanocoap__add_get_proxy_uri(void) */ static void test_nanocoap__token_length_over_limit(void) { - /* RFC7252 states that TKL must be within 0-8: - * "Lengths 9-15 are reserved, MUST NOT be sent, - * and MUST be processed as a message format error." + /* RFC8974 states that TKL must not be 15: + * 15: Reserved. This value MUST NOT be sent and MUST be processed + * as a message-format error. */ uint16_t msgid = 0xABCD; uint8_t buf_invalid[] = { - 0x49, 0x01, 0xAB, 0xCD, + 0x4F, 0x01, 0xAB, 0xCD, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }; uint8_t buf_valid[] = { @@ -1059,11 +1059,64 @@ static void test_nanocoap__token_length_over_limit(void) TEST_ASSERT_EQUAL_INT(8, coap_get_token_len(&pkt)); TEST_ASSERT_EQUAL_INT(0, pkt.payload_len); - /* Invalid packet (TKL = 9) */ + /* Invalid packet (TKL = 15) */ res = coap_parse(&pkt, buf_invalid, sizeof(buf_invalid)); TEST_ASSERT_EQUAL_INT(-EBADMSG, res); } +/* + * Verifies that coap_parse() recognizes 8 bit extended token length + */ +static void test_nanocoap__token_length_ext_16(void) +{ + const char *token = "0123456789ABCDEF"; + + uint8_t buf[32]; + coap_hdr_t *hdr = (void *)buf; + + TEST_ASSERT_EQUAL_INT(21, coap_build_hdr(hdr, COAP_TYPE_CON, + (void *)token, strlen(token), + COAP_CODE_204, 23)); + coap_pkt_t pkt; + int res = coap_parse(&pkt, buf, 21); + + TEST_ASSERT_EQUAL_INT(0, res); + TEST_ASSERT_EQUAL_INT(204, coap_get_code(&pkt)); + TEST_ASSERT_EQUAL_INT(23, coap_get_id(&pkt)); + TEST_ASSERT_EQUAL_INT(strlen(token), coap_get_token_len(&pkt)); + TEST_ASSERT_EQUAL_INT(0, memcmp(coap_get_token(&pkt), token, strlen(token))); + TEST_ASSERT_EQUAL_INT(0, pkt.payload_len); + TEST_ASSERT_EQUAL_INT(13, hdr->ver_t_tkl & 0xf); +} + +/* + * Verifies that coap_parse() recognizes 16 bit extended token length + */ +static void test_nanocoap__token_length_ext_269(void) +{ + const char *token = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr," + "sed diam nonumy eirmod tempor invidunt ut labore et dolore" + "magna aliquyam erat, sed diam voluptua. At vero eos et accusam" + "et justo duo dolores et ea rebum. Stet clita kasd gubergren," + "no sea takimata sanctus est Lore."; + uint8_t buf[280]; + coap_hdr_t *hdr = (void *)buf; + + TEST_ASSERT_EQUAL_INT(275, coap_build_hdr(hdr, COAP_TYPE_CON, + (void *)token, strlen(token), + COAP_CODE_204, 23)); + coap_pkt_t pkt; + int res = coap_parse(&pkt, buf, 275); + + TEST_ASSERT_EQUAL_INT(0, res); + TEST_ASSERT_EQUAL_INT(204, coap_get_code(&pkt)); + TEST_ASSERT_EQUAL_INT(23, coap_get_id(&pkt)); + TEST_ASSERT_EQUAL_INT(strlen(token), coap_get_token_len(&pkt)); + TEST_ASSERT_EQUAL_INT(0, memcmp(coap_get_token(&pkt), token, strlen(token))); + TEST_ASSERT_EQUAL_INT(0, pkt.payload_len); + TEST_ASSERT_EQUAL_INT(14, hdr->ver_t_tkl & 0xf); +} + Test *tests_nanocoap_tests(void) { EMB_UNIT_TESTFIXTURES(fixtures) { @@ -1100,6 +1153,8 @@ Test *tests_nanocoap_tests(void) new_TestFixture(test_nanocoap__add_path_unterminated_string), new_TestFixture(test_nanocoap__add_get_proxy_uri), new_TestFixture(test_nanocoap__token_length_over_limit), + new_TestFixture(test_nanocoap__token_length_ext_16), + new_TestFixture(test_nanocoap__token_length_ext_269), }; EMB_UNIT_TESTCALLER(nanocoap_tests, NULL, NULL, fixtures); From 115a3ea100e4d04966f2f1c65f1c93bc73a7f995 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Fri, 7 Jul 2023 08:16:35 +0200 Subject: [PATCH 3/4] drivers/st7735: support for ST7789 ST7735 driver can also be used for ST7789. st7789 is simply defined as pseudomodule that pulls in automatically module st7735. --- drivers/Makefile.dep | 4 ++++ drivers/include/st7735.h | 4 ++++ drivers/st7735/Kconfig | 10 ++++++++++ drivers/st7735/Makefile.include | 2 ++ drivers/st7735/st7735.c | 7 ++++++- 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index 9be99ff67e82..46b78b5cd747 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -204,6 +204,10 @@ ifneq (,$(filter stmpe811_%,$(USEMODULE))) USEMODULE += stmpe811 endif +ifneq (,$(filter st7789,$(USEMODULE))) + USEMODULE += st7735 +endif + ifneq (,$(filter sx126%,$(USEMODULE))) USEMODULE += sx126x endif diff --git a/drivers/include/st7735.h b/drivers/include/st7735.h index 8198c08ebf43..ccc0e10efa86 100644 --- a/drivers/include/st7735.h +++ b/drivers/include/st7735.h @@ -28,6 +28,10 @@ * when strictly necessary. This option will slow down the driver as it * certainly can't use DMA anymore, every short has to be converted before * transfer. + * + * @note The driver can also be used for the ST7789 which is compatible with + * the ST7735 but supports higher resolutions. Just enable the module + * `st7789` instead of `st7735` if your board uses the ST7789. */ diff --git a/drivers/st7735/Kconfig b/drivers/st7735/Kconfig index f914e59f19e7..40fa5643b727 100644 --- a/drivers/st7735/Kconfig +++ b/drivers/st7735/Kconfig @@ -22,6 +22,16 @@ config HAVE_ST7735 help Indicates that an ST7735 display is present. +config MODULE_ST7789 + bool "ST7789 display driver" + select MODULE_ST7735 + +config HAVE_ST7789 + bool + select MODULE_ST7789 if MODULE_DISP_DEV + help + Indicates that an ST7789 display is present. + menuconfig KCONFIG_USEMODULE_ST7735 bool "Configure ST7735 driver" depends on USEMODULE_ST7735 diff --git a/drivers/st7735/Makefile.include b/drivers/st7735/Makefile.include index 6bd23d7e46b2..4958157cd4d4 100644 --- a/drivers/st7735/Makefile.include +++ b/drivers/st7735/Makefile.include @@ -1,2 +1,4 @@ +PSEUDOMODULES += st7789 + USEMODULE_INCLUDES_st7735 := $(LAST_MAKEFILEDIR)/include USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_st7735) diff --git a/drivers/st7735/st7735.c b/drivers/st7735/st7735.c index c95e5588642e..2c7deef504da 100644 --- a/drivers/st7735/st7735.c +++ b/drivers/st7735/st7735.c @@ -66,7 +66,12 @@ static uint8_t _st7735_calc_vml(int16_t vcoml) static int _init(lcd_t *dev, const lcd_params_t *params) { - assert(params->lines <= 162); + if (IS_USED(MODULE_ST7789)) { + assert(params->lines <= 320); + } + else { + assert(params->lines <= 162); + } dev->params = params; uint8_t command_params[4] = { 0 }; From d68c82661f0a3838ec459cc91fa2bd9058af21d1 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Fri, 7 Jul 2023 15:34:35 +0200 Subject: [PATCH 4/4] boards: add support for ESP32-S3-USB-OTG --- boards/esp32s3-usb-otg/Kconfig | 38 ++++ boards/esp32s3-usb-otg/Makefile | 5 + boards/esp32s3-usb-otg/Makefile.dep | 32 +++ boards/esp32s3-usb-otg/Makefile.features | 17 ++ boards/esp32s3-usb-otg/Makefile.include | 5 + boards/esp32s3-usb-otg/board.c | 26 +++ boards/esp32s3-usb-otg/doc.txt | 185 +++++++++++++++++ boards/esp32s3-usb-otg/include/board.h | 199 +++++++++++++++++++ boards/esp32s3-usb-otg/include/gpio_params.h | 75 +++++++ boards/esp32s3-usb-otg/include/periph_conf.h | 132 ++++++++++++ 10 files changed, 714 insertions(+) create mode 100644 boards/esp32s3-usb-otg/Kconfig create mode 100644 boards/esp32s3-usb-otg/Makefile create mode 100644 boards/esp32s3-usb-otg/Makefile.dep create mode 100644 boards/esp32s3-usb-otg/Makefile.features create mode 100644 boards/esp32s3-usb-otg/Makefile.include create mode 100644 boards/esp32s3-usb-otg/board.c create mode 100644 boards/esp32s3-usb-otg/doc.txt create mode 100644 boards/esp32s3-usb-otg/include/board.h create mode 100644 boards/esp32s3-usb-otg/include/gpio_params.h create mode 100644 boards/esp32s3-usb-otg/include/periph_conf.h diff --git a/boards/esp32s3-usb-otg/Kconfig b/boards/esp32s3-usb-otg/Kconfig new file mode 100644 index 000000000000..79dee2c1f2a3 --- /dev/null +++ b/boards/esp32s3-usb-otg/Kconfig @@ -0,0 +1,38 @@ +# Copyright (c) 2020 HAW Hamburg +# 2022 Gunar Schorcht +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. + +config BOARD + default "esp32s3-usb-otg" if BOARD_ESP32S3_USB_OTG + +config BOARD_ESP32S3_USB_OTG + bool + default y + select BOARD_COMMON_ESP32S3 + select CPU_MODEL_ESP32S3_MINI_1X_N8 + select HAS_ESP_JTAG + select HAS_HIGHLEVEL_STDIO + select HAS_PERIPH_ADC + select HAS_PERIPH_PWM + select HAS_PERIPH_SPI + select HAS_PERIPH_UART + select HAS_PERIPH_USBDEV + select HAS_SDCARD_SPI + select HAS_TINYUSB_DEVICE + select HAVE_MTD_SDCARD_DEFAULT + select HAVE_ST7789 + select MODULE_FATFS_VFS if MODULE_VFS_DEFAULT + # Only this board has a requirement to use USB_BOARD_RESET with STDIO_USB_SERIAL_JTAG + select MODULE_USB_BOARD_RESET if MODULE_STDIO_USB_SERIAL_JTAG + select REQUIRES_USB_STDIO if MODULE_USBUS || MODULE_TINYUSB_DEVICE + +choice STDIO_IMPLEMENTATION + default MODULE_STDIO_CDC_ACM if MODULE_USBUS + default MODULE_STDIO_TINYUSB_CDC_ACM if MODULE_TINYUSB_DEVICE + default MODULE_STDIO_USB_SERIAL_JTAG +endchoice + +source "$(RIOTBOARD)/common/esp32s3/Kconfig" diff --git a/boards/esp32s3-usb-otg/Makefile b/boards/esp32s3-usb-otg/Makefile new file mode 100644 index 000000000000..a8b9d8fbed28 --- /dev/null +++ b/boards/esp32s3-usb-otg/Makefile @@ -0,0 +1,5 @@ +MODULE = board + +DIRS = $(RIOTBOARD)/common/esp32s3 + +include $(RIOTBASE)/Makefile.base diff --git a/boards/esp32s3-usb-otg/Makefile.dep b/boards/esp32s3-usb-otg/Makefile.dep new file mode 100644 index 000000000000..c9a81e518986 --- /dev/null +++ b/boards/esp32s3-usb-otg/Makefile.dep @@ -0,0 +1,32 @@ +ifeq (,$(filter stdio_% slipdev_stdio usbus usbus% tinyusb_device,$(USEMODULE))) + # Use stdio_usb_serial_jtag if no other stdio is requested explicitly + # and neither USBUS nor tinyusb_device are used + USEMODULE += stdio_usb_serial_jtag + # Even if only stdio_usb_serial_jtag is enabled, usb_board_reset is enabled + # since there should be a CDC ACM interface in any case. This is necessary, + # for example, to reset the board if stdio_cdc_acm or stdio_tinyusb_cdc_acm + # was previously used. + USEMODULE += usb_board_reset + include $(RIOTMAKE)/tools/usb_board_reset.mk +endif + +include $(RIOTBOARD)/common/esp32s3/Makefile.dep +include $(RIOTBOARD)/common/makefiles/stdio_cdc_acm.dep.mk + +# default to using fatfs on SD card +ifneq (,$(filter vfs_default,$(USEMODULE))) + USEMODULE += fatfs_vfs + USEMODULE += mtd +endif + +ifneq (,$(filter mtd,$(USEMODULE))) + USEMODULE += mtd_sdcard_default +endif + +ifneq (,$(filter disp_dev,$(USEMODULE))) + USEMODULE += st7789 +endif + +ifneq (,$(filter st7735,$(USEMODULE))) + USEMODULE += st7789 +endif diff --git a/boards/esp32s3-usb-otg/Makefile.features b/boards/esp32s3-usb-otg/Makefile.features new file mode 100644 index 000000000000..b43f63bb5058 --- /dev/null +++ b/boards/esp32s3-usb-otg/Makefile.features @@ -0,0 +1,17 @@ +CPU_MODEL = esp32s3_mini_1x_n8 + +# common board and CPU features +include $(RIOTBOARD)/common/esp32s3/Makefile.features + +# additional features provided by the board +FEATURES_PROVIDED += periph_adc +FEATURES_PROVIDED += periph_pwm +FEATURES_PROVIDED += periph_spi +FEATURES_PROVIDED += periph_uart +FEATURES_PROVIDED += periph_usbdev + +# unique features provided by the board +FEATURES_PROVIDED += esp_jtag +FEATURES_PROVIDED += highlevel_stdio +FEATURES_PROVIDED += sdcard_spi +FEATURES_PROVIDED += tinyusb_device diff --git a/boards/esp32s3-usb-otg/Makefile.include b/boards/esp32s3-usb-otg/Makefile.include new file mode 100644 index 000000000000..b804cf918761 --- /dev/null +++ b/boards/esp32s3-usb-otg/Makefile.include @@ -0,0 +1,5 @@ +PORT_LINUX ?= /dev/ttyACM0 + +OPENOCD_CONFIG ?= board/esp32s3-builtin.cfg + +include $(RIOTBOARD)/common/esp32s3/Makefile.include diff --git a/boards/esp32s3-usb-otg/board.c b/boards/esp32s3-usb-otg/board.c new file mode 100644 index 000000000000..c4331a7a5dcd --- /dev/null +++ b/boards/esp32s3-usb-otg/board.c @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2023 Gunar Schorcht + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_esp32s3_usb_otg + * @{ + * + * @file + * @brief Board specific initializations for ESP32-S3-USB-OTG boards + * + * @author Gunar Schorcht + */ + +#include "board.h" + +void board_init(void) +{ +#if MODULE_ST7735 + gpio_init(LCD_BACKLIGHT, GPIO_OUT); +#endif +} diff --git a/boards/esp32s3-usb-otg/doc.txt b/boards/esp32s3-usb-otg/doc.txt new file mode 100644 index 000000000000..4ae549cdcb73 --- /dev/null +++ b/boards/esp32s3-usb-otg/doc.txt @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2023 Gunar Schorcht + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup boards_esp32s3_usb_otg ESP32-S3-USB-OTG Board + * @ingroup boards_esp32s3 + * @brief Support for the ESP32-S3-USB-OTG board + * @author Gunar Schorcht + +\section esp32s3_usb_otg ESP32-S3-USB-OTG + +## Table of Contents {#esp32s3_usb_otg_toc} + +1. [Overview](#esp32s3_usb_otg_overview) +2. [Hardware](#esp32s3_usb_otg_hardware) + 1. [MCU](#esp32s3_usb_otg_mcu) + 2. [Board Configuration](#esp32s3_usb_otg_board_configuration) +3. [Flashing the Device](#esp32s3_usb_otg_flashing) +4. [Using STDIO](esp32s3_usb_otg_stdio) + +## Overview {#esp32s3_usb_otg_overview} + +The Espressif ESP32-S3-USB-OTG is a development board designed for the +development of applications that use the USB interface. For this purpose +it is equipped with two USB type A ports: + +- `USB_DEV` male port that is used to connect the board as a USB device to a host. +- `USB_HOST` female port that is used to connect other USB devices to the board. + +\image html "https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/_images/pic_board_top_lable.png" "Espressif ESP32-S3-USB-OTG" width=600px + +@note RIOT-OS does only support the `USB_DEV` port, that is the board can only + be used as USB device. + +The main features of the board are: + +| Feature | Support | +|:-------------------------------|:--------------:| +| ESP32-S3 SoC | yes (1 core) | +| 2.4 GHz WiFi 802.11b/g/n | yes | +| Bluetooth5, BLE | yes | +| 8 MByte Flash | yes | +| USB Type-A Host Interface | no | +| USB Type-A Device Interface | yes | +| SD Card Slot | yes (SPI mode) | +| LCD Color Display 240 x 240 | yes | + +## Hardware {#esp32s3_usb_otg_hardware} + +This section describes + +- the [MCU](#esp32s3_usb_otg_mcu), +- the default [board configuration](#esp32s3_usb_otg_board_configuration), + +[Back to table of contents](#esp32s3_usb_otg_toc) + +### MCU {#esp32s3_usb_otg_mcu} + +Most features of the board are provided by the ESP32-S3 SoC. For detailed +information about the ESP32-S3 SoC variant (family) and ESP32x SoCs, +see section \ref esp32_mcu_esp32 "ESP32 SoC Series". + +[Back to table of contents](#esp32s3_usb_otg_toc) + +### Board Configuration {#esp32s3_usb_otg_board_configuration} + +The Espressif ESP32-S3-USB-OTG is a development board that uses the +ESP32-S3-MINI-1 module. Most important features of the board are + +- Micro-SD Card interface +- 1.3" Color LCD display with ST7789 display controller +- USB-to-UART bridge +- `USB_DEV` Type-A male port +- `USB_HOST` Type-A female port + +
+Function | GPIOs | Remarks | Configuration +:-----------------|:-------|:------------|:---------------------------------- +BTN0 | GPIO0 | OK Button | | +BTN1 | GPIO14 | MENU Button | | +BTN2 | GPIO11 | DW- Button | | +BTN3 | GPIO10 | UP+ active | | +LED0 | GPIO15 | Green LED | | +LED1 | GPIO16 | Yellow LED | | +LCD_DC | GPIO4 | | | +LCD_EN | GPIO5 | | | +LCD_RST | GPIO8 | | | +LCD_BL | GPIO9 | LCD Backlight | | +ADC_LINE(0) | GPIO1 | USB_HOST Voltage | \ref esp32_adc_channels "ADC Channels" +ADC_LINE(1) | GPIO2 | Battery Voltage | \ref esp32_adc_channels "ADC Channels" +PWM_DEV(0):0 | GPIO15 | LED0 | \ref esp32_pwm_channels "PWM Channels" +PWM_DEV(0):1 | GPIO16 | LED1 | \ref esp32_pwm_channels "PWM Channels" +SPI_DEV(0):SCK | GPIO6 | LCD_SCLK | \ref esp32_spi_interfaces "SPI Interfaces" | +SPI_DEV(0):MOSI | GPIO7 | LCD_SDA | \ref esp32_spi_interfaces "SPI Interfaces" | +SPI_DEV(0):MISO | GPIO3 | no used | \ref esp32_spi_interfaces "SPI Interfaces" | +SPI_DEV(0):CS0 | GPIO5 | LCD_EN | \ref esp32_spi_interfaces "SPI Interfaces" | +SPI_DEV(1):SCK | GPIO36 | SD_CLK | \ref esp32_spi_interfaces "SPI Interfaces" | +SPI_DEV(1):MOSI | GPIO35 | SD_CMD | \ref esp32_spi_interfaces "SPI Interfaces" | +SPI_DEV(1):MISO | GPIO37 | SD_DATA0 | \ref esp32_spi_interfaces "SPI Interfaces" | +SPI_DEV(1):CS0 | GPIO34 | SD_DATA3 | \ref esp32_spi_interfaces "SPI Interfaces" | +UART_DEV(0):TxD | GPIO43 | USB-to-UART bridge | \ref esp32_uart_interfaces "UART interfaces" +UART_DEV(0):RxD | GPIO44 | USB-to-UART bridge | \ref esp32_uart_interfaces "UART interfaces" +
+\n + +For detailed information about the peripheral configurations of ESP32-S3 +boards, see section \ref esp32_peripherals "Common Peripherals". + +The corresponding board schematic can be found +[here](https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/_static/esp32-s3-usb-otg/schematics/SCH_ESP32-S3_USB_OTG.pdf) + +[Back to table of contents](#esp32s3_usb_otg_toc) + +## Flashing the Device {#esp32s3_usb_otg_flashing} + +There are two options to flash the board: + +1. USB Serial/JTAG interface using the `USB_DEV` port (default) +2. UART-to-UART bridge + +### Flashing the device using the USB Serial/JTAG interface (`USB_DEV` port) + +To flash the board via the USB Serial/JTAG interface just connect the board +with the `USB_DEV` port to your host computer and use the following command: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +BOARD=esp32s3_usb_otg make flash ... +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Usually the make system resets the board before flashing to enable the +USB Serial/JTAG controller and to reboot the ESP32-S3 in download mode. + +In some very special cases this reset does not work and the programmer cannot +connect to the card, so the flashing is aborted with a timeout: +``` +Serial port /dev/ttyACM0 +Connecting... +... +serial.serialutil.SerialTimeoutException: Write timeout +``` +This can happen either if RIOT is not yet installed or if the USB port was +previously used with the USB OTG controller, for example with USBUS or tinyUSB. +In this case, restart the board manually into download mode by pressing and +releasing the RESET button while holding down the BOOT button. +In download mode, the USB Serial/JTAG interface is always available. + +@note If the USB port was previously used with the USB OTG controller, an + automatic restart of the ESP32-S3 with the flashed application is not + possible. In this case the board must be reset manually using the RESET + button. In all other cases the ESP32-S3 automatically restarts with + the flashed application. + +### Flashing the device using USB-to-UART bridge + +Flashing RIOT using the USB-to-UART bridge is quite easy. The board has a +Micro-USB connector with reset/boot/flash logic. Just connect the board to +your host computer and type using the programming port: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +BOARD=esp32s3-usb-otg make flash ... PORT=/dev/ttyUSB0 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For detailed information about ESP32-S3 as well as configuring and compiling +RIOT for ESP32-S3 boards, see \ref esp32_riot. + +[Back to table of contents](#esp32s3_usb_otg_toc) + +## Using STDIO {#esp32s3_usb_otg_stdio} + +By default, the `USB_DEV` port and the USB Serial/JTAG interface are used for +the STDIO (module `stdio_usb_serial_jtag`). If the USB port is used by the +USBUS stack or the tinyUSB stack, implicitly the module `stdio_cdc_acm` or +`stdio_tinyusb_cdc_acm` is used for the STDIO via the USB CDC ACM interface. + +Alternatively, the USB-to-UART bridge and `UART_DEV(0)` could be used for the +STDIO. Simply add `stdio_uart` to the list of used modules for this purpose: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +BOARD=esp32s3-usb-otg USEMODULE=stdio_uart make flash ... +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + */ diff --git a/boards/esp32s3-usb-otg/include/board.h b/boards/esp32s3-usb-otg/include/board.h new file mode 100644 index 000000000000..de81aa75fcb6 --- /dev/null +++ b/boards/esp32s3-usb-otg/include/board.h @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2023 Gunar Schorcht + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_esp32s3_usb_otg + * @brief Board definitions for the ESP32-S3-USB-OTG boards + * @{ + * + * Any modifications required for specific applications + * can be overridden by \ref esp32_application_specific_configurations + * "application-specific board configuration". + * + * @file + * @author Gunar Schorcht + */ + +#ifndef BOARD_H +#define BOARD_H + +#include + +/** + * @name Button pin definitions + * @{ + */ + +/** + * @brief BOOT/OK button GPIO pin definition + * + * The BOOT button is connected to GPIO0 and is used as OK button during + * normal operation. The button is LOW active. + */ +#define BTN0_PIN GPIO0 + +/** + * @brief BOOT/OK button GPIO mode definition + */ +#define BTN0_MODE GPIO_IN_PU + +/** + * @brief Default interrupt flank definition for the BOOT/OK button GPIO + */ +#ifndef BTN0_INT_FLANK +#define BTN0_INT_FLANK GPIO_FALLING +#endif + +/** + * @brief Definition for compatibility with previous versions + */ +#define BUTTON0_PIN BTN0_PIN + +/** + * @brief MENU button GPIO pin definition + * + * The MENU button is connected to GPIO14. It is LOW active. + */ +#define BTN1_PIN GPIO14 + +/** + * @brief MENU button GPIO mode definition + */ +#define BTN1_MODE GPIO_IN_PU + +/** + * @brief Default interrupt flank definition for the MENU button GPIO + */ +#ifndef BTN1_INT_FLANK +#define BTN1_INT_FLANK GPIO_FALLING +#endif + +/** + * @brief Definition for compatibility with previous versions + */ +#define BUTTON1_PIN BTN1_PIN + +/** + * @brief DW- button GPIO pin definition + * + * The DW- button is connected to GPIO11. It is LOW active. + */ +#define BTN2_PIN GPIO11 + +/** + * @brief DW- button GPIO mode definition + */ +#define BTN2_MODE GPIO_IN_PU + +/** + * @brief Default interrupt flank definition for the DW- button GPIO + */ +#ifndef BTN2_INT_FLANK +#define BTN2_INT_FLANK GPIO_FALLING +#endif + +/** + * @brief Definition for compatibility with previous versions + */ +#define BUTTON2_PIN BTN2_PIN + +/** + * @brief UP+ button GPIO pin definition + * + * The MENU button is connected to GPIO10. It is LOW active. + */ +#define BTN3_PIN GPIO10 + +/** + * @brief UP+ button GPIO mode definition + */ +#define BTN3_MODE GPIO_IN_PU + +/** + * @brief Default interrupt flank definition for the UP+ button GPIO + */ +#ifndef BTN3_INT_FLANK +#define BTN3_INT_FLANK GPIO_FALLING +#endif + +/** + * @brief Definition for compatibility with previous versions + */ +#define BUTTON3_PIN BTN3_PIN + +/** @} */ + +/** + * @name LED (on-board) configuration + * + * ESP32-S3-USB-OTG boards have two LEDs on board. + * @{ + */ +#define LED0_PIN GPIO15 /**< Green LED */ +#define LED0_ACTIVE (1) /**< Green LED is high active */ + +#define LED1_PIN GPIO16 /**< Yellow LED */ +#define LED1_ACTIVE (1) /**< Yellow LED is high active */ +/** @} */ + +/** + * @name LCD configuration + * + * This configuration cannot be changed. + * @{ + */ +#if MODULE_ST7735 +#define LCD_DC GPIO4 /**< LCD DC signal */ +#define LCD_CS GPIO5 /**< LCD EN signal */ +#define LCD_RST GPIO8 /**< LCD RST signal */ +#define LCD_BACKLIGHT GPIO9 /**< LCD BL signal */ + +#define ST7735_PARAM_SPI SPI_DEV(0) +#define ST7735_PARAM_CS LCD_CS +#define ST7735_PARAM_DCX LCD_DC +#define ST7735_PARAM_RST LCD_RST +#define ST7735_PARAM_NUM_LINES 240 +#define ST7735_PARAM_RGB_CHANNELS 240 +#define ST7735_PARAM_ROTATION LCD_MADCTL_MV | LCD_MADCTL_MX | LCD_MADCTL_MY +#define ST7735_PARAM_INVERTED 1 +#define ST7735_PARAM_RGB 1 + +#define BACKLIGHT_ON gpio_set(LCD_BACKLIGHT) +#define BACKLIGHT_OFF gpio_clear(LCD_BACKLIGHT) +#endif +/** @} */ + +/** + * @name SD-Card interface configuration + * + * SD-Card interface uses SPI_DEV(1) on this board. + * @{ + */ +#if (MODULE_SDCARD_SPI) || DOXYGEN +#define SDCARD_SPI_PARAM_SPI SPI_DEV(1) +#define SDCARD_SPI_PARAM_CS SPI1_CS0 +#define SDCARD_SPI_PARAM_CLK SPI1_SCK +#define SDCARD_SPI_PARAM_MOSI SPI1_MOSI +#define SDCARD_SPI_PARAM_MISO SPI1_MISO +#define SDCARD_SPI_PARAM_POWER GPIO_UNDEF +#endif +/** @} */ + +/* include common board definitions as last step */ +#include "board_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} /* end extern "C" */ +#endif + +#endif /* BOARD_H */ +/** @} */ diff --git a/boards/esp32s3-usb-otg/include/gpio_params.h b/boards/esp32s3-usb-otg/include/gpio_params.h new file mode 100644 index 000000000000..e8c0723f3cd3 --- /dev/null +++ b/boards/esp32s3-usb-otg/include/gpio_params.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2023 Gunar Schorcht + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#ifndef GPIO_PARAMS_H +#define GPIO_PARAMS_H + +/** + * @ingroup boards_esp32s3_usb_otg + * @brief Board specific configuration of direct mapped GPIOs + * @file + * @author Gunar Schorcht + * @{ + */ + +#include "board.h" +#include "saul/periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LED and Button configuration + */ +static const saul_gpio_params_t saul_gpio_params[] = +{ + { + .name = "OK", + .pin = BTN0_PIN, + .mode = BTN0_MODE, + .flags = SAUL_GPIO_INVERTED + }, + { + .name = "MENU", + .pin = BTN1_PIN, + .mode = BTN1_MODE, + .flags = SAUL_GPIO_INVERTED + }, + { + .name = "DW-", + .pin = BTN2_PIN, + .mode = BTN2_MODE, + .flags = SAUL_GPIO_INVERTED + }, + { + .name = "UP+", + .pin = BTN3_PIN, + .mode = BTN3_MODE, + .flags = SAUL_GPIO_INVERTED + }, + { + .name = "LED red", + .pin = LED0_PIN, + .mode = GPIO_OUT, + .flags = SAUL_GPIO_INIT_CLEAR + }, + { + .name = "LED yellow", + .pin = LED1_PIN, + .mode = GPIO_OUT, + .flags = SAUL_GPIO_INIT_CLEAR + }, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* GPIO_PARAMS_H */ +/** @} */ diff --git a/boards/esp32s3-usb-otg/include/periph_conf.h b/boards/esp32s3-usb-otg/include/periph_conf.h new file mode 100644 index 000000000000..3c4e3263ca3b --- /dev/null +++ b/boards/esp32s3-usb-otg/include/periph_conf.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2023 Gunar Schorcht + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_esp32s3_usb_otg + * @brief Peripheral configurations for ESP32-S3-USB-OTG boards + * @{ + * + * Any modifications required for specific applications + * can be overridden by \ref esp32_application_specific_configurations + * "application-specific board configuration". + * + * For detailed information about the peripheral configuration for ESP32-S3 + * boards, see section \ref esp32_peripherals "Common Peripherals". + * + * @file + * @author Gunar Schorcht + */ + +#ifndef PERIPH_CONF_H +#define PERIPH_CONF_H + +#include + +#include "board.h" +#include "periph_cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name ADC channel configuration + * @{ + */ +/** + * @brief Declaration of GPIOs that can be used as ADC channels + * + * GPIO1 can be used for USB_DEV voltage monitoring as ADC_LINE(0). + * GPIO2 can be used for Battery voltage monitoring as ADC_LINE(1). + */ +#ifndef ADC_GPIOS +#define ADC_GPIOS { GPIO1, GPIO2 } +#endif +/** @} */ + +/** + * @name PWM channel configuration + * @{ + */ + +/** + * @brief Declaration of the channels for device PWM_DEV(0) + * + * LED pins are used as PWM channels. + */ +#ifndef PWM0_GPIOS +#define PWM0_GPIOS { LED0_PIN, LED1_PIN } +#endif +/** @} */ + +/** + * @name SPI configuration + * + * SPI_DEV(0) is used for LCD display + * SPI_DEV(1) is used for SPI SD Card (only configured if `sdcard_spi` is enabled) + * @{ + */ +#ifndef SPI0_CTRL +#define SPI0_CTRL SPI2_HOST /**< FSPI is configured as SPI_DEV(0) */ +#endif +#ifndef SPI0_SCK +#define SPI0_SCK GPIO6 /**< LCD SCLK */ +#endif +#ifndef SPI0_MOSI +#define SPI0_MOSI GPIO7 /**< LCD SDA */ +#endif +#ifndef SPI0_MISO +#define SPI0_MISO GPIO3 /**< not used (dummy pin) */ +#endif +#ifndef SPI0_CS0 +#define SPI0_CS0 GPIO5 /**< LCD CS */ +#endif + +#if IS_USED(MODULE_SDCARD_SPI) +#ifndef SPI1_CTRL +#define SPI1_CTRL SPI3_HOST /**< FSPI is configured as SPI_DEV(0) */ +#endif +#ifndef SPI1_SCK +#define SPI1_SCK GPIO36 /**< SD SCLK */ +#endif +#ifndef SPI1_MOSI +#define SPI1_MOSI GPIO35 /**< SD MOSI */ +#endif +#ifndef SPI1_MISO +#define SPI1_MISO GPIO37 /**< SD MISO */ +#endif +#ifndef SPI1_CS0 +#define SPI1_CS0 GPIO34 /**< SD CS */ +#endif +#endif +/** @} */ + +/** + * @name UART configuration + * + * ESP32-S3 provides 3 UART interfaces at maximum: + * + * UART_DEV(0) uses fixed standard configuration.
+ * UART_DEV(1) is not used.
+ * + * @{ + */ +#define UART0_TXD GPIO43 /**< direct I/O pin for UART_DEV(0) TxD, can't be changed */ +#define UART0_RXD GPIO44 /**< direct I/O pin for UART_DEV(0) RxD, can't be changed */ + +/** @} */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif + +/* include common peripheral definitions as last step */ +#include "periph_conf_common.h" + +#endif /* PERIPH_CONF_H */ +/** @} */