diff --git a/Documentation/platforms/risc-v/esp32c2/boards/esp8684-devkitm/esp8684-devkitm-1-pinout_v1.1.png b/Documentation/platforms/risc-v/esp32c2/boards/esp8684-devkitm/esp8684-devkitm-1-pinout_v1.1.png new file mode 100644 index 00000000000..fe9d50fff3c Binary files /dev/null and b/Documentation/platforms/risc-v/esp32c2/boards/esp8684-devkitm/esp8684-devkitm-1-pinout_v1.1.png differ diff --git a/Documentation/platforms/risc-v/esp32c2/boards/esp8684-devkitm/esp8684-devkitm-1-v0.1-block-diagram.png b/Documentation/platforms/risc-v/esp32c2/boards/esp8684-devkitm/esp8684-devkitm-1-v0.1-block-diagram.png new file mode 100644 index 00000000000..4e42842da89 Binary files /dev/null and b/Documentation/platforms/risc-v/esp32c2/boards/esp8684-devkitm/esp8684-devkitm-1-v0.1-block-diagram.png differ diff --git a/Documentation/platforms/risc-v/esp32c2/boards/esp8684-devkitm/esp8684-devkitm-1-v1.1-annotated-photo.png b/Documentation/platforms/risc-v/esp32c2/boards/esp8684-devkitm/esp8684-devkitm-1-v1.1-annotated-photo.png new file mode 100644 index 00000000000..bf87792bbe7 Binary files /dev/null and b/Documentation/platforms/risc-v/esp32c2/boards/esp8684-devkitm/esp8684-devkitm-1-v1.1-annotated-photo.png differ diff --git a/Documentation/platforms/risc-v/esp32c2/boards/esp8684-devkitm/esp8684-devkitm-1-v1.1-isometric.png b/Documentation/platforms/risc-v/esp32c2/boards/esp8684-devkitm/esp8684-devkitm-1-v1.1-isometric.png new file mode 100644 index 00000000000..0f92ea9d438 Binary files /dev/null and b/Documentation/platforms/risc-v/esp32c2/boards/esp8684-devkitm/esp8684-devkitm-1-v1.1-isometric.png differ diff --git a/Documentation/platforms/risc-v/esp32c2/boards/esp8684-devkitm/index.rst b/Documentation/platforms/risc-v/esp32c2/boards/esp8684-devkitm/index.rst new file mode 100644 index 00000000000..088bb894581 --- /dev/null +++ b/Documentation/platforms/risc-v/esp32c2/boards/esp8684-devkitm/index.rst @@ -0,0 +1,669 @@ +================= +ESP8684-DevKitM-1 +================= + +.. tags:: chip:esp32c2, chip:esp8684, arch:risc-v, vendor:espressif + +ESP8684-DevKitM-1 is an entry-level development board based on ESP8684-MINI-1, +a general-purpose module with 1 MB/2 MB/4 MB SPI flash. The module uses the +ESP32-C2 SoC and integrates Wi-Fi and Bluetooth LE. You can find the board +schematic +`here `_ +and the vendor user guide +`here `__. + +Most of the I/O pins are broken out to the pin headers on both sides for easy +interfacing. Developers can either connect peripherals with jumper wires or +mount ESP8684-DevKitM-1 on a breadboard. + +Toolchain, flashing and the serial console are described in the +:doc:`ESP32-C2 chip documentation <../../index>`. + +.. figure:: esp8684-devkitm-1-v1.1-isometric.png + :alt: ESP8684-DevKitM-1 Board Layout + :figclass: align-center + + ESP8684-DevKitM-1 with ESP8684-MINI-1 module + +The block diagram below presents the main components of the ESP8684-DevKitM-1. + +.. figure:: esp8684-devkitm-1-v0.1-block-diagram.png + :alt: ESP8684-DevKitM-1 Electrical Block Diagram + :figclass: align-center + + ESP8684-DevKitM-1 Electrical Block Diagram + +Hardware Components +------------------- + +.. figure:: esp8684-devkitm-1-v1.1-annotated-photo.png + :alt: ESP8684-DevKitM-1 Hardware Components + :figclass: align-center + + ESP8684-DevKitM-1 Hardware Components + +===================== ======================================================== +Key Component Description +===================== ======================================================== +ESP8684-MINI-1 Wi-Fi and Bluetooth LE module with PCB antenna and + on-board SPI flash (1 MB/2 MB/4 MB). Typical XTAL is + 26 MHz. +5 V to 3.3 V LDO Converts USB or 5 V header power to 3.3 V. +5 V Power On LED Turns on when USB power is connected. +Pin Headers All available GPIO pins broken out on J1 and J3. +Boot Button Download button. Hold **Boot** and press **Reset** to + enter Firmware Download mode. +Micro-USB Port Power supply and USB-to-UART communication. +Reset Button Restarts the system (connected to CHIP_EN). +USB-to-UART Bridge Single USB-to-UART bridge, up to 3 Mbps. +RGB LED On v1.1: discrete RGB LED on GPIO0 (R), GPIO1 (G) and + GPIO8 (B). On v1.0: addressable RGB LED on GPIO8 only. +===================== ======================================================== + +This board has no USB-Serial-JTAG port on the SoC. Console and flashing use +the on-board USB-to-UART bridge. + +Buttons and LEDs +================ + +Board Buttons +------------- + +There are two buttons labeled Boot and RST. The RST button is not available +to software. It pulls the chip enable line that doubles as a reset line. + +The BOOT button is connected to GPIO9. On reset it is used as a strapping +pin to determine whether the chip boots normally or into the serial +bootloader. After reset, however, the BOOT button can be used for software +input. + +Board LEDs +---------- + +There is one on-board LED that indicates the presence of USB power. + +The RGB LED mapping depends on the hardware revision: + +* **v1.1 (current):** discrete RGB LED driven by GPIO0 (red), GPIO1 (green) + and GPIO8 (blue). This is the mapping used by NuttX + (``LED_RED``, ``LED_GREEN`` and ``LED_BLUE`` in ``board.h``). +* **v1.0:** addressable RGB LED driven only by GPIO8. + +Both revisions are available on the market. See +`Hardware Revision Details `_. +GPIO8 and GPIO9 are also strapping pins of the ESP8684 chip. + +Power Supply +============ + +There are three mutually exclusive ways to provide power to the board: + +* Micro-USB port (default, recommended) +* 5V and G (GND) pins +* 3V3 and G (GND) pins + +Use a USB 2.0 cable (Standard-A to Micro-B) that carries data lines. +Charge-only cables will not enumerate the USB-to-UART bridge and cannot be +used to flash the board. + +Pin Mapping +=========== + +.. figure:: esp8684-devkitm-1-pinout_v1.1.png + :alt: ESP8684-DevKitM-1 pin layout + :figclass: align-center + + ESP8684-DevKitM-1 Pin Layout + +Default NuttX pin assignments for this board: + +============= ========== ========================================= +ESP8684 Pin Signal Notes +============= ========== ========================================= +GPIO20 U0TXD UART0 TX (serial console) +GPIO19 U0RXD UART0 RX (serial console) +GPIO9 BOOT Strapping pin; user button after reset +GPIO0 LED Red RGB LED (v1.1); ADC1_CH0 +GPIO1 LED Green RGB LED (v1.1); ADC1_CH1 +GPIO8 LED Blue RGB LED (v1.1) / WS2812 (v1.0); strapping +GPIO6 I2C0 SCL Default I2C clock +GPIO5 I2C0 SDA Default I2C data; ADC2_CH0 +GPIO7 SPI2 MOSI Default SPI2 MOSI (FSPID) +GPIO2 SPI2 MISO Default SPI2 MISO (FSPIQ); LEDC PWM ch0 +GPIO10 SPI2 CS Default SPI2 chip select +GPIO6 SPI2 CLK Default SPI2 clock (shared with I2C SCL) +============= ========== ========================================= + +**J1** + +===== ========== ========================================= +Pin Signal Notes +===== ========== ========================================= +1 G Ground +2 3V3 3.3 V power supply +3 3V3 3.3 V power supply +4 GPIO2 ADC1_CH2, FSPIQ +5 GPIO3 ADC1_CH3 +6 G Ground +7 RST CHIP_EN; High: enable; Low: power off +8 G Ground +9 GPIO0 ADC1_CH0, LED Red (v1.1) +10 GPIO1 ADC1_CH1, LED Green (v1.1) +11 GPIO10 FSPICS0 +12 G Ground +13 5V 5 V power supply +14 5V 5 V power supply +15 G Ground +===== ========== ========================================= + +**J3** + +===== ========== ========================================= +Pin Signal Notes +===== ========== ========================================= +1 G Ground +2 TX GPIO20, U0TXD +3 RX GPIO19, U0RXD +4 G Ground +5 GPIO9 Strapping pin, BOOT button +6 GPIO8 Strapping pin, LED Blue (v1.1) +7 G Ground +8 GPIO7 FSPID, MTDO +9 GPIO6 FSPICLK, MTCK +10 GPIO5 ADC2_CH0, FSPIWP, MTDI +11 GPIO4 ADC1_CH4, FSPIHD, MTMS +12 G Ground +13 GPIO18 +14 G Ground +15 G Ground +===== ========== ========================================= + +GPIO8 and GPIO9 are strapping pins. Their level at reset selects boot and +download mode. See the +`ESP8684 Datasheet `_ +section *Strapping Pins*. + +Configurations +============== + +All of the configurations presented below can be tested by running the following commands:: + + $ ./tools/configure.sh esp8684-devkitm: + $ make flash ESPTOOL_PORT=/dev/ttyUSB0 -j + +Where ```` is the name of board configuration you want to use, +i.e.: nsh, buttons, wifi... +Then use a serial console terminal like ``picocom`` configured to 115200 8N1. + +adc +--- + +The ``adc`` configuration enables the ADC driver and the ADC example application. +ADC Unit 1 is registered to ``/dev/adc0`` with channels 0, 1, 2 and 3 enabled by default. +Currently, the ADC operates in oneshot mode. + +More ADC channels can be enabled or disabled in ``ADC Configuration`` menu. + +This example shows channels 0 and 1 connected to 3.3 V and channels 2 and 3 to GND (all readings +show in units of mV):: + + nsh> adc -n 1 + adc_main: g_adcstate.count: 1 + adc_main: Hardware initialized. Opening the ADC device: /dev/adc0 + Sample: + 1: channel: 0 value: 2900 + 2: channel: 1 value: 2900 + 3: channel: 2 value: 0 + 4: channel: 3 value: 0 + +ble +--- + +This configuration is used to enable the Bluetooth Low Energy (BLE) of +the ESP32-C2 chip. + +To test it, just run the following commands below. + +Confirm that bnep interface exist:: + + nsh> ifconfig + bnep0 Link encap:UNSPEC at DOWN + inet addr:0.0.0.0 DRaddr:0.0.0.0 Mask:0.0.0.0 + +Get basic information from it:: + + nsh> bt bnep0 info + Device: bnep0 + BDAddr: 86:f7:03:09:41:4d + Flags: 0000 + Free: 20 + ACL: 20 + SCO: 0 + Max: + ACL: 24 + SCO: 0 + MTU: + ACL: 70 + SCO: 0 + Policy: 0 + Type: 0 + +Start the scanning process:: + + nsh> bt bnep0 scan start + +Wait a little bit before stopping it. + +Then after some minutes stop it:: + + nsh> bt bnep0 scan stop + +Get the list of BLE devices found around you:: + + nsh> bt bnep0 scan get + Scan result: + 1. addr: d7:c4:e6:xx:xx:xx type: 0 + rssi: -62 + response type: 4 + advertiser data: 10 09 4d 69 20 XX XX XX XX XX XX XX XX XX XX 20 e + nsh> + +bmp180 +------ + +This configuration enables the use of the BMP180 pressure sensor over I2C. +You can check that the sensor is working by using the ``bmp180`` application:: + + nsh> bmp180 + Pressure value = 91531 + Pressure value = 91526 + Pressure value = 91525 + +buttons +------- + +This configuration shows the use of the buttons subsystem. It can be used by executing +the ``buttons`` application and pressing the ``BOOT`` button on the board:: + + nsh> buttons + buttons_main: Starting the button_daemon + buttons_main: button_daemon started + button_daemon: Running + button_daemon: Opening /dev/buttons + button_daemon: Supported BUTTONs 0x01 + nsh> Sample = 1 + Sample = 0 + +crypto +------ + +This configuration enables support for the cryptographic hardware and +the ``/dev/crypto`` device file. Currently, we are supporting SHA-1, +and SHA-256 algorithms using hardware. +To test hardware acceleration, you can use `hmac` example and following output +should look like this:: + + nsh> hmac + ... + hmac sha1 success + hmac sha1 success + hmac sha1 success + hmac sha256 success + hmac sha256 success + hmac sha256 success + +efuse +----- + +This configuration demonstrates the use of the eFuse driver. It can be accessed +through the ``/dev/efuse`` device file. +Virtual eFuse mode can be used by enabling `CONFIG_ESPRESSIF_EFUSE_VIRTUAL` +option to prevent possible damages on chip. + +The following snippet demonstrates how to read MAC address: + +.. code-block:: C + + int fd; + int ret; + uint8_t mac[6]; + struct efuse_param_s param; + struct efuse_desc_s mac_addr = + { + .bit_offset = 1, + .bit_count = 48 + }; + + const efuse_desc_t* desc[] = + { + &mac_addr, + NULL + }; + param.field = desc; + param.size = 48; + param.data = mac; + + fd = open("/dev/efuse", O_RDONLY); + ret = ioctl(fd, EFUSEIOC_READ_FIELD, ¶m); + +To find offset and count variables for related eFuse, +please refer to Espressif's Technical Reference Manuals. + +gpio +---- + +This is a test for the GPIO driver. It uses GPIO1 and GPIO2 as outputs and +GPIO9 as an interrupt pin. + +At the nsh, we can turn the outputs on and off with the following:: + + nsh> gpio -o 1 /dev/gpio0 + nsh> gpio -o 1 /dev/gpio1 + + nsh> gpio -o 0 /dev/gpio0 + nsh> gpio -o 0 /dev/gpio1 + +We can use the interrupt pin to send a signal when the interrupt fires:: + + nsh> gpio -w 14 /dev/gpio2 + +The pin is configured as a rising edge interrupt, so after issuing the +above command, connect it to 3.3V. + +To use dedicated gpio for controlling multiple gpio pin at the same time +or having better response time, you need to enable +`CONFIG_ESPRESSIF_DEDICATED_GPIO` option. Dedicated GPIO is suitable +for faster response times required applications like simulate serial/parallel +interfaces in a bit-banging way. +After this option enabled GPIO4 and GPIO5 pins are ready to used as dedicated GPIO pins +as input/output mode. These pins are for example, you can use any pin up to 8 pins for +input and 8 pins for output for dedicated gpio. +To write and read data from dedicated gpio, you need to use +`write` and `read` calls. + +The following snippet demonstrates how to read/write to dedicated GPIO pins: + +.. code-block:: C + + int fd = open("/dev/dedic_gpio0", O_RDWR); + int rd_val = 0; + int wr_mask = 0xffff; + int wr_val = 3; + + while(1) + { + write(fd, &wr_val, wr_mask); + if (wr_val == 0) + { + wr_val = 3; + } + else + { + wr_val = 0; + } + read(fd, &rd_val, sizeof(uint32_t)); + printf("rd_val: %d", rd_val); + } + +i2c +--- + +This configuration can be used to scan and manipulate I2C devices. +You can scan for all I2C devices using the following command:: + + nsh> i2c dev 0x00 0x7f + +Default pins are GPIO6 (SCL) and GPIO5 (SDA). + +To use slave mode, you can enable `ESPRESSIF_I2C0_SLAVE_MODE` option. +To use slave mode driver following snippet demonstrates how write to i2c bus +using slave driver: + +.. code-block:: C + + #define ESP_I2C_SLAVE_PATH "/dev/i2cslv0" + int main(int argc, char *argv[]) + { + int i2c_slave_fd; + int ret; + uint8_t buffer[5] = {0xAA}; + i2c_slave_fd = open(ESP_I2C_SLAVE_PATH, O_RDWR); + ret = write(i2c_slave_fd, buffer, 5); + close(i2c_slave_fd); + } + +mcuboot_nsh +----------- + +This configuration is the same as the ``nsh`` configuration, but it generates the application +image in a format that can be used by MCUboot. It also makes the ``make bootloader`` command to +build the MCUboot bootloader image using the Espressif HAL. + +See :ref:`MCUBoot C2` for flash-layout limits on 2 MB modules. NuttX MCUBoot +support for ESP32-C2 is still in progress; there is no ``mcuboot_update_agent`` +configuration for this board. + +nsh +--- + +Basic configuration to run the NuttShell (nsh). + +ostest +------ + +This is the NuttX test at ``apps/testing/ostest`` that is run against all new +architecture ports to assure a correct implementation of the OS. + +pwm +--- + +This configuration demonstrates the use of PWM through LEDC channel 0, +which defaults to GPIO2. To test it, just execute the ``pwm`` application:: + + nsh> pwm + pwm_main: starting output with frequency: 10000 duty: 00008000 + pwm_main: stopping output + +random +------ + +This configuration shows the use of the ESP32-C2's True Random Number Generator. +To test it, just run ``rand`` to get 32 randomly generated bytes:: + + nsh> rand + Reading 8 random numbers + Random values (0x3ffe0b00): + 0000 98 b9 66 a2 a2 c0 a2 ae 09 70 93 d1 b5 91 86 c8 ..f......p...... + 0010 8f 0e 0b 04 29 64 21 72 01 92 7c a2 27 60 6f 90 ....)d!r..|.'`o. + +romfs +----- + +This configuration demonstrates the use of ROMFS (Read-Only Memory File System) to provide +automated system initialization and startup scripts. ROMFS allows embedding a read-only +filesystem directly into the NuttX binary, which is mounted at ``/etc`` during system startup. + +**What ROMFS provides:** + +* **System initialization script** (``/etc/init.d/rc.sysinit``): Executed after board bring-up +* **Startup script** (``/etc/init.d/rcS``): Executed after system init, typically used to start applications + +**Default behavior:** + +When this configuration is used, NuttX will: + +1. Create a read-only RAM disk containing the ROMFS filesystem +2. Mount the ROMFS at ``/etc`` +3. Execute ``/etc/init.d/rc.sysinit`` during system initialization +4. Execute ``/etc/init.d/rcS`` for application startup + +**Customizing startup scripts:** + +The startup scripts are located in: +``boards/risc-v/esp32c2/common/src/etc/init.d/`` + +* ``rc.sysinit`` - System initialization script +* ``rcS`` - Application startup script + +To customize these scripts: + +1. **Edit the script files** in ``boards/risc-v/esp32c2/common/src/etc/init.d/`` +2. **Add your initialization commands** using any NSH-compatible commands + +**Example customizations:** + +* **rc.sysinit** - Set up system services, mount additional filesystems, configure network. +* **rcS** - Start your application, launch daemons, configure peripherals. This is executed after the rc.sysinit script. + +Example output:: + + *** Booting NuttX *** + [...] + rc.sysinit is called! + rcS file is called! + NuttShell (NSH) NuttX-12.8.0 + nsh> ls /etc/init.d + /etc/init.d: + . + .. + rc.sysinit + rcS + +rtc +--- + +This configuration demonstrates the use of the RTC driver through alarms. +You can set an alarm, check its progress and receive a notification after it expires:: + + nsh> alarm 10 + alarm_daemon started + alarm_daemon: Running + Opening /dev/rtc0 + Alarm 0 set in 10 seconds + nsh> alarm -r + Opening /dev/rtc0 + Alarm 0 is active with 10 seconds to expiration + nsh> alarm_daemon: alarm 0 received + +The ESP32-C2 has no RTC retention memory, so the saved time does not +survive deep sleep. + +sdmmc_spi +--------- + +This configuration is used to mount a FAT/FAT32 SD Card into the OS' filesystem. +It uses SPI to communicate with the SD Card, defaulting to SPI2. + +The SD slot number, SPI port number and minor number can be modified in ``Application Configuration → NSH Library``. + +To access the card's files, make sure ``/dev/mmcsd0`` exists and then execute the following commands:: + + nsh> ls /dev + /dev: + console + mmcsd0 + null + ttyS0 + zero + nsh> mount -t vfat /dev/mmcsd0 /mnt + +This will mount the SD Card to ``/mnt``. Now, you can use the SD Card as a normal filesystem. +For example, you can read a file and write to it:: + + nsh> ls /mnt + /mnt: + hello.txt + nsh> cat /mnt/hello.txt + Hello World + nsh> echo 'NuttX RTOS' >> /mnt/hello.txt + nsh> cat /mnt/hello.txt + Hello World! + NuttX RTOS + nsh> + +spi +--- + +This configuration enables the support for the SPI driver. +You can test it by connecting MOSI and MISO pins which are GPIO7 and GPIO2 +by default to each other and running the ``spi`` example:: + + nsh> spi exch -b 2 "AB" + Sending: AB + Received: AB + +If SPI peripherals are already in use you can also use bitbang driver which is a +software implemented SPI peripheral by enabling `CONFIG_ESPRESSIF_SPI_BITBANG` +option. + +spiflash +-------- + +This config tests the external SPI that comes with the ESP8684-MINI-1 module +connected through SPI1. + +By default a SmartFS file system is selected. +Once booted you can use the following commands to mount the file system:: + + nsh> mksmartfs /dev/smart0 + nsh> mount -t smartfs /dev/smart0 /mnt + +The storage partition defaults to offset ``0x110000`` and size ``0xf0000`` +on 2 MB flash so that it fits after the application image. + +temperature_sensor +------------------ + +This configuration enables the on-chip temperature sensor driver. The sensor is +exposed through the uORB interface and can be read with the ``sensortest`` +utility:: + + nsh> sensortest temp + +tickless +-------- + +This configuration enables the support for tickless scheduler mode. + +timers +------ + +This configuration tests the general purpose timer. The ESP32-C2 has a +single timer group. It adds driver support, registers the timer as a device +and includes the timer example. + +To test it, just run the following:: + + nsh> timer -d /dev/timer0 + +watchdog +-------- + +This configuration tests the watchdog timers. It includes the MWDT of the +single timer group, adds driver support, registers the WDT as a device and +includes the watchdog example application. + +To test it, just run the following command:: + + nsh> wdog -i /dev/watchdog0 + +wifi +---- + +Enables Wi-Fi support. You can define your credentials this way:: + + $ make menuconfig + -> Application Configuration + -> Network Utilities + -> Network initialization (NETUTILS_NETINIT [=y]) + -> WAPI Configuration + +Or if you don't want to keep it saved in the firmware you can do it +at runtime:: + + nsh> wapi psk wlan0 mypasswd 3 + nsh> wapi essid wlan0 myssid 1 + nsh> renew wlan0 + +.. tip:: Please refer to :ref:`ESP32 Wi-Fi Station Mode ` + for more information. diff --git a/Documentation/platforms/risc-v/esp32c2/index.rst b/Documentation/platforms/risc-v/esp32c2/index.rst new file mode 100644 index 00000000000..1e9e106b710 --- /dev/null +++ b/Documentation/platforms/risc-v/esp32c2/index.rst @@ -0,0 +1,635 @@ +.. _esp32c2: + +================== +Espressif ESP32-C2 +================== + +The ESP32-C2 (also sold as ESP8684) is a highly integrated, low-power SoC +with a RISC-V core. It supports 2.4 GHz Wi-Fi 4 (802.11b/g/n) and +Bluetooth 5 (LE). + +* Internal Memory + - 576 KB ROM + - 272 KB SRAM (16 KB can be configured as cache) + - No RTC retention SRAM (saved RTC time does not survive deep sleep) +* External Memory + - SPI flash in the module (typically 1 MB, 2 MB or 4 MB) +* Connectivity + - 2.4 GHz Wi-Fi + - Bluetooth Low Energy 5 +* GPIO + - 14 user GPIOs (GPIO0–GPIO10, GPIO18–GPIO20) +* Clock + - Main XTAL is 26 MHz on ESP8684-MINI-1 modules (40 MHz is also supported) + +ESP32-C2 Toolchain +================== + +A generic RISC-V toolchain can be used to build ESP32-C2 projects. It's recommended to use the same +toolchain used by NuttX CI. Please refer to the Docker +`container `_ and +check for the current compiler version being used. For instance: + +.. code-block:: + + ############################################################################### + # Build image for tool required by RISCV builds + ############################################################################### + FROM nuttx-toolchain-base AS nuttx-toolchain-riscv + # Download the latest RISCV GCC toolchain prebuilt by xPack + RUN mkdir riscv-none-elf-gcc && \ + curl -s -L "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz" \ + | tar -C riscv-none-elf-gcc --strip-components 1 -xz + +It uses the xPack's prebuilt toolchain based on GCC 13.2.0-2. + +Installing +---------- + +First, create a directory to hold the toolchain: + +.. code-block:: console + + $ mkdir -p /path/to/your/toolchain/riscv-none-elf-gcc + +Download and extract toolchain: + +.. code-block:: console + + $ curl -s -L "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz" \ + | tar -C /path/to/your/toolchain/riscv-none-elf-gcc --strip-components 1 -xz + +Add the toolchain to your `PATH`: + +.. code-block:: console + + $ echo "export PATH=/path/to/your/toolchain/riscv-none-elf-gcc/bin:$PATH" >> ~/.bashrc + +You can edit your shell's rc files if you don't use bash. + +Building and flashing NuttX +=========================== + +Installing esptool +------------------ + +Make sure that ``esptool.py`` is installed and up-to-date. +This tool is used to convert the ELF to a compatible ESP32-C2 image and to flash the image into the board. + +It can be installed with: ``pip install esptool>=4.8.1``. + +.. warning:: + Installing ``esptool.py`` may required a Python virtual environment on newer systems. + This will be the case if the ``pip install`` command throws an error such as: + ``error: externally-managed-environment``. + + If you are not familiar with virtual environments, refer to `Managing esptool on virtual environment`_ for instructions on how to install ``esptool.py``. + +Bootloader and partitions +------------------------- + +NuttX can boot the ESP32-C2 directly using the so-called "Simple Boot". +An externally-built 2nd stage bootloader is not required in this case as all +functions required to boot the device are built within NuttX. Simple boot does not +require any specific configuration (it is selectable by default if no other +2nd stage bootloader is used). + +If features like `Flash Encryption`_ are required, an externally-built +2nd stage bootloader is needed. The MCUBoot bootloader is built using +the ``make bootloader`` command. This command generates the firmware in the +``nuttx`` folder. The ``ESPTOOL_BINDIR`` is used in the ``make flash`` command +to specify the path to the bootloader. For compatibility among other SoCs and +future options of 2nd stage bootloaders, the commands ``make bootloader`` and +the ``ESPTOOL_BINDIR`` option (for the ``make flash``) can be used even if no +externally-built 2nd stage bootloader is being built (they will be ignored if +Simple Boot is used, for instance):: + + $ make bootloader + +.. note:: + MCUBoot support for ESP32-C2 on NuttX is still in progress. The + ``mcuboot_nsh`` board configuration can build an MCUBoot-format image, + but there is no ``mcuboot_update_agent`` configuration yet. The default + MCUBoot slot map in Kconfig assumes at least 4 MB of flash and does + **not** fit the 2 MB modules used on many ESP8684-DevKitM-1 boards. + +.. note:: It is recommended that if this is the first time you are using the board with NuttX to + perform a complete SPI FLASH erase. + + .. code-block:: console + + $ esptool.py erase_flash + +Building and Flashing +--------------------- + +This is a two-step process where the first step converts the ELF file into an ESP32-C2 compatible binary +and the second step flashes it to the board. These steps are included in the build system and it is +possible to build and flash the NuttX firmware simply by running:: + + $ make flash ESPTOOL_PORT= ESPTOOL_BINDIR=./ + +where: + +* ``ESPTOOL_PORT`` is typically ``/dev/ttyUSB0`` or similar. +* ``ESPTOOL_BINDIR=./`` is the path of the externally-built 2nd stage bootloader and the partition table (if applicable): when built using the ``make bootloader``, these files are placed into ``nuttx`` folder. +* ``ESPTOOL_BAUD`` is able to change the flash baud rate if desired. + +The ESP32-C2 port defaults to **2 MB** flash and **60 MHz** flash clock. + +Flashing NSH Example +-------------------- + +This example shows how to build and flash the ``nsh`` defconfig for the ESP8684-DevKitM-1 board:: + + $ cd nuttx + $ make distclean + $ ./tools/configure.sh esp8684-devkitm:nsh + $ make -j$(nproc) + +When the build is complete, the firmware can be flashed to the board using the command:: + + $ make -j$(nproc) flash ESPTOOL_PORT= ESPTOOL_BINDIR=./ + +where ```` is the serial port where the board is connected:: + + $ make flash ESPTOOL_PORT=/dev/ttyUSB0 ESPTOOL_BINDIR=./ + CP: nuttx.hex + MKIMAGE: NuttX binary + esptool.py -c esp32c2 elf2image --ram-only-header -fs 2MB -fm dio -ff 60m -o nuttx.bin nuttx + [...] + Generated: nuttx.bin + esptool.py -c esp32c2 -p /dev/ttyUSB0 -b 921600 write_flash -fs 2MB -fm dio -ff 60m 0x0000 nuttx.bin + [...] + Hard resetting via RTS pin... + +Now opening the serial port with a terminal emulator should show the NuttX console:: + + $ picocom -b 115200 /dev/ttyUSB0 + NuttShell (NSH) NuttX-12.8.0 + nsh> uname -a + NuttX 12.8.0 ... risc-v esp8684-devkitm + +The USB-to-UART bridge on the DevKit exposes UART0. The default UART0 pins +are GPIO20 (TX) and GPIO19 (RX). Use a USB cable that carries data lines; +charge-only cables will not enumerate the bridge. + +Building with CMake +------------------- + +General CMake usage (out-of-tree build, ``menuconfig`` target, and so on) is described in +:doc:`/quickstart/compiling_cmake`. The ESP32-C2 common arch enables post-build steps that +produce ``nuttx.bin`` (and related images) under the **CMake binary directory**; the build +log also prints suggested ``esptool.py`` command lines for your layout. + +Example (NuttX shell defconfig, Ninja generator):: + + $ cd nuttx + $ cmake -B build -DBOARD_CONFIG=esp8684-devkitm:nsh -GNinja + $ cmake --build build + +To reconfigure the tree after changing options (same as other NuttX CMake boards):: + + $ cmake --build build -t menuconfig + $ cmake --build build + +Persistent HAL cache (``NXTMPDIR``) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Pass ``-DNXTMPDIR=ON`` at **configure** time to reuse a persistent clone of the +``esp-hal-3rdparty`` repository under ``nuttx/../nxtmpdir/esp-hal-3rdparty``. CMake checks +the expected revision; if it does not match, the cache directory is refreshed. This cuts +repeat configure/build time when the HAL checkout would otherwise be re-fetched into the +binary directory. + +Example:: + + $ cmake -B build -DBOARD_CONFIG=esp8684-devkitm:nsh -DNXTMPDIR=ON -GNinja + $ cmake --build build + +MCUBoot: building the 2nd-stage bootloader (``-t bootloader``) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For configurations that use MCUboot, build the bootloader the same way as +with Make, but via the CMake target:: + + $ cmake --build build -t bootloader + +The image is installed as ``mcuboot-esp32c2.bin`` in the NuttX **source** directory (not +inside ``build/``). + +.. note:: + + Flashing paths differ from the pure-Make flow: the application image is under your CMake + build directory (for example ``build/nuttx.bin``), while MCUboot binaries live next to + ``nuttx`` sources. + +Target flashing (``-t flash``) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +After a successful CMake build, you can flash the chip with the ``flash`` custom target. +This is the CMake-side equivalent of the Make ``FLASH`` logic in +``tools/espressif/Config.mk``. + +**Serial port:** you must set ``ESPTOOL_PORT`` to a non-empty value (for example +``/dev/ttyUSB0``). If it is unset or empty, the flash step fails. + +Example:: + + $ export ESPTOOL_PORT=/dev/ttyUSB0 + $ cmake --build build -t flash + +Or for a single invocation:: + + $ ESPTOOL_PORT=/dev/ttyUSB0 cmake --build build -t flash + +Debugging +========= + +This section describes debugging techniques for the ESP32-C2. + +Debugging with ``openocd`` and ``gdb`` +-------------------------------------- + +Espressif uses a specific version of OpenOCD to support ESP32-C2: `openocd-esp32 `_. + +Please check `Building OpenOCD from Sources `_ +for more information on how to build OpenOCD for ESP32-C2. + +The ESP32-C2 does **not** integrate a USB-to-JTAG adapter. An external JTAG +adapter is required and can be connected as follows: + +============ =========== +ESP32-C2 Pin JTAG Signal +============ =========== +GPIO4 TMS +GPIO5 TDI +GPIO6 TCK +GPIO7 TDO +============ =========== + +These pins are also the default MTMS / MTDI / MTCK / MTDO strapping functions +on the ESP8684-DevKitM-1 header. + +OpenOCD can then be used:: + + openocd -c 'set ESP_RTOS hwthread; set ESP_FLASH_SIZE 0' -f board/esp32c2-ftdi.cfg + +Once OpenOCD is running, you can use GDB to connect to it and debug your application:: + + riscv-none-elf-gdb -x gdbinit nuttx + +whereas the content of the ``gdbinit`` file is:: + + target remote :3333 + set remote hardware-watchpoint-limit 2 + mon reset halt + flushregs + monitor reset halt + thb nsh_main + c + +.. note:: ``nuttx`` is the ELF file generated by the build process. Please note that ``CONFIG_DEBUG_SYMBOLS`` must be enabled in the ``menuconfig``. + +.. note:: + ``appimage_offset`` should be set to ``0x0`` when ``Simple Boot`` is used. For MCUboot, this value should be set to + ``CONFIG_ESPRESSIF_OTA_PRIMARY_SLOT_OFFSET`` (``0x20000`` by default). + +Please refer to :doc:`/quickstart/debugging` for more information about debugging techniques. + +Stack Dump and Backtrace Dump +----------------------------- + +NuttX has a feature to dump the stack of a task and to dump the backtrace of it (and of all +the other tasks). This feature is useful to debug the system when it is not behaving as expected, +especially when it is crashing. + +In order to enable this feature, the following options must be enabled in the NuttX configuration: +``CONFIG_SCHED_BACKTRACE``, ``CONFIG_DEBUG_SYMBOLS`` and, optionally, ``CONFIG_ALLSYMS``. + +.. note:: + The first two options enable the backtrace dump. The third option enables the backtrace dump + with the associated symbols, but increases the size of the generated NuttX binary. + +Espressif also provides a tool to translate the backtrace dump into a human-readable format. +This tool is called ``btdecode.sh`` and is available at ``tools/espressif/btdecode.sh`` of NuttX +repository. + +.. note:: + This tool is not necessary if ``CONFIG_ALLSYMS`` is enabled. In this case, the backtrace dump + contains the function names. + +Save a crash dump that contains ``sched_dumpstack`` lines to a file and decode it with:: + + ./tools/espressif/btdecode.sh esp32c2 /tmp/backtrace.txt + +Peripheral Support +================== + +The following list indicates the state of peripherals' support in NuttX: + +=========== ======= ==================== +Peripheral Support NOTES +=========== ======= ==================== +ADC Yes Oneshot +AES Yes +Bluetooth Yes +CAN/TWAI No +DMA Yes +eFuse Yes Also virtual mode supported +GPIO Yes Dedicated GPIO supported +HMAC No +I2C Yes Master and Slave mode supported +I2S Yes +LED/PWM Yes +RMT Yes +RNG Yes +RSA No +RTC Yes No RTC retention SRAM +SHA Yes +SPI Yes +SPIFLASH Yes +SPIRAM No +Timers Yes One timer group +UART Yes +USB Serial No No USB-Serial-JTAG on this SoC +Watchdog Yes +Wi-Fi Yes WPA3-SAE supported +=========== ======= ==================== + +Analog-to-digital converter (ADC) +--------------------------------- + +Two ADC units are available for the ESP32-C2: + +* ADC1 with 5 channels. +* ADC2 with 1 channel. **This unit is not implemented.** + +Those units are independent and can be used simultaneously. During bringup, GPIOs for selected channels are +configured automatically to be used as ADC inputs. +If available, ADC calibration is automatically applied (see +`this page `__ for more details). +Otherwise, a simple conversion is applied based on the attenuation and resolution. + +The ADC unit is accessible using the ADC character driver, which returns data for the enabled channels. + +The ADC1 unit can be enabled in the menu :menuselection:`System Type --> Peripheral Support --> Analog-to-digital converter (ADC)`. + +Then, it can be customized in the menu :menuselection:`System Type --> ADC Configuration`, which includes operating mode, gain and channels. + +========== =========== + Channel ADC1 GPIO +========== =========== +0 0 +1 1 +2 2 +3 3 +4 4 +========== =========== + +ADC2 channel 0 is GPIO5. + +.. warning:: Maximum measurable voltage may saturate around 2900 mV. + +.. _MCUBoot C2: + +MCUBoot +======= + +The ESP32-C2 can use MCUBoot as a 2nd stage bootloader. NuttX integration is +still marked as in progress upstream (see +`MCUBoot Espressif port `__). + +The ``esp8684-devkitm:mcuboot_nsh`` configuration produces an MCUBoot-compatible +application image and enables ``make bootloader``. There is no +``mcuboot_update_agent`` defconfig for this board yet. + +.. warning:: + Default MCUBoot Kconfig offsets (primary ``0x20000``, secondary ``0x170000``, + scratch ``0x2C0000``, optional storage ``0x300000``) assume **4 MB or more** + of flash. ESP8684-DevKitM-1 boards commonly ship with **2 MB**. Using those + defaults on 2 MB flash will place partitions past the end of the device. + Override ``ESPRESSIF_OTA_*`` and ``ESPRESSIF_STORAGE_MTD_*`` before enabling + MCUBoot on 2 MB parts. + +For Simple Boot on 2 MB flash, the storage MTD defaults to offset ``0x110000`` +and size ``0xf0000``. + +Flash Encryption +---------------- + +Flash encryption is intended for encrypting the contents of the ESP32-C2's off-chip flash memory. Once this feature is enabled, +firmware is flashed as plaintext, and then the data is encrypted in place on the first boot. As a result, physical readout +of flash will not be sufficient to recover most flash contents. + +The current state of flash encryption for ESP32-C2 allows the use of Virtual E-Fuses and development mode, which permit users to evaluate and test the firmware before making definitive changes such as burning E-Fuses. + +Flash encryption supports the following features: + + .. list-table:: + :header-rows: 1 + + * - Feature + - Description + * - **Flash Encryption with Virtual E-Fuses** + - Use flash encryption without burning E-Fuses. Default selection when flash encryption is enabled. + * - **Flash Encryption in Development mode** + - Allows reflashing an encrypted device by appending the ``--encrypt`` argument to the ``esptool.py write_flash`` command. This is done automatically if ``ESPRESSIF_SECURE_FLASH_ENC_FLASH_DEVICE_ENCRYPTED`` is set. + * - **Flash Encryption in Release mode** + - Does not allow reflashing the device. This is a permanent setting. + * - **Flash Encryption key** + - A user-generated key is required by default. Alternatively, a device-generated key is possible, but it will not be recoverable by the user (not recommended). See ``ESPRESSIF_SECURE_FLASH_ENC_USE_HOST_KEY``. + * - **Encrypted MTD Partition** + - If SPI Flash is enabled, an empty user MTD partition will be automatically encrypted on first flash. + +.. note:: + + It is **strongly suggested** to read the following before working on flash encryption: + + - `MCUBoot Flash Encryption `_ + - `General E-Fuse documentation `_ + - `Flash Encryption Relevant E-Fuses `_ + + ESP32-C2 Secure Boot V2 uses **ECDSA**, not RSA. + +Flash Encryption Requirements +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Flash encryption requires burning E-Fuses to enable it on chip. This is not a reversible operation and should be done with caution. +There is, however, a way to test the flash encryption by simulating them on flash. + +Build System Features +''''''''''''''''''''' + +The build system contains some safeguards to avoid accidentally burning E-Fuses and automations for convenience. Those are summarized below: + + 1. A yellow warning will show up during build alerting that flash encryption is enabled (same for Virtual E-Fuses). + 2. If ``ESPRESSIF_SECURE_FLASH_ENC_USE_HOST_KEY`` is set, build will fail if the flash encryption key is not found. + 3. If SPI Flash is enabled, the user MTD partition is automatically encrypted with the provided encryption key. + 4. ``make flash`` command will prompt the user for confirmation before burning the E-Fuse, if Virtual E-Fuses are disabled. + +Simulating Flash Encryption with Virtual E-Fuses +''''''''''''''''''''''''''''''''''''''''''''''''' + +It is highly recommended to use this method for testing the flash encryption before actually burning the E-Fuses. +The E-Fuses are stored in flash and persist between reboots. No real E-Fuses are changed. + +To enable virtual E-Fuses for flash encryption testing, open ``menuconfig`` and: + 1. Enable flash encryption on boot on: :menuselection:`System Type --> Bootloader and Image Configuration` + 2. Verify Virtual E-Fuses are enabled (this is done by default): :menuselection:`System Type --> Peripheral Support --> E-Fuse support` + +Actual encryption and burning E-Fuses +''''''''''''''''''''''''''''''''''''' + +E-Fuses are burned by esptool and the bootloader on the first boot after flashing with encryption enabled. +This process is automated on NuttX build system. + +.. warning:: Burning E-Fuses is NOT a reversible operation and should be done with caution. + +To build a firmware with E-Fuse support and flash encryption enabled, open ``menuconfig`` and: + 1. Enable flash encryption on boot on: :menuselection:`System Type --> Bootloader and Image Configuration` + 2. Disable Virtual E-Fuses :menuselection:`System Type --> Peripheral Support --> E-Fuse support` + 3. Check usage mode is Development (this allows reflashing, while Release mode does not). + +.. note:: If using development mode of flash encryption (see menuconfig and documentation above), it is still possible to re-flash the device with esptool by + setting ``ESPRESSIF_SECURE_FLASH_ENC_FLASH_DEVICE_ENCRYPTED`` which adds ``--encrypt`` argument to the ``esptool.py write_flash`` command. + This will apply the burned encryption key to the image while flashing. + +Flash Allocation for MCUBoot +---------------------------- + +When MCUBoot is enabled, the **default** Kconfig layout is the same as on other +Espressif RISC-V chips (4 MB class). Do not use it unchanged on 2 MB flash. + +**Default flash layout (MCUBoot enabled, 4 MB+)** + +.. list-table:: + :header-rows: 1 + :widths: 40 20 20 + :align: left + + * - Region + - Offset + - Size + * - Bootloader + - 0x000000 + - 64KB + * - E-Fuse Virtual (see Note) + - 0x010000 + - 64KB + * - Primary Application Slot (/dev/ota0) + - 0x020000 + - 1.4MB + * - Secondary Application Slot (/dev/ota1) + - 0x170000 + - 1.4MB + * - Scratch Partition (/dev/otascratch) + - 0x2C0000 + - 256KB + * - Storage MTD (optional) + - 0x300000 + - 1MB + * - Available Flash + - 0x400000+ + - Remaining + +.. raw:: html + +
+ +**Note**: The E-Fuse Virtual region is optional and only used when +``ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH`` is enabled. However, this 64KB +location is always allocated in the memory layout to prevent accidental +erasure during board flashing operations, ensuring data preservation if +virtual E-Fuses are later enabled. + +The key KConfig options that control this layout: + +- ``ESPRESSIF_OTA_PRIMARY_SLOT_OFFSET`` (default: 0x20000) +- ``ESPRESSIF_OTA_SECONDARY_SLOT_OFFSET`` (default: 0x170000) +- ``ESPRESSIF_OTA_SLOT_SIZE`` (default: 0x150000) +- ``ESPRESSIF_OTA_SCRATCH_OFFSET`` (default: 0x2C0000) +- ``ESPRESSIF_OTA_SCRATCH_SIZE`` (default: 0x40000) +- ``ESPRESSIF_STORAGE_MTD_OFFSET`` (default: 0x300000 when MCUBoot enabled) +- ``ESPRESSIF_STORAGE_MTD_SIZE`` (default: 0x100000) + +For MCUBoot operation: + +- The **Primary Slot** contains the currently running application +- The **Secondary Slot** receives OTA updates +- The **Scratch Partition** is used by MCUBoot for image swapping during updates +- MCUBoot manages image validation, confirmation, and rollback functionality + +_`Managing esptool on virtual environment` +========================================== + +This section describes how to install ``esptool``, ``imgtool`` or any other Python packages in a +proper environment. + +Normally, a Linux-based OS would already have Python 3 installed by default. Up to a few years ago, +you could simply call ``pip install`` to install packages globally. However, this is no longer recommended +as it can lead to conflicts between packages and versions. The recommended way to install Python packages +is to use a virtual environment. + +A virtual environment is a self-contained directory that contains a Python installation for a particular +version of Python, plus a number of additional packages. You can create a virtual environment for each +project you are working on, and install the required packages in that environment. + +Two alternatives are explained below, you can select any one of those. + +Using pipx (recommended) +------------------------ + +``pipx`` is a tool that makes it easy to install Python packages in a virtual environment. To install +``pipx``, you can run the following command (using apt as example):: + + $ apt install pipx + +Once you have installed ``pipx``, you can use it to install Python packages in a virtual environment. For +example, to install the ``esptool`` package, you can run the following command:: + + $ pipx install esptool + +This will create a new virtual environment in the ``~/.local/pipx/venvs`` directory, which contains the +``esptool`` package. You can now use the ``esptool`` command as normal, and so will the build system. + +Make sure to run ``pipx ensurepath`` to add the ``~/.local/bin`` directory to your ``PATH``. This will +allow you to run the ``esptool`` command from any directory. + +Using venv (alternative) +------------------------ +To create a virtual environment, you can use the ``venv`` module, which is included in the Python standard +library. To create a virtual environment, you can run the following command:: + + $ python3 -m venv myenv + +This will create a new directory called ``myenv`` in the current directory, which contains a Python +installation and a copy of the Python standard library. To activate the virtual environment, you can run +the following command:: + + $ source myenv/bin/activate + +This will change your shell prompt to indicate that you are now working in the virtual environment. You can +now install packages using ``pip``. For example, to install the ``esptool`` package, you can run the following +command:: + + $ pip install esptool + +This will install the ``esptool`` package in the virtual environment. You can now use the ``esptool`` command as +normal. When you are finished working in the virtual environment, you can deactivate it by running the following +command:: + + $ deactivate + +This will return your shell prompt to its normal state. You can reactivate the virtual environment at any time by +running the ``source myenv/bin/activate`` command again. You can also delete the virtual environment by deleting +the directory that contains it. + +Supported Boards +================ + +.. toctree:: + :glob: + :maxdepth: 1 + + boards/*/*