From 619776a30fbccd5b683b375a6f9a730790223fe4 Mon Sep 17 00:00:00 2001 From: RockBase-Ronnie Date: Tue, 2 Jun 2026 17:32:31 +0800 Subject: [PATCH] boards: Add Rockbase iot NM-CYD-C5 --- .../boards/rockbase-iot/nm_cyd_c5/README.md | 114 ++++++++++++++++++ .../rockbase-iot/nm_cyd_c5/board_devices.yaml | 91 ++++++++++++++ .../rockbase-iot/nm_cyd_c5/board_info.yaml | 5 + .../nm_cyd_c5/board_peripherals.yaml | 41 +++++++ .../nm_cyd_c5/sdkconfig.defaults.board | 21 ++++ .../rockbase-iot/nm_cyd_c5/setup_device.c | 23 ++++ 6 files changed, 295 insertions(+) create mode 100644 application/edge_agent/boards/rockbase-iot/nm_cyd_c5/README.md create mode 100644 application/edge_agent/boards/rockbase-iot/nm_cyd_c5/board_devices.yaml create mode 100644 application/edge_agent/boards/rockbase-iot/nm_cyd_c5/board_info.yaml create mode 100644 application/edge_agent/boards/rockbase-iot/nm_cyd_c5/board_peripherals.yaml create mode 100644 application/edge_agent/boards/rockbase-iot/nm_cyd_c5/sdkconfig.defaults.board create mode 100644 application/edge_agent/boards/rockbase-iot/nm_cyd_c5/setup_device.c diff --git a/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/README.md b/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/README.md new file mode 100644 index 000000000..00066524a --- /dev/null +++ b/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/README.md @@ -0,0 +1,114 @@ +# RockBase-iot NM-CYD-C5 + +ESP-Claw board package for the [RockBase-iot NM-CYD-C5](https://github.com/RockBase-iot/NM-CYD-C5), an ESP32-C5 Cheap Yellow Display style board with dual-band Wi-Fi 6, BLE 5, Thread/Zigbee radio support, 16 MB flash, 8 MB PSRAM, and a 2.8 inch LCD. + +## Hardware Overview + +| Feature | Specification | +| --- | --- | +| SoC | ESP32-C5-WROOM-1, RISC-V @ 240 MHz | +| Flash / PSRAM | 16 MB flash, 8 MB quad PSRAM | +| Display | 2.8 inch ST7789 TFT LCD, 320x240 logical landscape resolution | +| Touch | XPT2046 resistive touch controller on the shared SPI2 bus | +| Storage | microSD slot on shared SPI2 bus | +| RGB LED | Single WS2812 pixel on GPIO27 | +| GPS connector | LP-UART P5, intended for NM-ATGM336H style NMEA GPS modules | +| Expansion | CN1 I2C header, P1 GPIO header, 12-pin FPC2 extension | +| Button | BOOT button on GPIO0, active low | + +## GPIO Mapping + +| Function | GPIO | +| --- | --- | +| SPI SCLK | GPIO6 | +| SPI MISO | GPIO2 | +| SPI MOSI | GPIO7 | +| LCD CS | GPIO23 | +| LCD DC | GPIO24 | +| LCD reset | Board reset (`-1`) | +| Backlight PWM | GPIO25 | +| Touch CS | GPIO1 | +| microSD CS | GPIO10 | +| WS2812 DIN | GPIO27 | +| GPS RX | GPIO4 | +| GPS TX | GPIO5 | +| I2C SDA | GPIO9 | +| I2C SCL | GPIO8 | +| BOOT | GPIO0 | + +## ESP-Claw Device Coverage + +Defined in `board_devices.yaml`: + +- `display_lcd`: ST7789 over SPI2, 320x240, 40 MHz, landscape orientation (`swap_xy: true`, `mirror_y: true`). +- `lcd_brightness`: LEDC backlight control on GPIO25, active high, 5 kHz. +- `led_strip`: metadata-only WS2812 entry on GPIO27. Runtime scripts create and release the LED strip driver on demand to avoid RMT channel leaks. +- `fs_sdcard`: metadata-only SPI microSD entry on the shared SPI bus, CS=GPIO10. It is `init_skip: true` so mounting is explicit and does not block LCD use when no card is inserted. +- `lcd_touch`: metadata-only XPT2046 entry, CS=GPIO1. The shared SPI wiring is reserved for future or custom touch drivers. +- `gps_uart`: metadata-only NMEA UART entry, RX=GPIO4, TX=GPIO5, 9600 baud. +- `buttons`: metadata-only BOOT button entry on GPIO0. + +The board also ships Lua helpers in the ESP-Claw FATFS image for screen display, backlight, RGB LED, and GPS usage. XPT2046 touch is reserved in metadata; scripts that need input should provide a BOOT-button fallback unless SPI touch support is enabled. + +## Build And Flash + +```powershell +cd application/edge_agent +idf.py set-target esp32c5 +idf.py bmgr --customer-path ./boards -b nm_cyd_c5 +idf.py build +idf.py -p flash monitor +``` + +## Validation Checklist + +Use this list when preparing or reviewing a PR for this board: + +- `idf.py bmgr --customer-path ./boards -b nm_cyd_c5` generates board-manager code without YAML errors. +- `idf.py build` completes for target `esp32c5`. +- Device boots into the ESP-Claw agent loop. +- Captive portal loads and can save Wi-Fi / LLM / IM settings. +- `display_lcd` initializes and renders the ESP-Claw mascot or a Lua display demo. +- Backlight responds through `display.brightness(...)` or the `nm_cyd_c5_backlight` Lua script. +- `nm_cyd_c5_screen` can show color/text/message/clear modes on the LCD. +- `nm_cyd_c5_rgb` can set solid colors, blink, and run a short rainbow on GPIO27. +- `nm_cyd_c5_gps` can read NMEA sentences from a GPS module on P5 if connected. +- SD card mount is tested manually if a card is inserted. + +## PR Summary Template + +Add support for the RockBase-iot NM-CYD-C5 board. + +Description + +This board package follows the existing `esp_board_manager` YAML-driven pattern used by other supported ESP-Claw boards and ports the previously validated NM-CYD-C5 basic_demo configuration into `application/edge_agent/boards`. + +The following hardware definitions were added: + +Chip: + +ESP32-C5-WROOM-1, 16 MB flash, 8 MB quad PSRAM, RISC-V @ 240 MHz. + +Display: + +2.8 inch ST7789 TFT LCD, 320x240 logical landscape resolution. Shared SPI2 bus: MOSI=GPIO7, MISO=GPIO2, CLK=GPIO6, LCD CS=GPIO23, DC=GPIO24, reset tied to board reset. Backlight is GPIO25 active-high PWM via LEDC @ 5 kHz. + +Storage: + +microSD card slot on the shared SPI2 bus, CS=GPIO10. The device is metadata-only and mounted on demand to avoid bus contention. + +Touch: + +XPT2046 resistive touch on the shared SPI2 bus, CS=GPIO1. The device is reserved as metadata for future or custom SPI touch support. + +Expansion: + +WS2812 RGB LED on GPIO27, GPS UART on GPIO4/GPIO5, I2C header on GPIO9/GPIO8, BOOT button on GPIO0. + +Related + +https://github.com/RockBase-iot/NM-CYD-C5 + +Testing + +I validated that board-manager code generation and the ESP-Claw firmware build succeed. Hardware smoke testing should cover display rendering, backlight, RGB LED, GPS UART, settings portal, Lua display APIs, and optional SD card mounting. \ No newline at end of file diff --git a/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/board_devices.yaml b/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/board_devices.yaml new file mode 100644 index 000000000..338441a18 --- /dev/null +++ b/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/board_devices.yaml @@ -0,0 +1,91 @@ +version: 1.0.0 +# Devices Configuration for NM-CYD-C5 (ESP32-C5) + +devices: + - name: display_lcd + chip: st7789 + type: display_lcd + sub_type: spi + version: default + config: + mirror_x: false + mirror_y: true + swap_xy: true + invert_color: false + x_max: 320 + y_max: 240 + io_spi_config: + cs_gpio_num: 23 + dc_gpio_num: 24 + spi_mode: 0 + pclk_hz: 40000000 + lcd_panel_config: + reset_gpio_num: -1 + data_endian: LCD_RGB_DATA_ENDIAN_BIG + vendor_config: NULL + peripherals: + - name: spi_display + + - name: lcd_brightness + type: ledc_ctrl + version: default + config: + default_percent: 100 + peripherals: + - name: ledc_backlight + + - name: led_strip + chip: ws2812 + type: custom + version: default + init_skip: true + dependencies: + espressif/led_strip: + version: "^3.0" + public: true + config: + gpio_num: 27 + max_leds: 1 + + - name: fs_sdcard + type: fs_fat + sub_type: spi + version: default + init_skip: true + config: + sub_config: + cs_gpio_num: 10 + frequency: SDMMC_FREQ_DEFAULT + peripherals: + - name: spi_display + + - name: lcd_touch + chip: xpt2046 + type: custom + version: default + init_skip: true + config: + cs_gpio_num: 1 + x_max: 320 + y_max: 240 + peripherals: + - name: spi_display + + - name: gps_uart + chip: nmea_gps + type: custom + version: default + init_skip: true + config: + rx_gpio_num: 4 + tx_gpio_num: 5 + baud_rate: 9600 + + - name: buttons + chip: gpio_button + type: custom + version: default + init_skip: true + config: + boot_gpio_num: 0 + active_level: 0 \ No newline at end of file diff --git a/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/board_info.yaml b/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/board_info.yaml new file mode 100644 index 000000000..815595c97 --- /dev/null +++ b/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/board_info.yaml @@ -0,0 +1,5 @@ +board: nm_cyd_c5 +chip: esp32c5 +version: 1.0.0 +description: "RockBase-iot NM-CYD-C5 Cheap Yellow Display with 2.8-inch ST7789 LCD" +manufacturer: "RockBase-iot" \ No newline at end of file diff --git a/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/board_peripherals.yaml b/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/board_peripherals.yaml new file mode 100644 index 000000000..05415b4f6 --- /dev/null +++ b/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/board_peripherals.yaml @@ -0,0 +1,41 @@ +version: 1.0.0 +# Peripherals Configuration for NM-CYD-C5 (ESP32-C5) +# +# Pin assignment is taken from the official RockBase-iot/NM-CYD-C5 project: +# Display (ST7789) : SCK=6, MISO=2, MOSI=7, CS=23, DC=24, RST=board RST, BL=25 +# Touch (XPT2046) : SCK=6, MISO=2, MOSI=7, CS=1, shared SPI2 bus +# SD card slot : SCK=6, MISO=2, MOSI=7, CS=10, shared SPI2 bus +# WS2812 RGB LED : DIN=27 +# GPS LP-UART P5 : ESP32 RX=4 (GPS TX), ESP32 TX=5 (GPS RX) +# I2C CN1 header : SDA=9, SCL=8 + +peripherals: + - name: i2c_master + type: i2c + role: master + config: + port: 0 + pins: + sda: 9 + scl: 8 + + - name: spi_display + type: spi + role: master + config: + spi_bus_config: + spi_port: SPI2_HOST + mosi_io_num: 7 + miso_io_num: 2 + sclk_io_num: 6 + max_transfer_sz: 6400 + + - name: ledc_backlight + type: ledc + role: none + config: + gpio_num: 25 + freq_hz: 5000 + duty: 1023 + duty_resolution: LEDC_TIMER_10_BIT + output_invert: false \ No newline at end of file diff --git a/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/sdkconfig.defaults.board b/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/sdkconfig.defaults.board new file mode 100644 index 000000000..119711d2b --- /dev/null +++ b/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/sdkconfig.defaults.board @@ -0,0 +1,21 @@ +# Board specific defaults for NM-CYD-C5 (ESP32-C5, 16 MB flash, 8 MB PSRAM). + +CONFIG_IDF_TARGET="esp32c5" +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y + +# Flash: 16 MB DIO 80 MHz +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_16MB.csv" + +# PSRAM: 8 MB quad 80 MHz. ESP32-C5 does not use ESP32-S3 OPI PSRAM options. +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_QUAD=y +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM_TYPE_AUTO=y + +# USB: Serial JTAG +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y +CONFIG_ESP_CONSOLE_SECONDARY_NONE=y \ No newline at end of file diff --git a/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/setup_device.c b/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/setup_device.c new file mode 100644 index 000000000..91176cf60 --- /dev/null +++ b/application/edge_agent/boards/rockbase-iot/nm_cyd_c5/setup_device.c @@ -0,0 +1,23 @@ +#include + +#include "esp_check.h" +#include "esp_lcd_panel_io.h" +#include "esp_lcd_panel_ops.h" +#include "esp_lcd_panel_st7789.h" +#include "esp_log.h" + +static const char *TAG = "nm_cyd_c5"; + +esp_err_t lcd_panel_factory_entry_t(esp_lcd_panel_io_handle_t io, + const esp_lcd_panel_dev_config_t *panel_dev_config, + esp_lcd_panel_handle_t *ret_panel) +{ + esp_lcd_panel_dev_config_t panel_dev_cfg = {0}; + memcpy(&panel_dev_cfg, panel_dev_config, sizeof(esp_lcd_panel_dev_config_t)); + esp_err_t ret = esp_lcd_new_panel_st7789(io, &panel_dev_cfg, ret_panel); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to create ST7789 panel: %s", esp_err_to_name(ret)); + return ret; + } + return ESP_OK; +} \ No newline at end of file