Crate esp_hal

Source
Expand description

§Bare-metal (no_std) HAL for all Espressif ESP32 devices.

This documentation is built for the ESP32-S3 . Please ensure you are reading the correct documentation for your target device.

§Choosing a Device

Depending on your target device, you need to enable the chip feature for that device. You may also need to do this on ancillary esp-hal crates.

§Overview

§Peripheral drivers

The HAL implements both blocking and async APIs for many peripherals. Where applicable, driver implement the embedded-hal and embedded-hal-async traits.

§Peripheral singletons

Each peripheral driver needs a peripheral singleton that tells the driver which hardware block to use. The peripheral singletons are created by the HAL initialization, and are returned from init as fields of the Peripherals struct.

These singletons, by default, represent peripherals for the entire lifetime of the program. To allow for reusing peripherals, the HAL provides a reborrow method on each peripheral singleton. This method creates a new handle to the peripheral with a shorter lifetime. This allows you to pass the handle to a driver, while still keeping the original handle alive. Once you drop the driver, you will be able to reborrow the peripheral again.

For example, if you want to use the I2c driver and you don’t intend to drop the driver, you can pass the peripheral singleton to the driver by value:

// Peripheral singletons are returned from the `init` function.
let peripherals = esp_hal::init(esp_hal::Config::default());

let mut i2c = I2C::new(peripherals.I2C0, /* ... */);

If you want to use the peripheral in multiple places (for example, you want to drop the driver for some period of time to minimize power consumption), you can reborrow the peripheral singleton and pass it to the driver by reference:

// Note that in this case, `peripherals` needs to be mutable.
let mut peripherals = esp_hal::init(esp_hal::Config::default());

let i2c = I2C::new(peripherals.I2C0.reborrow(), /* ... */);

// Do something with the I2C driver...

core::mem::drop(i2c); // Drop the driver to minimize power consumption.

// Do something else...

// You can then take or reborrow the peripheral singleton again.
let i2c = I2C::new(peripherals.I2C0.reborrow(), /* ... */);

§Examples

We have a plethora of examples in the esp-hal repository. We use an xtask to automate the building, running, and testing of code and examples within esp-hal.

Invoke the following command in the root of the esp-hal repository to get started:

cargo xtask help

§Creating a Project

We have a book that explains the full esp-rs ecosystem and how to get started, it’s advisable to give that a read before proceeding. We also have a training that covers some common scenarios with examples.

We have developed a project generation tool, esp-generate, which we recommend when starting new projects. It can be installed and run, e.g. for the ESP32-C6, as follows:

cargo install esp-generate
esp-generate --chip=esp32c6 your-project

§Blinky

Some minimal code to blink an LED looks like this:

#![no_std]
#![no_main]

use esp_hal::{
    clock::CpuClock,
    gpio::{Io, Level, Output, OutputConfig},
    main,
    time::{Duration, Instant},
};

// You need a panic handler. Usually, you you would use esp_backtrace, panic-probe, or
// something similar, but you can also bring your own like this:
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
    esp_hal::system::software_reset()
}

#[main]
fn main() -> ! {
    let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
    let peripherals = esp_hal::init(config);

    // Set GPIO0 as an output, and set its state high initially.
    let mut led = Output::new(peripherals.GPIO0, Level::High, OutputConfig::default());

    loop {
        led.toggle();
        // Wait for half a second
        let delay_start = Instant::now();
        while delay_start.elapsed() < Duration::from_millis(500) {}
    }
}

§Additional configuration

We’ve exposed some configuration options that don’t fit into cargo features. These can be set via environment variables, or via cargo’s [env] section inside .cargo/config.toml. Note that unstable options can only be enabled when the unstable feature is enabled for the crate. Below is a table of tunable parameters for this crate:

NameDescriptionDefault valueAllowed value

ESP_HAL_CONFIG_PLACE_SPI_MASTER_DRIVER_IN_RAM

⚠️ Unstable

Places the SPI master driver in RAM for better performance

false

ESP_HAL_CONFIG_PLACE_SWITCH_TABLES_IN_RAM

Stable since 1.0.0-beta.0

Places switch-tables, some lookup tables and constants related to interrupt handling into RAM - resulting in better performance but slightly more RAM consumption.

true

ESP_HAL_CONFIG_PLACE_ANON_IN_RAM

Stable since 1.0.0-beta.0

Places anonymous symbols into RAM - resulting in better performance at the cost of significant more RAM consumption. Best to be combined with place-switch-tables-in-ram.

false

ESP_HAL_CONFIG_PSRAM_MODE

⚠️ Unstable

SPIRAM chip mode

quad
One of:
  • quad
  • octal

ESP_HAL_CONFIG_STACK_GUARD_OFFSET

Stable since 1.0.0-beta.0

The stack guard variable will be placed this many bytes from the stack’s end.

4096

ESP_HAL_CONFIG_STACK_GUARD_VALUE

Stable since 1.0.0-beta.0

The value to be written to the stack guard variable.

3740121773

