### Running Examples with xtask Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/lib.rs.html?search=u32+-%3E+bool Provides the command to get started with examples in the esp-hal repository using the `xtask` build tool. ```bash cargo xtask help ``` -------------------------------- ### Blinky LED Example Setup Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/lib.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E A minimal code snippet demonstrating the setup for blinking an LED. This serves as a basic entry point for hardware interaction. ```rust Some minimal code to blink an LED looks like this: ``` -------------------------------- ### ShaBackend Example Usage Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/sha/struct.ShaBackend.html Example demonstrating how to initialize, start, and use the ShaBackend with Sha1Context for hashing data. ```APIDOC ## Example Usage ### Description This example shows how to initialize a `ShaBackend`, start it to enable SHA operations, and then use it with a `Sha1Context` to compute a SHA-1 hash of input data. ### Code ```rust use esp_hal::sha::{Sha1Context, ShaBackend}; // Assuming `peripherals.SHA` is available and represents the SHA peripheral // let mut sha = ShaBackend::new(peripherals.SHA); // Start the backend, which allows processing SHA operations. // let _backend = sha.start(); // Create a new context to hash data with SHA-1. // let mut sha1_ctx = Sha1Context::new(); // SHA-1 outputs a 20-byte digest. // let mut digest: [u8; 20] = [0; 20]; // Process data. The `update` function returns a handle which can be used to wait // for the operation to finish. // sha1_ctx.update(b"input data").wait_blocking(); // sha1_ctx.update(b"input data").wait_blocking(); // sha1_ctx.update(b"input data").wait_blocking(); // Extract the final hash. This resets the context. // sha1_ctx.finalize(&mut digest).wait_blocking(); // `digest` now contains the SHA-1 hash of the input. ``` ``` -------------------------------- ### SPI Master Basic Initialization Example Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/spi/master/mod.rs.html?search= Demonstrates the basic setup of an SPI Master peripheral. This includes creating a new Spi instance with a given peripheral and configuration. ```rust use esp_hal::spi::{ Mode, master::Config, }; let mut spi = Spi::new( peripherals.SPI2, Config::new().baudrate(100.kHz()).data_mode(Mode { spi_mode: esp_hal::spi::SpiModeFlags::SPI_MODE_0 }), ); ``` -------------------------------- ### RSA Backend Example Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/rsa/mod.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Demonstrates creating and starting an RSA backend for processing operations. The backend manages work items placed in a queue. ```rust # use esp_hal::rsa::{RsaBackend, RsaContext, operand_sizes::Op512}; # let mut rsa_backend = RsaBackend::new(peripherals.RSA); let _driver = rsa_backend.start(); async fn perform_512bit_big_number_multiplication( operand_a: &[u32; 16], operand_b: &[u32; 16], result: &mut [u32; 32], ) { let mut rsa = RsaContext::new(); let mut handle = rsa.multiply::(operand_a, operand_b, result); handle.wait().await; } ``` -------------------------------- ### Project Generation Tool Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/index.html Example of how to install and use the esp-generate tool for creating new projects, specifying the target chip. ```bash cargo install esp-generate esp-generate --chip=esp32c6 your-project ``` -------------------------------- ### SPI Master Driver Example Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/spi/master/mod.rs.html?search=u32+-%3E+bool Example of how to initialize and configure an SPI master peripheral. This snippet shows the basic setup for using the Spi driver with a specific SPI instance. ```rust use esp_hal::spi:: Mode, master::{Config, Spi}, }; let mut spi = Spi::new( peripherals.SPI2, ``` -------------------------------- ### UHCI UART Example Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/uart/uhci/index.html?search=std%3A%3Avec This example demonstrates the full setup and usage of the UHCI wrapper for UART communication. It includes initializing the UART, configuring DMA buffers, setting up UHCI for both receive and transmit, and performing a read-modify-write cycle for data. ```rust #![no_std] #![no_main] #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } use esp_hal:: clock::CpuClock, dma::{DmaRxBuf, DmaTxBuf}, dma_buffers, main, rom::software_reset, uart, uart::{RxConfig, Uart, uhci, uhci::Uhci}, ; #[main] fn main() -> ! { let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let peripherals = esp_hal::init(config); let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let peripherals = esp_hal::init(config); let config = uart::Config::default() .with_rx(RxConfig::default().with_fifo_full_threshold(64)) .with_baudrate(115200); let uart = Uart::new(peripherals.UART1, config) .unwrap() .with_tx(peripherals.GPIO2) .with_rx(peripherals.GPIO3); let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(4092); let dma_rx = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap(); let mut dma_tx = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap(); let mut uhci = Uhci::new(uart, peripherals.UHCI0, peripherals.DMA_CH0); uhci.apply_rx_config( &uart::uhci::RxConfig::default().with_chunk_limit(dma_rx.len() as u16), ) .unwrap(); uhci.apply_tx_config(&uart::uhci::TxConfig::default()) .unwrap(); let config = uart::Config::default() .with_rx(RxConfig::default().with_fifo_full_threshold(64)) .with_baudrate(9600); uhci.set_uart_config(&config).unwrap(); let (uhci_rx, uhci_tx) = uhci.split(); // Waiting for message let transfer = uhci_rx .read(dma_rx) .unwrap_or_else(|x| panic!("Something went horribly wrong: {:?}", x.0)); let (err, _uhci_rx, dma_rx) = transfer.wait(); err.unwrap(); let received = dma_rx.number_of_received_bytes(); // println!("Received dma bytes: {}", received); let rec_slice = &dma_rx.as_slice()[0..received]; if received > 0 { match core::str::from_utf8(&rec_slice) { Ok(x) => { // println!("Received DMA message: \"{}\"", x); dma_tx.as_mut_slice()[0..received].copy_from_slice(&rec_slice); dma_tx.set_length(received); let transfer = uhci_tx .write(dma_tx) .unwrap_or_else(|x| panic!("Something went horribly wrong: {:?}", x.0)); let (err, _uhci, _dma_tx) = transfer.wait(); err.unwrap(); } Err(x) => panic!("Error string: {}", x), } } software_reset() } ``` -------------------------------- ### Async UART Read and Write Example Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/uart/mod.rs.html Demonstrates asynchronous reading and writing to a UART peripheral. Ensure the UART is configured with appropriate pins and settings before use. This example assumes prior setup of the UART instance. ```rust /// .with_tx(peripherals.GPIO2) /// .into_async(); /// /// const MESSAGE: &[u8] = b"Hello, world!"; /// uart.write_async(&MESSAGE).await?; /// uart.flush_async().await?; /// /// let mut buf = [0u8; MESSAGE.len()]; /// uart.read_async(&mut buf[..]).await.unwrap(); /// # { /// # after_snippet /// # } /// ``` ``` -------------------------------- ### Initializing SpiDma with DMA Buffers Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/spi/master/struct.SpiDma.html?search= Example of initializing a DMA-capable SPI instance using `dma_buffers` and configuring it with frequency and mode. This setup is recommended for DMA transfers. ```rust use esp_hal:: dma::{DmaRxBuf, DmaTxBuf}, dma_buffers, spi:: Mode, master::{Config, Spi}, }; let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(32000); let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer)?; let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer)?; let mut spi = Spi::new( peripherals.SPI2, Config::default() .with_frequency(Rate::from_khz(100)) .with_mode(Mode::_0), )? .with_dma(peripherals.DMA_CH0) .with_buffers(dma_rx_buf, dma_tx_buf); ``` -------------------------------- ### Default System Initialization Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/lib.rs.html?search=std%3A%3Avec Initializes the ESP-HAL system with default configuration. This is the simplest way to get started. ```rust # {before_snippet} let peripherals = esp_hal::init(esp_hal::Config::default()); # {after_snippet} ``` -------------------------------- ### Initialize and Start AesBackend Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/aes/struct.AesBackend.html Creates a new AES backend instance. The backend must be started using `start()` before it can process operations. ```rust use esp_hal::aes::AesBackend; let mut aes = AesBackend::new(peripherals.AES); ``` -------------------------------- ### RSA Backend Example Usage Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/rsa/mod.rs.html?search= Demonstrates how to set up and use the RSA backend for performing a 512-bit big number multiplication. It involves creating a backend, starting the driver, and enqueuing a multiplication task. ```rust let mut rsa_backend = RsaBackend::new(peripherals.RSA); let _driver = rsa_backend.start(); async fn perform_512bit_big_number_multiplication( operand_a: &[u32; 16], operand_b: &[u32; 16], result: &mut [u32; 32], ) { let mut rsa = RsaContext::new(); let mut handle = rsa.multiply::(operand_a, operand_b, result); handle.wait().await; } ``` -------------------------------- ### Initialize and Start AesDmaBackend Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/aes/dma/struct.AesDmaBackend.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Demonstrates how to create and start the AesDmaBackend for DMA-accelerated AES operations. The backend must be started before processing any AES tasks. ```rust use esp_hal::aes::dma::AesDmaBackend; let mut aes = AesDmaBackend::new(peripherals.AES, peripherals.DMA_CH0); let _handle = aes.start(); ``` -------------------------------- ### Async Driver Mode Example Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/lib.rs.html?search= Demonstrates converting a blocking UART driver to async mode. This setup is required for utilizing async APIs within the driver. ```rust ```rust, no_run # {before_snippet} # use esp_hal::uart::{Config, Uart}; let uart = Uart::new(peripherals.UART0, Config::default())? .with_rx(peripherals.GPIO1) .with_tx(peripherals.GPIO2) .into_async(); /// # {after_snippet} ``` ``` -------------------------------- ### UHCI UART DMA Example Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/uart/uhci/index.html?search=u32+-%3E+bool This example demonstrates the full setup and usage of UHCI for UART communication with DMA. It includes initializing peripherals, configuring UART and UHCI, performing a DMA read, processing received data, and echoing it back via DMA write. Ensure the `unstable` feature is enabled. ```rust #![no_std] #![no_main] #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } use esp_hal:: clock::CpuClock, dma::{DmaRxBuf, DmaTxBuf}, dma_buffers, main, rom::software_reset, uart, uart::{RxConfig, Uart, uhci, uhci::Uhci}, ; #[main] fn main() -> ! { let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let peripherals = esp_hal::init(config); let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let peripherals = esp_hal::init(config); let config = uart::Config::default() .with_rx(RxConfig::default().with_fifo_full_threshold(64)) .with_baudrate(115200); let uart = Uart::new(peripherals.UART1, config) .unwrap() .with_tx(peripherals.GPIO2) .with_rx(peripherals.GPIO3); let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(4092); let dma_rx = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap(); let mut dma_tx = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap(); let mut uhci = Uhci::new(uart, peripherals.UHCI0, peripherals.DMA_CH0); uhci.apply_rx_config( &uart::uhci::RxConfig::default().with_chunk_limit(dma_rx.len() as u16), ) .unwrap(); uhci.apply_tx_config(&uart::uhci::TxConfig::default()) .unwrap(); let config = uart::Config::default() .with_rx(RxConfig::default().with_fifo_full_threshold(64)) .with_baudrate(9600); uhci.set_uart_config(&config).unwrap(); let (uhci_rx, uhci_tx) = uhci.split(); // Waiting for message let transfer = uhci_rx .read(dma_rx) .unwrap_or_else(|x| panic!("Something went horribly wrong: {:?}", x.0)); let (err, _uhci_rx, dma_rx) = transfer.wait(); err.unwrap(); let received = dma_rx.number_of_received_bytes(); // println!("Received dma bytes: {}", received); let rec_slice = &dma_rx.as_slice()[0..received]; if received > 0 { match core::str::from_utf8(&rec_slice) { Ok(x) => { // println!("Received DMA message: \"{}\"", x); dma_tx.as_mut_slice()[0..received].copy_from_slice(&rec_slice); dma_tx.set_length(received); let transfer = uhci_tx .write(dma_tx) .unwrap_or_else(|x| panic!("Something went horribly wrong: {:?}", x.0)); let (err, _uhci, _dma_tx) = transfer.wait(); err.unwrap(); } Err(x) => panic!("Error string: {}", x), } } software_reset() } ``` -------------------------------- ### ShaBackend Example Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/sha/struct.ShaBackend.html?search= Example demonstrating the usage of ShaBackend for SHA-1 hashing. ```APIDOC ## Example Usage ```rust use esp_hal::sha::{Sha1Context, ShaBackend}; // Assuming 'peripherals' is available and contains the SHA peripheral // let mut sha = ShaBackend::new(peripherals.SHA); // Start the backend, which allows processing SHA operations. // let mut _backend = sha.start(); // Create a new context to hash data with SHA-1. // let mut sha1_ctx = Sha1Context::new(); // SHA-1 outputs a 20-byte digest. // let mut digest: [u8; 20] = [0; 20]; // Process data. The `update` function returns a handle which can be used to wait // for the operation to finish. // sha1_ctx.update(b"input data").wait_blocking(); // sha1_ctx.update(b"input data").wait_blocking(); // sha1_ctx.update(b"input data").wait_blocking(); // Extract the final hash. This resets the context. // sha1_ctx.finalize(&mut digest).wait_blocking(); // 'digest' now contains the SHA-1 hash of the input. ``` ``` -------------------------------- ### RSA Interrupt Example Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/peripherals/struct.RSA.html?search=std%3A%3Avec Example demonstrating how to set up and manage RSA peripheral interrupts, including enabling and disabling them. ```rust use esp_hal::interrupt::Priority; #[unsafe(no_mangle)] unsafe extern "C" fn RSA() { // do something } peripherals.RSA.enable_peri_interrupt(Priority::Priority1); peripherals.RSA.disable_peri_interrupt_on_all_cores(); ``` -------------------------------- ### Default Initialization Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/struct.Config.html?search= Demonstrates how to create a default `Config` instance and initialize peripherals with it. ```APIDOC ### §Examples #### §Default initialization ```rust let peripherals = esp_hal::init(esp_hal::Config::default()); ``` ``` -------------------------------- ### Example: Get Weekday in New York Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/rtc_cntl/struct.Rtc.html?search= Demonstrates how to get the current weekday in a specific time zone (New York) using the RTC's current time and the `jiff` crate. This example is suitable for core-only environments. ```rust use jiff:: { Timestamp, tz::{self, TimeZone}, }; static TZ: TimeZone = tz::get!("America/New_York"); let rtc = Rtc::new(peripherals.LPWR); let now = Timestamp::from_microsecond(rtc.current_time_us() as i64)?; let weekday_in_new_york = now.to_zoned(TZ.clone()).weekday(); ``` -------------------------------- ### RSA Interrupt Example Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/peripherals/struct.RSA.html Example demonstrating how to set up an interrupt handler and enable/disable the RSA peripheral interrupt. Requires the `unstable` feature. ```rust use esp_hal::interrupt::Priority; #[unsafe(no_mangle)] unsafe extern "C" fn RSA() { // do something } peripherals.RSA.enable_peri_interrupt(Priority::Priority1); peripherals.RSA.disable_peri_interrupt_on_all_cores(); ``` -------------------------------- ### Default Initialization Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/struct.Config.html?search=u32+-%3E+bool Demonstrates how to initialize the system configuration using the default settings. ```APIDOC ## Default initialization ```rust let peripherals = esp_hal::init(esp_hal::Config::default()); ``` ``` -------------------------------- ### Get Current Time in Microseconds Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/rtc_cntl/struct.Rtc.html Fetches the current time in microseconds. This example demonstrates how to use the `jiff` crate to get the weekday in a specific timezone. ```rust use jiff::{ Timestamp, tz::{self, TimeZone}, }; static TZ: TimeZone = tz::get!("America/New_York"); let rtc = Rtc::new(peripherals.LPWR); let now = Timestamp::from_microsecond(rtc.current_time_us() as i64)?; let weekday_in_new_york = now.to_zoned(TZ.clone()).weekday(); ``` -------------------------------- ### Blinky Example for ESP32-C3 Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal?search= A minimal 'blinky' example for the ESP32-C3 that blinks an LED connected to GPIO0. It includes necessary setup for a no_std environment and a panic handler. ```rust #![no_std] #![no_main] use esp_hal:: clock::CpuClock, gpio::{Io, Level, Output, OutputConfig}, main, time::{Duration, Instant}, ; #[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); let mut led = Output::new(peripherals.GPIO0, Level::High, OutputConfig::default()); loop { led.toggle(); let delay_start = Instant::now(); while delay_start.elapsed() < Duration::from_millis(500) {} } } ``` -------------------------------- ### esp_hal::init Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/fn.init.html?search= Initializes the system by setting up the CPU clock and watchdog. It returns the peripherals and clocks. ```APIDOC ## init ### Description Initializes the system. This function sets up the CPU clock and watchdog, then returns the peripherals and clocks. ### Signature ```rust pub fn init(config: Config) -> Peripherals ``` ### Availability Available on `crate feature`rt` only. ### Parameters #### Path Parameters - **config** (Config) - Description: Configuration for system initialization. ### Returns - **Peripherals** - The initialized system peripherals and clocks. ### Example ```rust use esp_hal::{Config, init}; let peripherals = init(Config::default()); ``` ``` -------------------------------- ### Blinky Example Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/index.html A minimal 'blinky' example demonstrating how to initialize the system, configure a GPIO pin as an output, and toggle an LED with a delay. Includes a custom panic handler. ```rust #![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 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) {} } } ``` -------------------------------- ### EfuseBlock Address Access Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/efuse/esp32c2/mod.rs.html Provides a method to get the memory address of the start of an efuse block. ```APIDOC ## EfuseBlock::address ### Description Returns the memory address of the start of the specified efuse block. ### Signature ```rust pub(crate) fn address(self) -> *const u32 ``` ### Parameters * `self`: An instance of `EfuseBlock` representing the efuse block to access. ### Returns A raw pointer (`*const u32`) to the beginning of the efuse block's data in memory. ### Usage Example ```rust let block0_address = EfuseBlock::Block0.address(); let block1_address = EfuseBlock::Block1.address(); ``` ``` -------------------------------- ### Get time in ms from RTC Timer (Duplicate) Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/rtc_cntl/index.html?search= Demonstrates how to get the current RTC time in milliseconds and set the time to a past value. Requires `Rtc` and `Delay` initialization. This is a duplicate of a previous example. ```rust let rtc = Rtc::new(peripherals.LPWR); let delay = Delay::new(); loop { // Get the current RTC time in milliseconds let time_ms = rtc.current_time_us() / 1000; delay.delay_millis(1000); // Set the time to half a second in the past let new_time = rtc.current_time_us() - 500_000; rtc.set_current_time_us(new_time); } ``` -------------------------------- ### Peripheral Singleton Usage (I2C Example) Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal?search= Demonstrates how to initialize and use peripheral singletons, showing both direct usage and reborrowing for scenarios where a peripheral needs to be released and reused. ```rust let peripherals = esp_hal::init(esp_hal::Config::default()); let mut i2c = I2c::new(peripherals.I2C0, /* ... */); ``` ```rust let mut peripherals = esp_hal::init(esp_hal::Config::default()); let i2c = I2C::new(peripherals.I2C0.reborrow(), /* ... */); core::mem::drop(i2c); let i2c = I2C::new(peripherals.I2C0.reborrow(), /* ... */); ``` -------------------------------- ### System Initialization Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/lib.rs.html Initializes the system by setting up the CPU clock and watchdog, then returns peripherals and clocks. This function is part of the runtime feature. ```APIDOC ## init ### Description Initializes the system. This function sets up the CPU clock and watchdog, then returns the peripherals and clocks. It requires the `rt` feature to be enabled. ### Example ```rust, no_run use esp_hal::{Config, init}; let peripherals = init(Config::default()); ``` ### Signature `#[cfg_attr(docsrs, doc(cfg(feature = "rt")))] #[cfg(feature = "rt")] pub fn init(config: Config) -> Peripherals` ``` -------------------------------- ### Minimal LED Blink Example in Rust Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/lib.rs.html This is a basic example demonstrating how to blink an LED using the ESP-HAL library. It includes necessary setup for a no_std environment and a panic handler. Ensure you have a suitable panic handler for your project. ```rust #![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 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) {} } } ``` -------------------------------- ### Async I2C Transaction Example Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/i2c/master/struct.I2c.html?search= Demonstrates executing a sequence of I2C operations (writes and reads) as a single atomic transaction. This method provides fine-grained control over the transaction's start, repeated start, and stop conditions. ```rust use esp_hal::i2c::master::{Config, I2c, Operation}; const DEVICE_ADDR: u8 = 0x77; let mut i2c = I2c::new(peripherals.I2C0, Config::default())? .with_sda(peripherals.GPIO1) .with_scl(peripherals.GPIO2) .into_async(); let mut data = [0u8; 22]; i2c.transaction_async( DEVICE_ADDR, &mut [Operation::Write(&[0xaa]), Operation::Read(&mut data)], ) .await?; ``` -------------------------------- ### RSA Backend Initialization and Start Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/rsa/mod.rs.html?search=std%3A%3Avec Demonstrates how to create and start an RSA backend. The backend processes work items placed in the RSA work queue, allowing operations without holding the peripheral singleton. ```rust use esp_hal::rsa::{RsaBackend, RsaContext, operand_sizes::Op512}; let mut rsa_backend = RsaBackend::new(peripherals.RSA); let _driver = rsa_backend.start(); async fn perform_512bit_big_number_multiplication( operand_a: &[u32; 16], operand_b: &[u32; 16], result: &mut [u32; 32], ) { let mut rsa = RsaContext::new(); let mut handle = rsa.multiply::(operand_a, operand_b, result); handle.wait().await; } ``` ```rust use esp_hal::rsa::RsaBackend; let mut rsa = RsaBackend::new(peripherals.RSA); ``` ```rust use esp_hal::rsa::RsaBackend; let mut rsa = RsaBackend::new(peripherals.RSA); // Start the backend, which allows processing RSA operations. let _backend = rsa.start(); ``` -------------------------------- ### Config Initialization and Usage Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/struct.Config.html Demonstrates how to initialize the Config struct using default values and how to customize it with specific settings like CPU clock frequency. ```APIDOC ## Struct Config System configuration. This `struct` is marked with `#[non_exhaustive]` and can’t be instantiated directly. This is done to prevent breaking changes when new fields are added to the `struct`. Instead, use the `Config::default()` method to create a new instance. ### §Examples #### §Default initialization ``` let peripherals = esp_hal::init(esp_hal::Config::default()); ``` #### §Custom initialization ``` use esp_hal::{clock::CpuClock, time::Duration}; let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let peripherals = esp_hal::init(config); ``` ## Implementations ### impl Config #### pub fn with_cpu_clock(self, cpu_clock: impl Into) -> Self Apply a clock configuration. With the `unstable` feature enabled, this function accepts both `ClockConfig` and `CpuClock`. #### pub fn cpu_clock(&self) -> CpuClock Deprecated: Use `clock_config` instead. The CPU clock configuration preset. ##### §Panics This function will panic if the CPU clock configuration is not **exactly** one of the `CpuClock` presets. #### pub fn clock_config(&self) -> ClockConfig Available on **crate feature`unstable`** only. The CPU clock configuration. ##### §Stability **This API is marked as unstable** and is only available when the `unstable` crate feature is enabled. This comes with no stability guarantees, and could be changed or removed at any time. ### impl Default for Config #### fn default() -> Config Returns the “default value” for a type. ``` -------------------------------- ### Getting pre_idle_count from AtCmdConfig Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/uart/struct.AtCmdConfig.html Retrieves the configured `pre_idle_count`, which is an optional idle time in clock cycles before AT command detection starts. ```rust pub fn pre_idle_count(&self) -> Option ``` -------------------------------- ### System Initialization Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/lib.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Initializes the system by setting up the CPU clock, watchdog timers, and making peripherals available. This is the primary entry point for using the HAL. ```APIDOC ## init ### Description Initializes the system. This function sets up the CPU clock and watchdog, then returns the peripherals and clocks. ### Arguments - `config` (`Config`): The configuration for the system initialization. ### Returns - `Peripherals`: An instance of the system's peripherals. ### Example ```rust, no_run use esp_hal::{Config, init}; let peripherals = init(Config::default()); ``` ``` -------------------------------- ### Instantiate Rng Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/rng/struct.Rng.html?search=u32+-%3E+bool Creates a new random number generator instance. Use this to get started with generating random numbers. ```rust use esp_hal::rng::Rng; let rng = Rng::new(); ``` -------------------------------- ### Basic ESP-HAL Application with GPIO Control Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/lib.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E This example demonstrates a minimal ESP-HAL application that initializes the system, configures a GPIO pin as an output, and toggles it every half second. It includes a custom panic handler. ```rust #![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 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) {} } } ``` -------------------------------- ### Initialize System with esp_hal::init Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/fn.init.html?search= Call this function to set up the CPU clock and watchdog. It returns the system's peripherals and clocks. Requires the `rt` crate feature. ```rust use esp_hal::{Config, init}; let peripherals = init(Config::default()); ``` -------------------------------- ### ChipRevision Usage Example Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/efuse/struct.ChipRevision.html?search=std%3A%3Avec Demonstrates how to get the current chip revision, compare it with other revisions, and convert it to different numeric representations. ```rust use esp_hal::efuse::ChipRevision; let rev = esp_hal::efuse::chip_revision(); println!("Chip revision: {}.{}", rev.major, rev.minor); // You can compare against other ChipRevision objects if rev < ChipRevision::from_combined(300) { // You can print a debug representation println!("Chip revision is too old: {:?}", rev); } if rev >= ChipRevision::from_packed(0x400) { println!("Chip revision is too new: {:?}", rev); } // You can convert into two different numeric representations. assert!(rev.packed() >= 0x300); assert!(rev.combined() >= 300); ``` -------------------------------- ### Initialize System with Default Configuration Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/fn.init.html Use this snippet to initialize the ESP system with default configuration. It sets up the CPU clock and watchdog, returning the peripherals and clocks. ```rust use esp_hal::{Config, init}; let peripherals = init(Config::default()); ``` -------------------------------- ### Default UART Config Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/uart/mod.rs.html?search=u32+-%3E+bool Provides the default configuration values for the `Config` struct, ensuring a sensible starting point for UART setup. ```APIDOC ## Default Config Implementation ### Description Implements the `Default` trait for `Config`, providing default values for all configuration fields. ### Default Values - **rx**: `RxConfig::default()` - **tx**: `TxConfig::default()` - **baudrate**: `115_200` - **baudrate_tolerance**: `BaudrateTolerance::default()` - **data_bits**: `Default::default()` - **parity**: `Default::default()` - **stop_bits**: `Default::default()` - **sw_flow_ctrl**: `Default::default()` - **hw_flow_ctrl**: `Default::default()` - **clock_source**: `Default::default()` ``` -------------------------------- ### Blinky Example Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/index.html?search= A minimal example demonstrating how to blink an LED connected to GPIO0. This includes setting up the system clock, initializing peripherals, configuring the GPIO pin as an output, and implementing a blinking loop. ```rust #![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 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) {} } } ``` -------------------------------- ### SPI Initialization and Configuration Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/spi/master/struct.Spi.html?search=std%3A%3Avec Demonstrates how to initialize an SPI master instance with basic configuration, including setting the clock frequency, mode, and assigning pins for SCK, MOSI, and MISO. ```APIDOC ## Spi::new ### Description Constructs an SPI instance in 8bit dataframe mode. ### Method `Spi::new(spi: impl Instance + 'd, config: Config) -> Result` ### Parameters - `spi`: An SPI peripheral instance. - `config`: The SPI configuration, including frequency and mode. ### Errors See `Spi::apply_config`. ### Example ```rust use esp_hal::spi::master::{Config, Spi}; let mut spi = Spi::new(peripherals.SPI2, Config::default())? .with_sck(peripherals.GPIO0) .with_mosi(peripherals.GPIO1) .with_miso(peripherals.GPIO2); ``` ``` ```APIDOC ## Spi::with_sck ### Description Assign the SCK (Serial Clock) pin for the SPI instance. ### Method `Spi::with_sck(self, sclk: impl PeripheralOutput<'d>) -> Self` ### Parameters - `sclk`: The pin to be used for the SPI clock signal. ### Behavior Configures the specified pin to push-pull output and connects it to the SPI clock signal. Disconnects the previous pin that was assigned with `with_sck`. ### Example ```rust use esp_hal::spi::master::{Config, Spi}; let mut spi = Spi::new(peripherals.SPI2, Config::default())?.with_sck(peripherals.GPIO0); ``` ``` -------------------------------- ### Get eFuse Block Address Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/efuse/esp32c2/mod.rs.html Returns the memory address of the start of a specific eFuse block. Used for direct register access. ```rust impl EfuseBlock { pub(crate) fn address(self) -> *const u32 { let efuse = EFUSE::regs(); match self { Self::Block0 => efuse.rd_wr_dis().as_ptr(), Self::Block1 => efuse.rd_blk1_data0().as_ptr(), Self::Block2 => efuse.rd_blk2_data0().as_ptr(), Self::Block3 => efuse.rd_blk3_data0().as_ptr(), } } } ``` -------------------------------- ### RsaContext::new Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/rsa/struct.RsaContext.html?search=u32+-%3E+bool Creates a new RsaContext instance, initializing the RSA hardware context. ```APIDOC ## RsaContext::new ### Description Creates a new context for RSA operations. ### Returns - `Self`: A new instance of `RsaContext`. ``` -------------------------------- ### Get Wakeup Cause Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/rtc_cntl/fn.wakeup_cause.html Call this function to retrieve the `SleepSource` enum variant that indicates the reason for waking up from deep sleep. No setup is required. ```rust pub fn wakeup_cause() -> SleepSource ``` -------------------------------- ### Create and Use DedicatedGpioInputBundle Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/gpio/dedicated/struct.DedicatedGpioInputBundle.html Demonstrates creating dedicated input channels, bundling them, and reading their states simultaneously. Ensure the necessary GPIO peripherals and input configurations are set up. ```rust use esp_hal::gpio::{ Input, InputConfig, dedicated::{DedicatedGpio, DedicatedGpioInput, DedicatedGpioInputBundle}, }; // Create channels: let channels = DedicatedGpio::new(peripherals.GPIO_DEDICATED); // Create input drivers for two channels: let p0 = Input::new(peripherals.GPIO0, InputConfig::default()); let p1 = Input::new(peripherals.GPIO1, InputConfig::default()); let in0 = DedicatedGpioInput::new(channels.channel0, p0); let in1 = DedicatedGpioInput::new(channels.channel1, p1); // Build a bundle that reads channels 0 and 1: let mut bundle = DedicatedGpioInputBundle::new(); bundle.enable_input(&in0).enable_input(&in1); // Read both channels at once: let bits = bundle.levels(); // bit 0 -> channel 0, bit 1 -> channel 1, ... ``` -------------------------------- ### Get configured receive length of DmaRxBuf Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/dma/buffers.rs.html Returns the maximum number of bytes this DMA buffer is currently configured to receive. This is determined by the descriptor setup. ```rust pub fn len(&self) -> usize { self.descriptors .linked_iter() .map(|d| d.size()) .sum::() } ``` -------------------------------- ### Input Initialization Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/gpio/struct.Input.html Demonstrates how to create a new Input pin instance with default configuration. ```APIDOC ## Input::new ### Description Initializes a new GPIO pin as an input with the specified configuration. ### Parameters - `pin`: The GPIO pin to configure. - `config`: The `InputConfig` for the pin. ### Example ```rust use esp_hal::gpio::{Input, InputConfig}; let pin = Input::new(peripherals.GPIO5, InputConfig::default()); ``` ``` -------------------------------- ### Configure and Use General-purpose Timer Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/timer/timg/index.html Demonstrates how to initialize a general-purpose timer, get the current timestamp, set a timeout, start the timer, and wait for an interrupt. ```rust use esp_hal::timer::{Timer, timg::TimerGroup}; let timg0 = TimerGroup::new(peripherals.TIMG0); let timer0 = timg0.timer0; // Get the current timestamp, in microseconds: let now = timer0.now(); // Wait for timeout: timer0.load_value(Duration::from_secs(1)); timer0.start(); while !timer0.is_interrupt_set() { // Wait } timer0.clear_interrupt(); ``` -------------------------------- ### Example Usage of RtcioWakeupSource Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/rtc_cntl/sleep/struct.RtcioWakeupSource.html?search=std%3A%3Avec Demonstrates how to initialize Rtc, get wakeup reasons, configure timer and Rtcio wakeup sources, and initiate deep sleep. ```rust let mut rtc = Rtc::new(peripherals.LPWR); let reason = reset_reason(Cpu::ProCpu); let wake_reason = wakeup_cause(); println!("{:?} {{}}", reason, wake_reason); let delay = Delay::new(); let timer = TimerWakeupSource::new(Duration::from_secs(10)); let wakeup_pins: &mut [(&mut dyn gpio::RtcPinWithResistors, WakeupLevel)] = &mut [ (&mut peripherals.GPIO2, WakeupLevel::Low), (&mut peripherals.GPIO3, WakeupLevel::High), ]; let rtcio = RtcioWakeupSource::new(wakeup_pins); delay.delay_millis(100); rtc.sleep_deep(&[&timer, &rtcio]); ``` -------------------------------- ### Io::new Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/gpio/struct.Io.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Initializes the I/O driver. This API is unstable and requires the 'unstable' crate feature. ```APIDOC ## Io::new ### Description Initializes the I/O driver. ### Stability **This API is marked as unstable** and is only available when the `unstable` crate feature is enabled. This comes with no stability guarantees, and could be changed or removed at any time. ### Signature ```rust pub fn new(_io_mux: IO_MUX<'d>) -> Self ``` ``` -------------------------------- ### System Initialization Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/fn.init.html Initializes the system by setting up the CPU clock and watchdog. This function is available only when the `rt` crate feature is enabled. ```APIDOC ## init ### Description Initializes the system. This function sets up the CPU clock and watchdog, then returns the peripherals and clocks. ### Signature ```rust pub fn init(config: Config) -> Peripherals ``` ### Availability Available on `crate feature` `rt` only. ### Parameters * `config` (Config) - Configuration for the initialization process. ### Returns * `Peripherals` - The initialized peripherals and clocks. ### Example ```rust use esp_hal::{Config, init}; let peripherals = init(Config::default()); ``` ``` -------------------------------- ### Initialize and Start RsaBackend Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/rsa/struct.RsaBackend.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Demonstrates how to create a new RsaBackend instance and start it to enable RSA operations. The returned driver object must be kept alive for operations to be processed. ```rust use esp_hal::rsa::{RsaBackend, RsaContext, operand_sizes::Op512}; let mut rsa_backend = RsaBackend::new(peripherals.RSA); let _driver = rsa_backend.start(); async fn perform_512bit_big_number_multiplication( operand_a: &[u32; 16], operand_b: &[u32; 16], result: &mut [u32; 32], ) { let mut rsa = RsaContext::new(); let mut handle = rsa.multiply::(operand_a, operand_b, result); handle.wait().await; } ``` -------------------------------- ### System Initialization Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/lib.rs.html?search=std%3A%3Avec Initializes the system by setting up the CPU clock, watchdog, and peripherals. This function is crucial for starting the ESP32-C3. ```APIDOC ## init ### Description Initializes the system. This function sets up the CPU clock and watchdog, then returns the peripherals and clocks. ### Example ```rust, no_run # use esp_hal::{Config, init}; let peripherals = init(Config::default()); ``` ### Parameters - **config** (Config) - Configuration for system initialization. ### Returns - **Peripherals** - The initialized peripherals of the ESP32-C3. ``` -------------------------------- ### Io::new Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/gpio/struct.Io.html?search=u32+-%3E+bool Initializes the I/O driver. This method is unstable and requires the `unstable` crate feature. ```APIDOC ### pub fn new(_io_mux: IO_MUX<'d>) -> Self Initialize the I/O driver. **Stability**: **This API is marked as unstable** and is only available when the `unstable` crate feature is enabled. This comes with no stability guarantees, and could be changed or removed at any time. ``` -------------------------------- ### Rust Slice `windows` Iterator Example Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/dma/struct.DmaLoopBuf.html Demonstrates how to use the `windows` iterator to get overlapping sub-slices of a given size. Panics if the slice is shorter than the window size. ```rust let slice = ['l', 'o', 'r', 'e', 'm']; let mut iter = slice.windows(3); assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']); assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']); assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']); assert!(iter.next().is_none()); ``` ```rust let slice = ['f', 'o', 'o']; let mut iter = slice.windows(4); assert!(iter.next().is_none()); ``` -------------------------------- ### Example Usage of RSA Multiply Operation Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/src/esp_hal/rsa/mod.rs.html?search=u32+-%3E+bool Demonstrates how to perform a standard multiplication using RsaContext. It shows the setup of input and output buffers, initiating the operation, and waiting for completion. ```rust /// let mut handle = rsa.multiply::(&x, &y, &mut outbuf); /// handle.wait_blocking(); ``` ```rust # // Inputs # let x: [u32; 16] = [0; 16]; # let y: [u32; 16] = [0; 16]; # // let x: [u32; 16] = [...]; # // let y: [u32; 16] = [...]; let mut outbuf = [0; 32]; use esp_hal::rsa::{RsaContext, operand_sizes::Op512}; // Now perform the actual computation: let mut rsa = RsaContext::new(); let mut handle = rsa.multiply::(&x, &y, &mut outbuf); handle.wait_blocking(); ``` -------------------------------- ### Default Config Initialization Source: https://docs.espressif.com/projects/rust/esp-hal/1.1.1/esp32c3/esp_hal/struct.Config.html Initialize the system with default configuration settings. This is the recommended way to create a Config instance. ```rust let peripherals = esp_hal::init(esp_hal::Config::default()); ```