Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ jobs:
target: esp32p4
- path: 'components/esp32-p4-nano/example'
target: esp32p4
- path: 'components/esp32-p4-wifi6-dev-kit/example'
target: esp32p4
- path: 'components/esp32-p4-wifi6-poe-eth/example'
target: esp32p4
- path: 'components/esp32-timer-cam/example'
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/upload_components.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ jobs:
# Note: ethernet is intentionally listed ahead of the esp32-p4-* board
# BSPs (esp32-p4-eth / esp32-p4-function-ev-board /
# esp32-p4-module-dev-kit / esp32-p4-nano /
# esp32-p4-wifi6-poe-eth), which depend on
# espp/ethernet, so it is uploaded to the registry first.
# esp32-p4-wifi6-dev-kit / esp32-p4-wifi6-poe-eth),
# which depend on espp/ethernet, so
# ethernet is uploaded to the registry ahead of them.
#
# Note: magnetic_encoder is intentionally listed ahead of as5600 and
# mt6701, which depend on espp/magnetic_encoder, so it is
Expand Down Expand Up @@ -84,6 +85,7 @@ jobs:
components/esp32-p4-function-ev-board
components/esp32-p4-module-dev-kit
components/esp32-p4-nano
components/esp32-p4-wifi6-dev-kit
components/esp32-p4-wifi6-poe-eth
components/esp32-timer-cam
components/event_manager
Expand Down
24 changes: 24 additions & 0 deletions components/esp32-p4-wifi6-dev-kit/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
idf_component_register(
INCLUDE_DIRS "include"
SRC_DIRS "src"
REQUIRES
"base_component"
"ethernet"
"esp_netif"
"fatfs"
"esp_driver_sdmmc"
"sdmmc"
"codec"
"i2c"
"task"
"esp_driver_i2s"
"display"
"display_drivers"
"gt911"
"input_drivers"
"interrupt"
"esp_lcd"
"esp_video"
"esp_cam_sensor"
REQUIRED_IDF_TARGETS "esp32p4"
)
84 changes: 84 additions & 0 deletions components/esp32-p4-wifi6-dev-kit/Kconfig.projbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
menu "ESP32-P4-WIFI6-DEV-KIT Configuration"

choice ESP32_P4_WIFI6_DEV_KIT_DISPLAY
prompt "MIPI-DSI display panel"
default ESP32_P4_WIFI6_DEV_KIT_DISPLAY_JD9365_10_1
help
Select the MIPI-DSI panel attached to the Waveshare ESP32-P4-WIFI6-DEV-KIT. The BSP
does not auto-detect the panel (runtime DSI-ID probing hangs the boot
watchdog on some panels), so set this to the panel you have.

config ESP32_P4_WIFI6_DEV_KIT_DISPLAY_JD9365_10_1
bool "10.1\" 800x1280 (JD9365) - the panel Waveshare sells for this board"
help
The Waveshare 10.1-inch 800x1280 DSI panel, which uses a JD9365
controller, driven by the espp::Jd9365 display driver (vendor init
over DSI/DBI + DPI panel). Reset is handled over DSI (no reset GPIO).
The backlight is driven by an on-board I2C controller (addr 0x45), so
there is no backlight GPIO; brightness() writes the controller.

config ESP32_P4_WIFI6_DEV_KIT_DISPLAY_ILI9881C
bool "ILI9881C (10.1-inch, 800x1280)"
help
A 10.1-inch 800x1280 ILI9881C panel. EXPERIMENTAL on this board: the
panel Waveshare sells for this board is a JD9365, and the ILI9881C
init sequence wedges the DSI link on it (task-watchdog hang). Only
select this if you have actually attached an ILI9881C panel. Reset is
handled over DSI (no reset GPIO). The backlight is driven by an
on-board I2C controller, so there is no backlight GPIO.

config ESP32_P4_WIFI6_DEV_KIT_DISPLAY_EK79007
bool "EK79007 (7-inch, 1024x600)"
help
The 7-inch 1024x600 EK79007 panel. Reset is handled over DSI (no reset
GPIO). The backlight is driven by an on-board I2C controller, so there is
no backlight GPIO.
endchoice