ESP_HAL_CONFIG_IMPL_CRITICAL_SECTION

⚠️ Unstable

Provide a critical-section implementation. Note that if disabled, you will need to provide a critical-section implementation which is using restore-state-u32.

true

§Don’t use core::mem::forget

You should never use core::mem::forget on any type defined in the HAL. Some types heavily rely on their Drop implementation to not leave the hardware in undefined state and causing UB.

You might want to consider using #[deny(clippy::mem_forget) in your project.

§Feature Flags

§Logging Feature Flags

  • log-04 — Enable logging output using version 0.4 of the log crate.
  • defmt — Enable logging output using defmt and implement defmt::Format on certain types.

§PSRAM Feature Flags

  • psram — Use externally connected PSRAM (quad by default, can be configured to octal via ESP_HAL_CONFIG_PSRAM_MODE)

§Unstable APIs

Unstable APIs are drivers and features that are not yet ready for general use. They may be incomplete, have bugs, or be subject to change without notice. Unstable APIs are not covered by semver guarantees.

  • unstable — Enables APIs that are not stable and thus come with no stability guarantees.

Re-exports§

pub use xtensa_lx_rt;unstable
pub use xtensa_lx_rt::xtensa_lx;unstable

Modules§

aesunstable
Advanced Encryption Standard (AES).
analogunstable
Analog Peripherals
assist_debugunstable
Debug Assistant (ASSIST_DEBUG)
asynchunstable
Asynchronous utilities.
clock
CPU Clock Control
configunstable
Configuration
debuggerunstable
Debugger utilities
delayunstable
Delay
dmaunstable
Direct Memory Access (DMA)
efuseunstable
Stability
gpio
General Purpose Input/Output (GPIO)
hmacunstable
Hash-based Message Authentication Code (HMAC) Accelerator
i2c
Inter-Integrated Circuit (I2C)
i2sunstable
Inter-IC Sound (I2S)
interruptunstable
Interrupt support
lcd_camunstable
LCD and Camera
ledcunstable
LED Controller (LEDC)
mcpwmunstable
Motor Control Pulse Width Modulator (MCPWM)
otg_fsunstable
USB On-The-Go (USB OTG)
pcntunstable
Pulse Counter (PCNT)
peripheral
Exclusive peripheral access
peripherals
Peripheral Instances
psramunstable
Stability
rmtunstable
Remote Control Peripheral (RMT)
rngunstable
Random Number Generator (RNG)
romunstable
ESP ROM libraries
rsaunstable
RSA (Rivest–Shamir–Adleman) accelerator.
rtc_cntlunstable
Real-Time Control and Low-power Management (RTC_CNTL)
shaunstable
Secure Hash Algorithm (SHA) Accelerator
spi
Serial Peripheral Interface (SPI)
system
System Control
time
Timekeeping
timerunstable
General-purpose Timers
trapframeunstable
State of the CPU saved when entering exception or interrupt
twaiunstable
Two-wire Automotive Interface (TWAI)
uart
Universal Asynchronous Receiver/Transmitter (UART)
ulp_coreunstable
Stability
usb_serial_jtagunstable
USB Serial/JTAG Controller (USB_SERIAL_JTAG)

Macros§

chip
The name of the chip (“esp32s3”) as &str
dma_buffersunstable
Convenience macro to create DMA buffers and descriptors.
dma_buffers_chunk_sizeunstable
Convenience macro to create DMA buffers and descriptors with specific chunk size.
dma_circular_buffersunstable
Convenience macro to create circular DMA buffers and descriptors.
dma_circular_buffers_chunk_sizeunstable
Convenience macro to create circular DMA buffers and descriptors with specific chunk size.
dma_circular_descriptorsunstable
Convenience macro to create circular DMA descriptors.
dma_circular_descriptors_chunk_sizeunstable
Convenience macro to create circular DMA descriptors with specific chunk size
dma_descriptorsunstable
Convenience macro to create DMA descriptors.
dma_descriptors_chunk_sizeunstable
Convenience macro to create DMA descriptors with specific chunk size
dma_loop_bufferunstable
Convenience macro to create a DmaLoopBuf from a buffer size.
dma_rx_stream_bufferunstable
Convenience macro to create a DmaRxStreamBuf from buffer size and optional chunk size (uses max if unspecified). The buffer and descriptors are statically allocated and used to create the DmaRxStreamBuf.
dma_tx_bufferunstable
Convenience macro to create a DmaTxBuf from buffer size. The buffer and descriptors are statically allocated and used to create the DmaTxBuf.
load_lp_codeunstable
Load code to be run on the LP/ULP core.

Structs§

Async
Marker type signalling that a driver is initialized in async mode.
Blocking
Marker type signalling that a driver is initialized in blocking mode.
Config
System configuration.

Traits§

DriverMode
A marker trait for driver modes.
Persistableunstable
Marker trait for types that can be safely used in #[ram(persistent)].

Functions§

init
Initialize the system.

Attribute Macros§

handlerunstable
Stability
main
Attribute to declare the entry point of the program
ramunstable
Stability