Working with ESP-IDF
This chapter includes the following two sections, please read as needed:
ESP-IDF Getting Started
New to ESP32 ESP-IDF development and looking to get started quickly? We have prepared a general Getting Started Tutorial for you.
- Section 1: Environment Setup
- Section 2: Running Examples
- Section 3: Creating a Project
- Section 4: Using Components
- Section 5: Debugging
- Section 6: FreeRTOS
- Section 7: Peripherals
- Section 8: Wi-Fi Programming
- Section 9: BLE Programming
Please Note: This tutorial uses the ESP32-S3-Zero as a teaching example, and all hardware code is based on its pinout. Before you start, it is recommended that you check the pinout of your development board to ensure the pin configuration is correct.
Setting Up Development Environment
For the ESP32-P4-ETH development board, it is recommended to use ESP-IDF V5.3.1 or a later version.
The following guide uses Windows as an example, demonstrating development using VS Code + the ESP-IDF extension. macOS and Linux users should refer to the official documentation.
Install the ESP-IDF Development Environment
-
Download the installation manager from the ESP-IDF Installation Manager page. This is Espressif's latest cross-platform installer. The following steps demonstrate how to use its offline installation feature.
Click the Offline Installer tab on the page, then select Windows as the operating system and choose your desired version from the filter bar.

After confirming your selection, click the download button. The browser will automatically download two files: the ESP-IDF Offline Package (.zst) and the ESP-IDF Installer (.exe).

Please wait for both files to finish downloading.
-
Once the download is complete, double-click to run the ESP-IDF Installer (eim-gui-windows-x64.exe).
The installer will automatically detect if the offline package exists in the same directory. Click Install from archive.

Next, select the installation path. We recommend using the default path. If you need to customize it, ensure the path does not contain Chinese characters or spaces. Click Start installation to proceed.

-
When you see the following screen, the ESP-IDF installation is successful.

-
We recommend installing the drivers as well. Click Finish installation, then select Install driver.

Install Visual Studio Code and the ESP-IDF Extension
-
Download and install Visual Studio Code.
-
During installation, it is recommended to check Add "Open with Code" action to Windows Explorer file context menu to facilitate opening project folders quickly.
-
In VS Code, click the Extensions icon
in the Activity Bar on the side (or use the shortcut Ctrl + Shift + X) to open the Extensions view.
-
Enter ESP-IDF in the search box, locate the ESP-IDF extension, and click Install.

-
For ESP-IDF extension versions ≥ 2.0, the extension will automatically detect and recognize the ESP-IDF environment installed in the previous steps, requiring no manual configuration.
Demo
The ESP-IDF demos are located in the ESP-IDF directory of the demo package.
This wiki continuously updates the ESP32-P4 example programs. Some applications may depend on specific ESP-IDF versions and require some time for testing and updates. Please be patient.
Getting Started
The best way to learn a language or development environment is to start from the basics. This section will provide a detailed guide on how to create projects, develop from existing projects, and include embedded classic tutorials such as HelloWorld and the usage of common port I2C.
1. Introduction to Basic Structure of an ESP-IDF Project
-
Project Structure:
-
Open the ESP-IDF plugin, click New project, select the ESP-IDF demo -- > sample_project -- > click Create
-
After creation and opening in a new window, you can view the VS Code structure as follows:
├── CMakeLists.txt├── main│ ├── CMakeLists.txt│ └── main.c└── README.md
-
-
ESP-IDF Project Details:
-
Component: In ESP-IDF, components are the basic building blocks of an application. Each component is typically a relatively independent codebase or library that implements specific functions or services and can be reused by the application or other components, similar to the concept of libraries in Python development.
-
Referencing Components: In the Python development environment, importing a library only requires "import library name or path". However, ESP-IDF is based on C language, and importing libraries is configured and defined through CMakeLists.txt.
-
When using online components, we typically use
idf.py add-dependency <componetsName>to add an online component to the project, which generates anidf_component.ymlfile for managing components. -
Role of CmakeLists.txt: During ESP-IDF compilation, the CMake tool first reads the build rules by reading the content of the top-level CMakeLists.txt in the project directory, identifying what needs to be compiled. When the required components and demos are imported into the CMakeLists.txt, the compilation tool CMake will import everything that needs to be compiled according to the index. The compilation process is as follows:

-
-
-
Description of VS Code User Interface Bottom Toolbar:
When opening an ESP-IDF project, the environment will be loaded automatically at the bottom. For the development of ESP32-P4-ETH, the bottom toolbar is very important, as shown in the figure:

- ①. ESP-IDF Development Environment Version Manager: When our project needs to distinguish between different development environment versions, we can manage them separately by installing different versions of ESP-IDF. When a project uses a specific version, you can switch using this manager
- ②. Device Flash COM port: Select the COM port to flash the compiled program into the chip
- ③. Select set-target chip model: Select the corresponding chip model, for example, ESP32-P4-ETH needs to choose esp32p4 as the target chip
- ④. menuconfig: Click it to modify sdkconfig configuration file
- ⑤. fullclean Button: When a project compilation error or other operations pollute the compilation content, click to clean all compilation content
- ⑥. Build Project: When a project meets the build requirements, use this button to compile
- ⑦. flash button: When a project Build passes, select the corresponding board COM port and click this button to flash the compiled firmware to the chip
- ⑧. monitor: Start flash port monitoring. After a project Build -> Flash, you can click this button to view the log output from the flash/debug port to observe whether the application is working correctly
- ⑨. Build Flash Monitor One-click Button: Used to sequentially execute Build -> Flash -> Monitor, often referred to as "Little Flame"
2. HelloWorld Example
After understanding the explanation of the VS Code user interface bottom toolbar, the Hello World project allows for a quick start and understanding of the basic project structure of the ESP32 development environment. It demonstrates how to use ESP-IDF to create a basic application and covers the ESP32 development process, including compilation, flashing, and monitor debugging steps.
-
After opening the example project
HelloWorld, set the target port and chip type (Note: when selecting the chip type, there is a loading action in the lower right corner. This is ESP-IDF executing theidf.py set-target esp32p4operation command. It needs to pull the architecture package environment for the corresponding chip from the package manager, which takes some time. Please be patient. If you click build or other operations at this time, errors will occur!!!) -
By using the bottom tool 🔥 to build, burn, and monitor with just one click. You can see the terminal output "Hello World!".
-
Code content analysis
- There is only one
app_mainmain function in the code, which determines the print content output through conditional judgment, and adds a loop at the end to achieve 10s restart of the chip. - The
app_mainfunction is the entry point for user applications in the ESP-IDF (Espressif IoT Development Framework) development framework. It is the core function of an ESP-IDF project, equivalent to the main function in a standard C program. In ESP32 development, theapp_mainfunction is the first task scheduled by the Real-Time Operating System (FreeRTOS), marking the starting point for user code execution.
- There is only one
3. I2C Example
I2C is a commonly used serial communication bus, which can communicate through two lines, one data cable (SDA, Serial Data) and one clock cable (SCL, Serial Clock), and supports multi-master and multi-slave mode. The ESP32-P4 chip features two I2C bus interfaces. Internally, the GPIO switch matrix allows these interfaces to be configured to use any GPIO pin. This flexibility enables users to freely assign any GPIO as I2C pins. Additionally, the ESP32-P4 I2C supports both slave and master modes. The following section focuses on the I2C master mode, which is used by the ESP32-P4 to initiate communication, control, and send data requests to or receive data from slave devices (such as any I2C‑compatible sensor). On the ESP32-P4-ETH, the I2C pins are configured by default as SCL(GPIO8) and SDA(GPIO7)
, set it to I2C_CLK_SRC_DEFAULT.i2c_master_bus_config_t::i2c_portsets the I2C port to be used by the controller. As mentioned above, the ESP32-P4 has two I2C ports. When two different I2C buses need to be enabled simultaneously, this is used to distinguish them.i2c_master_bus_config_t::scl_io_numsets the GPIO number for the Serial Clock (SCL) line. On the ESP32-P4-ETH, this is 8.i2c_master_bus_config_t::sda_io_numsets the GPIO number for the Serial Data (SDA) line. On the ESP32-P4-ETH, this is 7.i2c_master_bus_config_t::glitch_ignore_cntsets the Glitch Period for the Master Bus. If the glitch period on the line is less than this value, it can be filtered out. The typical value is 7.i2c_master_bus_config_t::enable_internal_pullupenables internal pull-up resistors. On the ESP32-P4-ETH, external I2C pull-ups are already provided, so internal pull-ups should not be enabled.
Based on the above, the I2C configuration is defined as follows:
i2c_master_bus_config_t i2c_bus_config = {
.clk_source = I2C_CLK_SRC_DEFAULT,
.i2c_port = I2C_NUM_0,
.scl_io_num = 8,
.sda_io_num = 7,
.glitch_ignore_cnt = 7,
.flags.enable_internal_pullup = false,
};
-
Open the
i2c_toolsproject, select the correct COM port and chip model, then click the ⚙️ to enter the settings. This will open a new tab: SDK Configuration editor, also known as menuconfig. Directly search for "I2C" in the search bar. You will see the relevant retrieved content, and the SCL GPIO Num and SDA GPIO Num in the example code should already correspond toSCL(GPIO8)andSDA(GPIO7). -
Next, you can directly compile, flash, and monitor by clicking 🔥. After completion, a command menu will appear in the terminal. When you execute the i2cdetect command, it will print all I2C addresses. If a device is present, its address will be displayed as a number (the device at I2C address 0x18 is the onboard ES8311 Codec audio chip, which will be explained in detail in the I2S section), as shown in the figure:

-
The above steps have already implemented the foundation for I2C device communication. In devices that use the I2C communication protocol, it is often necessary to write register configurations to the device at the corresponding address via the I2C bus to enable the I2C device's functions. At this point, we need to write the initialization program for the I2C device in the code to drive it. Different I2C devices have different I2C addresses. During development, we can use the i2ctools tool to query the I2C address of the connected device, then read its chip manual to find the registers, configurations, etc., to implement I2C bus communication.
Intermediate
1. Ethernet Demo
Basic Ethernet Concepts
-
Ethernet is an asynchronous Carrier Sense Multiple Access with Collision Detection (CSMA/CD) protocol or interface. Generally speaking, Ethernet is not suitable for low-power applications. However, thanks to its wide range of deployments, efficient network connectivity, high data rates, and unlimited scalability, almost all wired communication can be carried over Ethernet. Currently, Ethernet is classified based on speed tiers as follows: standard Ethernet (10Mbit/s), fast Ethernet (100Mbit/s), gigabit Ethernet (1000Mbit/s), and faster ten-gigabit Ethernet (10Gbit/s).
-
Ethernet interface types include RJ45 interface, RJ11 interface (telephone line interface), etc. Among them, the RJ45 interface is the most commonly used Ethernet interface (computer interface) and is also the type of onboard Ethernet port on the ESP32-P4-ETH.
-
The ESP32-P4-ETH can be explained using the network model:

- Network Interface Layer of ESP32-P4-ETH: The ESP32-P4 connects to the IP101GRI via the RMII interface, and the RJ45 Ethernet port is connected through a network transformer. The development board uses the MAC layer integrated inside the ESP32-P4 chip to manage data frame encapsulation, checksums, and MAC addresses.
- Network Layer and Transport Layer of ESP32-P4-ETH: Implemented by the ESP32-P4 driving the IP101GRI.
- Application Layer of ESP32-P4-ETH: Once successfully connected to the network, the ESP32-P4 can implement HTTP requests, communicate with servers using MQTT, etc.
Demo Demonstration
This example demonstrates the basic usage of Ethernet driver and esp_netif. The initialization of the Ethernet driver is included in a separate subcomponent of the project to clearly distinguish between the initialization of the driver and the initialization of the esp_netif. The workflow for this demo is as follows:

-
RMII Definition: As mentioned earlier, the connection between the ESP32-P4 chip and the IP101GRI chip on the ESP32-P4-ETH is established via the RMII interface. The interface definitions are as follows:
TXD[1:0]: Transmit data lines, controlled by GPIO34, GPIO35RXD[1:0]: Receive data lines, controlled by GPIO30, GPIO29TX_EN: Transmit enable signal, controlled by GPIO49CRS_DV: Carrier sense and data valid signals, controlled by GPIO28REF_CLK: Reference clock, controlled by GPIO50, 50MHz generated by multiplying the 25 MHz passive crystal connected on the PHY sideMDIOandMDC: Management data interface for Ethernet (controlling and configuring the PHY), controlled by GPIO52, GPIO31RESET: Controls IP101GRI reset, controlled by GPIO51
-
Open the
ethernetbasicproject, select the correct COM port and chip model, click ⚙️ to enter settings. This will open a new tab: SDK Configuration editor(menuconfig). Search for "ETH" directly in the search bar. You will see the relevant content. Match the parameters in the image below accordingly:
-
Next, you can directly click 🔥 to compile, flash, and monitor. After completion, the terminal will show the program starting. When you insert the Ethernet cable, an IP address will be obtained; when you unplug it, the disconnection action will be shown, as in the image:

-
From the router, you can see a device named
espressifhas connected. At this point, the ESP32-P4-ETH is already connected to the network.
2. SDMMC Example
The ESP32-P4-ETH features an onboard 4-Wire SDIO 3.0 card slot for expanding off-chip storage.
-
Supported Rate Modes
- Default rate (20 MHz)
- High-speed mode (40 MHz)
-
Configuring Bus Width and Frequency
In ESP-IDF, configuration is set using
sdmmc_host_tandsdmmc_slot_config_t. For example, to set the default 20 MHz communication frequency with a 4‑line bus width, it would be:sdmmc_host_t host = SDMMC_HOST_DEFAULT();sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();In the design that supports 40 MHz communication, you can adjust the max_freq_khz field in the sdmmc_host_t structure to increase the bus frequency:
sdmmc_host_t host = SDMMC_HOST_DEFAULT();host.max_freq_khz = SDMMC_FREQ_HIGHSPEED;The SDMMC 4-wire connection on the ESP32-P4-ETH should be defined as:
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();slot_config.width = 4;slot_config.clk = 43;slot_config.cmd = 44;slot_config.d0 = 39;slot_config.d1 = 40;slot_config.d2 = 41;slot_config.d3 = 42;slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;-
Open the SDMMC project, select the appropriate COM port and chip model. Since the demo project defines the pins as macros, they need to be configured here; alternatively, you can directly enter the pin numbers. Click
⚙️button to enter the settings. This will open a new tab: SDK Configuration editor, also known as menuconfig. In the search bar, type SD to find the relevant configuration. The example settings are already prepared. Enable the option for default initialization and ensure the example file is created by default.
-
Next, insert the prepared TF card. Click 🔥 to compile, flash and monitor. After completion, the terminal will display a command menu and list the contents of the directory on the TF card.

-
3. I2S Audio Example
I2S (Inter-IC Sound) is a digital communication protocol designed for transmitting audio data. I2S is a serial bus interface mainly used for digital audio data transmission between audio devices, such as Digital Signal Processors (DSPs), Digital-to-Analog Converters (DACs), Analog-to-Digital Converters (ADCs), and audio codecs. The ESP32-P4 includes one I2S peripheral. By configuring these peripherals, you can use the I2S driver to input and output sampled data.
The ESP32-P4-ETH board integrates an ES8311 Codec chip and an NS4150B power amplifier. The I2S bus and pin assignments are as follows:
- MCLK (Master Clock): The master clock signal. The clock is typically provided to the ES8311 by an external device (such as an MCU or DSP), which serves as the clock source for its internal digital audio processing module.
- SCLK (Serial Clock): The serial clock signal. This signal is typically used for clock synchronization for I2S data transmission and is generated by the master device to indicate the rate at which the data is transferred. The transmission of each bit of each audio sample requires a clock cycle.
- ASDOUT (Audio Serial Data Output) or DOUT: The audio data output pin. The ES8311 outputs decoded digital audio data to this pin, which is then transmitted to an amplifier chip or other audio device.
- LRCK (Left/Right Clock) or WS (Word Select): The left/right channel selection signal, indicating whether the current data sample belongs to the left or right channel. Typically in the I2S protocol, one clock cycle represents the left channel data and the other clock cycle represents the right channel data.
- DSDIN (Digital Serial Data Input) or DIN: The digital audio data input pin. This pin receives audio data from an external audio device or a master. The ES8311 decodes this data and processes the audio signals through an internal digital signal processing module.

