The new tiny and low power RISC-V MCU from Espressif – ESP32-C3 – has been around for a while now. While the ESP-IDF has grown to have good support for all core features, there are items that need your attention when you are trying to port ESP32 code to ESP32-C3.
This article with notes is a result of changes I had to make when trying to port ESP-ADF Lyra audio kit driver from ESP32 to ESP32-C3. ESP32-C3 examples do not use an ES8388 codec within the ESP-ADF, which means you need to port the code to make audio applications with ESP32-C3 and ES8388. In this case, we are using our ES8388 codec module.
Most generic, everyday code can simply work with an ESP32-C3. There are some major limitations that you need to work around. Here is a list of the common ones that you will have to deal with:
1. ESP32-C3 is single core
The ESP32-C3 should be treated like an ESP8266.
It only has a single core that runs at 160 MHz. While that is a lot of processing power in the embedded world, you must take care that your RTOS code is capable of running on the same core that also handles all real-time networking tasks.
In case of audio and GUI applications, this means that you must offload all large data transfers to the DMA and also ensure that your tasks do not completely block the core or starve the idle process.
Converting all polling based code segments to interrupt, RTOS event or flag based processes is a good idea to start with.
2. Lower GPIO count
ESP32 had more GPIOs to work with. When you port ESP32 code to the ESP32-C3, you need to make sure your application can run with constrained GPIOs.
The number of GPIOs alone should not be considered. There are other factors that matter too:
- Strapping pin states must be respected
- RTC domain and analog GPIOs vs digital, regular GPIOs
- Default pull-up or pull-down state of the GPIO (in ultra low power applications)
- If external flash is used in DIO mode, 2 GPIOs can be used for other functions
Here is a good list of ESP32-C3 GPIOs and capabilities.
If you leave unavailable GPIO numbers in the source code, you will encounter errors like
error: ‘GPIO_NUM_23’ undeclared (first use in this function); did you mean ‘GPIO_NUM_21’?
3. Lower peripheral count
Peripheral count is low on the ESP32-C3. You do not get 3 I2C blocks or multiple SPI and I2S hosts with parallel interface options for cameras and displays like you had on the ESP32. Therefore, you need to remove references from the code to peripheral indices that do not exist on the ESP32-C3.
While peripherals may appear similar, there are subtle differences:
- I2S peripheral does not have parallel data option
- There is no APLL on ESP32-C3, the I2S needs to be clocked from PLL_D2_CLK instead
- many other similar differences that are noted in the technical reference manual
If you mention a peripheral that does not exist, you will see errors like the following:
error: ‘I2C_NUM_1’ undeclared (first use in this function); did you mean ‘I2C_NUM_0’?
4. Although similar, ESP-IDF functions may differ
You can do certain things with the ESP32-C3 that are not possible in the regular ESP32 series. For example, the ESP32-C3 MCLK output for the audio MCLK can be routed through the GPIO matrix to any GPIO. With the ESP32, you could not do that.
So with the ESP32-C3, you can initialize the I2S structure and route MCLK to any GPIO without the need to explicitly enable clock output using additional code. The same function call will fail for an ESP32.
Feel free to ask away via the Quick Contact form in the sidebar, or leave a comment below.
- 28 January 2023
– Initial Release