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:
Name | Description | Default value | Allowed value |
---|---|---|---|
ESP_HAL_CONFIG_PLACE_SPI_MASTER_DRIVER_IN_RAM ⚠️ Unstable | Places the SPI master driver in RAM for better performance | ||
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. | ||
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 | ||
ESP_HAL_CONFIG_PSRAM_MODE ⚠️ Unstable | SPIRAM chip mode |
| |
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. | ||
ESP_HAL_CONFIG_STACK_GUARD_VALUE Stable since 1.0.0-beta.0 | The value to be written to the stack guard variable. | ||
ESP_HAL_CONFIG_IMPL_CRITICAL_SECTION ⚠️ Unstable | Provide a |
§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 thelog
crate.defmt
— Enable logging output usingdefmt
and implementdefmt::Format
on certain types.
§PSRAM Feature Flags
psram
— Use externally connected PSRAM (quad
by default, can be configured tooctal
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§
- aes
unstable
- Advanced Encryption Standard (AES).
- analog
unstable
- Analog Peripherals
- assist_
debug unstable
- Debug Assistant (ASSIST_DEBUG)
- asynch
unstable
- Asynchronous utilities.
- clock
- CPU Clock Control
- config
unstable
- Configuration
- debugger
unstable
- Debugger utilities
- delay
unstable
- Delay
- dma
unstable
- Direct Memory Access (DMA)
- efuse
unstable
- Stability
- gpio
- General Purpose Input/Output (GPIO)
- hmac
unstable
- Hash-based Message Authentication Code (HMAC) Accelerator
- i2c
- Inter-Integrated Circuit (I2C)
- i2s
unstable
- Inter-IC Sound (I2S)
- interrupt
unstable
- Interrupt support
- lcd_cam
unstable
- LCD and Camera
- ledc
unstable
- LED Controller (LEDC)
- mcpwm
unstable
- Motor Control Pulse Width Modulator (MCPWM)
- otg_fs
unstable
- USB On-The-Go (USB OTG)
- pcnt
unstable
- Pulse Counter (PCNT)
- peripheral
- Exclusive peripheral access
- peripherals
- Peripheral Instances
- psram
unstable
- Stability
- rmt
unstable
- Remote Control Peripheral (RMT)
- rng
unstable
- Random Number Generator (RNG)
- rom
unstable
- ESP ROM libraries
- rsa
unstable
- RSA (Rivest–Shamir–Adleman) accelerator.
- rtc_
cntl unstable
- Real-Time Control and Low-power Management (RTC_CNTL)
- sha
unstable
- Secure Hash Algorithm (SHA) Accelerator
- spi
- Serial Peripheral Interface (SPI)
- system
- System Control
- time
- Timekeeping
- timer
unstable
- General-purpose Timers
- trapframe
unstable
- State of the CPU saved when entering exception or interrupt
- twai
unstable
- Two-wire Automotive Interface (TWAI)
- uart
- Universal Asynchronous Receiver/Transmitter (UART)
- ulp_
core unstable
- Stability
- usb_
serial_ jtag unstable
- USB Serial/JTAG Controller (USB_SERIAL_JTAG)
Macros§
- chip
- The name of the chip (“esp32s3”) as
&str
- dma_
buffers unstable
- Convenience macro to create DMA buffers and descriptors.
- dma_
buffers_ chunk_ size unstable
- Convenience macro to create DMA buffers and descriptors with specific chunk size.
- dma_
circular_ buffers unstable
- Convenience macro to create circular DMA buffers and descriptors.
- dma_
circular_ buffers_ chunk_ size unstable
- Convenience macro to create circular DMA buffers and descriptors with specific chunk size.
- dma_
circular_ descriptors unstable
- Convenience macro to create circular DMA descriptors.
- dma_
circular_ descriptors_ chunk_ size unstable
- Convenience macro to create circular DMA descriptors with specific chunk size
- dma_
descriptors unstable
- Convenience macro to create DMA descriptors.
- dma_
descriptors_ chunk_ size unstable
- Convenience macro to create DMA descriptors with specific chunk size
- dma_
loop_ buffer unstable
- Convenience macro to create a DmaLoopBuf from a buffer size.
- dma_
rx_ stream_ buffer unstable
- 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_ buffer unstable
- Convenience macro to create a DmaTxBuf from buffer size. The buffer and
descriptors are statically allocated and used to create the
DmaTxBuf
. - load_
lp_ code unstable
- 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§
- Driver
Mode - A marker trait for driver modes.
- Persistable
unstable
- Marker trait for types that can be safely used in
#[ram(persistent)]
.
Functions§
- init
- Initialize the system.