config ESP32_P4_WIFI6_DEV_KIT_INTERRUPT_STACK_SIZE
int "Interrupt task stack size (bytes)"
default 8192
help
Size of the stack used for the GPIO interrupt handler task.

config ESP32_P4_WIFI6_DEV_KIT_INTERRUPT_PRIORITY
int "Interrupt task priority"
default 0
range 0 25
help
FreeRTOS priority of the GPIO interrupt handler task (0 = lowest). Raise it
if interrupt callbacks must run promptly relative to other tasks.

config ESP32_P4_WIFI6_DEV_KIT_INTERRUPT_CORE_ID
int "Interrupt task core ID"
default -1
range -1 1
help
Core to pin the GPIO interrupt handler task to (-1 = not pinned to any core).

config ESP32_P4_WIFI6_DEV_KIT_TOUCH_TASK_STACK_SIZE
int "Touch polling task stack size (bytes)"
default 8192
help
Size of the stack used for the GT911 touch polling task. Used only in
polling mode (see ESP32_P4_WIFI6_DEV_KIT_TOUCH_INTERRUPT).

config ESP32_P4_WIFI6_DEV_KIT_TOUCH_INTERRUPT
bool "Use interrupt-driven touch instead of polling"
default n
help
By default the ESP32-P4-WIFI6-DEV-KIT does not route the GT911 touch INT pin to the
ESP32-P4, so touch is polled in a task. If you wire the touch INT pin to a
free ESP32-P4 GPIO, enable this to read the GT911 from a GPIO interrupt
instead of polling (lower CPU usage and latency). The GPIO is set below and
can also be overridden at runtime via initialize_touch().

config ESP32_P4_WIFI6_DEV_KIT_TOUCH_INTERRUPT_GPIO
int "Touch interrupt GPIO"
depends on ESP32_P4_WIFI6_DEV_KIT_TOUCH_INTERRUPT
default 33
help
GPIO that the GT911 touch INT pin is wired to. Must be a free GPIO not used
by another on-board peripheral.

endmenu
58 changes: 58 additions & 0 deletions components/esp32-p4-wifi6-dev-kit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# ESP32-P4-WIFI6-DEV-KIT Board Support Package (BSP)

[![Badge](https://components.espressif.com/components/espp/esp32-p4-wifi6-dev-kit/badge.svg)](https://components.espressif.com/components/espp/esp32-p4-wifi6-dev-kit)

Board Support Package for the [Waveshare ESP32-P4-WIFI6-DEV-KIT](https://www.waveshare.com/wiki/ESP32-P4-WIFI6-DEV-KIT)
board — an ESP32-P4NRW32 (32 MB stacked PSRAM; 16 MB NOR flash per the product
page, though the wiki self-contradicts on 16 vs 32 MB — unverified on
hardware) with an onboard
ESP32-C6 co-processor for Wi-Fi 6 / Bluetooth 5 (LE) over SDIO (ESP-Hosted).
The `espp::Esp32P4Wifi6DevKit` class is a singleton hardware abstraction that
brings up the board's peripherals with a small, uniform API.

## Supported peripherals

<table>
<tr><th>Peripheral</th><th>Hardware</th><th>API</th></tr>
<tr><td>Display</td><td>MIPI-DSI panel (JD9365 / ILI9881C 10.1" 800x1280 or EK79007 7" 1024x600, selected via Kconfig)</td><td><code>initialize_lcd()</code>, <code>initialize_display()</code></td></tr>
<tr><td>Touch</td><td>GT911 capacitive multi-touch (polled; INT/RST not routed)</td><td><code>initialize_touch()</code></td></tr>
<tr><td>Camera</td><td>MIPI-CSI (OV5647 by default) via esp_video / V4L2, RGB565 frames</td><td><code>initialize_camera()</code>, <code>stop_camera()</code></td></tr>
<tr><td>Audio out</td><td>ES8311 codec + NS4150B amplifier over I2S</td><td><code>initialize_audio()</code>, <code>play_audio()</code>, <code>volume()</code></td></tr>
<tr><td>Microphone</td><td>Onboard analog mic through the ES8311 ADC (full-duplex)</td><td><code>initialize_microphone()</code></td></tr>
<tr><td>uSD / TF card</td><td>4-bit SDMMC, powered by the on-chip LDO</td><td><code>initialize_sdcard()</code></td></tr>
<tr><td>Ethernet</td><td>10/100 internal EMAC + IP101GRI RMII PHY (DHCP client/server); RJ45 with optional external PoE-module header</td><td><code>initialize_ethernet()</code></td></tr>
<tr><td>Wi-Fi 6 / BT5</td><td>Onboard ESP32-C6 over SDIO (ESP-Hosted)</td><td>Not part of the BSP — use <code>espressif/esp_hosted</code> + <code>espressif/esp_wifi_remote</code> and the standard <code>esp_wifi</code> API (see below)</td></tr>
</table>

The ES8311 codec, GT911 touch controller, and camera SCCB share a single
internal I2C bus (`internal_i2c()`, SDA=GPIO7 / SCL=GPIO8). The Ethernet
bring-up is delegated to the reusable `espp::Ethernet` component; this BSP
supplies the board-specific RMII pin mapping.

The MIPI-CSI camera pipeline (esp_video + esp_cam_sensor) is fetched by the IDF
component manager. PSRAM must be enabled (the camera capture buffers and display
framebuffers live in PSRAM). See the example's `sdkconfig.defaults` for the
required Kconfig options (PSRAM, the MIPI-CSI video device, and the sensor).

## Wi-Fi 6 / Bluetooth via the onboard ESP32-C6

The ESP32-P4 has no radio of its own; the board pairs it with an ESP32-C6
running the ESP-Hosted slave firmware, connected over SDIO (CLK=GPIO18,
CMD=GPIO19, D0-D3=GPIO14-17, C6 reset=GPIO54 — the ESP-Hosted defaults for the
ESP32-P4). To use Wi-Fi from your application, add the two managed components:

```
idf.py add-dependency "espressif/esp_wifi_remote"
idf.py add-dependency "espressif/esp_hosted"
```

then select `esp32c6` as the slave target (menuconfig: `Component config ->
Wi-Fi Remote -> choose slave target`) and use the standard `esp_wifi` API
unchanged. The BSP intentionally does not wrap this — ESP-Hosted hooks in below
`esp_wifi`, so there is no board-specific code to add beyond the defaults.

## Example

The [example](./example) brings up the display + touch, audio (record /
playback), the camera (live feed), the uSD card, and Ethernet, and drives an
LVGL GUI with Status / Audio / Camera tabs.
49 changes: 49 additions & 0 deletions components/esp32-p4-wifi6-dev-kit/example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
cmake_minimum_required(VERSION 3.20)

# Set the C++ standard before project()/project.cmake so the IDF build system
# picks it up when it configures the toolchain.
set(CMAKE_CXX_STANDARD 23)

# The component manager is needed to pull the managed camera components
# (espressif/esp_video + espressif/esp_cam_sensor). They are declared as
# dependencies of the esp32-p4-wifi6-dev-kit BSP (components/esp32-p4-wifi6-dev-kit/idf_component.yml)
# and fetched transitively. Enable it explicitly so this example configures even
# if the build environment defaults it off (it is on by default in ESP-IDF).
set(ENV{IDF_COMPONENT_MANAGER} "1")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)

# Enumerate the specific espp component dirs (rather than globbing the whole
# components/ tree): with the component manager enabled, every discovered
# component's manifest is target-checked, and some espp components (e.g. byte90)
# declare targets that exclude esp32p4. Listing only what this BSP needs avoids
# those false incompatibilities.
set(EXTRA_COMPONENT_DIRS
"../"
"../../../components/base_component"
"../../../components/base_peripheral"
"../../../components/cli"
"../../../components/codec"
"../../../components/display"
"../../../components/display_drivers"
"../../../components/ethernet"
"../../../components/format"
"../../../components/gt911"
"../../../components/i2c"
"../../../components/input_drivers"
"../../../components/interrupt"
"../../../components/led"
"../../../components/logger"
"../../../components/lvgl"
"../../../components/spi"
"../../../components/task"
"../../../components/touch"
)

set(
COMPONENTS
"main esptool_py esp32-p4-wifi6-dev-kit display lvgl"
CACHE STRING
"List of components to include"
)

project(esp32_p4_wifi6_dev_kit_example)
63 changes: 63 additions & 0 deletions components/esp32-p4-wifi6-dev-kit/example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# ESP32-P4-WIFI6-DEV-KIT Example

Brings up the Waveshare ESP32-P4-WIFI6-DEV-KIT board through the `espp::Esp32P4Wifi6DevKit` BSP
and drives an LVGL GUI. It exercises the display, touch, audio, microphone,
camera, uSD card and Ethernet:

- **Display + touch (MIPI-DSI + GT911):** a tabview GUI. On the **Status** tab,
touch the screen to draw circles and play a click; it also shows live
subsystem state (panel, touch, SD, Ethernet, camera size, memory / uptime).
The rotate / clear buttons rotate the display and clear the drawing.
- **Audio (ES8311 + NS4150B):** the **Audio** tab has record / play buttons and
speaker / microphone volume controls. Recording captures from the onboard
microphone (full-duplex through the codec) into a PSRAM buffer; play streams it
back to the speaker.
- **Camera (MIPI-CSI, OV5647):** the **Camera** tab shows the live RGB565 feed.
Each frame from the BSP capture task is copied into an LVGL canvas.
- **uSD / TF card (4-bit SDMMC):** mounted at boot (if a card is present); its
size is logged and shown on the Status tab.
- **Ethernet (internal EMAC + IP101GRI RMII PHY):** started as a DHCP client; the
acquired IP is logged and shown on the Status tab.

Wi-Fi 6 (via the onboard ESP32-C6) is not exercised by this example — see
below for how to enable it in your own project.

## Wi-Fi 6 via the onboard ESP32-C6 (ESP-Hosted)

The ESP32-P4 has no radio; the board's ESP32-C6 (running the ESP-Hosted slave
firmware it ships with) provides Wi-Fi 6 / BT5 over SDIO (CLK=GPIO18,
CMD=GPIO19, D0-D3=GPIO14-17, C6 reset=GPIO54 — the ESP-Hosted defaults for the
ESP32-P4, so no pin configuration is needed). To add Wi-Fi to a project using
this BSP:

```
idf.py add-dependency "espressif/esp_wifi_remote"
idf.py add-dependency "espressif/esp_hosted"
```

then in `menuconfig` set `Component config -> Wi-Fi Remote -> choose slave
target` to `esp32c6`, and use the standard `esp_wifi` / `esp_netif` APIs
unchanged (e.g. ESP-IDF's `wifi/getting_started/station` example works as-is).
Note the C6 is 2.4 GHz-only. To (re)flash the C6's ESP-Hosted slave firmware,
see the [Waveshare wiki FAQ](https://www.waveshare.com/wiki/ESP32-P4-WIFI6-DEV-KIT)
(hold C6_IO9 low at power-on and flash via the C6 UART pads).

## How the camera feed reaches the GUI

`initialize_camera()` runs a capture task in the BSP that hands each RGB565 frame
to a callback. The example forwards it to the thread-safe
`Gui::set_camera_frame(data, w, h)`, which copies the frame into a PSRAM canvas
buffer (allocated lazily on the first frame / a size change) and invalidates the
LVGL canvas. The GUI's LVGL task then renders it on the Camera tab.

## Build and flash

```
idf.py set-target esp32p4
idf.py build flash monitor
```

The example uses a custom 16 MB flash partition table (`partitions.csv`) because
the display + LVGL + camera + audio application no longer fits the default 1 MB
app partition. PSRAM and the MIPI-CSI camera pipeline are enabled via
`sdkconfig.defaults`.
5 changes: 5 additions & 0 deletions components/esp32-p4-wifi6-dev-kit/example/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
idf_component_register(
SRC_DIRS "."
INCLUDE_DIRS "."
EMBED_FILES click.wav
)
Binary file not shown.
Loading
Loading