| Functional Pin | ESP32-P4-ETH Pin |
|---|---|
| MCLK | GPIO13 |
| SCLK | GPIO12 |
| ASDOUT | GPIO11 |
| LRCK | GPIO10 |
| DSDIN | GPIO9 |
| PA_Ctrl (Power amplifier chip enable pin, active high) | GPIO53 |
The ES8311 driver for ESP32-P4-ETH utilizes the ES8311 component, which can be added via the IDF Component Manager:
idf.py add-dependency "espressif/es8311"
-
Open the
i2scodecproject and proceed to add the required components.
- Open the ESP-IDF Terminal.
- Add the required components in the Terminal.
- After successful addition, an
idf_component.ymlfile will appear in the main folder of the project. As explained in the ESP‑IDF project directory section, this file is used to manage project components. - Once opened, you can see that
espressif/es8311component has been added, and will be included in the project during the build process.
-
Next, click the ⚙️ button to open the settings, search for Example, and adjust the volume to a suitable level.

-
Connect the speaker, you can directly compile, flash, and monitor by clicking 🔥. After completion, the terminal will display the following result, indicating that the ESP32-P4-ETH is now playing audio.

-
When the
echomode is set in the settings, the audio will be recorded by the microphone and output through the speaker.
4. MIPI-DSI Display Example
The ESP32-P4-ETH utilizes the ESP32-P4NRW32 chip, which features the following new capabilities:
- Compliant with the MIPI-DSI protocol, using D-PHY v1.1, supporting up to 2-lane x 1.5Gbps (3Gbps total)
- Supports RGB888, RGB565, and YUV422 input formats
- Supports RGB888, RGB666, and RGB565 output formats
- Uses video mode to output video streams and supports outputting fixed image patterns
For MIPI-DSI image processing, it can also utilize the 2D-DMA controller, supporting the PPA and JPEG codec peripherals.
MIPI-DSI LCD Driving Principle

Hardware Required
- Compatible 10.1inch display and its accessories, or other supported screens
- ESP32-P4-ETH development board
Display Initialization Steps
-
The compatible screen driver has been packaged as a component, available in the ESP Component Registry
-
Open the corresponding project, select the esp32p4 target, then proceed by clicking 🔥 to compile, flash, and monitor. Upon completion, you can observe that the screen has lit up and is displaying color bars.

Advanced
1. LVGL HMI Human-Machine Interaction
This example shows that the ESP32-P4 displays LVGL images through the MIPI DSI interface, which fully demonstrates the powerful image processing capabilities of the ESP32-P4
Hardware Required
- Compatible 10.1inch display and its accessories, or other supported screens
- ESP32-P4-ETH development board
Display Initialization Steps
-
The compatible screen driver is packaged as a component and invoked via the BSP (Board Support Package).
-
After opening the project, configure the relevant parameters in menuconfig under the Display settings. Select the esp32p4 target, then proceed by clicking 🔥 to compile, flash, and monitor. Upon completion, the display will show the rendered images.






Comprehensive Application
1. ESP-Phone
This example is based on ESP_Brookesia and demonstrates an Android-like interface containing various applications. This example uses the board's MIPI-DSI port, MIPI-CSI port, ESP32-C6, TF card slot, and audio jack. Based on this example, you can create a use case based on ESP_Brookesia to efficiently develop multimedia applications.
Hardware Required
- Compatible 10.1inch display and its accessories, or other supported screens
- OV5647 or SC2336 camera and cable
- 8Ω 2W speaker
- ESP32-P4-ETH development board
Display Initialization Steps
-
The compatible screen driver has been packaged as a component, located in the ESP Component Registry
-
After opening the project, select the esp32p4 core, and you can directly click 🔥 to compile, flash, and monitor. After completion, you can view the screen:





