mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-29 05:10:55 +00:00
Documenting a number of peripherals and packages (#680)
* Initial documentation improvements * More documentation improvements * More documentation improvements More modules documented * Finished SOC documentation for esp32 + TWAI * Fix: fix incorrect formatting * Adding more documentation to rom, and soc peripherals for multiple chips * Adding documentation for multiple peripherals * Adding SOC module documentation * Analog and clock modules are documented * Adding module-level documentation for DMA and INTERRUPT peripherals * Finishing job + minor fixes * Fix unopened HTML break * Rustfmt adjustment formatting Fix typo * Add CHANGELOG record Fix typo * Fix typos, mistakes, improving docs Co-authored-by: Dániel Buga <bugadani@gmail.com> Fix typo Co-authored-by: Dániel Buga <bugadani@gmail.com> Fix typo Co-authored-by: Dániel Buga <bugadani@gmail.com> Fix typo Co-authored-by: Dániel Buga <bugadani@gmail.com> fix typo Co-authored-by: Dániel Buga <bugadani@gmail.com> Fix typo Co-authored-by: Dániel Buga <bugadani@gmail.com> Fix typo Co-authored-by: Scott Mabin <scott@mabez.dev> Fixing typos, mistakes, improving docs. * Fix formatting, mistakes and typos * Fixing a bunch of logical, grammatical and formatting mistakes
This commit is contained in:
parent
4baf0b96c6
commit
2bd10526a7
@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Implement sleep with some wakeup methods for `esp32-s3` (#660, #689, #696)
|
||||
- Add feature enabling directly hooking the interrupt vector table
|
||||
- Add `ClockControl::max` helper for all chips (#701)
|
||||
- Added module-level documentation for all peripherals
|
||||
- Added module-level documentation for all peripherals (#680)
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -1,10 +1,61 @@
|
||||
//! Advanced Encryption Standard (AES) support.
|
||||
//! # Advanced Encryption Standard (AES) support.
|
||||
//!
|
||||
//! This module provides functions and structs for AES encryption and
|
||||
//! decryption.
|
||||
//! ## Overview
|
||||
//! The AES module provides an interface to interact with the AES peripheral,
|
||||
//! provides encryption and decryption capabilities for ESP chips using the AES
|
||||
//! algorithm. We currently support the following AES encryption modes:
|
||||
//! * AES-128
|
||||
//! * AES-192
|
||||
//! * AES-256
|
||||
//!
|
||||
//! ## Example
|
||||
//! ### Initialization
|
||||
//! ```no_run
|
||||
//! let mut aes = Aes::new(peripherals.AES, &mut system.peripheral_clock_control);
|
||||
//! ```
|
||||
//! ### Creating key and block Buffer
|
||||
//! ```no_run
|
||||
//! let keytext = "SUp4SeCp@sSw0rd".as_bytes();
|
||||
//! let plaintext = "message".as_bytes();
|
||||
//!
|
||||
//! // create an array with aes128 key size
|
||||
//! let mut keybuf = [0_u8; 16];
|
||||
//! keybuf[..keytext.len()].copy_from_slice(keytext);
|
||||
//!
|
||||
//! // create an array with aes block size
|
||||
//! let mut block_buf = [0_u8; 16];
|
||||
//! block_buf[..plaintext.len()].copy_from_slice(plaintext);
|
||||
//! ```
|
||||
//!
|
||||
//! ### Encrypting and Decrypting (using hardware)
|
||||
//! ```no_run
|
||||
//! let key = Key::<Aes128>::from(&keybuf);
|
||||
//!
|
||||
//! let mut cipher = Cipher::new(&mut aes, &key);
|
||||
//! let mut block = block_buf.clone();
|
||||
//! cipher.encrypt_block(&mut block);
|
||||
//!
|
||||
//! let hw_encrypted = block.clone();
|
||||
//! cipher.decrypt_block(&mut block);
|
||||
//! let hw_decrypted = block;
|
||||
//! ```
|
||||
//!
|
||||
//! ### Encrypting and Decrypting (using software)
|
||||
//! ```no_run
|
||||
//! let key = GenericArray::from(keybuf);
|
||||
//!
|
||||
//! let mut block = GenericArray::from(block_buf);
|
||||
//! let cipher = Aes128SW::new(&key);
|
||||
//! cipher.encrypt_block(&mut block);
|
||||
//!
|
||||
//! let sw_encrypted = block.clone();
|
||||
//! cipher.decrypt_block(&mut block);
|
||||
//!
|
||||
//! let sw_decrypted = block;
|
||||
//! ```
|
||||
//!
|
||||
//! ### Implementation State
|
||||
//! * DMA mode is currently not supported.
|
||||
//! * DMA mode is currently not supported ⚠️
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
|
@ -421,10 +421,15 @@ macro_rules! impl_adc_interface {
|
||||
pub use impl_adc_interface;
|
||||
|
||||
pub mod implementation {
|
||||
//! Analog to digital (ADC) conversion support.
|
||||
//! # Analog to digital (ADC) conversion support.
|
||||
//!
|
||||
//! This module provides functions for reading analog values from two
|
||||
//! analog to digital converters available on the ESP32: `ADC1` and `ADC2`.
|
||||
//! ## Overview
|
||||
//! The `ADC` module in the `analog` driver enables users to perform
|
||||
//! analog-to-digital conversions, allowing them to measure real-world
|
||||
//! analog signals with high accuracy.
|
||||
//!
|
||||
//! This module provides functions for reading analog values from the
|
||||
//! analog to digital converter available on the ESP32: `ADC1` and `ADC2`.
|
||||
//!
|
||||
//! The following pins can be configured for analog readout:
|
||||
//!
|
||||
@ -440,6 +445,28 @@ pub mod implementation {
|
||||
//! | 7 | GPIO35 (VDET_2) | GPIO27 |
|
||||
//! | 8 | | GPIO25 |
|
||||
//! | 9 | | GPIO26 |
|
||||
//!
|
||||
//! ## Example
|
||||
//! #### ADC on Xtensa architecture
|
||||
//! ```no_run
|
||||
//! // Create ADC instances
|
||||
//! let analog = peripherals.SENS.split();
|
||||
//!
|
||||
//! let mut adc1_config = AdcConfig::new();
|
||||
//!
|
||||
//! let mut pin3 =
|
||||
//! adc1_config.enable_pin(io.pins.gpio3.into_analog(), Attenuation::Attenuation11dB);
|
||||
//!
|
||||
//! let mut adc1 = ADC::<ADC1>::adc(analog.adc1, adc1_config).unwrap();
|
||||
//!
|
||||
//! let mut delay = Delay::new(&clocks);
|
||||
//!
|
||||
//! loop {
|
||||
//! let pin3_value: u16 = nb::block!(adc1.read(&mut pin3)).unwrap();
|
||||
//! println!("PIN3 ADC reading = {}", pin3_value);
|
||||
//! delay.delay_ms(1500u32);
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use embedded_hal::adc::Channel;
|
||||
|
||||
|
@ -691,10 +691,41 @@ pub use impl_adc_interface;
|
||||
|
||||
#[cfg(esp32c2)]
|
||||
pub mod implementation {
|
||||
//! Analog to digital (ADC) conversion support.
|
||||
//! # Analog to digital (ADC) conversion support.
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `ADC` module in the `analog` driver enables users to perform
|
||||
//! analog-to-digital conversions, allowing them to measure real-world
|
||||
//! analog signals with high accuracy.
|
||||
//!
|
||||
//! This module provides functions for reading analog values from the
|
||||
//! analog to digital converter available on the ESP32-C2: `ADC1`.
|
||||
//!
|
||||
//! ## Example
|
||||
//! #### ADC on Risc-V architecture
|
||||
//! ```no_run
|
||||
//! // Create ADC instances
|
||||
//! let analog = peripherals.APB_SARADC.split();
|
||||
//!
|
||||
//! let mut adc1_config = AdcConfig::new();
|
||||
//!
|
||||
//! let mut pin = adc1_config.enable_pin(io.pins.gpio2.into_analog(), Attenuation::Attenuation11dB);
|
||||
//!
|
||||
//! let mut adc1 = ADC::<ADC1>::adc(
|
||||
//! &mut system.peripheral_clock_control,
|
||||
//! analog.adc1,
|
||||
//! adc1_config,
|
||||
//! )
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! let mut delay = Delay::new(&clocks);
|
||||
//!
|
||||
//! loop {
|
||||
//! let pin_value: u16 = nb::block!(adc1.read(&mut pin)).unwrap();
|
||||
//! println!("PIN2 ADC reading = {}", pin_value);
|
||||
//! delay.delay_ms(1500u32);
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use embedded_hal::adc::Channel;
|
||||
|
||||
@ -714,11 +745,42 @@ pub mod implementation {
|
||||
|
||||
#[cfg(esp32c3)]
|
||||
pub mod implementation {
|
||||
//! Analog to digital (ADC) conversion support.
|
||||
//! # Analog to digital (ADC) conversion support.
|
||||
//!
|
||||
//! This module provides functions for reading analog values from two
|
||||
//! analog to digital converters available on the ESP32-C3: `ADC1` and
|
||||
//! ## Overview
|
||||
//! The `ADC` module in the `analog` driver enables users to perform
|
||||
//! analog-to-digital conversions, allowing them to measure real-world
|
||||
//! analog signals with high accuracy.
|
||||
//!
|
||||
//! This module provides functions for reading analog values from the
|
||||
//! analog to digital converter available on the ESP32-C3: `ADC1` and
|
||||
//! `ADC2`.
|
||||
//!
|
||||
//! ## Example
|
||||
//! #### ADC on Risc-V architecture
|
||||
//! ```no_run
|
||||
//! // Create ADC instances
|
||||
//! let analog = peripherals.APB_SARADC.split();
|
||||
//!
|
||||
//! let mut adc1_config = AdcConfig::new();
|
||||
//!
|
||||
//! let mut pin = adc1_config.enable_pin(io.pins.gpio2.into_analog(), Attenuation::Attenuation11dB);
|
||||
//!
|
||||
//! let mut adc1 = ADC::<ADC1>::adc(
|
||||
//! &mut system.peripheral_clock_control,
|
||||
//! analog.adc1,
|
||||
//! adc1_config,
|
||||
//! )
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! let mut delay = Delay::new(&clocks);
|
||||
//!
|
||||
//! loop {
|
||||
//! let pin_value: u16 = nb::block!(adc1.read(&mut pin)).unwrap();
|
||||
//! println!("PIN2 ADC reading = {}", pin_value);
|
||||
//! delay.delay_ms(1500u32);
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use embedded_hal::adc::Channel;
|
||||
|
||||
@ -744,10 +806,41 @@ pub mod implementation {
|
||||
|
||||
#[cfg(esp32c6)]
|
||||
pub mod implementation {
|
||||
//! Analog to digital (ADC) conversion support.
|
||||
//! # Analog to digital (ADC) conversion support.
|
||||
//!
|
||||
//! This module provides functions for reading analog values from one
|
||||
//! ## Overview
|
||||
//! The `ADC` module in the `analog` driver enables users to perform
|
||||
//! analog-to-digital conversions, allowing them to measure real-world
|
||||
//! analog signals with high accuracy.
|
||||
//!
|
||||
//! This module provides functions for reading analog values from the
|
||||
//! analog to digital converter available on the ESP32-C6: `ADC1`.
|
||||
//!
|
||||
//! ## Example
|
||||
//! #### ADC on Risc-V architecture
|
||||
//! ```no_run
|
||||
//! // Create ADC instances
|
||||
//! let analog = peripherals.APB_SARADC.split();
|
||||
//!
|
||||
//! let mut adc1_config = AdcConfig::new();
|
||||
//!
|
||||
//! let mut pin = adc1_config.enable_pin(io.pins.gpio2.into_analog(), Attenuation::Attenuation11dB);
|
||||
//!
|
||||
//! let mut adc1 = ADC::<ADC1>::adc(
|
||||
//! &mut system.peripheral_clock_control,
|
||||
//! analog.adc1,
|
||||
//! adc1_config,
|
||||
//! )
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! let mut delay = Delay::new(&clocks);
|
||||
//!
|
||||
//! loop {
|
||||
//! let pin_value: u16 = nb::block!(adc1.read(&mut pin)).unwrap();
|
||||
//! println!("PIN2 ADC reading = {}", pin_value);
|
||||
//! delay.delay_ms(1500u32);
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use embedded_hal::adc::Channel;
|
||||
|
||||
@ -769,10 +862,41 @@ pub mod implementation {
|
||||
|
||||
#[cfg(esp32h2)]
|
||||
pub mod implementation {
|
||||
//! Analog to digital (ADC) conversion support.
|
||||
//! # Analog to digital (ADC) conversion support.
|
||||
//!
|
||||
//! This module provides functions for reading analog values from one
|
||||
//! analog to digital converter available on the ESP32-H2: `ADC1`.
|
||||
//! ## Overview
|
||||
//! The `ADC` module in the `analog` driver enables users to perform
|
||||
//! analog-to-digital conversions, allowing them to measure real-world
|
||||
//! analog signals with high accuracy.
|
||||
//!
|
||||
//! This module provides functions for reading analog values from the
|
||||
//! analog to digital converter available on the ESP32-H2: `ADC1`.
|
||||
//!
|
||||
//! ## Example
|
||||
//! #### ADC on Risc-V architecture
|
||||
//! ```no_run
|
||||
//! // Create ADC instances
|
||||
//! let analog = peripherals.APB_SARADC.split();
|
||||
//!
|
||||
//! let mut adc1_config = AdcConfig::new();
|
||||
//!
|
||||
//! let mut pin = adc1_config.enable_pin(io.pins.gpio2.into_analog(), Attenuation::Attenuation11dB);
|
||||
//!
|
||||
//! let mut adc1 = ADC::<ADC1>::adc(
|
||||
//! &mut system.peripheral_clock_control,
|
||||
//! analog.adc1,
|
||||
//! adc1_config,
|
||||
//! )
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! let mut delay = Delay::new(&clocks);
|
||||
//!
|
||||
//! loop {
|
||||
//! let pin_value: u16 = nb::block!(adc1.read(&mut pin)).unwrap();
|
||||
//! println!("PIN2 ADC reading = {}", pin_value);
|
||||
//! delay.delay_ms(1500u32);
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use embedded_hal::adc::Channel;
|
||||
|
||||
|
@ -753,11 +753,38 @@ pub use impl_adc_interface;
|
||||
|
||||
#[cfg(esp32s3)]
|
||||
pub mod implementation {
|
||||
//! Analog to digital (ADC) conversion support.
|
||||
//! # Analog to digital (ADC) conversion support.
|
||||
//!
|
||||
//! This module provides functions for reading analog values from two
|
||||
//! analog to digital converters available on the ESP32-S3: `ADC1` and
|
||||
//! ## Overview
|
||||
//! The `ADC` module in the `analog` driver enables users to perform
|
||||
//! analog-to-digital conversions, allowing them to measure real-world
|
||||
//! analog signals with high accuracy.
|
||||
//!
|
||||
//! This module provides functions for reading analog values from the
|
||||
//! analog to digital converter available on the ESP32-S3: `ADC1` and
|
||||
//! `ADC2`.
|
||||
//!
|
||||
//! ## Example
|
||||
//! #### ADC on Xtensa architecture
|
||||
//! ```no_run
|
||||
//! // Create ADC instances
|
||||
//! let analog = peripherals.SENS.split();
|
||||
//!
|
||||
//! let mut adc1_config = AdcConfig::new();
|
||||
//!
|
||||
//! let mut pin3 =
|
||||
//! adc1_config.enable_pin(io.pins.gpio3.into_analog(), Attenuation::Attenuation11dB);
|
||||
//!
|
||||
//! let mut adc1 = ADC::<ADC1>::adc(analog.adc1, adc1_config).unwrap();
|
||||
//!
|
||||
//! let mut delay = Delay::new(&clocks);
|
||||
//!
|
||||
//! loop {
|
||||
//! let pin3_value: u16 = nb::block!(adc1.read(&mut pin3)).unwrap();
|
||||
//! println!("PIN3 ADC reading = {}", pin3_value);
|
||||
//! delay.delay_ms(1500u32);
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use embedded_hal::adc::Channel;
|
||||
|
||||
@ -798,11 +825,38 @@ pub mod implementation {
|
||||
|
||||
#[cfg(esp32s2)]
|
||||
pub mod implementation {
|
||||
//! Analog to digital (ADC) conversion support.
|
||||
//! # Analog to digital (ADC) conversion support.
|
||||
//!
|
||||
//! This module provides functions for reading analog values from two
|
||||
//! analog to digital converters available on the ESP32-S2: `ADC1` and
|
||||
//! ## Overview
|
||||
//! The `ADC` module in the `analog` driver enables users to perform
|
||||
//! analog-to-digital conversions, allowing them to measure real-world
|
||||
//! analog signals with high accuracy.
|
||||
//!
|
||||
//! This module provides functions for reading analog values from the
|
||||
//! analog to digital converter available on the ESP32-S2: `ADC1` and
|
||||
//! `ADC2`.
|
||||
//!
|
||||
//! ## Example
|
||||
//! #### ADC on Xtensa architecture
|
||||
//! ```no_run
|
||||
//! // Create ADC instances
|
||||
//! let analog = peripherals.SENS.split();
|
||||
//!
|
||||
//! let mut adc1_config = AdcConfig::new();
|
||||
//!
|
||||
//! let mut pin3 =
|
||||
//! adc1_config.enable_pin(io.pins.gpio3.into_analog(), Attenuation::Attenuation11dB);
|
||||
//!
|
||||
//! let mut adc1 = ADC::<ADC1>::adc(analog.adc1, adc1_config).unwrap();
|
||||
//!
|
||||
//! let mut delay = Delay::new(&clocks);
|
||||
//!
|
||||
//! loop {
|
||||
//! let pin3_value: u16 = nb::block!(adc1.read(&mut pin3)).unwrap();
|
||||
//! println!("PIN3 ADC reading = {}", pin3_value);
|
||||
//! delay.delay_ms(1500u32);
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use embedded_hal::adc::Channel;
|
||||
|
||||
|
@ -1,3 +1,17 @@
|
||||
//! # Analog peripherals - Digital to Analog Converter
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `DAC` module is part of the `Analog` driver designed for ESP
|
||||
//! microcontrollers, providing functionalities for `digital-to-analog`
|
||||
//! conversion.
|
||||
//!
|
||||
//! This module simplifies digital-to-analog conversion on ESP microcontrollers,
|
||||
//! enabling precise control over analog output signals. Developers can choose
|
||||
//! the `DAC` channel they want to use based on the GPIO pin assignments for
|
||||
//! each channel. By providing a unified interface for DAC control, the module
|
||||
//! makes it easier for users to generate accurate analog voltages in their
|
||||
//! applications, such as audio generation, sensor calibration, and analog
|
||||
//! signal synthesis.
|
||||
use crate::{
|
||||
peripheral::PeripheralRef,
|
||||
peripherals::{RTC_IO, SENS},
|
||||
|
@ -1,3 +1,87 @@
|
||||
//! # Analog peripherals
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `Analog` Driver is a module designed for ESP microcontrollers, that
|
||||
//! provides an interface to interact with analog peripherals on the chip. The
|
||||
//! module includes support for `Analog-to-Digital Converters (ADC)` and
|
||||
//! `Digital-to-Analog Converters (DAC)`, offering functionality for precise
|
||||
//! analog measurements and generating analog output signals.
|
||||
//!
|
||||
//! The `ADC` module in the `analog` driver enables users to perform
|
||||
//! analog-to-digital conversions, allowing them to measure real-world analog
|
||||
//! signals with high accuracy. The module provides access to multiple ADC
|
||||
//! units, such as `ADC1` and `ADC2`, which may differ based on the specific ESP
|
||||
//! microcontroller being used.
|
||||
//!
|
||||
//! The `DAC` module in the `analog` driver enables users to generate
|
||||
//! analog output signals with precise control over voltage levels. The module
|
||||
//! supports multiple DAC units, such as `DAC1` and `DAC2`, which may vary
|
||||
//! depending on the specific ESP microcontroller.
|
||||
//!
|
||||
//! #### Xtensa architecture
|
||||
//! For ESP microcontrollers using the `Xtensa` architecture, the driver
|
||||
//! provides access to the `SENS` peripheral, allowing users to split it into
|
||||
//! independent parts using the [`SensExt`] trait. This extension trait provides
|
||||
//! access to the following analog peripherals:
|
||||
//! * ADC1
|
||||
//! * ADC2
|
||||
//! * DAC1
|
||||
//! * DAC2
|
||||
//!
|
||||
//! #### RISC-V architecture
|
||||
//! For ESP microcontrollers using the `RISC-V` architecture, the driver
|
||||
//! provides access to the `APB_SARADC` peripheral. The `SarAdcExt` trait allows
|
||||
//! users to split this peripheral into independent parts, providing access to
|
||||
//! the following analog peripheral:
|
||||
//! * ADC1
|
||||
//! * ADC2
|
||||
//!
|
||||
//! ## Examples
|
||||
//! #### ADC on Risc-V architecture
|
||||
//! ```no_run
|
||||
//! // Create ADC instances
|
||||
//! let analog = peripherals.APB_SARADC.split();
|
||||
//!
|
||||
//! let mut adc1_config = AdcConfig::new();
|
||||
//!
|
||||
//! let mut pin = adc1_config.enable_pin(io.pins.gpio2.into_analog(), Attenuation::Attenuation11dB);
|
||||
//!
|
||||
//! let mut adc1 = ADC::<ADC1>::adc(
|
||||
//! &mut system.peripheral_clock_control,
|
||||
//! analog.adc1,
|
||||
//! adc1_config,
|
||||
//! )
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! let mut delay = Delay::new(&clocks);
|
||||
//!
|
||||
//! loop {
|
||||
//! let pin_value: u16 = nb::block!(adc1.read(&mut pin)).unwrap();
|
||||
//! println!("PIN2 ADC reading = {}", pin_value);
|
||||
//! delay.delay_ms(1500u32);
|
||||
//! }
|
||||
//! ```
|
||||
//! #### ADC on Xtensa architecture
|
||||
//! ```no_run
|
||||
//! // Create ADC instances
|
||||
//! let analog = peripherals.SENS.split();
|
||||
//!
|
||||
//! let mut adc1_config = AdcConfig::new();
|
||||
//!
|
||||
//! let mut pin3 =
|
||||
//! adc1_config.enable_pin(io.pins.gpio3.into_analog(), Attenuation::Attenuation11dB);
|
||||
//!
|
||||
//! let mut adc1 = ADC::<ADC1>::adc(analog.adc1, adc1_config).unwrap();
|
||||
//!
|
||||
//! let mut delay = Delay::new(&clocks);
|
||||
//!
|
||||
//! loop {
|
||||
//! let pin3_value: u16 = nb::block!(adc1.read(&mut pin3)).unwrap();
|
||||
//! println!("PIN3 ADC reading = {}", pin3_value);
|
||||
//! delay.delay_ms(1500u32);
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
#[cfg_attr(esp32, path = "adc/esp32.rs")]
|
||||
#[cfg_attr(riscv, path = "adc/riscv.rs")]
|
||||
#[cfg_attr(any(esp32s2, esp32s3), path = "adc/xtensa.rs")]
|
||||
|
@ -1,4 +1,10 @@
|
||||
//! Debug Assistant
|
||||
//! # Debug Assistant
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The Assist Debug driver provides functionality for debugging and monitoring
|
||||
//! features on ESP chips. It includes capabilities such as monitoring stack
|
||||
//! pointer (SP), monitoring memory regions, and handling interrupts related to
|
||||
//! debugging.
|
||||
//!
|
||||
//! Debug Assistant is an auxiliary module that features a set of functions to
|
||||
//! help locate bugs and issues during software debugging.
|
||||
@ -8,9 +14,7 @@
|
||||
//! (e.g. _Saved PC:0x42002ff2_). Make sure the reset was triggered by a TIMG
|
||||
//! watchdog. Not an RTC or SWD watchdog.
|
||||
//!
|
||||
//! Not all targets support all the features.
|
||||
//!
|
||||
//! Bus write access logging is not available via this API.
|
||||
//! ⚠️ Bus write access logging is not available via this API. ⚠️
|
||||
|
||||
use crate::{
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
|
@ -1,4 +1,53 @@
|
||||
//! # Clock Control
|
||||
//!
|
||||
//! ## Overview
|
||||
//! This `Clock` driver provides an interface for configuring and managing
|
||||
//! various clocks present on the `ESP` microcontrollers.
|
||||
//!
|
||||
//! Proper clock configuration is essential for the correct functioning of the
|
||||
//! microcontroller and its peripherals.
|
||||
//!
|
||||
//! The `Clock` driver supports configuring multiple clocks, including:
|
||||
//! * CPU clock
|
||||
//! * APB (Advanced Peripheral Bus) clock
|
||||
//! * XTAL clock
|
||||
//! * PLL clock
|
||||
//!
|
||||
//! and other specific clocks based on the ESP microcontroller's architecture.
|
||||
//!
|
||||
//! The `CPU clock` is responsible for defining the speed at which the central
|
||||
//! processing unit (CPU) operates. This driver provides predefined options for
|
||||
//! different CPU clock speeds, such
|
||||
//! * 80 MHz
|
||||
//! * 96 MHz
|
||||
//! * 120 MHz
|
||||
//! * 160 MHz
|
||||
//! * 240 MHz
|
||||
//!
|
||||
//! and others, depending on the microcontroller model.
|
||||
//!
|
||||
//! #### Clock Control
|
||||
//! The `ClockControl` struct allows users to configure the desired clock
|
||||
//! frequencies before applying them. It offers flexibility in selecting
|
||||
//! appropriate clock frequencies based on specific application requirements.
|
||||
//!
|
||||
//! #### Frozen clock frequencies
|
||||
//! Once the clock configuration is applied using the `freeze` function of the
|
||||
//! ClockControl struct, the clock frequencies become `frozen` and cannot be
|
||||
//! changed. The `Clocks` struct is returned after freezing, providing read-only
|
||||
//! access to the configured clock frequencies.
|
||||
//!
|
||||
//! ## Examples
|
||||
//!
|
||||
//! #### Initialize with default clock frequency for this chip
|
||||
//! ```no_run
|
||||
//! let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
//! ```
|
||||
//!
|
||||
//! #### Initialize with custom clock frequency
|
||||
//! ```no_run
|
||||
//! let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock160MHz).freeze();
|
||||
//! ```
|
||||
use fugit::HertzU32;
|
||||
|
||||
use crate::{
|
||||
|
@ -1,10 +1,23 @@
|
||||
//! Delay driver implement the blocking [DelayMs] and [DelayUs] traits from
|
||||
//! [embedded-hal].
|
||||
//! # Delay driver
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The Delay driver provides blocking delay functionalities using the
|
||||
//! `SYSTIMER` peripheral for RISC-V devices and the built-in Xtensa timer for
|
||||
//! Xtensa devices. This module implements the blocking [DelayMs] and [DelayUs]
|
||||
//! traits from [embedded-hal].
|
||||
//!
|
||||
//! The delays are implemented in a "best-effort" way, meaning that the CPU will
|
||||
//! block for at least the amount of time specified, but accuracy can be
|
||||
//! affected by many factors, including interrupt usage.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let mut clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
//! let mut delay = Delay::new(&clocks);
|
||||
//!
|
||||
//! delay.delay_ms(1000 as u32);
|
||||
//! ```
|
||||
//!
|
||||
//! [DelayMs]: embedded_hal::blocking::delay::DelayMs
|
||||
//! [DelayUs]: embedded_hal::blocking::delay::DelayUs
|
||||
//! [embedded-hal]: https://docs.rs/embedded-hal/latest/embedded_hal/
|
||||
|
@ -1,4 +1,25 @@
|
||||
//! Direct Memory Access
|
||||
//! # Direct Memory Access
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The GDMA (General DMA) module is a part of the DMA (Direct Memory Access)
|
||||
//! driver for ESP chips. Of the Espressif chip range, every chip except of
|
||||
//! `ESP32` and `ESP32-S2` uses the `GDMA` type of direct memory access.
|
||||
//!
|
||||
//! DMA is a hardware feature that allows data transfer between memory and
|
||||
//! peripherals without involving the CPU, resulting in efficient data movement
|
||||
//! and reduced CPU overhead. The `GDMA` module provides multiple DMA channels,
|
||||
//! each capable of managing data transfer for various peripherals.
|
||||
//!
|
||||
//! This module implements DMA channels, such as `channel0`, `channel1` and so
|
||||
//! on. Each channel struct implements the `ChannelTypes` trait, which provides
|
||||
//! associated types for peripheral configuration.
|
||||
//!
|
||||
//! GDMA peripheral can be initializes using the `new` function, which requires
|
||||
//! a DMA peripheral instance and a clock control reference. ```no_run
|
||||
//! let dma = Gdma::new(peripherals.DMA, &mut system.peripheral_clock_control);
|
||||
//! ```
|
||||
//!
|
||||
//! <em>PS: Note that the number of DMA channels is chip-specific.</em>
|
||||
|
||||
use crate::{
|
||||
dma::*,
|
||||
|
@ -1,7 +1,72 @@
|
||||
//! Direct Memory Access Commons
|
||||
//! # Direct Memory Access Commons
|
||||
//!
|
||||
//! Descriptors should be sized as `((BUFFERSIZE + 4091) / 4092) * 3`. I.e., to
|
||||
//! transfer buffers of size `1..=4092`, you need 3 descriptors.
|
||||
//! ## Overview
|
||||
//! The `DMA` driver provides an interface to efficiently transfer data between
|
||||
//! different memory regions within the ESP microcontroller without involving
|
||||
//! the CPU. The `Direct Memory Access` (DMA) controller is a hardware
|
||||
//! block responsible for managing these data transfers.
|
||||
//!
|
||||
//! The driver is organized into several components and traits, each responsible
|
||||
//! for handling specific functionalities of the `DMA` controller. Below is an
|
||||
//! overview of the main components and their functionalities:
|
||||
//! * `Tx` and `Rx` traits:
|
||||
//! - These traits define the behaviors and functionalities required for
|
||||
//! DMA transmit and receive operations.<br> The `Tx` trait includes
|
||||
//! functions to start, stop, and check the completion status of an
|
||||
//! outbound DMA transfer.<br> On the other hand, the Rx trait provides
|
||||
//! similar functionalities for inbound DMA transfers.
|
||||
//! * `DmaTransfer` and `DmaTransferRxTx` traits:
|
||||
//! - The `DmaTransfer` trait and `DmaTransferRxTx` trait are used for
|
||||
//! in-progress DMA transfers.<br> They allow waiting for the transfer to
|
||||
//! complete and checking its status. Additionally, the `DmaTransferRxTx`
|
||||
//! trait extends the functionalities to support both receive and
|
||||
//! transmit operations in a single trait.
|
||||
//! * `RegisterAccess` trait:
|
||||
//! - This trait defines a set of methods that allow low-level access to
|
||||
//! the DMA controller's registers.<br> It provides functions to
|
||||
//! initialize DMA channels, configure burst mode, priority, and
|
||||
//! peripheral for both input and output data transfers.<br>Additionally,
|
||||
//! it supports clearing interrupts, resetting channels, setting
|
||||
//! descriptor addresses, and checking for descriptor errors.
|
||||
//!
|
||||
//! Notice, that this module is a common version of the DMA driver, `ESP32` and
|
||||
//! `ESP32-S2` are using older `PDMA` controller, whenever other chips are using
|
||||
//! newer `GDMA` controller.
|
||||
//!
|
||||
//! ## Example
|
||||
//! #### Initialize and utilize DMA controller in `SPI`
|
||||
//! ```no_run
|
||||
//! let dma = Gdma::new(peripherals.DMA, &mut system.peripheral_clock_control);
|
||||
//! let dma_channel = dma.channel0;
|
||||
//!
|
||||
//! // For `ESP32` and `ESP32-S2` chips use `Pdma` controller instead:
|
||||
//! // let dma = Dma::new(system.dma, &mut system.peripheral_clock_control);
|
||||
//! // let dma_channel = dma.spi2channel;
|
||||
//!
|
||||
//! let mut descriptors = [0u32; 8 * 3];
|
||||
//! let mut rx_descriptors = [0u32; 8 * 3];
|
||||
//!
|
||||
//! let mut spi = Spi::new(
|
||||
//! peripherals.SPI2,
|
||||
//! sclk,
|
||||
//! mosi,
|
||||
//! miso,
|
||||
//! cs,
|
||||
//! 100u32.kHz(),
|
||||
//! SpiMode::Mode0,
|
||||
//! &mut system.peripheral_clock_control,
|
||||
//! &clocks,
|
||||
//! )
|
||||
//! .with_dma(dma_channel.configure(
|
||||
//! false,
|
||||
//! &mut descriptors,
|
||||
//! &mut rx_descriptors,
|
||||
//! DmaPriority::Priority0,
|
||||
//! ));
|
||||
//! ```
|
||||
//!
|
||||
//! ⚠️ Note: Descriptors should be sized as `((BUFFERSIZE + 4091) / 4092) * 3`.
|
||||
//! I.e., to transfer buffers of size `1..=4092`, you need 3 descriptors.
|
||||
|
||||
use core::{marker::PhantomData, sync::atomic::compiler_fence};
|
||||
|
||||
@ -308,6 +373,7 @@ where
|
||||
fn waker() -> &'static embassy_sync::waitqueue::AtomicWaker;
|
||||
}
|
||||
|
||||
// DMA receive channel
|
||||
pub struct ChannelRx<'a, T, R>
|
||||
where
|
||||
T: RxChannel<R>,
|
||||
@ -607,6 +673,7 @@ where
|
||||
fn waker() -> &'static embassy_sync::waitqueue::AtomicWaker;
|
||||
}
|
||||
|
||||
/// DMA transmit channel
|
||||
pub struct ChannelTx<'a, T, R>
|
||||
where
|
||||
T: TxChannel<R>,
|
||||
|
@ -1,4 +1,20 @@
|
||||
//! Direct Memory Access
|
||||
//! # Direct Memory Access
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `pdma` module is part of the DMA (Direct Memory Access) driver designed
|
||||
//! for ESP chips. Of the Espressif chip range, only `ESP32` and `ESP32-S2` use
|
||||
//! the `PDMA` type of direct memory access.
|
||||
//!
|
||||
//! This module provides efficient direct data transfer capabilities between
|
||||
//! peripherals and memory without involving the CPU. It enables bidirectional
|
||||
//! data transfers through DMA channels, making it particularly useful for
|
||||
//! high-speed data transfers, such as [SPI] and
|
||||
//! [I2S] communication.
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//! [SPI]: ../spi/index.html
|
||||
//! [I2S]: ../i2s/index.html
|
||||
|
||||
use crate::{
|
||||
dma::*,
|
||||
|
@ -1,3 +1,72 @@
|
||||
//! # Embassy driver
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `embassy` driver for ESP chips is an essential part of the Embassy
|
||||
//! embedded async/await runtime and is used by applications to perform
|
||||
//! time-based operations and schedule asynchronous tasks. It provides a
|
||||
//! high-level API for handling timers and alarms, abstracting the underlying
|
||||
//! hardware details, and allowing users to focus on application logic rather
|
||||
//! than low-level timer management.
|
||||
//!
|
||||
//! Here are important details about the module:
|
||||
//! * `time_driver` module (`time_driver_systimer` or `time_driver_timg`,
|
||||
//! depends on enabled feature)
|
||||
//! - This module contains the implementations of the timer drivers for
|
||||
//! different ESP chips.<br> It includes the `EmbassyTimer` struct, which
|
||||
//! is responsible for handling alarms and timer events.
|
||||
//! - `EmbassyTimer` struct represents timer driver for ESP chips. It
|
||||
//! contains `alarms` - an array of `AlarmState` structs, which describe
|
||||
//! the state of alarms associated with the timer driver.
|
||||
//! * `AlarmState` struct
|
||||
//! - This struct represents the state of an alarm. It contains information
|
||||
//! about the alarm's timestamp, a callback function to be executed when
|
||||
//! the alarm triggers, and a context pointer for passing user-defined
|
||||
//! data to the callback.
|
||||
//!
|
||||
//! ## Example
|
||||
//! The following example demonstrates how to use the `embassy` driver to
|
||||
//! schedule asynchronous tasks.<br> In this example, we use the `embassy`
|
||||
//! driver to wait for a GPIO 9 pin state to change. ```no_run
|
||||
//! #[cfg(feature = "embassy-time-systick")]
|
||||
//! embassy::init(
|
||||
//! &clocks,
|
||||
//! esp32c6_hal::systimer::SystemTimer::new(peripherals.SYSTIMER),
|
||||
//! );
|
||||
//!
|
||||
//! #[cfg(feature = "embassy-time-timg0")]
|
||||
//! embassy::init(&clocks, timer_group0.timer0);
|
||||
//!
|
||||
//! let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//! // GPIO 9 as input
|
||||
//! let input = io.pins.gpio9.into_pull_down_input();
|
||||
//!
|
||||
//! // Async requires the GPIO interrupt to wake futures
|
||||
//! esp32c6_hal::interrupt::enable(
|
||||
//! esp32c6_hal::peripherals::Interrupt::GPIO,
|
||||
//! esp32c6_hal::interrupt::Priority::Priority1,
|
||||
//! )
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! let executor = EXECUTOR.init(Executor::new());
|
||||
//! executor.run(|spawner| {
|
||||
//! spawner.spawn(ping(input)).ok();
|
||||
//! });
|
||||
//! ```
|
||||
//!
|
||||
//! Where `ping` defined as:
|
||||
//! ```no_run
|
||||
//! async fn ping(mut pin: Gpio9<Input<PullDown>>) {
|
||||
//! loop {
|
||||
//! esp_println::println!("Waiting...");
|
||||
//! pin.wait_for_rising_edge().await.unwrap();
|
||||
//! esp_println::println!("Ping!");
|
||||
//! Timer::after(Duration::from_millis(100)).await;
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
//! For more embassy-related examples check out the [examples repo](https://github.com/esp-rs/esp-hal/tree/main/esp32-hal/examples)
|
||||
//! for a corresponding board.
|
||||
|
||||
use core::{cell::Cell, ptr};
|
||||
|
||||
use embassy_time::driver::{AlarmHandle, Driver};
|
||||
|
@ -1,12 +1,26 @@
|
||||
//! General Purpose I/Os
|
||||
//! # General Purpose I/Os
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The GPIO peripheral provides access to General Purpose Input/Output pins on
|
||||
//! ESP chips.
|
||||
//!
|
||||
//! This driver supports various operations on GPIO pins, including setting the
|
||||
//! pin mode, direction, and manipulating the pin state (setting high/low,
|
||||
//! toggling). It provides an interface to interact with GPIO pins on ESP chips,
|
||||
//! allowing developers to control and read the state of the pins. This module
|
||||
//! also implements a number of traits from [embedded-hal] to provide a common
|
||||
//! interface for GPIO pins.
|
||||
//!
|
||||
//! To get access to the pins, you first need to convert them into a HAL
|
||||
//! designed struct from the pac struct `GPIO` and `IO_MUX` using `IO::new`.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//! let mut led = io.pins.gpio5.into_push_pull_output();
|
||||
//! ```
|
||||
//!
|
||||
//! [embedded-hal]: https://docs.rs/embedded-hal/latest/embedded_hal/
|
||||
|
||||
use core::{convert::Infallible, marker::PhantomData};
|
||||
|
||||
|
@ -1,6 +1,37 @@
|
||||
//! I2C Driver
|
||||
//! # I2C Driver
|
||||
//!
|
||||
//! Supports multiple I2C peripheral instances
|
||||
//! ## Overview
|
||||
//! The I2C Peripheral Driver for ESP chips is a software module that
|
||||
//! facilitates communication with I2C devices using ESP microcontroller chips.
|
||||
//! It provides an interface to initialize, configure, and perform read and
|
||||
//! write operations over the I2C bus.
|
||||
//!
|
||||
//! The driver supports features such as handling transmission errors,
|
||||
//! asynchronous operations, and interrupt-based communication, also supports
|
||||
//! multiple I2C peripheral instances on `ESP32`, `ESP32H2`, `ESP32S2`, and
|
||||
//! `ESP32S3` chips
|
||||
//!
|
||||
//! ## Example
|
||||
//! Following code shows how to read data from a BMP180 sensor using I2C.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! // Create a new peripheral object with the described wiring
|
||||
//! // and standard I2C clock speed
|
||||
//! let mut i2c = I2C::new(
|
||||
//! peripherals.I2C0,
|
||||
//! io.pins.gpio1,
|
||||
//! io.pins.gpio2,
|
||||
//! 100u32.kHz(),
|
||||
//! &mut system.peripheral_clock_control,
|
||||
//! &clocks,
|
||||
//! );
|
||||
//! loop {
|
||||
//! let mut data = [0u8; 22];
|
||||
//! i2c.write_read(0x77, &[0xaa], &mut data).ok();
|
||||
//!
|
||||
//! println!("{:02x?}", data);
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use fugit::HertzU32;
|
||||
|
||||
|
@ -1,4 +1,70 @@
|
||||
//! I2S Master
|
||||
//! # I2S Master
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The I2S Master peripheral driver provides support for the I2S (Inter-IC
|
||||
//! Sound) Master functionality on ESP chips. It enables audio data transmission
|
||||
//! and reception with external audio devices, such as DACs (Digital-to-Analog
|
||||
//! Converters) and ADCs (Analog-to-Digital Converters) through the I2S
|
||||
//! interface. Also this module supports different data formats, including
|
||||
//! varying data and channel widths, different standards, such as the Philips
|
||||
//! standard and configurable pin mappings for I2S clock (BCLK), word select
|
||||
//! (WS), and data input/output (DOUT/DIN).
|
||||
//!
|
||||
//! The driver uses DMA (Direct Memory Access) for efficient data transfer and
|
||||
//! supports various configurations, such as different data formats, standards
|
||||
//! (e.g., Philips) and pin configurations. It relies on other peripheral
|
||||
//! modules, such as
|
||||
//! - `GPIO`
|
||||
//! - `DMA`
|
||||
//! - `system` (to configure and enable the I2S peripheral)
|
||||
//!
|
||||
//! ## Examples
|
||||
//!
|
||||
//! ### initialization
|
||||
//! ```no_run
|
||||
//! let i2s = I2s::new(
|
||||
//! peripherals.I2S0,
|
||||
//! MclkPin::new(io.pins.gpio4),
|
||||
//! Standard::Philips,
|
||||
//! DataFormat::Data16Channel16,
|
||||
//! 44100u32.Hz(),
|
||||
//! dma_channel.configure(
|
||||
//! false,
|
||||
//! &mut tx_descriptors,
|
||||
//! &mut rx_descriptors,
|
||||
//! DmaPriority::Priority0,
|
||||
//! ),
|
||||
//! &mut system.peripheral_clock_control,
|
||||
//! &clocks,
|
||||
//! );
|
||||
//! ```
|
||||
//!
|
||||
//! ### Reading
|
||||
//! ```no_run
|
||||
//! let i2s_rx = i2s.i2s_rx.with_pins(PinsBclkWsDin::new(
|
||||
//! io.pins.gpio1,
|
||||
//! io.pins.gpio2,
|
||||
//! io.pins.gpio5,
|
||||
//! ));
|
||||
//!
|
||||
//! // Creating DMA buffer
|
||||
//! static mut BUFFER: [u8; 4092 * 4] = [0u8; 4092 * 4];
|
||||
//! let buffer: &'static mut [u8; 4092 * 4] = unsafe { &mut BUFFER };
|
||||
//!
|
||||
//! let mut transfer = i2s_rx.read_dma_circular(buffer).unwrap();
|
||||
//! println!("Started transfer");
|
||||
//!
|
||||
//! loop {
|
||||
//! let avail = transfer.available();
|
||||
//!
|
||||
//! if avail > 0 {
|
||||
//! let mut rcv = [0u8; 5000];
|
||||
//! transfer.pop(&mut rcv[..avail]).unwrap();
|
||||
//! println!("Received {:x?}...", &rcv[..30]);
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use embedded_dma::{ReadBuffer, WriteBuffer};
|
||||
use private::*;
|
||||
|
@ -1,4 +1,56 @@
|
||||
//! Interrupt support
|
||||
//! # Interrupt support
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `interrupt` driver is a crucial module for ESP chips. Its primary
|
||||
//! purpose is to manage and handle interrupts, which are asynchronous events
|
||||
//! requiring immediate attention from the CPU. Interrupts are essential in
|
||||
//! various applications, such as real-time tasks, I/O communications, and
|
||||
//! handling external events like hardware signals.
|
||||
//!
|
||||
//! The core functionality of the `interrupt` driver revolves around the
|
||||
//! management of interrupts. When an interrupt occurs, it temporarily stops the
|
||||
//! ongoing CPU operations, saves its current state, and starts executing the
|
||||
//! corresponding interrupt service routine (ISR). The interrupt service routine
|
||||
//! is a user-defined function that performs the necessary actions to handle the
|
||||
//! specific interrupt. Once the ISR is executed, the driver restores the saved
|
||||
//! CPU state and resumes normal program execution.
|
||||
//!
|
||||
//! In scenarios where multiple interrupts may occur simultaneously, the
|
||||
//! interrupt driver determines the `priority` of each interrupt. This
|
||||
//! prioritization ensures that critical or high-priority tasks are handled
|
||||
//! first. It helps prevent delays in time-sensitive applications and allows the
|
||||
//! system to allocate resources efficiently. This functionality is provided and
|
||||
//! implemented by the `priority` enum.
|
||||
//!
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! #[entry]
|
||||
//! fn main() -> ! {
|
||||
//! ...
|
||||
//! critical_section::with(|cs| SWINT.borrow_ref_mut(cs).replace(sw_int));
|
||||
//!
|
||||
//! interrupt::enable(
|
||||
//! peripherals::Interrupt::FROM_CPU_INTR0,
|
||||
//! interrupt::Priority::Priority1,
|
||||
//! )
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! loop {}
|
||||
//! }
|
||||
//!
|
||||
//! #[interrupt]
|
||||
//! fn FROM_CPU_INTR0() {
|
||||
//! esp_println::println!("SW interrupt0");
|
||||
//! critical_section::with(|cs| {
|
||||
//! SWINT
|
||||
//! .borrow_ref_mut(cs)
|
||||
//! .as_mut()
|
||||
//! .unwrap()
|
||||
//! .reset(SoftwareInterrupt::SoftwareInterrupt0);
|
||||
//! });
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
#[cfg(riscv)]
|
||||
pub use riscv::*;
|
||||
|
@ -1,4 +1,4 @@
|
||||
//! Interrupt handling - RISCV
|
||||
//! Interrupt handling - RISC-V
|
||||
//!
|
||||
//! When the `vectored` feature is enabled, CPU interrupts 1 through 15 are
|
||||
//! reserved for each of the possible interrupt priorities.
|
||||
|
@ -1,3 +1,14 @@
|
||||
//! # LEDC channel
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `LEDC Channel` module is a part of the `LED Controller (LEDC)` driver
|
||||
//! designed for ESP microcontrollers. It provides a high-level interface to
|
||||
//! configure and control individual PWM channels of the LEDC peripheral.
|
||||
//!
|
||||
//! The module allows precise and flexible control over LED lighting and other
|
||||
//! `Pulse-Width Modulation (PWM)` applications by offering configurable duty
|
||||
//! cycles and frequencies.
|
||||
|
||||
use paste::paste;
|
||||
|
||||
#[cfg(esp32)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
//! LEDC (LED PWM Controller) peripheral control
|
||||
//! # LEDC (LED PWM Controller) peripheral control
|
||||
//!
|
||||
//! Currently only supports fixed-frequency output. Interrupts are not currently
|
||||
//! implemented. High Speed channels are available for the ESP32 only, while Low
|
||||
@ -9,18 +9,22 @@
|
||||
//! The following will configure the Low Speed Channel0 to 24kHz output with
|
||||
//! 10% duty using the ABPClock
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
//! let mut ledc = LEDC::new(peripherals.LEDC, &clock_control, &mut system.peripheral_clock_control);
|
||||
//! ```no_run
|
||||
//! let mut ledc = LEDC::new(
|
||||
//! peripherals.LEDC,
|
||||
//! &clock_control,
|
||||
//! &mut system.peripheral_clock_control,
|
||||
//! );
|
||||
//! ledc.set_global_slow_clock(LSGlobalClkSource::APBClk);
|
||||
//!
|
||||
//! let mut lstimer0 = ledc.get_timer::<LowSpeed>(timer::Number::Timer0);
|
||||
//! lstimer0
|
||||
//! .configure(timer::config::Config {
|
||||
//! duty: timer::config::Duty::Duty5Bit,
|
||||
//! clock_source: timer::LSClockSource::APBClk,
|
||||
//! frequency: 24u32.kHz(),
|
||||
//! })
|
||||
//! .unwrap();
|
||||
//! .configure(timer::config::Config {
|
||||
//! duty: timer::config::Duty::Duty5Bit,
|
||||
//! clock_source: timer::LSClockSource::APBClk,
|
||||
//! frequency: 24u32.kHz(),
|
||||
//! })
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! let mut channel0 = ledc.get_channel(channel::Number::Channel0, led);
|
||||
//! channel0
|
||||
@ -36,17 +40,21 @@
|
||||
//! The following will configure the High Speed Channel0 to 24kHz output with
|
||||
//! 10% duty using the ABPClock
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
//! let ledc = LEDC::new(peripherals.LEDC, &clock_control, &mut system.peripheral_clock_control);
|
||||
//! ```no_run
|
||||
//! let ledc = LEDC::new(
|
||||
//! peripherals.LEDC,
|
||||
//! &clock_control,
|
||||
//! &mut system.peripheral_clock_control,
|
||||
//! );
|
||||
//!
|
||||
//! let mut hstimer0 = ledc.get_timer::<HighSpeed>(timer::Number::Timer0);
|
||||
//! hstimer0
|
||||
//! .configure(timer::config::Config {
|
||||
//! duty: timer::config::Duty::Duty5Bit,
|
||||
//! clock_source: timer::HSClockSource::APBClk,
|
||||
//! frequency: 24u32.kHz(),
|
||||
//! })
|
||||
//! .unwrap();
|
||||
//! .configure(timer::config::Config {
|
||||
//! duty: timer::config::Duty::Duty5Bit,
|
||||
//! clock_source: timer::HSClockSource::APBClk,
|
||||
//! frequency: 24u32.kHz(),
|
||||
//! })
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! let mut channel0 = ledc.get_channel(channel::Number::Channel0, led);
|
||||
//! channel0
|
||||
|
@ -1,3 +1,14 @@
|
||||
//! # LEDC timer
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `LEDC Timer` module is a part of the `LED Controller (LEDC)` driver
|
||||
//! designed for ESP microcontrollers. It provides a high-level interface to
|
||||
//! configure and control individual timers of the `LEDC` peripheral.
|
||||
//!
|
||||
//! The module allows precise and flexible control over timer configurations,
|
||||
//! duty cycles and frequencies, making it ideal for Pulse-Width Modulation
|
||||
//! (PWM) applications and LED lighting control.
|
||||
|
||||
use fugit::HertzU32;
|
||||
|
||||
#[cfg(esp32)]
|
||||
|
@ -1,6 +1,7 @@
|
||||
//! MCPWM (Motor Control Pulse Width Modulator) peripheral
|
||||
//! # MCPWM (Motor Control Pulse Width Modulator) peripheral
|
||||
//!
|
||||
//! # Peripheral capabilities:
|
||||
//! ## Overview
|
||||
//! #### Peripheral capabilities
|
||||
//! * PWM Timers 0, 1 and 2
|
||||
//! * Every PWM timer has a dedicated 8-bit clock prescaler.
|
||||
//! * The 16-bit counter in the PWM timer can work in count-up mode,
|
||||
@ -22,11 +23,11 @@
|
||||
//! * Fault Detection Module (Not yet implemented)
|
||||
//! * Capture Module (Not yet implemented)
|
||||
//!
|
||||
//! # Example
|
||||
//! ## Example
|
||||
//! Uses timer0 and operator0 of the MCPWM0 peripheral to output a 50% duty
|
||||
//! signal at 20 kHz. The signal will be output to the pin assigned to `pin`.
|
||||
//!
|
||||
//! ```
|
||||
//! ```no_run
|
||||
//! # use esp_hal_common::{mcpwm, prelude::*};
|
||||
//! use mcpwm::{operator::PwmPinConfig, timer::PwmWorkingMode, PeripheralClockConfig, MCPWM};
|
||||
//!
|
||||
|
@ -1,3 +1,15 @@
|
||||
//! # MCPWM peripheral - operator module
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `operator` module is part of the `MCPWM` peripheral driver for
|
||||
//! `ESP` chips. It is responsible for
|
||||
//! generating `PWM (Pulse Width Modulation)` signals and handling various
|
||||
//! aspects related to `PWM` signal generation.
|
||||
//!
|
||||
//! This module provides flexibility in configuring the PWM outputs. Its
|
||||
//! implementation allows for motor control and other applications that demand
|
||||
//! accurate pulse timing and sophisticated modulation techniques.
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::{
|
||||
|
@ -1,3 +1,11 @@
|
||||
//! # MCPWM peripheral - timer module
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `timer` module is a part of the `MCPWM (Motor Control Pulse Width
|
||||
//! Modulator)` driver for ESP chips. It provides an interface to configure and
|
||||
//! use timers for generating `PWM` signals used in motor control and other
|
||||
//! applications.
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use fugit::HertzU32;
|
||||
@ -27,7 +35,7 @@ impl<const TIM: u8, PWM: PwmPeripheral> Timer<TIM, PWM> {
|
||||
/// Apply the given timer configuration.
|
||||
///
|
||||
/// ### Note:
|
||||
/// The prescalar and period configuration will be applied immediately and
|
||||
/// The prescaler and period configuration will be applied immediately and
|
||||
/// before setting the [`PwmWorkingMode`].
|
||||
/// If the timer is already running you might want to call [`Timer::stop`]
|
||||
/// and/or [`Timer::set_counter`] first
|
||||
|
@ -1,4 +1,30 @@
|
||||
//! USB OTG full-speed peripheral
|
||||
//! # USB OTG full-speed peripheral
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The USB OTG Full-speed peripheral driver provides support for the USB
|
||||
//! On-The-Go (OTG) full-speed functionality on ESP chips, allows communication
|
||||
//! with USB devices.
|
||||
//!
|
||||
//! The driver uses the `esp_synopsys_usb_otg` crate, which provides the `USB
|
||||
//! bus` implementation and `USB peripheral traits`. It also relies on other
|
||||
//! peripheral modules, such as `GPIO`, `system`, and `clock control`, to
|
||||
//! configure and enable the `USB` peripheral.
|
||||
//!
|
||||
//! To use the USB OTG Full-speed peripheral driver, you need to initialize the
|
||||
//! peripheral and configure its settings. The USB struct represents the USB
|
||||
//! peripheral and requires the implementation of the `UsbSel`, `UsbDp`, and
|
||||
//! `UsbDm` traits, which define the specific types used for USB pin selection
|
||||
//! and data pins.
|
||||
//!
|
||||
//! The USB struct provides a `new` function for initialization.
|
||||
//! Inside the `new` function, the `into_ref!` macro is used to convert the
|
||||
//! peripheral references into `PeripheralRef` instances.
|
||||
//!
|
||||
//! The `USB` struct implements the `UsbPeripheral` trait from the
|
||||
//! `esp_synopsys_usb_otg` crate, which defines the required constants and
|
||||
//! functions for `USB peripheral` operation. The trait implementation includes
|
||||
//! enabling the `USB peripheral`, configuring the `USB` settings and connecting
|
||||
//! the appropriate `GPIO` pins to the `USB peripheral`.
|
||||
|
||||
pub use esp_synopsys_usb_otg::UsbBus;
|
||||
use esp_synopsys_usb_otg::UsbPeripheral;
|
||||
|
@ -1,3 +1,13 @@
|
||||
//! # PCNT - channel configuration
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `channel` module is part of the `PCNT` peripheral driver
|
||||
//! for `ESP` chips.
|
||||
//!
|
||||
//! It provides a convenient and efficient way to configure and use
|
||||
//! individual channels of the `PCNT` peripheral of pulse counting and signal
|
||||
//! edge detection on ESP chips.
|
||||
|
||||
use super::unit;
|
||||
use crate::{
|
||||
gpio::{InputPin, InputSignal, ONE_INPUT, ZERO_INPUT},
|
||||
|
@ -1,4 +1,136 @@
|
||||
//! Pulse Counter peripheral driver
|
||||
//! # Pulse Counter peripheral driver
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `PCNT (Pulse Counter)` driver for `ESP` chips is a software component
|
||||
//! that provides an interface for controlling and utilizing the `PCNT`
|
||||
//! peripheral. The `PCNT` peripheral is a hardware module available in `ESP`
|
||||
//! chips, which functions as a pulse counter and encoder. It is capable of
|
||||
//! counting pulses and monitoring changes in signal levels from external
|
||||
//! sources.
|
||||
//!
|
||||
//! The `PCNT` driver is designed to offer convenient and efficient access to
|
||||
//! the functionalities of the `PCNT` peripheral. It consists of two main
|
||||
//! modules:
|
||||
//! * [channel]
|
||||
//! * [unit]
|
||||
//!
|
||||
//! The `channel` module allows users to configure and manage individual
|
||||
//! channels of the `PCNT` peripheral. It provides methods to set various
|
||||
//! parameters for each channel, such as control modes for signal edges, action
|
||||
//! on control level, and configurations for positive and negative edge count
|
||||
//! modes.
|
||||
//!
|
||||
//! The `unit` module is responsible for configuring and handling individual
|
||||
//! units of the `PCNT` peripheral. Each unit represents a separate instance of
|
||||
//! the `PCNT` module, identified by unit numbers like `Unit0`, `Unit1`, and so
|
||||
//! on. Users can interact with these units to configure settings such as low
|
||||
//! and high limits, thresholds, and optional filtering. The unit module also
|
||||
//! enables users to pause, resume, and clear the counter, as well as enable or
|
||||
//! disable interrupts for specific events associated with the unit.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let unit_number = unit::Number::Unit1;
|
||||
//!
|
||||
//! // setup a pulse couter
|
||||
//! println!("setup pulse counter unit 0");
|
||||
//! let pcnt = PCNT::new(peripherals.PCNT, &mut system.peripheral_clock_control);
|
||||
//! let mut u0 = pcnt.get_unit(unit_number);
|
||||
//! u0.configure(unit::Config {
|
||||
//! low_limit: -100,
|
||||
//! high_limit: 100,
|
||||
//! filter: Some(min(10u16 * 80, 1023u16)),
|
||||
//! ..Default::default()
|
||||
//! })
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! println!("setup channel 0");
|
||||
//! let mut ch0 = u0.get_channel(channel::Number::Channel0);
|
||||
//! let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//! let mut pin_a = io.pins.gpio5.into_pull_up_input();
|
||||
//! let mut pin_b = io.pins.gpio6.into_pull_up_input();
|
||||
//!
|
||||
//! ch0.configure(
|
||||
//! PcntSource::from_pin(&mut pin_a),
|
||||
//! PcntSource::from_pin(&mut pin_b),
|
||||
//! channel::Config {
|
||||
//! lctrl_mode: channel::CtrlMode::Reverse,
|
||||
//! hctrl_mode: channel::CtrlMode::Keep,
|
||||
//! pos_edge: channel::EdgeMode::Decrement,
|
||||
//! neg_edge: channel::EdgeMode::Increment,
|
||||
//! invert_ctrl: false,
|
||||
//! invert_sig: false,
|
||||
//! },
|
||||
//! );
|
||||
//!
|
||||
//! println!("setup channel 1");
|
||||
//! let mut ch1 = u0.get_channel(channel::Number::Channel1);
|
||||
//! ch1.configure(
|
||||
//! PcntSource::from_pin(&mut pin_b),
|
||||
//! PcntSource::from_pin(&mut pin_a),
|
||||
//! channel::Config {
|
||||
//! lctrl_mode: channel::CtrlMode::Reverse,
|
||||
//! hctrl_mode: channel::CtrlMode::Keep,
|
||||
//! pos_edge: channel::EdgeMode::Increment,
|
||||
//! neg_edge: channel::EdgeMode::Decrement,
|
||||
//! invert_ctrl: false,
|
||||
//! invert_sig: false,
|
||||
//! },
|
||||
//! );
|
||||
//! println!("subscribing to events");
|
||||
//! u0.events(unit::Events {
|
||||
//! low_limit: true,
|
||||
//! high_limit: true,
|
||||
//! thresh0: false,
|
||||
//! thresh1: false,
|
||||
//! zero: false,
|
||||
//! });
|
||||
//!
|
||||
//! println!("enabling interrupts");
|
||||
//! u0.listen();
|
||||
//! println!("resume pulse counter unit 0");
|
||||
//! u0.resume();
|
||||
//!
|
||||
//! critical_section::with(|cs| UNIT0.borrow_ref_mut(cs).replace(u0));
|
||||
//!
|
||||
//! interrupt::enable(peripherals::Interrupt::PCNT, interrupt::Priority::Priority2).unwrap();
|
||||
//!
|
||||
//! let mut last_value: i32 = 0;
|
||||
//! loop {
|
||||
//! critical_section::with(|cs| {
|
||||
//! let mut u0 = UNIT0.borrow_ref_mut(cs);
|
||||
//! let u0 = u0.as_mut().unwrap();
|
||||
//! let value: i32 = u0.get_value() as i32 + VALUE.load(Ordering::SeqCst);
|
||||
//! if value != last_value {
|
||||
//! println!("value: {value}");
|
||||
//! last_value = value;
|
||||
//! }
|
||||
//! });
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! Where the `PCNT` interrupt handler is defined as:
|
||||
//! ```no_run
|
||||
//! #[interrupt]
|
||||
//! fn PCNT() {
|
||||
//! critical_section::with(|cs| {
|
||||
//! let mut u0 = UNIT0.borrow_ref_mut(cs);
|
||||
//! let u0 = u0.as_mut().unwrap();
|
||||
//! if u0.interrupt_set() {
|
||||
//! let events = u0.get_events();
|
||||
//! if events.high_limit {
|
||||
//! VALUE.fetch_add(100, Ordering::SeqCst);
|
||||
//! } else if events.low_limit {
|
||||
//! VALUE.fetch_add(-100, Ordering::SeqCst);
|
||||
//! }
|
||||
//! u0.reset_interrupt();
|
||||
//! }
|
||||
//! });
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! [channel]: channel/index.html
|
||||
//! [unit]: unit/index.html
|
||||
|
||||
use self::unit::Unit;
|
||||
use crate::{
|
||||
|
@ -1,3 +1,15 @@
|
||||
//! # PCNT - Unit module
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `unit` module is a part of the `PCNT` peripheral driver
|
||||
//! for ESP chips. It offers functionalities for configuring and utilizing
|
||||
//! specific units of the PCNT peripheral.
|
||||
//!
|
||||
//! Each unit is identified by a unit number, such as `Unit0`, `Unit1`, `Unit2`,
|
||||
//! and so on. This module provides methods to configure a unit with specific
|
||||
//! settings, like low and high limits, thresholds, and optional filtering.
|
||||
//! Users can easily configure these units based on their requirements.
|
||||
|
||||
use critical_section::CriticalSection;
|
||||
|
||||
use super::channel;
|
||||
|
@ -1,4 +1,39 @@
|
||||
//! Exclusive peripheral access
|
||||
//! # Exclusive peripheral access
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The Peripheral module provides an exclusive access mechanism to peripherals
|
||||
//! on ESP chips. It includes the `PeripheralRef` struct, which represents an
|
||||
//! exclusive reference to a peripheral. It offers memory efficiency benefits
|
||||
//! for zero-sized types.
|
||||
//!
|
||||
//! The `PeripheralRef` struct is used to access and interact with peripherals.
|
||||
//! It implements the `Deref` and `DerefMut` traits, allowing you to dereference
|
||||
//! it to access the underlying peripheral. It also provides methods for cloning
|
||||
//! and re-borrowing the peripheral.
|
||||
//!
|
||||
//! The module also defines the `Peripheral` trait, which is implemented by
|
||||
//! types that can be used as peripherals. The trait allows conversion between
|
||||
//! owned and borrowed peripherals and provides an unsafe method for cloning the
|
||||
//! peripheral. By implementing this trait, a type can be used with the
|
||||
//! `PeripheralRef` struct.
|
||||
//!
|
||||
//! The module also includes a `peripheral_macros` module, which contains macros
|
||||
//! for generating peripheral structs and associated traits based on
|
||||
//! configuration options.
|
||||
//!
|
||||
//! ## Examples
|
||||
//!
|
||||
//! ### Initialization
|
||||
//! ```no_run
|
||||
//! let peripherals = Peripherals::take();
|
||||
//! ```
|
||||
//! ### Accessing peripherals
|
||||
//! ```no_run
|
||||
//! let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
//! ```
|
||||
//! ```no_run
|
||||
//! let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//! ```
|
||||
|
||||
use core::{
|
||||
marker::PhantomData,
|
||||
|
@ -1,5 +1,18 @@
|
||||
//! Wireless communication peripheral implementations
|
||||
|
||||
//! # Wireless communication peripheral implementations
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The radio module provides implementations for different wireless
|
||||
//! communication peripherals, including WiFi, Bluetooth and
|
||||
//! IEEE 802.15.4 Low Rate wireless personal area radio.
|
||||
//!
|
||||
//! In addition to the structures defined in this module, the module also
|
||||
//! defines the `RadioExt` trait, which provides a `split` method. This method
|
||||
//! allows splitting the general `Radio` peripheral into its individual
|
||||
//! components.
|
||||
//!
|
||||
//! Additionally, the module includes implementation blocks for each wireless
|
||||
//! communication peripheral, providing necessary functions and traits for each
|
||||
//! peripheral.
|
||||
pub trait RadioExt {
|
||||
type Components;
|
||||
|
||||
|
@ -1,4 +1,32 @@
|
||||
//! Hardware and Software Reset
|
||||
//! # Hardware and Software Reset
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The Hardware and Software Reset module provides functions for performing
|
||||
//! hardware and software resets on ESP chips. It also includes functions for
|
||||
//! retrieving the reset reason and the wakeup cause after a reset.
|
||||
//!
|
||||
//! The module defines a set of sleep sources (`SleepSource`) that indicate the
|
||||
//! source of the wakeup event. These sources include:
|
||||
//! - external signals
|
||||
//! - timers
|
||||
//! - touchpads
|
||||
//! - ULP programs
|
||||
//! - GPIOs
|
||||
//! - UART
|
||||
//! - Wi-Fi
|
||||
//! - COCPU interrupts
|
||||
//! - BT (Bluetooth)
|
||||
//!
|
||||
//! The module also includes a set of flags (`WakeupReason`) that represent
|
||||
//! different wakeup sources and enable/disable wakeup triggers for specific
|
||||
//! events such as:
|
||||
//! - GPIO
|
||||
//! - timers
|
||||
//! - UART
|
||||
//! - touch sensors
|
||||
//! - ULP
|
||||
//! - Wi-Fi
|
||||
//! - BT
|
||||
|
||||
use crate::rtc_cntl::SocResetReason;
|
||||
|
||||
@ -70,17 +98,20 @@ bitflags::bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs a software reset on the chip.
|
||||
pub fn software_reset() {
|
||||
unsafe { crate::rtc_cntl::software_reset() }
|
||||
}
|
||||
/// Performs a software reset on the CPU.
|
||||
pub fn software_reset_cpu() {
|
||||
unsafe { crate::rtc_cntl::software_reset_cpu() }
|
||||
}
|
||||
|
||||
/// Retrieves the reason for the last reset as a SocResetReason enum value.
|
||||
/// Returns `None` if the reset reason cannot be determined.
|
||||
pub fn get_reset_reason() -> Option<SocResetReason> {
|
||||
crate::rtc_cntl::get_reset_reason(crate::get_core())
|
||||
}
|
||||
|
||||
/// Retrieves the cause of the last wakeup event as a SleepSource enum value.
|
||||
pub fn get_wakeup_cause() -> SleepSource {
|
||||
crate::rtc_cntl::get_wakeup_cause()
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! # Remote Control Peripheral (RMT)
|
||||
//!
|
||||
//! ## Overview
|
||||
//! Some ESP32 variants include a remote control peripheral (RMT) that
|
||||
//! is designed to handle infrared remote control signals. For that
|
||||
//! purpose, it can convert bitstreams of data (from the RAM) into
|
||||
@ -35,9 +36,9 @@
|
||||
//! For more information, please refer to the ESP-IDF documentation:
|
||||
//! <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/rmt.html>
|
||||
//!
|
||||
//! # Examples
|
||||
//! ## Examples
|
||||
//!
|
||||
//! ## Initialization
|
||||
//! ### Initialization
|
||||
//!
|
||||
//! ```no_run
|
||||
//! let rmt = Rmt::new(peripherals.RMT, 80u32.MHz(), &mut clock_control, &clocks).unwrap();
|
||||
@ -60,7 +61,7 @@
|
||||
//! (on ESP32 and ESP32-S2 you cannot specify a base frequency other than 80
|
||||
//! MHz)
|
||||
//!
|
||||
//! ## Sending a pulse sequence
|
||||
//! ### Sending a pulse sequence
|
||||
//!
|
||||
//! ```no_run
|
||||
//! let data = [
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! Random Number Generator
|
||||
//! # Random Number Generator
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The Random Number Generator (RNG) Driver for ESP chips is a software module
|
||||
//! that provides an interface to generate random numbers using the RNG
|
||||
//! peripheral on ESP chips. This driver allows you to generate random numbers
|
||||
|
@ -1,10 +1,11 @@
|
||||
//! Cyclic Redundancy Check
|
||||
//! # Cyclic Redundancy Check
|
||||
//!
|
||||
//! ## Overview
|
||||
//! These are safe abstractions to the CRC functions in the ESP32 ROM.
|
||||
//! Some chips may not include all of these functions so they will be compiled
|
||||
//! into the program binary in those cases.
|
||||
//!
|
||||
//! # Parameters
|
||||
//! ## Parameters
|
||||
//!
|
||||
//! The ROM provides the following polynomials for each CRC width:
|
||||
//!
|
||||
@ -31,7 +32,7 @@
|
||||
//! crc = !crc32_be(crc, &data2); // finish
|
||||
//! ```
|
||||
//!
|
||||
//! # Examples
|
||||
//! ## Examples
|
||||
//!
|
||||
//! A catalogue of these parameters can be found at
|
||||
//! <https://reveng.sourceforge.io/crc-catalogue/all.htm>
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! MD5 Message-Digest Algorithm
|
||||
//! # MD5 Message-Digest Algorithm
|
||||
//!
|
||||
//! # Security Warning
|
||||
//! ## ⚠️ Security Warning ⚠️
|
||||
//!
|
||||
//! MD5 is a **cryptographically broken** message digest. It should **not**
|
||||
//! be used for data security, for example, to check if data has been
|
||||
@ -12,7 +12,7 @@
|
||||
//! flash. This is especially important on microcontrollers where the
|
||||
//! computational efficiency of MD5 is desired.
|
||||
//!
|
||||
//! # Compatibility
|
||||
//! ## Compatibility
|
||||
//!
|
||||
//! The public API exposed by this module tries to *mimic* the public API
|
||||
//! offered by the [MD5][1] crate in an effort to act as a drop-in replacement.
|
||||
@ -24,7 +24,7 @@
|
||||
//! all of them. Usage of this module may help make program binaries smaller
|
||||
//! than it would be if you included an MD5 implementation in your project.
|
||||
//!
|
||||
//! # Example
|
||||
//! ## Example
|
||||
//!
|
||||
//! To compute a full digest from a single buffer, use the following:
|
||||
//!
|
||||
|
@ -1,7 +1,27 @@
|
||||
//! ESP ROM libraries
|
||||
//! # ESP ROM libraries
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `rom` driver provides functionality related to the ROM (Read-Only
|
||||
//! Memory) on ESP chips. It includes implementations for the [CRC (Cyclic
|
||||
//! Redundancy Check)] and [MD5 (Message Digest 5)] algorithms.
|
||||
//!
|
||||
//! The driver's functionality allows users to perform CRC calculations and MD5
|
||||
//! hashing using the ROM functions provided by the ESP chip. This can be useful
|
||||
//! for various applications that require data integrity checks or cryptographic
|
||||
//! operations.
|
||||
//!
|
||||
//! It uses `CRC` error-checking techniques to detect changes in data during
|
||||
//! transmission or storage.
|
||||
//!
|
||||
//! This module also implements the `MD5` algorithm, which is widely used for
|
||||
//! cryptographic hash function. It's commonly used to verify data integrity and
|
||||
//! to check whether the data has been modified.
|
||||
//!
|
||||
//! Safe abstractions to the additional libraries provided in the ESP's
|
||||
//! read-only memory.
|
||||
//! Read-Only Memory.
|
||||
//!
|
||||
//! [CRC (Cyclic Redundancy Check)]: ./crc/index.html
|
||||
//! [MD5 (Message Digest 5)]: ./md5/index.html
|
||||
|
||||
pub mod crc;
|
||||
pub mod md5;
|
||||
|
@ -1,7 +1,39 @@
|
||||
//! RSA Accelerator support.
|
||||
//! # RSA Accelerator support.
|
||||
//!
|
||||
//! This module provides functions and structs for multi precision arithmetic
|
||||
//! operations used in RSA asym-metric cipher algorithms
|
||||
//! ## Overview
|
||||
//! The `RSA` driver provides a set of functions to accelerate `RSA
|
||||
//! (Rivest–Shamir–Adleman)` cryptographic operations on ESP chips. `RSA` is a
|
||||
//! widely used `public-key` cryptographic algorithm that involves complex
|
||||
//! mathematical computations, and the `RSA` accelerator on `ESP` chips is
|
||||
//! designed to optimize these computations for faster performance.
|
||||
//!
|
||||
//! Implementation details;
|
||||
//! * The driver uses low-level peripheral access to read and write data
|
||||
//! from/to the `RSA` peripheral.
|
||||
//! * The driver contains `unsafe` code blocks as it directly manipulates
|
||||
//! memory addresses for data transfer.
|
||||
//! * The driver supports different sizes of operands based on the generic
|
||||
//! types provided during instantiation.
|
||||
//! * The [nb] crate is used to handle non-blocking operations.
|
||||
//! * The driver provides a set of high-level abstractions to simplify `RSA`
|
||||
//! cryptographic operations on `ESP` chips, allowing developers to
|
||||
//! leverage the `RSA accelerator` for improved performance.
|
||||
//!
|
||||
//! ## Examples
|
||||
//! ### Initialization
|
||||
//! ```no_run
|
||||
//! let peripherals = Peripherals::take();
|
||||
//! let mut system = peripherals.PCR.split();
|
||||
//!
|
||||
//! let mut rsa = Rsa::new(peripherals.RSA, &mut system.peripheral_clock_control);
|
||||
//! ```
|
||||
//!
|
||||
//! ⚠️: The examples for RSA peripheral are quite extensive, so for a more
|
||||
//! detailed study of how to use this driver please visit [the repository
|
||||
//! with corresponding example].
|
||||
//!
|
||||
//! [nb]: https://docs.rs/nb/1.1.0/nb/
|
||||
//! [the repository with corresponding example]: https://github.com/esp-rs/esp-hal/blob/main/esp32-hal/examples/rsa.rs
|
||||
|
||||
use core::{convert::Infallible, marker::PhantomData, ptr::copy_nonoverlapping};
|
||||
|
||||
|
@ -1,4 +1,73 @@
|
||||
//! Low-power Management
|
||||
//! # RTC_CNTL (Real-Time Clock Control) and Low-power Management
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `rtc_cntl` module provides a driver for the `RTC_CNTL` peripheral on ESP
|
||||
//! chips.
|
||||
//!
|
||||
//! The `Real-Time Clock Control (RTC_CNTL)` peripheral is responsible for
|
||||
//! managing the real-time clock and low-power modes on the chip.
|
||||
//!
|
||||
//! The `rtc_cntl` driver module contains functions and data structures to
|
||||
//! interact with the `RTC_CNTL` peripheral on ESP chips. It also includes the
|
||||
//! necessary configurations and constants for clock sources and low-power
|
||||
//! management. The driver provides the following features and functionalities:
|
||||
//! * Clock Configuration
|
||||
//! * Calibration
|
||||
//! * Low-Power Management
|
||||
//! * Real-Time Clock
|
||||
//! * Handling Watchdog Timers
|
||||
//!
|
||||
//! ## Examples
|
||||
//! ### Print time in milliseconds from the RTC Timer
|
||||
//! ```no_run
|
||||
//! let mut delay = Delay::new(&clocks);
|
||||
//!
|
||||
//! loop {
|
||||
//! esp_println::println!("rtc time in milliseconds is {}", rtc.get_time_ms());
|
||||
//! delay.delay_ms(1000u32);
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ### RTC Watchdog Timer
|
||||
//! ```no_run
|
||||
//! rtc.rwdt.start(2000u64.millis());
|
||||
//! rtc.rwdt.listen();
|
||||
//!
|
||||
//! interrupt::enable(
|
||||
//! peripherals::Interrupt::LP_WDT,
|
||||
//! interrupt::Priority::Priority1,
|
||||
//! )
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! critical_section::with(|cs| RWDT.borrow_ref_mut(cs).replace(rtc.rwdt));
|
||||
//!
|
||||
//! unsafe {
|
||||
//! riscv::interrupt::enable();
|
||||
//! }
|
||||
//!
|
||||
//! loop {}
|
||||
//! ```
|
||||
//!
|
||||
//! Where the `LP_WDT` interrupt handler is defined as:
|
||||
//! ```no_run
|
||||
//! // Handle the corresponding interrupt
|
||||
//! #[interrupt]
|
||||
//! fn LP_WDT() {
|
||||
//! critical_section::with(|cs| {
|
||||
//! esp_println::println!("RWDT Interrupt");
|
||||
//!
|
||||
//! let mut rwdt = RWDT.borrow_ref_mut(cs);
|
||||
//! let rwdt = rwdt.as_mut().unwrap();
|
||||
//!
|
||||
//! rwdt.clear_interrupt();
|
||||
//!
|
||||
//! esp_println::println!("Restarting in 5 seconds...");
|
||||
//!
|
||||
//! rwdt.start(5000u64.millis());
|
||||
//! rwdt.unlisten();
|
||||
//! });
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use embedded_hal::watchdog::{Watchdog, WatchdogDisable, WatchdogEnable};
|
||||
#[cfg(not(any(esp32c6, esp32h2)))]
|
||||
|
@ -1,3 +1,24 @@
|
||||
//! # RTC Control Sleep Module
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `sleep` module in the `RTC CNTL (Real-Time Clock Control)` driver
|
||||
//! provides functionality to manage sleep and wakeup sources for `ESP` chips.
|
||||
//! The `RTC_CNTL` is responsible for controlling the power and sleep behavior
|
||||
//! of the chip.
|
||||
//!
|
||||
//! The `sleep` module allows configuring various wakeup sources and setting up
|
||||
//! the sleep behavior based on those sources. The supported wakeup sources
|
||||
//! include:
|
||||
//! * `GPIO` pins - light sleep only
|
||||
//! * timers
|
||||
//! * `SDIO (Secure Digital Input/Output) - light sleep only`
|
||||
//! * `MAC (Media Access Control)` wake - light sleep only
|
||||
//! * `UART0` - light sleep only
|
||||
//! * `UART1` - light sleep only
|
||||
//! * `touch`
|
||||
//! * `ULP (Ultra-Low Power)` wake
|
||||
//! * `BT (Bluetooth) wake` - light sleep only
|
||||
|
||||
use core::{cell::RefCell, time::Duration};
|
||||
|
||||
use crate::{
|
||||
|
@ -1,4 +1,64 @@
|
||||
//! Secure Hash Algorithm peripheral driver
|
||||
//! # Secure Hash Algorithm peripheral driver
|
||||
//!
|
||||
//! ## Overview
|
||||
//! This SHA (Secure Hash Algorithm) driver for ESP chips is a software module
|
||||
//! that provides an interface to interact with the SHA peripheral on ESP
|
||||
//! microcontroller chips. This driver allows you to perform cryptographic hash
|
||||
//! operations using various hash algorithms supported by the SHA peripheral,
|
||||
//! such as:
|
||||
//! * SHA-1
|
||||
//! * SHA-224
|
||||
//! * SHA-256
|
||||
//! * SHA-384
|
||||
//! * SHA-512
|
||||
//!
|
||||
//! The driver supports two working modes:
|
||||
//! * Typical SHA
|
||||
//! * DMA-SHA (Direct Memory Access SHA is NOT implemented yet).
|
||||
//!
|
||||
//! It provides functions to update the hash calculation with input data, finish
|
||||
//! the hash calculation and retrieve the resulting hash value. The SHA
|
||||
//! peripheral on ESP chips can handle large data streams efficiently, making it
|
||||
//! suitable for cryptographic applications that require secure hashing.
|
||||
//!
|
||||
//! To use the SHA Peripheral Driver, you need to initialize it with the desired
|
||||
//! SHA mode and the corresponding SHA peripheral. Once initialized, you can
|
||||
//! update the hash calculation by providing input data, finish the calculation
|
||||
//! to retrieve the hash value and repeat the process for a new hash calculation
|
||||
//! if needed.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let source_data = "HELLO, ESPRESSIF!".as_bytes();
|
||||
//! let mut remaining = source_data.clone();
|
||||
//! let mut hasher = Sha::new(
|
||||
//! peripherals.SHA,
|
||||
//! ShaMode::SHA256,
|
||||
//! &mut system.peripheral_clock_control,
|
||||
//! );
|
||||
//!
|
||||
//! // Short hashes can be created by decreasing the output buffer to the desired
|
||||
//! // length
|
||||
//! let mut output = [0u8; 32];
|
||||
//!
|
||||
//! while remaining.len() > 0 {
|
||||
//! // All the HW Sha functions are infallible so unwrap is fine to use if you use
|
||||
//! // block!
|
||||
//! remaining = block!(hasher.update(remaining)).unwrap();
|
||||
//! }
|
||||
//!
|
||||
//! // Finish can be called as many times as desired to get multiple copies of the
|
||||
//! // output.
|
||||
//! block!(hasher.finish(output.as_mut_slice())).unwrap();
|
||||
//!
|
||||
//! println!("SHA256 Hash output {:02x?}", output);
|
||||
//!
|
||||
//! let mut hasher = Sha256::new();
|
||||
//! hasher.update(source_data);
|
||||
//! let soft_result = hasher.finalize();
|
||||
//!
|
||||
//! println!("SHA256 Hash output {:02x?}", soft_result);
|
||||
//! ```
|
||||
|
||||
use core::convert::Infallible;
|
||||
|
||||
|
@ -1,4 +1,53 @@
|
||||
//! Control CPU Cores
|
||||
//! # Control CPU Cores (ESP32)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! This module provides essential functionality for controlling
|
||||
//! and managing the CPU cores on the `ESP32` chip, allowing for fine-grained
|
||||
//! control over their execution and cache behavior. It is used in scenarios
|
||||
//! where precise control over CPU core operation is required, such as
|
||||
//! multi-threading or power management.
|
||||
//!
|
||||
//! The `CpuControl` struct represents the CPU control module and is responsible
|
||||
//! for managing the behavior and operation of the CPU cores. It is typically
|
||||
//! initialized with the `SystemCpuControl` struct, which is provided by the
|
||||
//! `system` module.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let counter = Mutex::new(RefCell::new(0));
|
||||
//!
|
||||
//! let mut cpu_control = CpuControl::new(system.cpu_control);
|
||||
//! let mut cpu1_fnctn = || {
|
||||
//! cpu1_task(&mut timer1, &counter);
|
||||
//! };
|
||||
//! let _guard = cpu_control.start_app_core(&mut cpu1_fnctn).unwrap();
|
||||
//!
|
||||
//! loop {
|
||||
//! block!(timer0.wait()).unwrap();
|
||||
//!
|
||||
//! let count = critical_section::with(|cs| *counter.borrow_ref(cs));
|
||||
//! println!("Hello World - Core 0! Counter is {}", count);
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! Where `cpu1_task()` may be defined as:
|
||||
//! ```no_run
|
||||
//! fn cpu1_task(
|
||||
//! timer: &mut Timer<Timer0<TIMG1>>,
|
||||
//! counter: &critical_section::Mutex<RefCell<i32>>,
|
||||
//! ) -> ! {
|
||||
//! println!("Hello World - Core 1!");
|
||||
//! loop {
|
||||
//! block!(timer.wait()).unwrap();
|
||||
//!
|
||||
//! critical_section::with(|cs| {
|
||||
//! let new_val = counter.borrow_ref_mut(cs).wrapping_add(1);
|
||||
//! *counter.borrow_ref_mut(cs) = new_val;
|
||||
//! });
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
|
@ -1,4 +1,37 @@
|
||||
//! Reading of eFuses
|
||||
//! # Reading of eFuses (ESP32)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `efuse` module provides functionality for reading eFuse data
|
||||
//! from the `ESP32` chip, allowing access to various chip-specific information
|
||||
//! such as :
|
||||
//! * MAC address
|
||||
//! * core count
|
||||
//! * CPU frequency
|
||||
//! * chip type
|
||||
//!
|
||||
//! and more. It is useful for retrieving chip-specific configuration and
|
||||
//! identification data during runtime.
|
||||
//!
|
||||
//! The `Efuse` struct represents the eFuse peripheral and is responsible for
|
||||
//! reading various eFuse fields and values.
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### Read chip's MAC address from the eFuse storage.
|
||||
//! ```no_run
|
||||
//! let mac_address = Efuse::get_mac_address();
|
||||
//! writeln!(
|
||||
//! serial_tx,
|
||||
//! "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
|
||||
//! mac_address[0],
|
||||
//! mac_address[1],
|
||||
//! mac_address[2],
|
||||
//! mac_address[3],
|
||||
//! mac_address[4],
|
||||
//! mac_address[5]
|
||||
//! );
|
||||
//! ```
|
||||
|
||||
use fugit::{HertzU32, RateExtU32};
|
||||
|
||||
@ -18,23 +51,6 @@ pub enum ChipType {
|
||||
}
|
||||
|
||||
impl Efuse {
|
||||
/// Reads chip's MAC address from the eFuse storage.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let mac_address = Efuse::get_mac_address();
|
||||
/// writeln!(
|
||||
/// serial_tx,
|
||||
/// "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
|
||||
/// mac_address[0],
|
||||
/// mac_address[1],
|
||||
/// mac_address[2],
|
||||
/// mac_address[3],
|
||||
/// mac_address[4],
|
||||
/// mac_address[5]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn get_mac_address() -> [u8; 6] {
|
||||
Self::read_field_be(MAC_FACTORY)
|
||||
}
|
||||
|
@ -1,3 +1,50 @@
|
||||
//! # GPIO configuration module (ESP32)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `GPIO` module provides functions and configurations for controlling the
|
||||
//! `General Purpose Input/Output` pins on the `ESP32` chip. It allows you to
|
||||
//! configure pins as inputs or outputs, set their state and read their state.
|
||||
//!
|
||||
//! Let's get through the functionality and configurations provided by this GPIO
|
||||
//! module:
|
||||
//! - `get_io_mux_reg(gpio_num: u8) -> &'static
|
||||
//! crate::peripherals::io_mux::GPIO0:`:
|
||||
//! * This function returns a reference to the GPIO register associated
|
||||
//! with the given GPIO number. It uses unsafe code and transmutation to
|
||||
//! access the GPIO registers based on the provided GPIO number.
|
||||
//! - `gpio_intr_enable(int_enable: bool, nmi_enable: bool) -> u8`:
|
||||
//! * This function enables or disables GPIO interrupts and Non-Maskable
|
||||
//! Interrupts (NMI). It takes two boolean arguments int_enable and
|
||||
//! nmi_enable to control the interrupt and NMI enable settings. The
|
||||
//! function returns an u8 value representing the interrupt enable
|
||||
//! settings.
|
||||
//! - `errata36(pin_num: u8, pull_up: bool, pull_down: bool)`:
|
||||
//! * Handles the configuration of pull-up and pull-down resistors for
|
||||
//! specific GPIO pins
|
||||
//! - `gpio` block:
|
||||
//! * Defines the pin configurations for various GPIO pins. Each line
|
||||
//! represents a pin and its associated options such as input/output
|
||||
//! mode, analog capability, and corresponding functions.
|
||||
//! - `analog` block:
|
||||
//! * Block defines the analog capabilities of various GPIO pins. Each
|
||||
//! line represents a pin and its associated options such as mux
|
||||
//! selection, function selection, and input enable.
|
||||
//! - `enum InputSignal`:
|
||||
//! * This enumeration defines input signals for the GPIO mux. Each input
|
||||
//! signal is assigned a specific value.
|
||||
//! - `enum OutputSignal`:
|
||||
//! * This enumeration defines output signals for the GPIO mux. Each
|
||||
//! output signal is assigned a specific value.
|
||||
//!
|
||||
//! This module also implements the `InterruptStatusRegisterAccess` trait for
|
||||
//! two different banks:
|
||||
//! * `InterruptStatusRegisterAccessBank0`
|
||||
//! * `InterruptStatusRegisterAccessBank1`.
|
||||
//! This trait provides functions to read the interrupt status and NMI status
|
||||
//! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the
|
||||
//! `gpio` peripheral to access the appropriate registers.
|
||||
|
||||
use crate::{
|
||||
gpio::{
|
||||
AlternateFunction,
|
||||
|
@ -1,3 +1,10 @@
|
||||
//! # SOC (System-on-Chip) module (ESP32)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `SOC` module provides access, functions and structures that are useful
|
||||
//! for interacting with various system-related peripherals on `ESP32` chip.
|
||||
|
||||
pub mod cpu_control;
|
||||
pub mod efuse;
|
||||
pub mod gpio;
|
||||
|
@ -1,4 +1,25 @@
|
||||
//! Peripheral instance singletons
|
||||
//! # Peripheral instance singletons (ESP32)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `Peripherals` module provides singleton instances of various peripherals
|
||||
//! and allows users to access and use them in their applications.
|
||||
//!
|
||||
//! These peripherals provide various functionalities and interfaces for
|
||||
//! interacting with different hardware components on the `ESP32` chip, such as
|
||||
//! timers, `GPIO` pins, `I2C`, `SPI`, `UART`, and more. Users can access and
|
||||
//! utilize these peripherals by importing the respective singleton instances
|
||||
//! from this module.
|
||||
//!
|
||||
//! It's important to note that the module also exports the `Interrupt` enum
|
||||
//! from the `ESP32` `PAC (Peripheral Access Crate)` for users to handle
|
||||
//! interrupts associated with these peripherals.
|
||||
//!
|
||||
//! ⚠️ NOTE: notice that `psram` and `radio` are marked with `false` in the
|
||||
//! `peripherals!` macro. Basically, that means that there's no real peripheral
|
||||
//! (no `PSRAM` nor `RADIO` peripheral in the PACs) but we're creating "virtual
|
||||
//! peripherals" for them in order to ensure the uniqueness of the instances
|
||||
//! (Singletons).
|
||||
|
||||
use esp32 as pac;
|
||||
// We need to export this for users to use
|
||||
|
@ -1,3 +1,24 @@
|
||||
//! # PSRAM "virtual peripheral" driver (ESP32)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `PSRAM` module provides support for accessing and controlling
|
||||
//! the `Pseudo Static Random Access Memory (PSRAM)` on the `ESP32`.
|
||||
//!
|
||||
//! The `PSRAM` module enables users to interface with the `PSRAM` memory
|
||||
//! present on the `ESP32` chip. `PSRAM` provides additional external memory to
|
||||
//! supplement the internal memory of the `ESP32`, allowing for increased
|
||||
//! storage capacity and improved performance in certain applications.
|
||||
//!
|
||||
//! The `PSRAM` module is accessed through a virtual address, defined as
|
||||
//! `PSRAM_VADDR`. The starting virtual address for the PSRAM module is
|
||||
//! 0x3F800000. The `PSRAM` module size depends on the configuration specified
|
||||
//! during the compilation process. The available `PSRAM` sizes are `2MB`,
|
||||
//! `4MB`, and `8MB`.
|
||||
//!
|
||||
//! NOTE: If you want to use `PSRAM` on `ESP32` or `ESP32-S3`, it'll work only
|
||||
//! in `release` mode.
|
||||
|
||||
const PSRAM_VADDR: u32 = 0x3F800000;
|
||||
|
||||
pub fn psram_vaddr_start() -> usize {
|
||||
|
@ -1,3 +1,16 @@
|
||||
//! # Radio clocks driver (ESP32)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `Radio Clocks` module provides control and configuration functions for
|
||||
//! various radio peripherals, such as `PHY`, `Bluetooth (BT)`, and `Wi-Fi`. The
|
||||
//! module allows enabling and disabling these peripherals, resetting the `Media
|
||||
//! Access Control (MAC)` and initializing clocks.
|
||||
//!
|
||||
//! The module defines a `RadioClockController` trait implemented by the
|
||||
//! `RadioClockControl` struct. This trait provides methods to enable, disable,
|
||||
//! reset the MAC, initialize clocks and perform other related operations.
|
||||
|
||||
use crate::system::{RadioClockControl, RadioClockController, RadioPeripherals};
|
||||
|
||||
const DPORT_WIFI_CLK_WIFI_BT_COMMON_M: u32 = 0x000003c9;
|
||||
|
@ -1,4 +1,37 @@
|
||||
//! Reading of eFuses
|
||||
//! # Reading of eFuses (ESP32-C2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `efuse` module provides functionality for reading eFuse data
|
||||
//! from the `ESP32-C2` chip, allowing access to various chip-specific
|
||||
//! information such as :
|
||||
//! * MAC address
|
||||
//! * core count
|
||||
//! * CPU frequency
|
||||
//! * chip type
|
||||
//!
|
||||
//! and more. It is useful for retrieving chip-specific configuration and
|
||||
//! identification data during runtime.
|
||||
//!
|
||||
//! The `Efuse` struct represents the eFuse peripheral and is responsible for
|
||||
//! reading various eFuse fields and values.
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### Read chip's MAC address from the eFuse storage.
|
||||
//! ```no_run
|
||||
//! let mac_address = Efuse::get_mac_address();
|
||||
//! writeln!(
|
||||
//! serial_tx,
|
||||
//! "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
|
||||
//! mac_address[0],
|
||||
//! mac_address[1],
|
||||
//! mac_address[2],
|
||||
//! mac_address[3],
|
||||
//! mac_address[4],
|
||||
//! mac_address[5]
|
||||
//! );
|
||||
//! ```
|
||||
|
||||
pub use crate::soc::efuse_field::*;
|
||||
use crate::{adc::Attenuation, peripherals::EFUSE};
|
||||
@ -7,22 +40,6 @@ pub struct Efuse;
|
||||
|
||||
impl Efuse {
|
||||
/// Reads chip's MAC address from the eFuse storage.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let mac_address = Efuse::get_mac_address();
|
||||
/// writeln!(
|
||||
/// serial_tx,
|
||||
/// "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
|
||||
/// mac_address[0],
|
||||
/// mac_address[1],
|
||||
/// mac_address[2],
|
||||
/// mac_address[3],
|
||||
/// mac_address[4],
|
||||
/// mac_address[5]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn get_mac_address() -> [u8; 6] {
|
||||
Self::read_field_be(MAC_FACTORY)
|
||||
}
|
||||
|
@ -1,3 +1,44 @@
|
||||
//! # GPIO configuration module (ESP32-C2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `GPIO` module provides functions and configurations for controlling the
|
||||
//! `General Purpose Input/Output` pins on the `ESP32-C2` chip. It allows you to
|
||||
//! configure pins as inputs or outputs, set their state and read their state.
|
||||
//!
|
||||
//! Let's get through the functionality and configurations provided by this GPIO
|
||||
//! module:
|
||||
//! - `get_io_mux_reg(gpio_num: u8) -> &'static
|
||||
//! crate::peripherals::io_mux::GPIO`:
|
||||
//! * Returns the IO_MUX register for the specified GPIO pin number.
|
||||
//! - `gpio_intr_enable(int_enable: bool, nmi_enable: bool) -> u8`:
|
||||
//! * This function enables or disables GPIO interrupts and Non-Maskable
|
||||
//! Interrupts (NMI). It takes two boolean arguments int_enable and
|
||||
//! nmi_enable to control the interrupt and NMI enable settings. The
|
||||
//! function returns an u8 value representing the interrupt enable
|
||||
//! settings.
|
||||
//! - `gpio` block:
|
||||
//! * Defines the pin configurations for various GPIO pins. Each line
|
||||
//! represents a pin and its associated options such as input/output
|
||||
//! mode, analog capability, and corresponding functions.
|
||||
//! - `analog` block:
|
||||
//! * Block defines the analog capabilities of various GPIO pins. Each
|
||||
//! line represents a pin and its associated options such as mux
|
||||
//! selection, function selection, and input enable.
|
||||
//! - `enum InputSignal`:
|
||||
//! * This enumeration defines input signals for the GPIO mux. Each input
|
||||
//! signal is assigned a specific value.
|
||||
//! - `enum OutputSignal`:
|
||||
//! * This enumeration defines output signals for the GPIO mux. Each
|
||||
//! output signal is assigned a specific value.
|
||||
//!
|
||||
//! This module also implements the `InterruptStatusRegisterAccess` trait for
|
||||
//! two different banks:
|
||||
//! * `InterruptStatusRegisterAccessBank0`
|
||||
//! * `InterruptStatusRegisterAccessBank1`.
|
||||
//! This trait provides functions to read the interrupt status and NMI status
|
||||
//! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the
|
||||
//! `gpio` peripheral to access the appropriate registers.
|
||||
use crate::{
|
||||
gpio::{
|
||||
AlternateFunction,
|
||||
|
@ -1,3 +1,10 @@
|
||||
//! # SOC (System-on-Chip) module (ESP32-C2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `SOC` module provides access, functions and structures that are useful
|
||||
//! for interacting with various system-related peripherals on `ESP32-C2` chip.
|
||||
|
||||
pub mod efuse;
|
||||
pub mod gpio;
|
||||
pub mod peripherals;
|
||||
|
@ -1,4 +1,24 @@
|
||||
//! Peripheral instance singletons
|
||||
//! # Peripheral instance singletons (ESP32-C2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `Peripherals` module provides singleton instances of various peripherals
|
||||
//! and allows users to access and use them in their applications.
|
||||
//!
|
||||
//! These peripherals provide various functionalities and interfaces for
|
||||
//! interacting with different hardware components on the `ESP32-C2` chip, such
|
||||
//! as timers, `GPIO` pins, `I2C`, `SPI`, `UART`, and more. Users can access and
|
||||
//! utilize these peripherals by importing the respective singleton instances
|
||||
//! from this module.
|
||||
//!
|
||||
//! It's important to note that the module also exports the `Interrupt` enum
|
||||
//! from the `ESP32-C2` `PAC (Peripheral Access Crate)` for users to handle
|
||||
//! interrupts associated with these peripherals.
|
||||
//!
|
||||
//! ⚠️ NOTE: notice that `radio` is marked with `false` in the `peripherals!`
|
||||
//! macro. Basically, that means that there's no real peripheral (no `RADIO`
|
||||
//! peripheral in the PACs) but we're creating "virtual peripherals" for it in
|
||||
//! order to ensure the uniqueness of the instance (Singleton).
|
||||
|
||||
use esp32c2 as pac;
|
||||
// We need to export this for users to use
|
||||
|
@ -1,3 +1,16 @@
|
||||
//! # Radio clocks driver (ESP32-C2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `Radio Clocks` module provides control and configuration functions for
|
||||
//! various radio peripherals, such as `PHY`, `Bluetooth (BT)`, and `Wi-Fi`. The
|
||||
//! module allows enabling and disabling these peripherals, resetting the `Media
|
||||
//! Access Control (MAC)` and initializing clocks.
|
||||
//!
|
||||
//! The module defines a `RadioClockController` trait implemented by the
|
||||
//! `RadioClockControl` struct. This trait provides methods to enable, disable,
|
||||
//! reset the MAC, initialize clocks and perform other related operations.
|
||||
|
||||
use crate::system::{RadioClockControl, RadioClockController, RadioPeripherals};
|
||||
|
||||
// Mask for clock bits used by both WIFI and Bluetooth, 0, 1, 2, 3, 7, 8, 9, 10,
|
||||
|
@ -1,4 +1,37 @@
|
||||
//! Reading of eFuses
|
||||
//! # Reading of eFuses (ESP32-C3)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `efuse` module provides functionality for reading eFuse data
|
||||
//! from the `ESP32-C3` chip, allowing access to various chip-specific
|
||||
//! information such as :
|
||||
//! * MAC address
|
||||
//! * core count
|
||||
//! * CPU frequency
|
||||
//! * chip type
|
||||
//!
|
||||
//! and more. It is useful for retrieving chip-specific configuration and
|
||||
//! identification data during runtime.
|
||||
//!
|
||||
//! The `Efuse` struct represents the eFuse peripheral and is responsible for
|
||||
//! reading various eFuse fields and values.
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### Read chip's MAC address from the eFuse storage.
|
||||
//! ```no_run
|
||||
//! let mac_address = Efuse::get_mac_address();
|
||||
//! writeln!(
|
||||
//! serial_tx,
|
||||
//! "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
|
||||
//! mac_address[0],
|
||||
//! mac_address[1],
|
||||
//! mac_address[2],
|
||||
//! mac_address[3],
|
||||
//! mac_address[4],
|
||||
//! mac_address[5]
|
||||
//! );
|
||||
//! ```
|
||||
|
||||
pub use crate::soc::efuse_field::*;
|
||||
use crate::{adc::Attenuation, peripherals::EFUSE};
|
||||
@ -7,22 +40,6 @@ pub struct Efuse;
|
||||
|
||||
impl Efuse {
|
||||
/// Reads chip's MAC address from the eFuse storage.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let mac_address = Efuse::get_mac_address();
|
||||
/// writeln!(
|
||||
/// serial_tx,
|
||||
/// "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
|
||||
/// mac_address[0],
|
||||
/// mac_address[1],
|
||||
/// mac_address[2],
|
||||
/// mac_address[3],
|
||||
/// mac_address[4],
|
||||
/// mac_address[5]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn get_mac_address() -> [u8; 6] {
|
||||
Self::read_field_be(MAC_FACTORY)
|
||||
}
|
||||
|
@ -1,3 +1,45 @@
|
||||
//! # GPIO configuration module (ESP32-C3)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `GPIO` module provides functions and configurations for controlling the
|
||||
//! `General Purpose Input/Output` pins on the `ESP32-C3` chip. It allows you to
|
||||
//! configure pins as inputs or outputs, set their state and read their state.
|
||||
//!
|
||||
//! Let's get through the functionality and configurations provided by this GPIO
|
||||
//! module:
|
||||
//! - `get_io_mux_reg(gpio_num: u8) -> &'static
|
||||
//! crate::peripherals::io_mux::GPIO0:`:
|
||||
//! * Returns the IO_MUX register for the specified GPIO pin number.
|
||||
//! - `gpio_intr_enable(int_enable: bool, nmi_enable: bool) -> u8`:
|
||||
//! * This function enables or disables GPIO interrupts and Non-Maskable
|
||||
//! Interrupts (NMI). It takes two boolean arguments int_enable and
|
||||
//! nmi_enable to control the interrupt and NMI enable settings. The
|
||||
//! function returns an u8 value representing the interrupt enable
|
||||
//! settings.
|
||||
//! - `gpio` block:
|
||||
//! * Defines the pin configurations for various GPIO pins. Each line
|
||||
//! represents a pin and its associated options such as input/output
|
||||
//! mode, analog capability, and corresponding functions.
|
||||
//! - `analog` block:
|
||||
//! * Block defines the analog capabilities of various GPIO pins. Each
|
||||
//! line represents a pin and its associated options such as mux
|
||||
//! selection, function selection, and input enable.
|
||||
//! - `enum InputSignal`:
|
||||
//! * This enumeration defines input signals for the GPIO mux. Each input
|
||||
//! signal is assigned a specific value.
|
||||
//! - `enum OutputSignal`:
|
||||
//! * This enumeration defines output signals for the GPIO mux. Each
|
||||
//! output signal is assigned a specific value.
|
||||
//!
|
||||
//! This module also implements the `InterruptStatusRegisterAccess` trait for
|
||||
//! two different banks:
|
||||
//! * `InterruptStatusRegisterAccessBank0`
|
||||
//! * `InterruptStatusRegisterAccessBank1`.
|
||||
//! This trait provides functions to read the interrupt status and NMI status
|
||||
//! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the
|
||||
//! `gpio` peripheral to access the appropriate registers.
|
||||
|
||||
use crate::{
|
||||
gpio::{
|
||||
AlternateFunction,
|
||||
|
@ -1,3 +1,14 @@
|
||||
//! # SOC (System-on-Chip) module (ESP32-C3)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `SOC` module provides access, functions and structures that are useful
|
||||
//! for interacting with various system-related peripherals on `ESP32-C3` chip.
|
||||
//!
|
||||
//! Also few constants are defined in this module for `ESP32-C3` chip:
|
||||
//! * I2S_SCLK: 160_000_000 - I2S clock frequency
|
||||
//! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source
|
||||
|
||||
pub mod efuse;
|
||||
pub mod gpio;
|
||||
pub mod peripherals;
|
||||
|
@ -1,4 +1,24 @@
|
||||
//! Peripheral instance singletons
|
||||
//! # Peripheral instance singletons (ESP32-C3)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `Peripherals` module provides singleton instances of various peripherals
|
||||
//! and allows users to access and use them in their applications.
|
||||
//!
|
||||
//! These peripherals provide various functionalities and interfaces for
|
||||
//! interacting with different hardware components on the `ESP32-C3` chip, such
|
||||
//! as timers, `GPIO` pins, `I2C`, `SPI`, `UART`, and more. Users can access and
|
||||
//! utilize these peripherals by importing the respective singleton instances
|
||||
//! from this module.
|
||||
//!
|
||||
//! It's important to note that the module also exports the `Interrupt` enum
|
||||
//! from the `ESP32-C3` `PAC (Peripheral Access Crate)` for users to handle
|
||||
//! interrupts associated with these peripherals.
|
||||
//!
|
||||
//! ⚠️ NOTE: notice that `radio` is marked with `false` in the `peripherals!`
|
||||
//! macro. Basically, that means that there's no real peripheral (no `RADIO`
|
||||
//! peripheral in the PACs) but we're creating "virtual peripherals" for it in
|
||||
//! order to ensure the uniqueness of the instance (Singleton).
|
||||
|
||||
use esp32c3 as pac;
|
||||
// We need to export this for users to use
|
||||
|
@ -1,3 +1,16 @@
|
||||
//! # Radio clocks driver (ESP32-C3)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `Radio Clocks` module provides control and configuration functions for
|
||||
//! various radio peripherals, such as `PHY`, `Bluetooth (BT)`, and `Wi-Fi`. The
|
||||
//! module allows enabling and disabling these peripherals, resetting the `Media
|
||||
//! Access Control (MAC)` and initializing clocks.
|
||||
//!
|
||||
//! The module defines a `RadioClockController` trait implemented by the
|
||||
//! `RadioClockControl` struct. This trait provides methods to enable, disable,
|
||||
//! reset the MAC, initialize clocks and perform other related operations.
|
||||
|
||||
use crate::system::{RadioClockControl, RadioClockController, RadioPeripherals};
|
||||
|
||||
// Mask for clock bits used by both WIFI and Bluetooth, 0, 1, 2, 3, 7, 8, 9, 10,
|
||||
|
@ -1,4 +1,37 @@
|
||||
//! Reading of eFuses
|
||||
//! # Reading of eFuses (ESP32-C6)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `efuse` module provides functionality for reading eFuse data
|
||||
//! from the `ESP32-C6` chip, allowing access to various chip-specific
|
||||
//! information such as :
|
||||
//! * MAC address
|
||||
//! * core count
|
||||
//! * CPU frequency
|
||||
//! * chip type
|
||||
//!
|
||||
//! and more. It is useful for retrieving chip-specific configuration and
|
||||
//! identification data during runtime.
|
||||
//!
|
||||
//! The `Efuse` struct represents the eFuse peripheral and is responsible for
|
||||
//! reading various eFuse fields and values.
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### Read chip's MAC address from the eFuse storage.
|
||||
//! ```no_run
|
||||
//! let mac_address = Efuse::get_mac_address();
|
||||
//! writeln!(
|
||||
//! serial_tx,
|
||||
//! "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
|
||||
//! mac_address[0],
|
||||
//! mac_address[1],
|
||||
//! mac_address[2],
|
||||
//! mac_address[3],
|
||||
//! mac_address[4],
|
||||
//! mac_address[5]
|
||||
//! );
|
||||
//! ```
|
||||
|
||||
pub use crate::soc::efuse_field::*;
|
||||
use crate::{adc::Attenuation, peripherals::EFUSE};
|
||||
@ -7,22 +40,6 @@ pub struct Efuse;
|
||||
|
||||
impl Efuse {
|
||||
/// Reads chip's MAC address from the eFuse storage.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let mac_address = Efuse::get_mac_address();
|
||||
/// writeln!(
|
||||
/// serial_tx,
|
||||
/// "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
|
||||
/// mac_address[0],
|
||||
/// mac_address[1],
|
||||
/// mac_address[2],
|
||||
/// mac_address[3],
|
||||
/// mac_address[4],
|
||||
/// mac_address[5]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn get_mac_address() -> [u8; 6] {
|
||||
Self::read_field_be(MAC_FACTORY)
|
||||
}
|
||||
|
@ -1,3 +1,45 @@
|
||||
//! # GPIO configuration module (ESP32-C6)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `GPIO` module provides functions and configurations for controlling the
|
||||
//! `General Purpose Input/Output` pins on the `ESP32-C6` chip. It allows you to
|
||||
//! configure pins as inputs or outputs, set their state and read their state.
|
||||
//!
|
||||
//! Let's get through the functionality and configurations provided by this GPIO
|
||||
//! module:
|
||||
//! - `get_io_mux_reg(gpio_num: u8) -> &'static
|
||||
//! crate::peripherals::io_mux::GPIO0:`:
|
||||
//! * Returns the IO_MUX register for the specified GPIO pin number.
|
||||
//! - `gpio_intr_enable(int_enable: bool, nmi_enable: bool) -> u8`:
|
||||
//! * This function enables or disables GPIO interrupts and Non-Maskable
|
||||
//! Interrupts (NMI). It takes two boolean arguments int_enable and
|
||||
//! nmi_enable to control the interrupt and NMI enable settings. The
|
||||
//! function returns an u8 value representing the interrupt enable
|
||||
//! settings.
|
||||
//! - `gpio` block:
|
||||
//! * Defines the pin configurations for various GPIO pins. Each line
|
||||
//! represents a pin and its associated options such as input/output
|
||||
//! mode, analog capability, and corresponding functions.
|
||||
//! - `analog` block:
|
||||
//! * Block defines the analog capabilities of various GPIO pins. Each
|
||||
//! line represents a pin and its associated options such as mux
|
||||
//! selection, function selection, and input enable.
|
||||
//! - `enum InputSignal`:
|
||||
//! * This enumeration defines input signals for the GPIO mux. Each input
|
||||
//! signal is assigned a specific value.
|
||||
//! - `enum OutputSignal`:
|
||||
//! * This enumeration defines output signals for the GPIO mux. Each
|
||||
//! output signal is assigned a specific value.
|
||||
//!
|
||||
//! This module also implements the `InterruptStatusRegisterAccess` trait for
|
||||
//! two different banks:
|
||||
//! * `InterruptStatusRegisterAccessBank0`
|
||||
//! * `InterruptStatusRegisterAccessBank1`.
|
||||
//! This trait provides functions to read the interrupt status and NMI status
|
||||
//! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the
|
||||
//! `gpio` peripheral to access the appropriate registers.
|
||||
|
||||
use crate::{
|
||||
gpio::{
|
||||
AlternateFunction,
|
||||
|
@ -1,4 +1,63 @@
|
||||
//! Control the LP core
|
||||
//! # Control the LP core
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `LP_CORE` driver provides an interface for controlling and managing the
|
||||
//! low power core of `ESP` chips, allowing efficient low power operation and
|
||||
//! wakeup from sleep based on configurable sources. The low power core is
|
||||
//! responsible for executing low power tasks while the high power core is in
|
||||
//! sleep mode.
|
||||
//!
|
||||
//! The `LpCore` struct provides methods to stop and run the low power core.
|
||||
//!
|
||||
//! The `stop` method stops the low power core, putting it into a sleep state.
|
||||
//!
|
||||
//! The `run` method starts the low power core and specifies the wakeup source.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! const CODE: &[u8] = &[
|
||||
//! 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00,
|
||||
//! 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00,
|
||||
//! 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13,
|
||||
//! 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
|
||||
//! 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00,
|
||||
//! 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00,
|
||||
//! 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13,
|
||||
//! 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
|
||||
//! 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x17, 0x05, 0x00, 0x00, 0x13, 0x05, 0x05,
|
||||
//! 0x04, 0x85, 0x45, 0x23, 0x00, 0xb5, 0x00, 0xb7, 0x26, 0x0b, 0x60, 0xa1, 0x06, 0x37, 0x26,
|
||||
//! 0x0b, 0x60, 0x11, 0x06, 0x09, 0x47, 0x18, 0xc2, 0xb7, 0x47, 0x0f, 0x00, 0x93, 0x87, 0x07,
|
||||
//! 0x24, 0xfd, 0x17, 0xfd, 0xff, 0x85, 0x05, 0x23, 0x00, 0xb5, 0x00, 0x98, 0xc2, 0xb7, 0x47,
|
||||
//! 0x0f, 0x00, 0x93, 0x87, 0x07, 0x24, 0xfd, 0x17, 0xfd, 0xff, 0xf9, 0xbf, 0x00, 0x00, 0x00,
|
||||
//! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
//! ];
|
||||
//!
|
||||
//! // configure GPIO 1 as LP output pin
|
||||
//! let mut lp_pin = io.pins.gpio1.into_low_power();
|
||||
//! lp_pin.output_enable(true);
|
||||
//!
|
||||
//! let mut lp_core = esp32c6_hal::lp_core::LpCore::new(peripherals.LP_CORE);
|
||||
//! lp_core.stop();
|
||||
//! println!("lp core stopped");
|
||||
//!
|
||||
//! // copy code to LP ram
|
||||
//! let lp_ram = 0x5000_0000 as *mut u8;
|
||||
//! unsafe {
|
||||
//! core::ptr::copy_nonoverlapping(CODE as *const _ as *const u8, lp_ram, CODE.len());
|
||||
//! }
|
||||
//! println!("copied code (len {})", CODE.len());
|
||||
//!
|
||||
//! // start LP core
|
||||
//! lp_core.run(lp_core::LpCoreWakeupSource::HpCpu);
|
||||
//! println!("lpcore run");
|
||||
//!
|
||||
//! let data = (0x500000c0) as *mut u32;
|
||||
//! loop {
|
||||
//! print!("Current {:x} \u{000d}", unsafe {
|
||||
//! data.read_volatile()
|
||||
//! });
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use esp32c6 as pac;
|
||||
|
||||
|
@ -1,3 +1,15 @@
|
||||
//! # SOC (System-on-Chip) module (ESP32-C6)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `SOC` module provides access, functions and structures that are useful
|
||||
//! for interacting with various system-related peripherals on `ESP32-C6` chip.
|
||||
//!
|
||||
//! Also few constants are defined in this module for `ESP32-C6` chip:
|
||||
//! * TIMG_DEFAULT_CLK_SRC: 1 - Timer clock source
|
||||
//! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source
|
||||
//! * I2S_SCLK: 160_000_000 - I2S clock frequency
|
||||
|
||||
pub mod efuse;
|
||||
pub mod gpio;
|
||||
pub mod lp_core;
|
||||
|
@ -1,4 +1,25 @@
|
||||
//! Peripheral instance singletons
|
||||
//! # Peripheral instance singletons (ESP32-C6)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `Peripherals` module provides singleton instances of various peripherals
|
||||
//! and allows users to access and use them in their applications.
|
||||
//!
|
||||
//! These peripherals provide various functionalities and interfaces for
|
||||
//! interacting with different hardware components on the `ESP32-C6` chip, such
|
||||
//! as timers, `GPIO` pins, `I2C`, `SPI`, `UART`, and more. Users can access and
|
||||
//! utilize these peripherals by importing the respective singleton instances
|
||||
//! from this module.
|
||||
//!
|
||||
//! It's important to note that the module also exports the `Interrupt` enum
|
||||
//! from the `ESP32-C6` `PAC (Peripheral Access Crate)` for users to handle
|
||||
//! interrupts associated with these peripherals.
|
||||
//!
|
||||
//! ⚠️ NOTE: notice that `radio` and `lp_core` are marked with `false` in the
|
||||
//! `peripherals!` macro. Basically, that means that there's no real peripheral
|
||||
//! (no `RADIO` nor `LP_CORE` peripheral in the PACs) but we're
|
||||
//! creating "virtual peripherals" for them in order to ensure the uniqueness of
|
||||
//! the instances (Singletons).
|
||||
|
||||
use esp32c6 as pac;
|
||||
// We need to export this for users to use
|
||||
|
@ -1,3 +1,16 @@
|
||||
//! # Radio clocks driver (ESP32-C6)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `Radio Clocks` module provides control and configuration functions for
|
||||
//! various radio peripherals, such as `PHY`, `Bluetooth (BT)`, and `Wi-Fi`. The
|
||||
//! module allows enabling and disabling these peripherals, resetting the `Media
|
||||
//! Access Control (MAC)` and initializing clocks.
|
||||
//!
|
||||
//! The module defines a `RadioClockController` trait implemented by the
|
||||
//! `RadioClockControl` struct. This trait provides methods to enable, disable,
|
||||
//! reset the MAC, initialize clocks and perform other related operations.
|
||||
|
||||
use crate::system::{RadioClockControl, RadioClockController, RadioPeripherals};
|
||||
|
||||
impl RadioClockController for RadioClockControl {
|
||||
|
@ -1,4 +1,37 @@
|
||||
//! Reading of eFuses
|
||||
//! # Reading of eFuses (ESP32-H2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `efuse` module provides functionality for reading eFuse data
|
||||
//! from the `ESP32-H2` chip, allowing access to various chip-specific
|
||||
//! information such as :
|
||||
//! * MAC address
|
||||
//! * core count
|
||||
//! * CPU frequency
|
||||
//! * chip type
|
||||
//!
|
||||
//! and more. It is useful for retrieving chip-specific configuration and
|
||||
//! identification data during runtime.
|
||||
//!
|
||||
//! The `Efuse` struct represents the eFuse peripheral and is responsible for
|
||||
//! reading various eFuse fields and values.
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### Read chip's MAC address from the eFuse storage.
|
||||
//! ```no_run
|
||||
//! let mac_address = Efuse::get_mac_address();
|
||||
//! writeln!(
|
||||
//! serial_tx,
|
||||
//! "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
|
||||
//! mac_address[0],
|
||||
//! mac_address[1],
|
||||
//! mac_address[2],
|
||||
//! mac_address[3],
|
||||
//! mac_address[4],
|
||||
//! mac_address[5]
|
||||
//! );
|
||||
//! ```
|
||||
|
||||
use crate::peripherals::EFUSE;
|
||||
pub use crate::soc::efuse_field::*;
|
||||
@ -7,22 +40,6 @@ pub struct Efuse;
|
||||
|
||||
impl Efuse {
|
||||
/// Reads chip's MAC address from the eFuse storage.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let mac_address = Efuse::get_mac_address();
|
||||
/// writeln!(
|
||||
/// serial_tx,
|
||||
/// "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
|
||||
/// mac_address[0],
|
||||
/// mac_address[1],
|
||||
/// mac_address[2],
|
||||
/// mac_address[3],
|
||||
/// mac_address[4],
|
||||
/// mac_address[5]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn get_mac_address() -> [u8; 6] {
|
||||
Self::read_field_be(MAC_FACTORY)
|
||||
}
|
||||
|
@ -1,3 +1,45 @@
|
||||
//! # GPIO configuration module (ESP32-H2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `GPIO` module provides functions and configurations for controlling the
|
||||
//! `General Purpose Input/Output` pins on the `ESP32-H2` chip. It allows you to
|
||||
//! configure pins as inputs or outputs, set their state and read their state.
|
||||
//!
|
||||
//! Let's get through the functionality and configurations provided by this GPIO
|
||||
//! module:
|
||||
//! - `get_io_mux_reg(gpio_num: u8) -> &'static
|
||||
//! crate::peripherals::io_mux::GPIO0:`:
|
||||
//! * Returns the IO_MUX register for the specified GPIO pin number.
|
||||
//! - `gpio_intr_enable(int_enable: bool, nmi_enable: bool) -> u8`:
|
||||
//! * This function enables or disables GPIO interrupts and Non-Maskable
|
||||
//! Interrupts (NMI). It takes two boolean arguments int_enable and
|
||||
//! nmi_enable to control the interrupt and NMI enable settings. The
|
||||
//! function returns an u8 value representing the interrupt enable
|
||||
//! settings.
|
||||
//! - `gpio` block:
|
||||
//! * Defines the pin configurations for various GPIO pins. Each line
|
||||
//! represents a pin and its associated options such as input/output
|
||||
//! mode, analog capability, and corresponding functions.
|
||||
//! - `analog` block:
|
||||
//! * Block defines the analog capabilities of various GPIO pins. Each
|
||||
//! line represents a pin and its associated options such as mux
|
||||
//! selection, function selection, and input enable.
|
||||
//! - `enum InputSignal`:
|
||||
//! * This enumeration defines input signals for the GPIO mux. Each input
|
||||
//! signal is assigned a specific value.
|
||||
//! - `enum OutputSignal`:
|
||||
//! * This enumeration defines output signals for the GPIO mux. Each
|
||||
//! output signal is assigned a specific value.
|
||||
//!
|
||||
//! This module also implements the `InterruptStatusRegisterAccess` trait for
|
||||
//! two different banks:
|
||||
//! * `InterruptStatusRegisterAccessBank0`
|
||||
//! * `InterruptStatusRegisterAccessBank1`.
|
||||
//! This trait provides functions to read the interrupt status and NMI status
|
||||
//! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the
|
||||
//! `gpio` peripheral to access the appropriate registers.
|
||||
|
||||
use crate::{
|
||||
gpio::{
|
||||
AlternateFunction,
|
||||
|
@ -1,3 +1,15 @@
|
||||
//! # SOC (System-on-Chip) module (ESP32-H2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `SOC` module provides access, functions and structures that are useful
|
||||
//! for interacting with various system-related peripherals on `ESP32-H2` chip.
|
||||
//!
|
||||
//! Also few constants are defined in this module for `ESP32-H2` chip:
|
||||
//! * TIMG_DEFAULT_CLK_SRC: 2 - Timer clock source
|
||||
//! * I2S_DEFAULT_CLK_SRC: 1 - I2S clock source
|
||||
//! * I2S_SCLK: 96_000_000 - I2S clock frequency
|
||||
|
||||
pub mod efuse;
|
||||
pub mod gpio;
|
||||
pub mod peripherals;
|
||||
|
@ -1,4 +1,24 @@
|
||||
//! Peripheral instance singletons
|
||||
//! # Peripheral instance singletons (ESP32-H2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `Peripherals` module provides singleton instances of various peripherals
|
||||
//! and allows users to access and use them in their applications.
|
||||
//!
|
||||
//! These peripherals provide various functionalities and interfaces for
|
||||
//! interacting with different hardware components on the `ESP32-H2` chip, such
|
||||
//! as timers, `GPIO` pins, `I2C`, `SPI`, `UART`, and more. Users can access and
|
||||
//! utilize these peripherals by importing the respective singleton instances
|
||||
//! from this module.
|
||||
//!
|
||||
//! It's important to note that the module also exports the `Interrupt` enum
|
||||
//! from the `ESP32-H2` `PAC (Peripheral Access Crate)` for users to handle
|
||||
//! interrupts associated with these peripherals.
|
||||
//!
|
||||
//! ⚠️ NOTE: notice that `radio` is marked with `false` in the `peripherals!`
|
||||
//! macro. Basically, that means that there's no real peripheral (no `RADIO`
|
||||
//! peripheral in the PACs) but we're creating "virtual peripherals" for it in
|
||||
//! order to ensure the uniqueness of the instance (Singleton).
|
||||
|
||||
use esp32h2 as pac;
|
||||
// We need to export this for users to use
|
||||
|
@ -1,3 +1,16 @@
|
||||
//! # Radio clocks driver (ESP32-H2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `Radio Clocks` module provides control and configuration functions for
|
||||
//! various radio peripherals, such as `PHY`, `Bluetooth (BT)`, and `Wi-Fi`. The
|
||||
//! module allows enabling and disabling these peripherals, resetting the `Media
|
||||
//! Access Control (MAC)` and initializing clocks.
|
||||
//!
|
||||
//! The module defines a `RadioClockController` trait implemented by the
|
||||
//! `RadioClockControl` struct. This trait provides methods to enable, disable,
|
||||
//! reset the MAC, initialize clocks and perform other related operations.
|
||||
|
||||
use crate::system::{RadioClockControl, RadioClockController, RadioPeripherals};
|
||||
|
||||
impl RadioClockController for RadioClockControl {
|
||||
|
@ -1,4 +1,37 @@
|
||||
//! Reading of eFuses
|
||||
//! # Reading of eFuses (ESP32-S2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `efuse` module provides functionality for reading eFuse data
|
||||
//! from the `ESP32-S2` chip, allowing access to various chip-specific
|
||||
//! information such as :
|
||||
//! * MAC address
|
||||
//! * core count
|
||||
//! * CPU frequency
|
||||
//! * chip type
|
||||
//!
|
||||
//! and more. It is useful for retrieving chip-specific configuration and
|
||||
//! identification data during runtime.
|
||||
//!
|
||||
//! The `Efuse` struct represents the eFuse peripheral and is responsible for
|
||||
//! reading various eFuse fields and values.
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### Read chip's MAC address from the eFuse storage.
|
||||
//! ```no_run
|
||||
//! let mac_address = Efuse::get_mac_address();
|
||||
//! writeln!(
|
||||
//! serial_tx,
|
||||
//! "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
|
||||
//! mac_address[0],
|
||||
//! mac_address[1],
|
||||
//! mac_address[2],
|
||||
//! mac_address[3],
|
||||
//! mac_address[4],
|
||||
//! mac_address[5]
|
||||
//! );
|
||||
//! ```
|
||||
|
||||
use crate::peripherals::EFUSE;
|
||||
pub use crate::soc::efuse_field::*;
|
||||
|
@ -1,3 +1,57 @@
|
||||
//! # GPIO configuration module (ESP32-S2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `GPIO` module provides functions and configurations for controlling the
|
||||
//! `General Purpose Input/Output` pins on the `ESP32-S2` chip. It allows you to
|
||||
//! configure pins as inputs or outputs, set their state and read their state.
|
||||
//!
|
||||
//! Let's get through the functionality and configurations provided by this GPIO
|
||||
//! module:
|
||||
//! - `get_io_mux_reg(gpio_num: u8) -> &'static
|
||||
//! crate::peripherals::io_mux::GPIO0:`:
|
||||
//! * This function returns a reference to the GPIO register associated
|
||||
//! with the given GPIO number. It uses unsafe code and transmutation to
|
||||
//! access the GPIO registers based on the provided GPIO number.
|
||||
//! - `gpio_intr_enable(int_enable: bool, nmi_enable: bool) -> u8`:
|
||||
//! * This function enables or disables GPIO interrupts and Non-Maskable
|
||||
//! Interrupts (NMI). It takes two boolean arguments int_enable and
|
||||
//! nmi_enable to control the interrupt and NMI enable settings. The
|
||||
//! function returns an u8 value representing the interrupt enable
|
||||
//! settings.
|
||||
//! - `impl_get_rtc_pad`:
|
||||
//! * This macro_rule generates a function to get a specific RTC pad. It
|
||||
//! takes a single argument `$pad_name`, which is an identifier
|
||||
//! representing the name of the pad. Returns a reference to the
|
||||
//! corresponding RTC pad.
|
||||
//! - `impl_get_rtc_pad_indexed`:
|
||||
//! * This macro_rule generates a function similar to the previous one but
|
||||
//! for indexed RTC pads. It takes two arguments: `$pad_name`, which
|
||||
//! represents the name of the pad, and `$idx`, which is the index of
|
||||
//! the specific pad. Returns a reference to the indexed RTC pad.
|
||||
//! - `gpio` block:
|
||||
//! * Defines the pin configurations for various GPIO pins. Each line
|
||||
//! represents a pin and its associated options such as input/output
|
||||
//! mode, analog capability, and corresponding functions.
|
||||
//! - `analog` block:
|
||||
//! * Block defines the analog capabilities of various GPIO pins. Each
|
||||
//! line represents a pin and its associated options such as mux
|
||||
//! selection, function selection, and input enable.
|
||||
//! - `enum InputSignal`:
|
||||
//! * This enumeration defines input signals for the GPIO mux. Each input
|
||||
//! signal is assigned a specific value.
|
||||
//! - `enum OutputSignal`:
|
||||
//! * This enumeration defines output signals for the GPIO mux. Each
|
||||
//! output signal is assigned a specific value.
|
||||
//!
|
||||
//! This module also implements the `InterruptStatusRegisterAccess` trait for
|
||||
//! two different banks:
|
||||
//! * `InterruptStatusRegisterAccessBank0`
|
||||
//! * `InterruptStatusRegisterAccessBank1`.
|
||||
//! This trait provides functions to read the interrupt status and NMI status
|
||||
//! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the
|
||||
//! `gpio` peripheral to access the appropriate registers.
|
||||
|
||||
use crate::{
|
||||
gpio::{
|
||||
AlternateFunction,
|
||||
|
@ -1,3 +1,13 @@
|
||||
//! # SOC (System-on-Chip) module (ESP32-S2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `SOC` module provides access, functions and structures that are useful
|
||||
//! for interacting with various system-related peripherals on `ESP32-S2` chip.
|
||||
//!
|
||||
//! Also few constants are defined in this module for `ESP32-S2` chip:
|
||||
//! * I2S_SCLK: 160_000_000 - I2S clock frequency
|
||||
//! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source
|
||||
pub mod efuse;
|
||||
pub mod gpio;
|
||||
pub mod peripherals;
|
||||
|
@ -1,4 +1,25 @@
|
||||
//! Peripheral instance singletons
|
||||
//! # Peripheral instance singletons (ESP32-S2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `Peripherals` module singleton instances of various peripherals and
|
||||
//! allows users to access and use them in their applications.
|
||||
//!
|
||||
//! These peripherals provide various functionalities and interfaces for
|
||||
//! interacting with different hardware components on the `ESP32-S2` chip, such
|
||||
//! as timers, `GPIO` pins, `I2C`, `SPI`, `UART`, and more. Users can access and
|
||||
//! utilize these peripherals by importing the respective singleton instances
|
||||
//! from this module.
|
||||
//!
|
||||
//! It's important to note that the module also exports the `Interrupt` enum
|
||||
//! from the `ESP32-S2` `PAC (Peripheral Access Crate)` for users to handle
|
||||
//! interrupts associated with these peripherals.
|
||||
//!
|
||||
//! ⚠️ NOTE: notice that `psram`, `radio` and `ulp_riscv_core` are marked with
|
||||
//! `false` in the `peripherals!` macro. Basically, that means that there's no
|
||||
//! real peripheral (no `PSRAM`, `RADIO` nor `ULP_RISCV_CORE` peripheral in the
|
||||
//! `PAC`s) but we're creating "virtual peripherals" for them in order to ensure
|
||||
//! the uniqueness of the instances (Singletons).
|
||||
|
||||
use esp32s2 as pac;
|
||||
// We need to export this for users to use
|
||||
|
@ -1,3 +1,20 @@
|
||||
//! # PSRAM "virtual peripheral" driver (ESP32-S2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `PSRAM` module provides support for accessing and controlling the
|
||||
//! `Pseudo Static Random Access Memory (PSRAM)` on the `ESP32-S2`.
|
||||
//!
|
||||
//! The `PSRAM` module enables users to interface with the `PSRAM` memory
|
||||
//! present on the `ESP32-S2` chip. `PSRAM` provides additional external memory
|
||||
//! to supplement the internal memory of the `ESP32-S2`, allowing for increased
|
||||
//! storage capacity and improved performance in certain applications.
|
||||
//!
|
||||
//! The `PSRAM` module is accessed through a virtual address, defined as
|
||||
//! `PSRAM_VADDR`. The starting virtual address for the PSRAM module is
|
||||
//! 0x3f500000. The `PSRAM` module size depends on the configuration specified
|
||||
//! during the compilation process. The available `PSRAM` sizes are `2MB`,
|
||||
//! `4MB`, and `8MB`.
|
||||
const PSRAM_VADDR: u32 = 0x3f500000;
|
||||
|
||||
pub fn psram_vaddr_start() -> usize {
|
||||
@ -123,6 +140,9 @@ pub fn init_psram(_peripheral: impl crate::peripheral::Peripheral<P = crate::per
|
||||
|
||||
#[cfg(any(feature = "psram_2m", feature = "psram_4m", feature = "psram_8m"))]
|
||||
pub(crate) mod utils {
|
||||
// Function initializes the PSRAM by configuring GPIO pins, resetting the PSRAM,
|
||||
// and enabling Quad I/O (QIO) mode. It also calls the psram_cache_init
|
||||
// function to configure cache parameters and read/write commands.
|
||||
pub(crate) fn psram_init() {
|
||||
psram_gpio_config();
|
||||
|
||||
|
@ -1,3 +1,16 @@
|
||||
//! # Radio clocks driver (ESP32-S2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `Radio Clocks` module provides control and configuration functions for
|
||||
//! various radio peripherals, such as `PHY`, `Bluetooth (BT)`, and `Wi-Fi`. The
|
||||
//! module allows enabling and disabling these peripherals, resetting the `Media
|
||||
//! Access Control (MAC)` and initializing clocks.
|
||||
//!
|
||||
//! The module defines a `RadioClockController` trait implemented by the
|
||||
//! `RadioClockControl` struct. This trait provides methods to enable, disable,
|
||||
//! reset the MAC, initialize clocks and perform other related operations.
|
||||
|
||||
use crate::system::{RadioClockControl, RadioClockController, RadioPeripherals};
|
||||
|
||||
// Mask for clock bits used by both WIFI and Bluetooth, bit 0, 3, 6, 7, 8, 9
|
||||
|
@ -1,5 +1,39 @@
|
||||
//! Control the ULP RISCV core
|
||||
|
||||
//! # Control the ULP core
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `ULP CORE` peripheral allows control over the `Ultra-Low Power
|
||||
//! (ULP) core` in `ESP` chips. The ULP core is a low-power processor
|
||||
//! designed for executing tasks in deep sleep mode, enabling efficient power
|
||||
//! management in ESP systems.
|
||||
//!
|
||||
//! The `UlpCore` struct provides an interface to interact with the `ULP`
|
||||
//! peripheral. It allows starting and configuring the ULP core for operation.
|
||||
//! The `UlpCore` struct is initialized with a peripheral reference to the `ULP
|
||||
//! CORE` instance.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let mut ulp_core = esp32s3_hal::ulp_core::UlpCore::new(peripherals.ULP_RISCV_CORE);
|
||||
//! ulp_core.stop();
|
||||
//! println!("ulp core stopped");
|
||||
//!
|
||||
//! // copy code to RTC ram
|
||||
//! let lp_ram = 0x5000_0000 as *mut u8;
|
||||
//! unsafe {
|
||||
//! core::ptr::copy_nonoverlapping(CODE as *const _ as *const u8, lp_ram, CODE.len());
|
||||
//! }
|
||||
//! println!("copied code (len {})", CODE.len());
|
||||
//!
|
||||
//! // start ULP core
|
||||
//! ulp_core.run(esp32s3_hal::ulp_core::UlpCoreWakeupSource::HpCpu);
|
||||
//! println!("ulpcore run");
|
||||
//!
|
||||
//! let data = (0x5000_0010 - 0) as *mut u32;
|
||||
//! loop {
|
||||
//! println!("Current {}", unsafe { data.read_volatile() });
|
||||
//! }
|
||||
//! ```
|
||||
use esp32s2 as pac;
|
||||
|
||||
use crate::peripheral::{Peripheral, PeripheralRef};
|
||||
@ -23,7 +57,7 @@ impl<'d> UlpCore<'d> {
|
||||
Self { _lp_core: lp_core }
|
||||
}
|
||||
|
||||
// currently stopping the ULP doesn't work (while following the proedures
|
||||
// currently stopping the ULP doesn't work (while following the proсedures
|
||||
// outlines in the TRM) - so don't offer this funtion for now
|
||||
//
|
||||
// pub fn stop(&mut self) {
|
||||
|
@ -1,4 +1,53 @@
|
||||
//! Control CPU Cores
|
||||
//! # Control CPU Cores (ESP32-S3)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! This module provides essential functionality for controlling
|
||||
//! and managing the CPU cores on the `ESP32-S3` chip allowing for fine-grained
|
||||
//! control over their execution and cache behavior. It is used in scenarios
|
||||
//! where precise control over CPU core operation is required, such as
|
||||
//! multi-threading or power management.
|
||||
//!
|
||||
//! The `CpuControl` struct represents the CPU control module and is responsible
|
||||
//! for managing the behavior and operation of the CPU cores. It is typically
|
||||
//! initialized with the `SystemCpuControl` struct, which is provided by the
|
||||
//! `system` module.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let counter = Mutex::new(RefCell::new(0));
|
||||
//!
|
||||
//! let mut cpu_control = CpuControl::new(system.cpu_control);
|
||||
//! let mut cpu1_fnctn = || {
|
||||
//! cpu1_task(&mut timer1, &counter);
|
||||
//! };
|
||||
//! let _guard = cpu_control.start_app_core(&mut cpu1_fnctn).unwrap();
|
||||
//!
|
||||
//! loop {
|
||||
//! block!(timer0.wait()).unwrap();
|
||||
//!
|
||||
//! let count = critical_section::with(|cs| *counter.borrow_ref(cs));
|
||||
//! println!("Hello World - Core 0! Counter is {}", count);
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! Where `cpu1_task()` may be defined as:
|
||||
//! ```no_run
|
||||
//! fn cpu1_task(
|
||||
//! timer: &mut Timer<Timer0<TIMG1>>,
|
||||
//! counter: &critical_section::Mutex<RefCell<i32>>,
|
||||
//! ) -> ! {
|
||||
//! println!("Hello World - Core 1!");
|
||||
//! loop {
|
||||
//! block!(timer.wait()).unwrap();
|
||||
//!
|
||||
//! critical_section::with(|cs| {
|
||||
//! let new_val = counter.borrow_ref_mut(cs).wrapping_add(1);
|
||||
//! *counter.borrow_ref_mut(cs) = new_val;
|
||||
//! });
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
|
@ -1,4 +1,37 @@
|
||||
//! Reading of eFuses
|
||||
//! # Reading of eFuses (ESP32-S3)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `efuse` module provides functionality for reading eFuse data
|
||||
//! from the `ESP32-S3` chip, allowing access to various chip-specific
|
||||
//! information such as :
|
||||
//! * MAC address
|
||||
//! * core count
|
||||
//! * CPU frequency
|
||||
//! * chip type
|
||||
//!
|
||||
//! and more. It is useful for retrieving chip-specific configuration and
|
||||
//! identification data during runtime.
|
||||
//!
|
||||
//! The `Efuse` struct represents the eFuse peripheral and is responsible for
|
||||
//! reading various eFuse fields and values.
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### Read chip's MAC address from the eFuse storage.
|
||||
//! ```no_run
|
||||
//! let mac_address = Efuse::get_mac_address();
|
||||
//! writeln!(
|
||||
//! serial_tx,
|
||||
//! "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
|
||||
//! mac_address[0],
|
||||
//! mac_address[1],
|
||||
//! mac_address[2],
|
||||
//! mac_address[3],
|
||||
//! mac_address[4],
|
||||
//! mac_address[5]
|
||||
//! );
|
||||
//! ```
|
||||
|
||||
pub use crate::soc::efuse_field::*;
|
||||
use crate::{analog::adc::Attenuation, peripherals::EFUSE};
|
||||
@ -7,22 +40,6 @@ pub struct Efuse;
|
||||
|
||||
impl Efuse {
|
||||
/// Reads chip's MAC address from the eFuse storage.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let mac_address = Efuse::get_mac_address();
|
||||
/// writeln!(
|
||||
/// serial_tx,
|
||||
/// "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
|
||||
/// mac_address[0],
|
||||
/// mac_address[1],
|
||||
/// mac_address[2],
|
||||
/// mac_address[3],
|
||||
/// mac_address[4],
|
||||
/// mac_address[5]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn get_mac_address() -> [u8; 6] {
|
||||
Self::read_field_be(MAC_FACTORY)
|
||||
}
|
||||
|
@ -1,3 +1,45 @@
|
||||
//! # GPIO configuration module (ESP32-S3)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `GPIO` module provides functions and configurations for controlling the
|
||||
//! `General Purpose Input/Output` pins on the `ESP32-S3` chip. It allows you to
|
||||
//! configure pins as inputs or outputs, set their state and read their state.
|
||||
//!
|
||||
//! Let's get through the functionality and configurations provided by this GPIO
|
||||
//! module:
|
||||
//! - `get_io_mux_reg(gpio_num: u8) -> &'static
|
||||
//! crate::peripherals::io_mux::GPIO0:`:
|
||||
//! * Returns the IO_MUX register for the specified GPIO pin number.
|
||||
//! - `gpio_intr_enable(int_enable: bool, nmi_enable: bool) -> u8`:
|
||||
//! * This function enables or disables GPIO interrupts and Non-Maskable
|
||||
//! Interrupts (NMI). It takes two boolean arguments int_enable and
|
||||
//! nmi_enable to control the interrupt and NMI enable settings. The
|
||||
//! function returns an u8 value representing the interrupt enable
|
||||
//! settings.
|
||||
//! - `gpio` block:
|
||||
//! * Defines the pin configurations for various GPIO pins. Each line
|
||||
//! represents a pin and its associated options such as input/output
|
||||
//! mode, analog capability, and corresponding functions.
|
||||
//! - `analog` block:
|
||||
//! * Block defines the analog capabilities of various GPIO pins. Each
|
||||
//! line represents a pin and its associated options such as mux
|
||||
//! selection, function selection, and input enable.
|
||||
//! - `enum InputSignal`:
|
||||
//! * This enumeration defines input signals for the GPIO mux. Each input
|
||||
//! signal is assigned a specific value.
|
||||
//! - `enum OutputSignal`:
|
||||
//! * This enumeration defines output signals for the GPIO mux. Each
|
||||
//! output signal is assigned a specific value.
|
||||
//!
|
||||
//! This module also implements the `InterruptStatusRegisterAccess` trait for
|
||||
//! two different banks:
|
||||
//! * `InterruptStatusRegisterAccessBank0`
|
||||
//! * `InterruptStatusRegisterAccessBank1`.
|
||||
//! This trait provides functions to read the interrupt status and NMI status
|
||||
//! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the
|
||||
//! `gpio` peripheral to access the appropriate registers.
|
||||
|
||||
use crate::{
|
||||
gpio::{
|
||||
AlternateFunction,
|
||||
|
@ -1,3 +1,13 @@
|
||||
//! # SOC (System-on-Chip) module (ESP32-S3)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `SOC` module provides access, functions and structures that are useful
|
||||
//! for interacting with various system-related peripherals on `ESP32-S3` chip.
|
||||
//!
|
||||
//! Also few constants are defined in this module for `ESP32-S3` chip:
|
||||
//! * I2S_SCLK: 160_000_000 - I2S clock frequency
|
||||
//! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source
|
||||
pub mod cpu_control;
|
||||
pub mod efuse;
|
||||
pub mod gpio;
|
||||
|
@ -1,4 +1,25 @@
|
||||
//! Peripheral instance singletons
|
||||
//! # Peripheral instance singletons (ESP32-S3)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `Peripherals` module provides singleton instances of various peripherals
|
||||
//! and allows users to access and use them in their applications.
|
||||
//!
|
||||
//! These peripherals provide various functionalities and interfaces for
|
||||
//! interacting with different hardware components on the `ESP32-S3` chip, such
|
||||
//! as timers, `GPIO` pins, `I2C`, `SPI`, `UART`, and more. Users can access and
|
||||
//! utilize these peripherals by importing the respective singleton instances
|
||||
//! from this module.
|
||||
//!
|
||||
//! It's important to note that the module also exports the `Interrupt` enum
|
||||
//! from the `ESP32-S3` `PAC (Peripheral Access Crate)` for users to handle
|
||||
//! interrupts associated with these peripherals.
|
||||
//!
|
||||
//! ⚠️ NOTE: notice that `psram`, `radio` and `ulp_riscv_core` are marked with
|
||||
//! `false` in the `peripherals!` macro. Basically, that means that there's no
|
||||
//! real peripheral (no `PSRAM` nor `RADIO` peripheral in the `PAC`s) but we're
|
||||
//! creating "virtual peripherals" for them in order to ensure the uniqueness of
|
||||
//! the instances (Singletons).
|
||||
|
||||
use esp32s3 as pac;
|
||||
// We need to export this for users to use
|
||||
|
@ -1,3 +1,20 @@
|
||||
//! # PSRAM "virtual peripheral" driver (ESP32-S2)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `PSRAM` module provides support for accessing and controlling the
|
||||
//! `Pseudo Static Random Access Memory (PSRAM)` on the `ESP32-S2`.
|
||||
//!
|
||||
//! The `PSRAM` module enables users to interface with the `PSRAM` memory
|
||||
//! present on the `ESP32-S2` chip. `PSRAM` provides additional external memory
|
||||
//! to supplement the internal memory of the `ESP32-S2`, allowing for increased
|
||||
//! storage capacity and improved performance in certain applications.
|
||||
//!
|
||||
//! The `PSRAM` module is accessed through a virtual address, defined as
|
||||
//! `PSRAM_VADDR`. The starting virtual address for the PSRAM module is
|
||||
//! 0x3f500000. The `PSRAM` module size depends on the configuration specified
|
||||
//! during the compilation process. The available `PSRAM` sizes are `2MB`,
|
||||
//! `4MB`, and `8MB`.
|
||||
static mut PSRAM_VADDR: u32 = 0x3C000000;
|
||||
|
||||
pub fn psram_vaddr_start() -> usize {
|
||||
|
@ -1,3 +1,15 @@
|
||||
//! # Radio clocks driver (ESP32-S3)
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `Radio Clocks` module provides control and configuration functions for
|
||||
//! various radio peripherals, such as `PHY`, `Bluetooth (BT)`, and `Wi-Fi`. The
|
||||
//! module allows enabling and disabling these peripherals, resetting the `Media
|
||||
//! Access Control (MAC)` and initializing clocks.
|
||||
//!
|
||||
//! The module defines a `RadioClockController` trait implemented by the
|
||||
//! `RadioClockControl` struct. This trait provides methods to enable, disable,
|
||||
//! reset the MAC, initialize clocks and perform other related operations.
|
||||
use crate::system::{RadioClockControl, RadioClockController, RadioPeripherals};
|
||||
|
||||
// Note: this comment has been copied from esp-idf, including the mistake.
|
||||
|
@ -1,4 +1,39 @@
|
||||
//! Control the ULP RISCV core
|
||||
//! Control the ULP core
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The `ULP CORE` peripheral allows control over the `Ultra-Low Power
|
||||
//! (ULP) core` in `ESP` chips. The ULP core is a low-power processor
|
||||
//! designed for executing tasks in deep sleep mode, enabling efficient power
|
||||
//! management in ESP systems.
|
||||
//!
|
||||
//! The `UlpCore` struct provides an interface to interact with the `ULP
|
||||
//! CORE` peripheral. It allows starting and configuring the ULP core for
|
||||
//! operation. The `UlpCore` struct is initialized with a peripheral reference
|
||||
//! to the `ULP CORE` instance.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let mut ulp_core = esp32s3_hal::ulp_core::UlpCore::new(peripherals.ULP_RISCV_CORE);
|
||||
//! ulp_core.stop();
|
||||
//! println!("ulp core stopped");
|
||||
//!
|
||||
//! // copy code to RTC ram
|
||||
//! let lp_ram = 0x5000_0000 as *mut u8;
|
||||
//! unsafe {
|
||||
//! core::ptr::copy_nonoverlapping(CODE as *const _ as *const u8, lp_ram, CODE.len());
|
||||
//! }
|
||||
//! println!("copied code (len {})", CODE.len());
|
||||
//!
|
||||
//! // start ULP core
|
||||
//! ulp_core.run(esp32s3_hal::ulp_core::UlpCoreWakeupSource::HpCpu);
|
||||
//! println!("ulpcore run");
|
||||
//!
|
||||
//! let data = (0x5000_0010 - 0) as *mut u32;
|
||||
//! loop {
|
||||
//! println!("Current {}", unsafe { data.read_volatile() });
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use esp32s3 as pac;
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
//! # Serial Peripheral Interface
|
||||
//!
|
||||
//! ## Overview
|
||||
//! There are multiple ways to use SPI, depending on your needs. Regardless of
|
||||
//! which way you choose, you must first create an SPI instance with
|
||||
//! [`Spi::new`].
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```rust
|
||||
//! let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//! let sclk = io.pins.gpio12;
|
||||
|
@ -1,8 +1,27 @@
|
||||
//! System Control
|
||||
//! # System Control
|
||||
//!
|
||||
//! The SYSTEM/DPORT peripheral needs to be split into several logical parts.
|
||||
//! ## Overview
|
||||
//! This `system` driver provides an interface to control and configure various
|
||||
//! system-related features and peripherals on ESP chips. It includes
|
||||
//! functionality to control peripheral clocks, manage software interrupts,
|
||||
//! configure chip clocks, and control radio peripherals.
|
||||
//!
|
||||
//! Example
|
||||
//! ### Software Interrupts
|
||||
//! The `SoftwareInterrupt` enum represents the available software interrupt
|
||||
//! sources.
|
||||
//!
|
||||
//! The SoftwareInterruptControl struct allows raising or resetting software
|
||||
//! interrupts using the `raise()` and `reset()` methods. The behavior of these
|
||||
//! methods depends on the specific chip variant.
|
||||
//!
|
||||
//! ### Peripheral Clock Control
|
||||
//! The `PeripheralClockControl` struct controls the enablement of peripheral
|
||||
//! clocks.
|
||||
//!
|
||||
//! It provides an `enable()` method to enable and reset specific peripherals.
|
||||
//! The available peripherals are represented by the `Peripheral` enum
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let peripherals = Peripherals::take();
|
||||
//! let system = peripherals.SYSTEM.split();
|
||||
|
@ -1,4 +1,30 @@
|
||||
//! System Timer peripheral driver
|
||||
//! # System Timer peripheral driver
|
||||
//!
|
||||
//! ## Overview
|
||||
//! This software module provides an interface to interact with the system timer
|
||||
//! (SYSTIMER) peripheral on ESP microcontroller chips.
|
||||
//!
|
||||
//! Each ESP chip provides a timer (`52-bit` or `64-bit`, depends on chip),
|
||||
//! which can be used to generate tick interrupts for operating system, or be
|
||||
//! used as a general timer to generate periodic interrupts or one-time
|
||||
//! interrupts. With the help of the RTC timer, system timer can be kept up to
|
||||
//! date after Light-sleep or Deep-sleep.
|
||||
//!
|
||||
//! The driver supports features such as retrieving the current system time,
|
||||
//! setting alarms for specific time points or periodic intervals, enabling and
|
||||
//! clearing interrupts, configuring various settings of the system timer.
|
||||
//!
|
||||
//! By using the SYSTIMER peripheral driver, you can leverage the system timer
|
||||
//! functionality of ESP chips for accurate timing measurements, event
|
||||
//! triggering and synchronization in your applications.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let peripherals = Peripherals::take();
|
||||
//!
|
||||
//! let syst = SystemTimer::new(peripherals.SYSTIMER);
|
||||
//! println!("SYSTIMER Current value = {}", SystemTimer::now());
|
||||
//! ```
|
||||
|
||||
use core::{intrinsics::transmute, marker::PhantomData};
|
||||
|
||||
|
@ -1,4 +1,46 @@
|
||||
//! General-purpose timers
|
||||
//! # General-purpose timers
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `general-purpose timer` peripheral consists of a timer group, which can
|
||||
//! have up to two timers (depending on the chip) and a watchdog timer. The
|
||||
//! timer group allows for the management of multiple timers and synchronization
|
||||
//! between them.
|
||||
//!
|
||||
//! This peripheral can be used to perform a variety of
|
||||
//! tasks, such as triggering an interrupt after a particular interval
|
||||
//! (periodically and aperiodically), precisely time an interval, act as a
|
||||
//! hardware clock and so on.
|
||||
//!
|
||||
//! Each timer group consists of two general purpose timers and one Main System
|
||||
//! Watchdog Timer(MSWDT). All general purpose timers are based on 16-bit
|
||||
//! prescalers and 54-bit auto-reload-capable up-down counters.
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ```no_run
|
||||
//! let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
//!
|
||||
//! // Create timer groups
|
||||
//! let timer_group0 = TimerGroup::new(
|
||||
//! peripherals.TIMG0,
|
||||
//! &clocks,
|
||||
//! &mut system.peripheral_clock_control,
|
||||
//! );
|
||||
//! // Get watchdog timers of timer groups
|
||||
//! let mut wdt0 = timer_group0.wdt;
|
||||
//! let timer_group1 = TimerGroup::new(
|
||||
//! peripherals.TIMG1,
|
||||
//! &clocks,
|
||||
//! &mut system.peripheral_clock_control,
|
||||
//! );
|
||||
//! let mut wdt1 = timer_group1.wdt;
|
||||
//!
|
||||
//! // Disable watchdog timers
|
||||
//! rtc.swd.disable();
|
||||
//! rtc.rwdt.disable();
|
||||
//! wdt0.disable();
|
||||
//! wdt1.disable();
|
||||
//! ```
|
||||
|
||||
use core::{
|
||||
marker::PhantomData,
|
||||
|
@ -1,8 +1,80 @@
|
||||
//! # Two-wire Automotive Interface (TWAI)
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The TWAI peripheral driver provides functions and structs specifically
|
||||
//! designed for the Two-Wire Automotive Interface (TWAI) on ESP chips. TWAI is
|
||||
//! a communication protocol commonly used in automotive applications for
|
||||
//! sending and receiving messages between electronic control units (ECUs) in a
|
||||
//! vehicle.
|
||||
//!
|
||||
//! The driver enables you to configure and utilize the TWAI module on ESP
|
||||
//! chips. It offers functions for initializing the TWAI peripheral, setting up
|
||||
//! the ti1ming parameters, configuring acceptance filters, handling interrupts,
|
||||
//! and transmitting/receiving messages on the TWAI bus.
|
||||
//!
|
||||
//! This driver manages the ISO 11898-1 (CAN Specification 2.0) compatible TWAI
|
||||
//! controllers. It supports Standard Frame Format (11-bit) and Extended Frame
|
||||
//! Format (29-bit) frame identifiers.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! // Use GPIO pins 2 and 3 to connect to the respective pins on the CAN
|
||||
//! // transceiver.
|
||||
//! let can_tx_pin = io.pins.gpio2;
|
||||
//! let can_rx_pin = io.pins.gpio3;
|
||||
//!
|
||||
//! // The speed of the CAN bus.
|
||||
//! const CAN_BAUDRATE: twai::BaudRate = twai::BaudRate::B1000K;
|
||||
//!
|
||||
//! // Begin configuring the TWAI peripheral. The peripheral is in a reset like
|
||||
//! // state that prevents transmission but allows configuration.
|
||||
//! let mut can_config = twai::TwaiConfiguration::new(
|
||||
//! peripherals.TWAI0,
|
||||
//! can_tx_pin,
|
||||
//! can_rx_pin,
|
||||
//! &mut system.peripheral_clock_control,
|
||||
//! &clocks,
|
||||
//! CAN_BAUDRATE,
|
||||
//! );
|
||||
//!
|
||||
//! // Partially filter the incoming messages to reduce overhead of receiving undesired messages
|
||||
//! const FILTER: twai::filter::SingleStandardFilter =
|
||||
//! twai::filter::SingleStandardFilter::new(b"xxxxxxxxxx0", b"x", [b"xxxxxxxx", b"xxxxxxxx"]);
|
||||
//! can_config.set_filter(FILTER);
|
||||
//!
|
||||
//! // Start the peripheral. This locks the configuration settings of the peripheral
|
||||
//! // and puts it into operation mode, allowing packets to be sent and
|
||||
//! // received.
|
||||
//! let mut can = can_config.start();
|
||||
//!
|
||||
//! loop {
|
||||
//! // Wait for a frame to be received.
|
||||
//! let frame = block!(can.receive()).unwrap();
|
||||
//!
|
||||
//! println!("Received a frame:");
|
||||
//!
|
||||
//! // Print different messages based on the frame id type.
|
||||
//! match frame.id() {
|
||||
//! Id::Standard(id) => {
|
||||
//! println!("\tStandard Id: {:?}", id);
|
||||
//! }
|
||||
//! Id::Extended(id) => {
|
||||
//! println!("\tExtended Id: {:?}", id);
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! // Print out the frame data or the requested data length code for a remote
|
||||
//! // transmission request frame.
|
||||
//! if frame.is_data_frame() {
|
||||
//! println!("\tData: {:?}", frame.data());
|
||||
//! } else {
|
||||
//! println!("\tRemote Frame. Data Length Code: {}", frame.dlc());
|
||||
//! }
|
||||
//!
|
||||
//! // Transmit the frame back.
|
||||
//! let _result = block!(can.transmit(&frame)).unwrap();
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
#[cfg(feature = "eh1")]
|
||||
use embedded_can::{nb::Can, Error, ErrorKind, ExtendedId, Frame, Id, StandardId};
|
||||
|
@ -1,4 +1,52 @@
|
||||
//! UART driver
|
||||
//! # UART driver
|
||||
//!
|
||||
//! ## Overview
|
||||
//! In embedded system applications, data is required to be transferred in a
|
||||
//! simple way with minimal system resources. This can be achieved by a
|
||||
//! Universal Asynchronous Receiver/Transmitter (UART), which flexibly exchanges
|
||||
//! data with other peripheral devices in full-duplex mode.
|
||||
//! The UART driver provides an interface to communicate with UART peripherals
|
||||
//! on ESP chips. It enables serial communication between the microcontroller
|
||||
//! and external devices using the UART protocol.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let config = Config {
|
||||
//! baudrate: 115200,
|
||||
//! data_bits: DataBits::DataBits8,
|
||||
//! parity: Parity::ParityNone,
|
||||
//! stop_bits: StopBits::STOP1,
|
||||
//! };
|
||||
//!
|
||||
//! let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//! let pins = TxRxPins::new_tx_rx(
|
||||
//! io.pins.gpio1.into_push_pull_output(),
|
||||
//! io.pins.gpio2.into_floating_input(),
|
||||
//! );
|
||||
//!
|
||||
//! let mut serial1 = Uart::new_with_config(
|
||||
//! peripherals.UART1,
|
||||
//! Some(config),
|
||||
//! Some(pins),
|
||||
//! &clocks,
|
||||
//! &mut system.peripheral_clock_control,
|
||||
//! );
|
||||
//!
|
||||
//! timer0.start(250u64.millis());
|
||||
//!
|
||||
//! println!("Start");
|
||||
//! loop {
|
||||
//! serial1.write(0x42).ok();
|
||||
//! let read = block!(serial1.read());
|
||||
//!
|
||||
//! match read {
|
||||
//! Ok(read) => println!("Read 0x{:02x}", read),
|
||||
//! Err(err) => println!("Error {:?}", err),
|
||||
//! }
|
||||
//!
|
||||
//! block!(timer0.wait()).unwrap();
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use self::config::Config;
|
||||
#[cfg(uart2)]
|
||||
|
@ -1,4 +1,22 @@
|
||||
//! USB Serial JTAG peripheral driver
|
||||
//! # USB Serial JTAG peripheral driver
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The USB Serial JTAG peripheral driver provides an interface to communicate
|
||||
//! with the USB Serial/JTAG peripheral on ESP chips. It enables serial
|
||||
//! communication and JTAG debugging capabilities, allowing developers to
|
||||
//! interact with the ESP chip for programming, debugging, and data transfer
|
||||
//! purposes, can be also used to program the SoC's flash, read program output,
|
||||
//! as well as attach a debugger to a running program.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let peripherals = Peripherals::take();
|
||||
//! let mut system = peripherals.SYSTEM.split();
|
||||
//! let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
//! ...
|
||||
//! // Initialize USB Serial/JTAG peripheral
|
||||
//! let mut usb_serial =
|
||||
//! UsbSerialJtag::new(peripherals.USB_DEVICE, &mut system.peripheral_clock_control);
|
||||
|
||||
use core::convert::Infallible;
|
||||
|
||||
|
@ -1,5 +1,49 @@
|
||||
//! Procedural macros for placing statics and functions into RAM, and for
|
||||
//! marking interrupt handlers.
|
||||
//! Procedural macros
|
||||
//!
|
||||
//! ## Overview
|
||||
//! The `esp-hal-procmacros` module provides procedural macros for placing
|
||||
//! statics and functions into RAM and for marking interrupt handlers on ESP
|
||||
//! microcontrollers.
|
||||
//!
|
||||
//! These macros offer developers a convenient way to control memory placement
|
||||
//! and define interrupt handlers in their embedded applications, allowing for
|
||||
//! optimized memory usage and precise handling of hardware interrupts.
|
||||
//!
|
||||
//! Key Components:
|
||||
//! - [ram](attr.ram.html) - Attribute macro for placing statics and functions
|
||||
//! into specific memory sections, such as SRAM or RTC RAM (slow or fast)
|
||||
//! with different initialization options. Supported options are:
|
||||
//! - `rtc_fast` - Use RTC fast RAM
|
||||
//! - `rtc_slow` - Use RTC slow RAM (not all targets support slow RTC RAM)
|
||||
//! - `uninitialized` - Skip initialization of the memory
|
||||
//! - `zeroed` - Initialize the memory to zero
|
||||
//! - [interrupt](attr.interrupt.html) - Attribute macro for marking interrupt
|
||||
//! handlers. Interrupt handlers are used to handle specific hardware
|
||||
//! interrupts generated by peripherals.<br> The macro allows users to
|
||||
//! specify the interrupt name explicitly or use the function name to match
|
||||
//! the interrupt.
|
||||
//!
|
||||
//! ## Examples
|
||||
//!
|
||||
//! #### `ram` macro
|
||||
//! ```no_run
|
||||
//! #[ram(rtc_fast)]
|
||||
//! static mut SOME_INITED_DATA: [u8; 2] = [0xaa, 0xbb];
|
||||
//!
|
||||
//! #[ram(rtc_fast, uninitialized)]
|
||||
//! static mut SOME_UNINITED_DATA: [u8; 2] = [0; 2];
|
||||
//!
|
||||
//! #[ram(rtc_fast, zeroed)]
|
||||
//! static mut SOME_ZEROED_DATA: [u8; 8] = [0; 8];
|
||||
//! ```
|
||||
//!
|
||||
//! #### `interrupt` macro
|
||||
//! ```no_run
|
||||
//! #[interrupt]
|
||||
//! fn INTR_NAME() {
|
||||
//! // Interrupt handling code here
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")]
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user