diff --git a/esp-backtrace/src/riscv.rs b/esp-backtrace/src/riscv.rs index 06d666174ee..50aae2bf17e 100644 --- a/esp-backtrace/src/riscv.rs +++ b/esp-backtrace/src/riscv.rs @@ -12,45 +12,93 @@ pub(super) const RA_OFFSET: usize = 4; /// Registers saved in trap handler #[doc(hidden)] -#[allow(missing_docs)] #[derive(Default, Clone, Copy)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(C)] pub(crate) struct TrapFrame { + /// Return address, stores the address to return to after a function call or + /// interrupt. pub ra: usize, + /// Temporary register t0, used for intermediate values. pub t0: usize, + /// Temporary register t1, used for intermediate values. pub t1: usize, + /// Temporary register t2, used for intermediate values. pub t2: usize, + /// Temporary register t3, used for intermediate values. pub t3: usize, + /// Temporary register t4, used for intermediate values. pub t4: usize, + /// Temporary register t5, used for intermediate values. pub t5: usize, + /// Temporary register t6, used for intermediate values. pub t6: usize, + /// Argument register a0, typically used to pass the first argument to a + /// function. pub a0: usize, + /// Argument register a1, typically used to pass the second argument to a + /// function. pub a1: usize, + /// Argument register a2, typically used to pass the third argument to a + /// function. pub a2: usize, + /// Argument register a3, typically used to pass the fourth argument to a + /// function. pub a3: usize, + /// Argument register a4, typically used to pass the fifth argument to a + /// function. pub a4: usize, + /// Argument register a5, typically used to pass the sixth argument to a + /// function. pub a5: usize, + /// Argument register a6, typically used to pass the seventh argument to a + /// function. pub a6: usize, + /// Argument register a7, typically used to pass the eighth argument to a + /// function. pub a7: usize, + /// Saved register s0, used to hold values across function calls. pub s0: usize, + /// Saved register s1, used to hold values across function calls. pub s1: usize, + /// Saved register s2, used to hold values across function calls. pub s2: usize, + /// Saved register s3, used to hold values across function calls. pub s3: usize, + /// Saved register s4, used to hold values across function calls. pub s4: usize, + /// Saved register s5, used to hold values across function calls. pub s5: usize, + /// Saved register s6, used to hold values across function calls. pub s6: usize, + /// Saved register s7, used to hold values across function calls. pub s7: usize, + /// Saved register s8, used to hold values across function calls. pub s8: usize, + /// Saved register s9, used to hold values across function calls. pub s9: usize, + /// Saved register s10, used to hold values across function calls. pub s10: usize, + /// Saved register s11, used to hold values across function calls. pub s11: usize, + /// Global pointer register, holds the address of the global data area. pub gp: usize, + /// Thread pointer register, holds the address of the thread-local storage + /// area. pub tp: usize, + /// Stack pointer register, holds the address of the top of the stack. pub sp: usize, + /// Program counter, stores the address of the next instruction to be + /// executed. pub pc: usize, + /// Machine status register, holds the current status of the processor, + /// including interrupt enable bits and privilege mode. pub mstatus: usize, + /// Machine cause register, contains the reason for the trap (e.g., + /// exception or interrupt number). pub mcause: usize, + /// Machine trap value register, contains additional information about the + /// trap (e.g., faulting address). pub mtval: usize, } diff --git a/esp-backtrace/src/xtensa.rs b/esp-backtrace/src/xtensa.rs index 64b8287ef6d..e22e1b5a938 100644 --- a/esp-backtrace/src/xtensa.rs +++ b/esp-backtrace/src/xtensa.rs @@ -9,8 +9,8 @@ use crate::MAX_BACKTRACE_ADDRESSES; #[cfg(feature = "panic-handler")] pub(super) const RA_OFFSET: usize = 3; +/// Exception Cause #[doc(hidden)] -#[allow(missing_docs)] #[derive(Debug, Clone, Copy)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(C)] @@ -95,89 +95,165 @@ pub enum ExceptionCause { Cp6Disabled = 38, /// Access To Coprocessor 7 When Disabled Cp7Disabled = 39, - + /// None None = 255, } #[doc(hidden)] -#[allow(missing_docs, non_snake_case)] +#[allow(non_snake_case)] #[derive(Clone, Copy)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(C)] pub struct Context { + /// Program counter, stores the address of the next instruction to be + /// executed. pub PC: u32, + /// Processor status, holds various status flags for the CPU. pub PS: u32, + /// General-purpose register A0 used for data storage and manipulation. pub A0: u32, + /// General-purpose register A1 used for data storage and manipulation. pub A1: u32, + /// General-purpose register A2 used for data storage and manipulation. pub A2: u32, + /// General-purpose register A3 used for data storage and manipulation. pub A3: u32, + /// General-purpose register A4 used for data storage and manipulation. pub A4: u32, + /// General-purpose register A5 used for data storage and manipulation. pub A5: u32, + /// General-purpose register A6 used for data storage and manipulation. pub A6: u32, + /// General-purpose register A7 used for data storage and manipulation. pub A7: u32, + /// General-purpose register A8 used for data storage and manipulation. pub A8: u32, + /// General-purpose register A9 used for data storage and manipulation. pub A9: u32, + /// General-purpose register A10 used for data storage and manipulation. pub A10: u32, + /// General-purpose register A11 used for data storage and manipulation. pub A11: u32, + /// General-purpose register A12 used for data storage and manipulation. pub A12: u32, + /// General-purpose register A13 used for data storage and manipulation. pub A13: u32, + /// General-purpose register A14 used for data storage and manipulation. pub A14: u32, + /// General-purpose register A15 used for data storage and manipulation. pub A15: u32, + /// Shift amount register, used for shift and rotate instructions. pub SAR: u32, + /// Exception cause, indicates the reason for the last exception. pub EXCCAUSE: u32, + /// Exception address, holds the address related to the exception. pub EXCVADDR: u32, + /// Loop start address, used in loop instructions. pub LBEG: u32, + /// Loop end address, used in loop instructions. pub LEND: u32, + /// Loop counter, used to count iterations in loop instructions. pub LCOUNT: u32, + /// Thread pointer, used for thread-local storage. pub THREADPTR: u32, + /// Compare register, used for certain compare instructions. pub SCOMPARE1: u32, + /// Break register, used for breakpoint-related operations. pub BR: u32, + /// Accumulator low register, used for extended arithmetic operations. pub ACCLO: u32, + /// Accumulator high register, used for extended arithmetic operations. pub ACCHI: u32, + /// Additional register M0 used for special operations. pub M0: u32, + /// Additional register M1 used for special operations. pub M1: u32, + /// Additional register M2 used for special operations. pub M2: u32, + /// Additional register M3 used for special operations. pub M3: u32, + /// 64-bit floating-point register (low part), available if the + /// `print-float-registers` feature is enabled. #[cfg(feature = "print-float-registers")] pub F64R_LO: u32, + /// 64-bit floating-point register (high part), available if the + /// `print-float-registers` feature is enabled. #[cfg(feature = "print-float-registers")] pub F64R_HI: u32, + /// Floating-point status register, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F64S: u32, + /// Floating-point control register, available if the + /// `print-float-registers` feature is enabled. #[cfg(feature = "print-float-registers")] pub FCR: u32, + /// Floating-point status register, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub FSR: u32, + /// Floating-point register F0, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F0: u32, + /// Floating-point register F1, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F1: u32, + /// Floating-point register F2, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F2: u32, + /// Floating-point register F3, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F3: u32, + /// Floating-point register F4, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F4: u32, + /// Floating-point register F5, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F5: u32, + /// Floating-point register F6, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F6: u32, + /// Floating-point register F7, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F7: u32, + /// Floating-point register F8, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F8: u32, + /// Floating-point register F9, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F9: u32, + /// Floating-point register F10, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F10: u32, + /// Floating-point register F11, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F11: u32, + /// Floating-point register F12, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F12: u32, + /// Floating-point register F13, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F13: u32, + /// Floating-point register F14, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F14: u32, + /// Floating-point register F15, available if the `print-float-registers` + /// feature is enabled. #[cfg(feature = "print-float-registers")] pub F15: u32, } diff --git a/esp-hal/src/dma/mod.rs b/esp-hal/src/dma/mod.rs index 3af076e8e23..1c174166402 100644 --- a/esp-hal/src/dma/mod.rs +++ b/esp-hal/src/dma/mod.rs @@ -523,17 +523,26 @@ pub enum DmaError { #[cfg(gdma)] #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[allow(missing_docs)] pub enum DmaPriority { + /// The lowest priority level (Priority 0). Priority0 = 0, + /// Priority level 1. Priority1 = 1, + /// Priority level 2. Priority2 = 2, + /// Priority level 3. Priority3 = 3, + /// Priority level 4. Priority4 = 4, + /// Priority level 5. Priority5 = 5, + /// Priority level 6. Priority6 = 6, + /// Priority level 7. Priority7 = 7, + /// Priority level 8. Priority8 = 8, + /// The highest priority level (Priority 9). Priority9 = 9, } @@ -542,8 +551,8 @@ pub enum DmaPriority { #[cfg(pdma)] #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[allow(missing_docs)] pub enum DmaPriority { + /// The lowest priority level (Priority 0). Priority0 = 0, } @@ -860,10 +869,12 @@ impl DescriptorChain { /// Block size for transfers to/from psram #[derive(Copy, Clone, Debug, PartialEq)] -#[allow(missing_docs)] pub enum DmaExtMemBKSize { + /// External memory block size of 16 bytes. Size16 = 0, + /// External memory block size of 32 bytes. Size32 = 1, + /// External memory block size of 64 bytes. Size64 = 2, } diff --git a/esp-hal/src/ecc.rs b/esp-hal/src/ecc.rs index e094deb2bf9..10d0a17fac5 100644 --- a/esp-hal/src/ecc.rs +++ b/esp-hal/src/ecc.rs @@ -25,8 +25,6 @@ //! //! [ECC]: https://github.com/esp-rs/esp-hal/blob/main/hil-test/tests/ecc.rs -#![allow(missing_docs)] // TODO: Remove when able - use core::marker::PhantomData; use crate::{ @@ -55,30 +53,47 @@ pub enum Error { PointNotOnSelectedCurve, } +/// Represents supported elliptic curves for cryptographic operations. pub enum EllipticCurve { + /// The P-192 elliptic curve, a 192-bit curve. P192 = 0, + /// The P-256 elliptic curve. a 256-bit curve. P256 = 1, } #[derive(Clone)] +/// Represents the operational modes for elliptic curve or modular arithmetic +/// computations. pub enum WorkMode { + /// Point multiplication mode. PointMultiMode = 0, #[cfg(esp32c2)] + /// Division mode. DivisionMode = 1, + /// Point verification mode. PointVerif = 2, + /// Point verification and multiplication mode. PointVerifMulti = 3, + /// Jacobian point multiplication mode. JacobianPointMulti = 4, #[cfg(esp32h2)] + /// Point addition mode. PointAdd = 5, + /// Jacobian point verification mode. JacobianPointVerif = 6, + /// Point verification and multiplication in Jacobian coordinates. PointVerifJacobianMulti = 7, #[cfg(esp32h2)] + /// Modular addition mode. ModAdd = 8, #[cfg(esp32h2)] + /// Modular subtraction mode. ModSub = 9, #[cfg(esp32h2)] + /// Modular multiplication mode. ModMulti = 10, #[cfg(esp32h2)] + /// Modular division mode. ModDiv = 11, } @@ -111,6 +126,7 @@ impl<'d> InterruptConfigurable for Ecc<'d, crate::Blocking> { } impl<'d, DM: crate::Mode> Ecc<'d, DM> { + /// Resets the ECC peripheral. pub fn reset(&mut self) { self.ecc.mult_conf().reset() } diff --git a/esp-hal/src/etm.rs b/esp-hal/src/etm.rs index 2b016fa456f..1e8322c1852 100644 --- a/esp-hal/src/etm.rs +++ b/esp-hal/src/etm.rs @@ -61,8 +61,6 @@ //! # } //! ``` -#![allow(missing_docs)] // TODO: Remove when able - use crate::{ peripheral::{Peripheral, PeripheralRef}, system::PeripheralClockControl, @@ -144,10 +142,14 @@ macro_rules! create_etm { /// Provides access to all the [EtmChannel] pub struct Etm<'d> { _peripheral: PeripheralRef<'d, crate::peripherals::SOC_ETM>, - $(pub [< channel $num >]: EtmChannel<$num>,)+ + $( + /// An individual ETM channel, identified by its index number. + pub [< channel $num >]: EtmChannel<$num>, + )+ } impl<'d> Etm<'d> { + /// Creates a new `Etm` instance. pub fn new(peripheral: impl Peripheral

+ 'd) -> Self { crate::into_ref!(peripheral); diff --git a/esp-hal/src/gpio/etm.rs b/esp-hal/src/gpio/etm.rs index 2c99f21d8ed..7cfe6d8b6ab 100644 --- a/esp-hal/src/gpio/etm.rs +++ b/esp-hal/src/gpio/etm.rs @@ -60,24 +60,39 @@ use crate::{ /// All the GPIO ETM channels #[non_exhaustive] -#[allow(missing_docs)] pub struct GpioEtmChannels<'d> { _gpio_sd: PeripheralRef<'d, crate::peripherals::GPIO_SD>, + /// Task channel 0 for triggering GPIO tasks. pub channel0_task: GpioEtmTaskChannel<0>, + /// Event channel 0 for handling GPIO events. pub channel0_event: GpioEtmEventChannel<0>, + /// Task channel 1 for triggering GPIO tasks. pub channel1_task: GpioEtmTaskChannel<1>, + /// Event channel 1 for handling GPIO events. pub channel1_event: GpioEtmEventChannel<1>, + /// Task channel 2 for triggering GPIO tasks. pub channel2_task: GpioEtmTaskChannel<2>, + /// Event channel 2 for handling GPIO events. pub channel2_event: GpioEtmEventChannel<2>, + /// Task channel 3 for triggering GPIO tasks. pub channel3_task: GpioEtmTaskChannel<3>, + /// Event channel 3 for handling GPIO events. pub channel3_event: GpioEtmEventChannel<3>, + /// Task channel 4 for triggering GPIO tasks. pub channel4_task: GpioEtmTaskChannel<4>, + /// Event channel 4 for handling GPIO events. pub channel4_event: GpioEtmEventChannel<4>, + /// Task channel 5 for triggering GPIO tasks. pub channel5_task: GpioEtmTaskChannel<5>, + /// Event channel 5 for handling GPIO events. pub channel5_event: GpioEtmEventChannel<5>, + /// Task channel 6 for triggering GPIO tasks. pub channel6_task: GpioEtmTaskChannel<6>, + /// Event channel 6 for handling GPIO events. pub channel6_event: GpioEtmEventChannel<6>, + /// Task channel 7 for triggering GPIO tasks. pub channel7_task: GpioEtmTaskChannel<7>, + /// Event channel 7 for handling GPIO events. pub channel7_event: GpioEtmEventChannel<7>, } diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index 14465ea4a93..11a363b65dc 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -170,31 +170,46 @@ pub struct RtcOutput; pub struct Analog; /// Drive strength (values are approximates) -#[allow(missing_docs)] pub enum DriveStrength { + /// Drive strength of approximately 5mA. I5mA = 0, + /// Drive strength of approximately 10mA. I10mA = 1, + /// Drive strength of approximately 20mA. I20mA = 2, + /// Drive strength of approximately 40mA. I40mA = 3, } /// Alternate functions +/// +/// GPIO pins can be configured for various functions, such as GPIO +/// or being directly connected to a peripheral's signal like UART, SPI, etc. +/// The `AlternateFunction` enum allows to select one of several functions that +/// a pin can perform, rather than using it as a general-purpose input or +/// output. #[derive(PartialEq)] -#[allow(missing_docs)] pub enum AlternateFunction { + /// Alternate function 0. Function0 = 0, + /// Alternate function 1. Function1 = 1, + /// Alternate function 2. Function2 = 2, + /// Alternate function 3. Function3 = 3, + /// Alternate function 4. Function4 = 4, + /// Alternate function 5. Function5 = 5, } /// RTC function #[derive(PartialEq)] -#[allow(missing_docs)] pub enum RtcFunction { + /// RTC mode. Rtc = 0, + /// Digital mode. Digital = 1, } @@ -1390,9 +1405,9 @@ macro_rules! gpio { )+ /// Pins available on this chip - #[allow(missing_docs)] pub struct Pins { $( + /// GPIO pin number `$gpionum`. pub [< gpio $gpionum >] : GpioPin<$gpionum>, )+ } diff --git a/esp-hal/src/hmac.rs b/esp-hal/src/hmac.rs index 200690e6e34..e7709972b50 100644 --- a/esp-hal/src/hmac.rs +++ b/esp-hal/src/hmac.rs @@ -34,8 +34,6 @@ //! //! [HMAC]: https://github.com/esp-rs/esp-hal/blob/main/examples/src/bin/hmac.rs -#![allow(missing_docs)] // TODO: Remove when able - use core::convert::Infallible; use crate::{ @@ -45,6 +43,9 @@ use crate::{ system::{Peripheral as PeripheralEnable, PeripheralClockControl}, }; +/// Provides an interface for interacting with the HMAC hardware peripheral. +/// It allows users to compute HMACs for cryptographic purposes, ensuring data +/// integrity and authenticity. pub struct Hmac<'d> { hmac: PeripheralRef<'d, HMAC>, alignment_helper: AlignmentHelper, @@ -79,12 +80,19 @@ pub enum HmacPurpose { #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +/// Represents the key identifiers for the HMAC peripheral. pub enum KeyId { + /// Key 0. Key0 = 0, + /// Key 1. Key1 = 1, + /// Key 2. Key2 = 2, + /// Key 3. Key3 = 3, + /// Key 4. Key4 = 4, + /// Key 5. Key5 = 5, } @@ -95,6 +103,7 @@ enum NextCommand { } impl<'d> Hmac<'d> { + /// Creates a new instance of the HMAC peripheral. pub fn new(hmac: impl Peripheral

+ 'd) -> Self { crate::into_ref!(hmac); @@ -155,6 +164,7 @@ impl<'d> Hmac<'d> { Ok(remaining) } + /// Finalizes the HMAC computation and retrieves the resulting hash output. pub fn finalize(&mut self, output: &mut [u8]) -> nb::Result<(), Infallible> { if self.is_busy() { return Err(nb::Error::WouldBlock); diff --git a/esp-hal/src/i2c.rs b/esp-hal/src/i2c.rs index a2274b0b328..b4c72604fea 100644 --- a/esp-hal/src/i2c.rs +++ b/esp-hal/src/i2c.rs @@ -69,8 +69,6 @@ //! # } //! ``` -#![allow(missing_docs)] // TODO: Remove when able - use core::marker::PhantomData; use fugit::HertzU32; @@ -100,11 +98,17 @@ const MAX_ITERATIONS: u32 = 1_000_000; #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { + /// The transmission exceeded the FIFO size. ExceedingFifo, + /// The acknowledgment check failed. AckCheckFailed, + /// A timeout occurred during transmission. TimeOut, + /// The arbitration for the bus was lost. ArbitrationLost, + /// The execution of the I2C command was incomplete. ExecIncomplete, + /// The number of commands issued exceeded the limit. CommandNrExceeded, } @@ -1010,19 +1014,29 @@ mod asynch { /// I2C Peripheral Instance pub trait Instance: crate::private::Sealed { + /// The identifier number for this I2C instance. const I2C_NUMBER: usize; + /// Returns the interrupt associated with this I2C peripheral. fn interrupt() -> crate::peripherals::Interrupt; + /// Returns the SCL output signal for this I2C peripheral. fn scl_output_signal(&self) -> OutputSignal; + /// Returns the SCL input signal for this I2C peripheral. fn scl_input_signal(&self) -> InputSignal; + /// Returns the SDA output signal for this I2C peripheral. fn sda_output_signal(&self) -> OutputSignal; + /// Returns the SDA input signal for this I2C peripheral. fn sda_input_signal(&self) -> InputSignal; + /// Returns a reference to the register block of the I2C peripheral. fn register_block(&self) -> &RegisterBlock; + /// Returns the I2C peripheral's index number. fn i2c_number(&self) -> usize; + /// Configures the I2C peripheral with the specified frequency, clocks, and + /// optional timeout. fn setup(&mut self, frequency: HertzU32, clocks: &Clocks<'_>, timeout: Option) { self.register_block().ctr().modify(|_, w| unsafe { // Clear register @@ -1339,6 +1353,7 @@ pub trait Instance: crate::private::Sealed { } #[allow(clippy::too_many_arguments, unused)] + /// Configures the clock and timing parameters for the I2C peripheral. fn configure_clock( &mut self, sclk_div: u32, @@ -1445,6 +1460,7 @@ pub trait Instance: crate::private::Sealed { } } + /// Configures the I2C peripheral for a write operation. fn setup_write<'a, I>(&self, addr: u8, bytes: &[u8], cmd_iterator: &mut I) -> Result<(), Error> where I: Iterator, @@ -1475,6 +1491,7 @@ pub trait Instance: crate::private::Sealed { Ok(()) } + /// Configures the I2C peripheral for a read operation. fn setup_read<'a, I>( &self, addr: u8, @@ -1528,6 +1545,7 @@ pub trait Instance: crate::private::Sealed { } #[cfg(not(any(esp32, esp32s2)))] + /// Reads all bytes from the RX FIFO. fn read_all_from_fifo(&self, buffer: &mut [u8]) -> Result<(), Error> { // Read bytes from FIFO // FIXME: Handle case where less data has been provided by the slave than @@ -1549,6 +1567,7 @@ pub trait Instance: crate::private::Sealed { } #[cfg(any(esp32, esp32s2))] + /// Reads all bytes from the RX FIFO. fn read_all_from_fifo(&self, buffer: &mut [u8]) -> Result<(), Error> { // on ESP32/ESP32-S2 we currently don't support I2C transactions larger than the // FIFO apparently it would be possible by using non-fifo mode @@ -1573,12 +1592,14 @@ pub trait Instance: crate::private::Sealed { Ok(()) } + /// Clears all pending interrupts for the I2C peripheral. fn clear_all_interrupts(&self) { self.register_block() .int_clr() .write(|w| unsafe { w.bits(I2C_LL_INTR_MASK) }); } + /// Waits for the completion of an I2C transaction. fn wait_for_completion(&self, end_only: bool) -> Result<(), Error> { let mut tout = MAX_ITERATIONS; loop { @@ -1604,6 +1625,7 @@ pub trait Instance: crate::private::Sealed { Ok(()) } + /// Checks whether all I2C commands have completed execution. fn check_all_commands_done(&self) -> Result<(), Error> { // NOTE: on esp32 executing the end command generates the end_detect interrupt // but does not seem to clear the done bit! So we don't check the done @@ -1618,6 +1640,14 @@ pub trait Instance: crate::private::Sealed { Ok(()) } + + /// Checks for I2C transmission errors and handles them. + /// + /// This function inspects specific I2C-related interrupts to detect errors + /// during communication, such as timeouts, failed acknowledgments, or + /// arbitration loss. If an error is detected, the function handles it + /// by resetting the I2C peripheral to clear the error condition and then + /// returns an appropriate error. fn check_errors(&self) -> Result<(), Error> { let interrupts = self.register_block().int_raw().read(); @@ -1658,6 +1688,15 @@ pub trait Instance: crate::private::Sealed { Ok(()) } + /// Updates the configuration of the I2C peripheral. + /// + /// This function ensures that the configuration values, such as clock + /// settings, SDA/SCL filtering, timeouts, and other operational + /// parameters, which are configured in other functions, are properly + /// propagated to the I2C hardware. This step is necessary to synchronize + /// the software-configured settings with the peripheral's internal + /// registers, ensuring that the hardware behaves according to the + /// current configuration. fn update_config(&self) { // Ensure that the configuration of the peripheral is correctly propagated // (only necessary for C2, C3, C6, H2 and S3 variant) @@ -1667,6 +1706,7 @@ pub trait Instance: crate::private::Sealed { .modify(|_, w| w.conf_upgate().set_bit()); } + /// Starts an I2C transmission. fn start_transmission(&self) { // Start transmission self.register_block() @@ -1675,6 +1715,7 @@ pub trait Instance: crate::private::Sealed { } #[cfg(not(any(esp32, esp32s2)))] + /// Fills the TX FIFO with data from the provided slice. fn fill_tx_fifo(&self, bytes: &[u8]) -> usize { let mut index = 0; while index < bytes.len() @@ -1704,6 +1745,8 @@ pub trait Instance: crate::private::Sealed { } #[cfg(not(any(esp32, esp32s2)))] + /// Writes remaining data from byte slice to the TX FIFO from the specified + /// index. fn write_remaining_tx_fifo(&self, start_index: usize, bytes: &[u8]) -> Result<(), Error> { let mut index = start_index; loop { @@ -1743,6 +1786,7 @@ pub trait Instance: crate::private::Sealed { } #[cfg(any(esp32, esp32s2))] + /// Fills the TX FIFO with data from the provided slice. fn fill_tx_fifo(&self, bytes: &[u8]) -> usize { // on ESP32/ESP32-S2 we currently don't support I2C transactions larger than the // FIFO apparently it would be possible by using non-fifo mode @@ -1760,6 +1804,8 @@ pub trait Instance: crate::private::Sealed { } #[cfg(any(esp32, esp32s2))] + /// Writes remaining data from byte slice to the TX FIFO from the specified + /// index. fn write_remaining_tx_fifo(&self, start_index: usize, bytes: &[u8]) -> Result<(), Error> { // on ESP32/ESP32-S2 we currently don't support I2C transactions larger than the // FIFO apparently it would be possible by using non-fifo mode @@ -1838,6 +1884,7 @@ pub trait Instance: crate::private::Sealed { .write(|w| w.rxfifo_full().clear_bit_by_one()); } + /// Executes an I2C write operation. fn write_operation<'a, I>( &self, address: u8, @@ -1870,6 +1917,7 @@ pub trait Instance: crate::private::Sealed { Ok(()) } + /// Executes an I2C read operation. fn read_operation<'a, I>( &self, address: u8, @@ -1964,6 +2012,7 @@ pub trait Instance: crate::private::Sealed { } } +/// Adds a command to the I2C command sequence. fn add_cmd<'a, I>(cmd_iterator: &mut I, command: Command) -> Result<(), Error> where I: Iterator, @@ -2139,12 +2188,19 @@ pub mod lp_i2c { #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { + /// The transmission exceeded the FIFO size. ExceedingFifo, + /// The acknowledgment check failed. AckCheckFailed, + /// A timeout occurred during transmission. TimeOut, + /// The arbitration for the bus was lost. ArbitrationLost, + /// The execution of the I2C command was incomplete. ExecIncomplete, + /// The number of commands issued exceeded the limit. CommandNrExceeded, + /// The response received from the I2C device was invalid. InvalidResponse, } @@ -2197,11 +2253,13 @@ pub mod lp_i2c { // Configure LP_EXT_I2C_CK_EN high to enable the clock source of I2C_SCLK. // Adjust the timing registers accordingly when the clock frequency changes. + /// Represents a Low-Power I2C peripheral. pub struct LpI2c { i2c: LP_I2C0, } impl LpI2c { + /// Creates a new instance of the `LpI2c` peripheral. pub fn new( i2c: LP_I2C0, _sda: LowPowerOutputOpenDrain<'_, 6>, @@ -2444,6 +2502,7 @@ pub mod lp_i2c { self.i2c.ctr().modify(|_, w| w.conf_upgate().set_bit()); } + /// Resets the transmit and receive FIFO buffers. fn reset_fifo(&self) { self.i2c .fifo_conf() diff --git a/esp-hal/src/i2s.rs b/esp-hal/src/i2s.rs index d39c3a0c778..08f0f3a5b32 100644 --- a/esp-hal/src/i2s.rs +++ b/esp-hal/src/i2s.rs @@ -80,8 +80,6 @@ //! - Only master mode is supported. //! - Only TDM Philips standard is supported. -#![allow(missing_docs)] // TODO: Remove when able - use core::marker::PhantomData; use enumset::{EnumSet, EnumSetType}; @@ -121,12 +119,17 @@ use crate::{ }; #[derive(EnumSetType)] +/// Represents the various interrupt types for the I2S peripheral. pub enum I2sInterrupt { + /// Transmit buffer hung, indicating a stall in data transmission. TxHung, + /// Receive buffer hung, indicating a stall in data reception. RxHung, #[cfg(not(any(esp32, esp32s2)))] + /// Transmission of data is complete. TxDone, #[cfg(not(any(esp32, esp32s2)))] + /// Reception of data is complete. RxDone, } @@ -150,8 +153,11 @@ impl AcceptedWord for i32 {} #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { + /// An unspecified or unknown error occurred during an I2S operation. Unknown, + /// A DMA-related error occurred during I2S operations. DmaError(DmaError), + /// An illegal or invalid argument was passed to an I2S function or method. IllegalArgument, } @@ -165,6 +171,7 @@ impl From for Error { #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Standard { + /// The Philips I2S standard. Philips, // Tdm, // Pdm, @@ -175,12 +182,19 @@ pub enum Standard { #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg(not(any(esp32, esp32s2)))] pub enum DataFormat { + /// 32-bit data width and 32-bit channel width. Data32Channel32, + /// 32-bit data width and 24-bit channel width. Data32Channel24, + /// 32-bit data width and 16-bit channel width. Data32Channel16, + /// 32-bit data width and 8-bit channel width. Data32Channel8, + /// 16-bit data width and 16-bit channel width. Data16Channel16, + /// 16-bit data width and 8-bit channel width. Data16Channel8, + /// 8-bit data width and 8-bit channel width. Data8Channel8, } @@ -189,12 +203,15 @@ pub enum DataFormat { #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg(any(esp32, esp32s2))] pub enum DataFormat { + /// 32-bit data width and 32-bit channel width. Data32Channel32, + /// 16-bit data width and 16-bit channel width. Data16Channel16, } #[cfg(not(any(esp32, esp32s2)))] impl DataFormat { + /// Returns the number of data bits for the selected data format. pub fn data_bits(&self) -> u8 { match self { DataFormat::Data32Channel32 => 32, @@ -207,6 +224,7 @@ impl DataFormat { } } + /// Returns the number of channel bits for the selected data format. pub fn channel_bits(&self) -> u8 { match self { DataFormat::Data32Channel32 => 32, @@ -222,6 +240,7 @@ impl DataFormat { #[cfg(any(esp32, esp32s2))] impl DataFormat { + /// Returns the number of data bits for the selected data format. pub fn data_bits(&self) -> u8 { match self { DataFormat::Data32Channel32 => 32, @@ -229,6 +248,7 @@ impl DataFormat { } } + /// Returns the number of channel bits for the selected data format. pub fn channel_bits(&self) -> u8 { match self { DataFormat::Data32Channel32 => 32, @@ -239,6 +259,7 @@ impl DataFormat { /// Blocking I2s Write pub trait I2sWrite { + /// Writes a slice of data to the I2S peripheral. fn write(&mut self, words: &[W]) -> Result<(), Error>; } @@ -269,6 +290,8 @@ where /// Blocking I2S Read pub trait I2sRead { + /// Reads a slice of data from the I2S peripheral and stores it in the + /// provided buffer. fn read(&mut self, words: &mut [W]) -> Result<(), Error>; } @@ -305,7 +328,9 @@ where CH: DmaChannel, DmaMode: Mode, { + /// Handles the transmission (TX) side of the I2S peripheral. pub i2s_tx: TxCreator<'d, I, CH, DmaMode>, + /// Handles the reception (RX) side of the I2S peripheral. pub i2s_rx: RxCreator<'d, I, CH, DmaMode>, phantom: PhantomData, } @@ -481,6 +506,7 @@ where ) } + /// Configures the I2S peripheral to use a master clock (MCLK) output pin. pub fn with_mclk(self, pin: impl Peripheral

+ 'd) -> Self { into_ref!(pin); pin.set_to_push_pull_output(crate::private::Internal); @@ -850,6 +876,7 @@ where } } +/// Provides an abstraction for accessing the I2S peripheral registers. pub trait RegisterAccess: RegisterAccessPrivate {} mod private { @@ -2153,6 +2180,7 @@ mod private { } } +/// Async functionality #[cfg(feature = "async")] pub mod asynch { use super::{Error, I2sRx, I2sTx, RegisterAccess}; diff --git a/esp-hal/src/interrupt/riscv.rs b/esp-hal/src/interrupt/riscv.rs index 19e062ef5f8..5770ede1e86 100644 --- a/esp-hal/src/interrupt/riscv.rs +++ b/esp-hal/src/interrupt/riscv.rs @@ -53,38 +53,68 @@ pub enum InterruptKind { #[repr(u32)] #[derive(Debug, Copy, Clone)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[allow(missing_docs)] pub enum CpuInterrupt { + /// Interrupt number 1. Interrupt1 = 1, + /// Interrupt number 2. Interrupt2, + /// Interrupt number 3. Interrupt3, + /// Interrupt number 4. Interrupt4, + /// Interrupt number 5. Interrupt5, + /// Interrupt number 6. Interrupt6, + /// Interrupt number 7. Interrupt7, + /// Interrupt number 8. Interrupt8, + /// Interrupt number 9. Interrupt9, + /// Interrupt number 10. Interrupt10, + /// Interrupt number 11. Interrupt11, + /// Interrupt number 12. Interrupt12, + /// Interrupt number 13. Interrupt13, + /// Interrupt number 14. Interrupt14, + /// Interrupt number 15. Interrupt15, + /// Interrupt number 16. Interrupt16, + /// Interrupt number 17. Interrupt17, + /// Interrupt number 18. Interrupt18, + /// Interrupt number 19. Interrupt19, + /// Interrupt number 20. Interrupt20, + /// Interrupt number 21. Interrupt21, + /// Interrupt number 22. Interrupt22, + /// Interrupt number 23. Interrupt23, + /// Interrupt number 24. Interrupt24, + /// Interrupt number 25. Interrupt25, + /// Interrupt number 26. Interrupt26, + /// Interrupt number 27. Interrupt27, + /// Interrupt number 28. Interrupt28, + /// Interrupt number 29. Interrupt29, + /// Interrupt number 30. Interrupt30, + /// Interrupt number 31. Interrupt31, } @@ -92,30 +122,45 @@ pub enum CpuInterrupt { #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(u8)] -#[allow(missing_docs)] pub enum Priority { + /// No priority. None = 0, + /// Priority level 1. Priority1, + /// Priority level 2. Priority2, + /// Priority level 3. Priority3, + /// Priority level 4. Priority4, + /// Priority level 5. Priority5, + /// Priority level 6. Priority6, + /// Priority level 7. Priority7, + /// Priority level 8. #[cfg(not(clic))] Priority8, + /// Priority level 9. #[cfg(not(clic))] Priority9, + /// Priority level 10. #[cfg(not(clic))] Priority10, + /// Priority level 11. #[cfg(not(clic))] Priority11, + /// Priority level 12. #[cfg(not(clic))] Priority12, + /// Priority level 13. #[cfg(not(clic))] Priority13, + /// Priority level 14. #[cfg(not(clic))] Priority14, + /// Priority level 15. #[cfg(not(clic))] Priority15, } diff --git a/esp-hal/src/interrupt/xtensa.rs b/esp-hal/src/interrupt/xtensa.rs index 04dc1789797..798837d52bc 100644 --- a/esp-hal/src/interrupt/xtensa.rs +++ b/esp-hal/src/interrupt/xtensa.rs @@ -27,39 +27,70 @@ pub enum Error { #[derive(Debug, Copy, Clone)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(u32)] -#[allow(missing_docs)] pub enum CpuInterrupt { + /// Level-triggered interrupt with priority 1. Interrupt0LevelPriority1 = 0, + /// Level-triggered interrupt with priority 1. Interrupt1LevelPriority1, + /// Level-triggered interrupt with priority 1. Interrupt2LevelPriority1, + /// Level-triggered interrupt with priority 1. Interrupt3LevelPriority1, + /// Level-triggered interrupt with priority 1. Interrupt4LevelPriority1, + /// Level-triggered interrupt with priority 1. Interrupt5LevelPriority1, + /// Timer 0 interrupt with priority 1. Interrupt6Timer0Priority1, + /// Software-triggered interrupt with priority 1. Interrupt7SoftwarePriority1, + /// Level-triggered interrupt with priority 1. Interrupt8LevelPriority1, + /// Level-triggered interrupt with priority 1. Interrupt9LevelPriority1, + /// Edge-triggered interrupt with priority 1. Interrupt10EdgePriority1, + /// Profiling-related interrupt with priority 3. Interrupt11ProfilingPriority3, + /// Level-triggered interrupt with priority 1. Interrupt12LevelPriority1, + /// Level-triggered interrupt with priority 1. Interrupt13LevelPriority1, + /// Non-maskable interrupt (NMI) with priority 7. Interrupt14NmiPriority7, + /// Timer 1 interrupt with priority 3. Interrupt15Timer1Priority3, + /// Timer 2 interrupt with priority 5. Interrupt16Timer2Priority5, + /// Level-triggered interrupt with priority 1. Interrupt17LevelPriority1, + /// Level-triggered interrupt with priority 1. Interrupt18LevelPriority1, + /// Level-triggered interrupt with priority 2. Interrupt19LevelPriority2, + /// Level-triggered interrupt with priority 2. Interrupt20LevelPriority2, + /// Level-triggered interrupt with priority 2. Interrupt21LevelPriority2, + /// Edge-triggered interrupt with priority 3. Interrupt22EdgePriority3, + /// Level-triggered interrupt with priority 3. Interrupt23LevelPriority3, + /// Level-triggered interrupt with priority 4. Interrupt24LevelPriority4, + /// Level-triggered interrupt with priority 4. Interrupt25LevelPriority4, + /// Level-triggered interrupt with priority 5. Interrupt26LevelPriority5, + /// Level-triggered interrupt with priority 3. Interrupt27LevelPriority3, + /// Edge-triggered interrupt with priority 4. Interrupt28EdgePriority4, + /// Software-triggered interrupt with priority 3. Interrupt29SoftwarePriority3, + /// Edge-triggered interrupt with priority 4. Interrupt30EdgePriority4, + /// Edge-triggered interrupt with priority 5. Interrupt31EdgePriority5, } @@ -267,11 +298,14 @@ mod vectored { #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(u8)] - #[allow(missing_docs)] pub enum Priority { + /// No priority. None = 0, + /// Priority level 1. Priority1, + /// Priority level 2. Priority2, + /// Priority level 3. Priority3, } diff --git a/esp-hal/src/lcd_cam/cam.rs b/esp-hal/src/lcd_cam/cam.rs index 111016d9110..a37a6f40fe3 100644 --- a/esp-hal/src/lcd_cam/cam.rs +++ b/esp-hal/src/lcd_cam/cam.rs @@ -102,20 +102,31 @@ pub enum EofMode { #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum VsyncFilterThreshold { + /// Requires 1 valid VSYNC pulse to trigger synchronization. One, + /// Requires 2 valid VSYNC pulse to trigger synchronization. Two, + /// Requires 3 valid VSYNC pulse to trigger synchronization. Three, + /// Requires 4 valid VSYNC pulse to trigger synchronization. Four, + /// Requires 5 valid VSYNC pulse to trigger synchronization. Five, + /// Requires 6 valid VSYNC pulse to trigger synchronization. Six, + /// Requires 7 valid VSYNC pulse to trigger synchronization. Seven, + /// Requires 8 valid VSYNC pulse to trigger synchronization. Eight, } +/// Represents the camera interface. pub struct Cam<'d> { + /// The LCD_CAM peripheral reference for managing the camera functionality. pub(crate) lcd_cam: PeripheralRef<'d, LCD_CAM>, } +/// Represents the camera interface with DMA support. pub struct Camera<'d, CH: DmaChannel> { lcd_cam: PeripheralRef<'d, LCD_CAM>, rx_channel: ChannelRx<'d, CH>, @@ -128,6 +139,7 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> where CH::P: LcdCamPeripheral, { + /// Creates a new `Camera` instance with DMA support. pub fn new( cam: Cam<'d>, mut channel: ChannelRx<'d, CH>, @@ -244,6 +256,7 @@ impl<'d, CH: DmaChannel> DmaSupportRx for Camera<'d, CH> { } impl<'d, CH: DmaChannel> Camera<'d, CH> { + /// Configures the byte order for the camera data. pub fn set_byte_order(&mut self, byte_order: ByteOrder) -> &mut Self { self.lcd_cam .cam_ctrl() @@ -251,6 +264,7 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> { self } + /// Configures the bit order for the camera data. pub fn set_bit_order(&mut self, bit_order: BitOrder) -> &mut Self { self.lcd_cam .cam_ctrl() @@ -258,6 +272,7 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> { self } + /// Configures the VSYNC filter threshold. pub fn set_vsync_filter(&mut self, threshold: Option) -> &mut Self { if let Some(threshold) = threshold { let value = match threshold { @@ -285,6 +300,7 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> { self } + /// Configures the master clock (MCLK) pin for the camera interface. pub fn with_master_clock(self, mclk: impl Peripheral

+ 'd) -> Self { crate::into_ref!(mclk); mclk.set_to_push_pull_output(crate::private::Internal); @@ -292,6 +308,7 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> { self } + /// Configures the pixel clock (PCLK) pin for the camera interface. pub fn with_pixel_clock(self, pclk: impl Peripheral

+ 'd) -> Self { crate::into_ref!(pclk); @@ -301,6 +318,8 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> { self } + /// Configures the control pins for the camera interface (VSYNC and + /// HENABLE). pub fn with_ctrl_pins( self, vsync: impl Peripheral

+ 'd, @@ -321,6 +340,8 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> { self } + /// Configures the control pins for the camera interface (VSYNC, HSYNC, and + /// HENABLE) with DE (data enable). pub fn with_ctrl_pins_and_de( self, vsync: impl Peripheral

+ 'd, @@ -388,6 +409,7 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> { self.rx_channel.start_transfer() } + /// Starts a DMA transfer to receive data from the camera peripheral. pub fn read_dma<'t, RXBUF: WriteBuffer>( &'t mut self, buf: &'t mut RXBUF, @@ -400,6 +422,8 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> { Ok(DmaTransferRx::new(self)) } + /// Starts a circular DMA transfer to receive data from the camera + /// peripheral. pub fn read_dma_circular<'t, RXBUF: WriteBuffer>( &'t mut self, buf: &'t mut RXBUF, @@ -413,12 +437,16 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> { } } +/// Represents an 8-bit wide camera data bus. +/// Is used to configure the camera interface to receive 8-bit data. pub struct RxEightBits { _pins: (), } impl RxEightBits { #[allow(clippy::too_many_arguments)] + /// Creates a new instance of `RxEightBits`, configuring the specified pins + /// as the 8-bit data bus. pub fn new<'d, P0, P1, P2, P3, P4, P5, P6, P7>( pin_0: impl Peripheral

+ 'd, pin_1: impl Peripheral

+ 'd, @@ -473,12 +501,16 @@ impl RxPins for RxEightBits { const BUS_WIDTH: usize = 1; } +/// Represents a 16-bit wide camera data bus. +/// Is used to configure the camera interface to receive 16-bit data. pub struct RxSixteenBits { _pins: (), } impl RxSixteenBits { #[allow(clippy::too_many_arguments)] + /// Creates a new instance of `RxSixteenBits`, configuring the specified + /// pins as the 16-bit data bus. pub fn new<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15>( pin_0: impl Peripheral

+ 'd, pin_1: impl Peripheral

+ 'd, diff --git a/esp-hal/src/lcd_cam/lcd/i8080.rs b/esp-hal/src/lcd_cam/lcd/i8080.rs index 288d5148410..0a67505bda9 100644 --- a/esp-hal/src/lcd_cam/lcd/i8080.rs +++ b/esp-hal/src/lcd_cam/lcd/i8080.rs @@ -91,6 +91,7 @@ use crate::{ Mode, }; +/// Represents the I8080 LCD interface. pub struct I8080<'d, CH: DmaChannel, P, DM: Mode> { lcd_cam: PeripheralRef<'d, LCD_CAM>, tx_channel: ChannelTx<'d, CH>, @@ -104,6 +105,7 @@ where CH::P: LcdCamPeripheral, P::Word: Into, { + /// Creates a new instance of the I8080 LCD interface. pub fn new( lcd: Lcd<'d, DM>, mut channel: ChannelTx<'d, CH>, @@ -287,6 +289,7 @@ impl<'d, CH: DmaChannel, P: TxPins, DM: Mode> I8080<'d, CH, P, DM> where P::Word: Into, { + /// Configures the byte order for data transmission. pub fn set_byte_order(&mut self, byte_order: ByteOrder) -> &mut Self { let is_inverted = byte_order != ByteOrder::default(); self.lcd_cam.lcd_user().modify(|_, w| { @@ -299,6 +302,7 @@ where self } + /// Configures the bit order for data transmission. pub fn set_bit_order(&mut self, bit_order: BitOrder) -> &mut Self { self.lcd_cam .lcd_user() @@ -306,6 +310,7 @@ where self } + /// Associates a CS pin with the I8080 interface. pub fn with_cs(self, cs: impl Peripheral

+ 'd) -> Self { crate::into_ref!(cs); cs.set_to_push_pull_output(crate::private::Internal); @@ -314,6 +319,7 @@ where self } + /// Configures the control pins for the I8080 interface. pub fn with_ctrl_pins( self, dc: impl Peripheral

+ 'd, @@ -331,6 +337,7 @@ where self } + /// Sends a command and data to the LCD using the I8080 interface. pub fn send( &mut self, cmd: impl Into>, @@ -350,6 +357,7 @@ where Ok(()) } + /// Sends a command and data to the LCD using DMA. pub fn send_dma<'t, TXBUF>( &'t mut self, cmd: impl Into>, @@ -374,6 +382,7 @@ impl<'d, CH: DmaChannel, P: TxPins> I8080<'d, CH, P, crate::Async> where P::Word: Into, { + /// Asynchronously sends a command and data to the LCD using DMA. pub async fn send_dma_async<'t, TXBUF>( &'t mut self, cmd: impl Into>, @@ -517,7 +526,9 @@ impl<'d, CH: DmaChannel, P, DM: Mode> core::fmt::Debug for I8080<'d, CH, P, DM> #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +/// Configuration settings for the I8080 interface. pub struct Config { + /// Specifies the clock mode, including polarity and phase settings. pub clock_mode: ClockMode, /// Setup cycles expected, must be at least 1. (6 bits) @@ -563,8 +574,11 @@ impl Default for Config { #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Command { + /// Suppresses the command phase. No command is sent. None, + /// Sends a single-word command. One(T), + /// Sends a two-word command. Two(T, T), } @@ -574,6 +588,8 @@ impl From for Command { } } +/// Represents a group of 8 output pins configured for 8-bit parallel data +/// transmission. pub struct TxEightBits<'d, P0, P1, P2, P3, P4, P5, P6, P7> { pin_0: PeripheralRef<'d, P0>, pin_1: PeripheralRef<'d, P1>, @@ -597,6 +613,7 @@ where P7: OutputPin, { #[allow(clippy::too_many_arguments)] + /// Creates a new `TxEightBits` instance with the provided output pins. pub fn new( pin_0: impl Peripheral

+ 'd, pin_1: impl Peripheral

+ 'd, @@ -670,6 +687,8 @@ where } } +/// Represents a group of 16 output pins configured for 16-bit parallel data +/// transmission. pub struct TxSixteenBits<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> { pin_0: PeripheralRef<'d, P0>, pin_1: PeripheralRef<'d, P1>, @@ -710,6 +729,7 @@ where P15: OutputPin, { #[allow(clippy::too_many_arguments)] + /// Creates a new `TxSixteenBits` instance with the provided output pins. pub fn new( pin_0: impl Peripheral

+ 'd, pin_1: impl Peripheral

+ 'd, diff --git a/esp-hal/src/lcd_cam/lcd/mod.rs b/esp-hal/src/lcd_cam/lcd/mod.rs index a1e5dc85153..cf7e8036b02 100644 --- a/esp-hal/src/lcd_cam/lcd/mod.rs +++ b/esp-hal/src/lcd_cam/lcd/mod.rs @@ -14,36 +14,53 @@ use crate::{peripheral::PeripheralRef, peripherals::LCD_CAM}; pub mod i8080; +/// Represents an LCD interface. pub struct Lcd<'d, DM: crate::Mode> { + /// The `LCD_CAM` peripheral reference for managing the LCD functionality. pub(crate) lcd_cam: PeripheralRef<'d, LCD_CAM>, + + /// A marker for the mode of operation (blocking or asynchronous). pub(crate) _mode: core::marker::PhantomData, } #[derive(Debug, Clone, Copy, PartialEq, Default)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +/// Represents the clock mode configuration for the LCD interface. pub struct ClockMode { + /// The polarity of the clock signal (idle high or low). pub polarity: Polarity, + + /// The phase of the clock signal (shift on the rising or falling edge). pub phase: Phase, } #[derive(Debug, Clone, Copy, PartialEq, Default)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +/// Represents the polarity of the clock signal for the LCD interface. pub enum Polarity { + /// The clock signal is low when idle. #[default] IdleLow, + + /// The clock signal is high when idle. IdleHigh, } #[derive(Debug, Clone, Copy, PartialEq, Default)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +/// Represents the phase of the clock signal for the LCD interface. pub enum Phase { + /// Data is shifted on the low (falling) edge of the clock signal. #[default] ShiftLow, + + /// Data is shifted on the high (rising) edge of the clock signal. ShiftHigh, } #[derive(Debug, Clone, Copy, PartialEq, Default)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +/// Represents the delay mode for the LCD signal output. pub enum DelayMode { /// Output without delay. #[default] diff --git a/esp-hal/src/lcd_cam/mod.rs b/esp-hal/src/lcd_cam/mod.rs index 196f81e7646..72c0ef54c9e 100644 --- a/esp-hal/src/lcd_cam/mod.rs +++ b/esp-hal/src/lcd_cam/mod.rs @@ -5,8 +5,6 @@ //! used simultaneously. For more information on these modules, please refer to //! the documentation in their respective modules. -#![allow(missing_docs)] // TODO: Remove when able - pub mod cam; pub mod lcd; @@ -21,12 +19,16 @@ use crate::{ InterruptConfigurable, }; +/// Represents a combined LCD and Camera interface. pub struct LcdCam<'d, DM: crate::Mode> { + /// The LCD interface. pub lcd: Lcd<'d, DM>, + /// The Camera interface. pub cam: Cam<'d>, } impl<'d> LcdCam<'d, crate::Blocking> { + /// Creates a new `LcdCam` instance. pub fn new(lcd_cam: impl Peripheral

+ 'd) -> Self { crate::into_ref!(lcd_cam); @@ -63,6 +65,7 @@ impl<'d> InterruptConfigurable for LcdCam<'d, crate::Blocking> { #[cfg(feature = "async")] impl<'d> LcdCam<'d, crate::Async> { + /// Creates a new `LcdCam` instance for asynchronous operation. pub fn new_async(lcd_cam: impl Peripheral

+ 'd) -> Self { crate::into_ref!(lcd_cam); diff --git a/esp-hal/src/ledc/channel.rs b/esp-hal/src/ledc/channel.rs index 21701ac82ba..aff67d1e6dc 100644 --- a/esp-hal/src/ledc/channel.rs +++ b/esp-hal/src/ledc/channel.rs @@ -48,15 +48,23 @@ pub enum Error { #[derive(PartialEq, Eq, Copy, Clone, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Number { + /// Channel 0 Channel0 = 0, + /// Channel 1 Channel1 = 1, + /// Channel 2 Channel2 = 2, + /// Channel 3 Channel3 = 3, + /// Channel 4 Channel4 = 4, + /// Channel 5 Channel5 = 5, #[cfg(not(any(esp32c2, esp32c3, esp32c6, esp32h2)))] + /// Channel 6 Channel6 = 6, #[cfg(not(any(esp32c2, esp32c3, esp32c6, esp32h2)))] + /// Channel 7 Channel7 = 7, } @@ -66,16 +74,22 @@ pub mod config { #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] + /// Pin configuration for the LEDC channel. pub enum PinConfig { + /// Push-pull pin configuration. PushPull, + /// Open-drain pin configuration. OpenDrain, } /// Channel configuration #[derive(Copy, Clone)] pub struct Config<'a, S: TimerSpeed> { + /// A reference to the timer associated with this channel. pub timer: &'a dyn TimerIFace, + /// The duty cycle percentage (0-100). pub duty_pct: u8, + /// The pin configuration (PushPull or OpenDrain). pub pin_config: PinConfig, } } @@ -108,6 +122,8 @@ pub trait ChannelHW { /// Configure Channel HW except for the duty which is set via /// [`Self::set_duty_hw`]. fn configure_hw(&mut self) -> Result<(), Error>; + /// Configure the hardware for the channel with a specific pin + /// configuration. fn configure_hw_with_pin_config(&mut self, cfg: config::PinConfig) -> Result<(), Error>; /// Set channel duty HW diff --git a/esp-hal/src/ledc/mod.rs b/esp-hal/src/ledc/mod.rs index 006308f3d58..c935daec320 100644 --- a/esp-hal/src/ledc/mod.rs +++ b/esp-hal/src/ledc/mod.rs @@ -60,8 +60,6 @@ //! - Source clock selection is not supported //! - Interrupts are not supported -#![allow(missing_docs)] // TODO: Remove when able - use self::{ channel::Channel, timer::{Timer, TimerSpeed}, @@ -79,6 +77,7 @@ pub mod timer; /// Global slow clock source #[derive(PartialEq, Eq, Copy, Clone, Debug)] pub enum LSGlobalClkSource { + /// APB clock. APBClk, } @@ -96,7 +95,9 @@ pub struct HighSpeed {} /// Used to specify LowSpeed Timer/Channel pub struct LowSpeed {} +/// Trait representing the speed mode of a clock or peripheral. pub trait Speed { + /// Boolean constant indicating whether the speed is high-speed. const IS_HS: bool; } diff --git a/esp-hal/src/ledc/timer.rs b/esp-hal/src/ledc/timer.rs index 5c81489e8c7..dee5876b9b4 100644 --- a/esp-hal/src/ledc/timer.rs +++ b/esp-hal/src/ledc/timer.rs @@ -33,6 +33,7 @@ pub enum Error { #[derive(PartialEq, Eq, Copy, Clone, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum HSClockSource { + /// APB clock. APBClk, // TODO RefTick, } @@ -41,6 +42,7 @@ pub enum HSClockSource { #[derive(PartialEq, Eq, Copy, Clone, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum LSClockSource { + /// APB clock. APBClk, // TODO SLOWClk } @@ -49,9 +51,13 @@ pub enum LSClockSource { #[derive(PartialEq, Eq, Copy, Clone, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Number { + /// Timer 0. Timer0 = 0, + /// Timer 1. Timer1 = 1, + /// Timer 2. Timer2 = 2, + /// Timer 3. Timer3 = 3, } @@ -63,56 +69,82 @@ pub mod config { #[derive(PartialEq, Eq, Copy, Clone, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Duty { + /// 1-bit resolution for duty cycle adjustment. Duty1Bit = 1, + /// 2-bit resolution for duty cycle adjustment. Duty2Bit, + /// 3-bit resolution for duty cycle adjustment. Duty3Bit, + /// 4-bit resolution for duty cycle adjustment. Duty4Bit, + /// 5-bit resolution for duty cycle adjustment. Duty5Bit, + /// 6-bit resolution for duty cycle adjustment. Duty6Bit, + /// 7-bit resolution for duty cycle adjustment. Duty7Bit, + /// 8-bit resolution for duty cycle adjustment. Duty8Bit, + /// 9-bit resolution for duty cycle adjustment. Duty9Bit, + /// 10-bit resolution for duty cycle adjustment. Duty10Bit, + /// 11-bit resolution for duty cycle adjustment. Duty11Bit, + /// 12-bit resolution for duty cycle adjustment. Duty12Bit, + /// 13-bit resolution for duty cycle adjustment. Duty13Bit, + /// 14-bit resolution for duty cycle adjustment. Duty14Bit, #[cfg(esp32)] + /// 15-bit resolution for duty cycle adjustment. Duty15Bit, #[cfg(esp32)] + /// 16-bit resolution for duty cycle adjustment. Duty16Bit, #[cfg(esp32)] + /// 17-bit resolution for duty cycle adjustment. Duty17Bit, #[cfg(esp32)] + /// 18-bit resolution for duty cycle adjustment. Duty18Bit, #[cfg(esp32)] + /// 19-bit resolution for duty cycle adjustment. Duty19Bit, #[cfg(esp32)] + /// 20-bit resolution for duty cycle adjustment. Duty20Bit, } /// Timer configuration #[derive(Copy, Clone)] pub struct Config { + /// The duty cycle resolution. pub duty: Duty, + /// The clock source for the timer. pub clock_source: CS, + /// The frequency of the PWM signal in Hertz. pub frequency: HertzU32, } } /// Trait defining the type of timer source pub trait TimerSpeed: Speed { + /// The type of clock source used by the timer in this speed mode. type ClockSourceType; } /// Timer source type for LowSpeed timers impl TimerSpeed for LowSpeed { + /// The clock source type for low-speed timers. type ClockSourceType = LSClockSource; } #[cfg(esp32)] /// Timer source type for HighSpeed timers impl TimerSpeed for HighSpeed { + /// The clock source type for high-speed timers. type ClockSourceType = HSClockSource; } diff --git a/esp-hal/src/otg_fs.rs b/esp-hal/src/otg_fs.rs index 62132428b69..802de2a37f7 100644 --- a/esp-hal/src/otg_fs.rs +++ b/esp-hal/src/otg_fs.rs @@ -36,8 +36,6 @@ //! ## Implementation State //! - Low-speed (LS) is not supported. -#![allow(missing_docs)] // TODO: Remove when able - pub use esp_synopsys_usb_otg::UsbBus; use esp_synopsys_usb_otg::UsbPeripheral; @@ -49,16 +47,20 @@ use crate::{ }; #[doc(hidden)] +/// Trait representing the USB D+ (data plus) pin. pub trait UsbDp: crate::private::Sealed {} #[doc(hidden)] +/// Trait representing the USB D- (data minus) pin. pub trait UsbDm: crate::private::Sealed {} +/// USB peripheral. pub struct Usb<'d> { _usb0: PeripheralRef<'d, peripherals::USB0>, } impl<'d> Usb<'d> { + /// Creates a new `Usb` instance. pub fn new( usb0: impl Peripheral

+ 'd, _usb_dp: impl Peripheral

+ 'd, @@ -129,7 +131,7 @@ unsafe impl<'d> UsbPeripheral for Usb<'d> { 80_000_000 } } - +/// Async functionality #[cfg(feature = "async")] pub mod asynch { use embassy_usb_driver::{ diff --git a/esp-hal/src/parl_io.rs b/esp-hal/src/parl_io.rs index 309ac6a2254..72cfdd3ddc8 100644 --- a/esp-hal/src/parl_io.rs +++ b/esp-hal/src/parl_io.rs @@ -1096,14 +1096,17 @@ fn internal_clear_interrupts(interrupts: EnumSet) { /// Parallel IO in full duplex mode /// /// Full duplex mode might limit the maximum possible bit width. -#[allow(missing_docs)] pub struct ParlIoFullDuplex<'d, CH, DM> where CH: DmaChannel, CH::P: ParlIoPeripheral, DM: Mode, { + /// The transmitter (TX) channel responsible for handling DMA transfers in + /// the parallel I/O full-duplex operation. pub tx: TxCreatorFullDuplex<'d, CH, DM>, + /// The receiver (RX) channel responsible for handling DMA transfers in the + /// parallel I/O full-duplex operation. pub rx: RxCreatorFullDuplex<'d, CH, DM>, } @@ -1191,13 +1194,14 @@ where } /// Parallel IO in half duplex / TX only mode -#[allow(missing_docs)] pub struct ParlIoTxOnly<'d, CH, DM> where CH: DmaChannel, CH::P: ParlIoPeripheral, DM: Mode, { + /// The transmitter (TX) channel responsible for handling DMA transfers in + /// the parallel I/O operation. pub tx: TxCreator<'d, CH, DM>, } @@ -1279,13 +1283,14 @@ where } /// Parallel IO in half duplex / RX only mode -#[allow(missing_docs)] pub struct ParlIoRxOnly<'d, CH, DM> where CH: DmaChannel, CH::P: ParlIoPeripheral, DM: Mode, { + /// The receiver (RX) channel responsible for handling DMA transfers in the + /// parallel I/O operation. pub rx: RxCreator<'d, CH, DM>, } diff --git a/esp-hal/src/pcnt/channel.rs b/esp-hal/src/pcnt/channel.rs index 1e6ac296f70..d0a2782486e 100644 --- a/esp-hal/src/pcnt/channel.rs +++ b/esp-hal/src/pcnt/channel.rs @@ -39,6 +39,8 @@ pub struct PcntSource { } impl PcntSource { + /// Creates a `PcntSource` from an input pin with the specified + /// configuration. pub fn from_pin<'a, P: InputPin>( pin: impl Peripheral

+ 'a, pin_config: PcntInputConfig, @@ -56,12 +58,16 @@ impl PcntSource { inverted: false, } } + + /// Creates a `PcntSource` that is always high. pub fn always_high() -> Self { Self { source: ONE_INPUT, inverted: false, } } + + /// Creates a `PcntSource` that is always low. pub fn always_low() -> Self { Self { source: ZERO_INPUT, @@ -69,6 +75,7 @@ impl PcntSource { } } + /// Inverts the `PcntSource` signal. pub fn invert(self) -> Self { Self { source: self.source, @@ -77,6 +84,7 @@ impl PcntSource { } } +/// Represents a channel within a pulse counter unit. pub struct Channel<'d, const UNIT: usize, const NUM: usize> { _phantom: PhantomData<&'d ()>, // Individual channels are not Send, since they share registers. diff --git a/esp-hal/src/pcnt/mod.rs b/esp-hal/src/pcnt/mod.rs index 36f7d6fdd09..4c4817c46cf 100644 --- a/esp-hal/src/pcnt/mod.rs +++ b/esp-hal/src/pcnt/mod.rs @@ -20,8 +20,6 @@ //! [unit]: unit/index.html //! [PCNT Encoder]: https://github.com/esp-rs/esp-hal/blob/main/examples/src/bin/pcnt_encoder.rs -#![allow(missing_docs)] // TODO: Remove when able - use self::unit::Unit; use crate::{ interrupt::{self, InterruptHandler}, @@ -34,6 +32,7 @@ use crate::{ pub mod channel; pub mod unit; +/// Pulse Counter (PCNT) peripheral driver. pub struct Pcnt<'d> { _instance: PeripheralRef<'d, peripherals::PCNT>, diff --git a/esp-hal/src/pcnt/unit.rs b/esp-hal/src/pcnt/unit.rs index 01e9c706eaa..1f0006f64e6 100644 --- a/esp-hal/src/pcnt/unit.rs +++ b/esp-hal/src/pcnt/unit.rs @@ -57,21 +57,30 @@ impl From for ZeroMode { } } -// Events +/// Events that can occur in a pulse counter unit. #[derive(Copy, Clone, Debug, Default)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Events { + /// Set when the pulse counter reaches the low limit. pub low_limit: bool, + /// Set when the pulse counter reaches the high limit. pub high_limit: bool, + /// Set when the pulse counter crosses threshold 0. pub threshold0: bool, + /// Set when the pulse counter crosses threshold 1. pub threshold1: bool, + /// Set when the pulse counter reaches zero. pub zero: bool, } +/// Represents a pulse counter unit. #[non_exhaustive] pub struct Unit<'d, const NUM: usize> { + /// The counter for PCNT unit. pub counter: Counter<'d, NUM>, + /// The first channel in PCNT unit. pub channel0: Channel<'d, NUM, 0>, + /// The second channel in PCNT unit. pub channel1: Channel<'d, NUM, 1>, } @@ -301,6 +310,7 @@ impl<'d, const NUM: usize> Drop for Unit<'d, NUM> { // The entire Unit is Send but the individual channels are not. unsafe impl<'d, const NUM: usize> Send for Unit<'d, NUM> {} +/// Represents the counter within a pulse counter unit. #[derive(Clone)] pub struct Counter<'d, const NUM: usize> { _phantom: PhantomData<&'d ()>, diff --git a/esp-hal/src/peripheral.rs b/esp-hal/src/peripheral.rs index 05824c5a556..323187f3b18 100644 --- a/esp-hal/src/peripheral.rs +++ b/esp-hal/src/peripheral.rs @@ -272,10 +272,12 @@ mod peripheral_macros { $crate::impl_dma_eligible!(MEM2MEM15,Mem2Mem15); } + /// The `Peripherals` struct provides access to all of the hardware peripherals on the chip. #[allow(non_snake_case)] pub struct Peripherals { $( $(#[$cfg])? + /// Each field represents a hardware peripheral. pub $name: peripherals::$name, )* } @@ -325,6 +327,7 @@ mod peripheral_macros { impl peripherals::$name { $( paste::paste!{ + /// Binds an interrupt handler to the corresponding interrupt for this peripheral. pub fn [](&mut self, handler: unsafe extern "C" fn() -> ()) { unsafe { $crate::interrupt::bind_interrupt($crate::peripherals::Interrupt::$interrupt, handler); } } @@ -350,11 +353,16 @@ mod peripheral_macros { #[doc(hidden)] #[macro_export] + /// Macro to create a peripheral structure. macro_rules! create_peripheral { ($(#[$cfg:meta])? $name:ident <= virtual) => { $(#[$cfg])? #[derive(Debug)] #[allow(non_camel_case_types)] + /// Represents a virtual peripheral with no associated hardware. + /// + /// This struct is generated by the `create_peripheral!` macro when the peripheral + /// is defined as virtual. pub struct $name { _inner: () } $(#[$cfg])? @@ -385,6 +393,10 @@ mod peripheral_macros { $(#[$cfg])? #[derive(Debug)] #[allow(non_camel_case_types)] + /// Represents a concrete hardware peripheral. + /// + /// This struct is generated by the `create_peripheral!` macro when the peripheral + /// is tied to an actual hardware device. pub struct $name { _inner: () } $(#[$cfg])? diff --git a/esp-hal/src/rmt.rs b/esp-hal/src/rmt.rs index d283569903a..99929bc44fd 100644 --- a/esp-hal/src/rmt.rs +++ b/esp-hal/src/rmt.rs @@ -642,15 +642,18 @@ mod impl_for_chip { use crate::peripheral::{Peripheral, PeripheralRef}; /// RMT Instance - #[allow(missing_docs)] pub struct Rmt<'d, M> where M: crate::Mode, { _peripheral: PeripheralRef<'d, crate::peripherals::RMT>, + /// RMT Channel 0. pub channel0: ChannelCreator, + /// RMT Channel 1. pub channel1: ChannelCreator, + /// RMT Channel 2. pub channel2: ChannelCreator, + /// RMT Channel 3. pub channel3: ChannelCreator, phantom: PhantomData, } @@ -710,19 +713,26 @@ mod impl_for_chip { use crate::peripheral::{Peripheral, PeripheralRef}; /// RMT Instance - #[allow(missing_docs)] pub struct Rmt<'d, M> where M: crate::Mode, { _peripheral: PeripheralRef<'d, crate::peripherals::RMT>, + /// RMT Channel 0. pub channel0: ChannelCreator, + /// RMT Channel 1. pub channel1: ChannelCreator, + /// RMT Channel 2. pub channel2: ChannelCreator, + /// RMT Channel 3. pub channel3: ChannelCreator, + /// RMT Channel 4. pub channel4: ChannelCreator, + /// RMT Channel 5. pub channel5: ChannelCreator, + /// RMT Channel 6. pub channel6: ChannelCreator, + /// RMT Channel 7. pub channel7: ChannelCreator, phantom: PhantomData, } @@ -818,15 +828,18 @@ mod impl_for_chip { use crate::peripheral::{Peripheral, PeripheralRef}; /// RMT Instance - #[allow(missing_docs)] pub struct Rmt<'d, M> where M: crate::Mode, { _peripheral: PeripheralRef<'d, crate::peripherals::RMT>, + /// RMT Channel 0. pub channel0: ChannelCreator, + /// RMT Channel 1. pub channel1: ChannelCreator, + /// RMT Channel 2. pub channel2: ChannelCreator, + /// RMT Channel 3. pub channel3: ChannelCreator, phantom: PhantomData, } @@ -894,19 +907,26 @@ mod impl_for_chip { use crate::peripheral::{Peripheral, PeripheralRef}; /// RMT Instance - #[allow(missing_docs)] pub struct Rmt<'d, M> where M: crate::Mode, { _peripheral: PeripheralRef<'d, crate::peripherals::RMT>, + /// RMT Channel 0. pub channel0: ChannelCreator, + /// RMT Channel 1. pub channel1: ChannelCreator, + /// RMT Channel 2. pub channel2: ChannelCreator, + /// RMT Channel 3. pub channel3: ChannelCreator, + /// RMT Channel 4. pub channel4: ChannelCreator, + /// RMT Channel 5. pub channel5: ChannelCreator, + /// RMT Channel 6. pub channel6: ChannelCreator, + /// RMT Channel 7. pub channel7: ChannelCreator, phantom: PhantomData, } diff --git a/esp-hal/src/rsa/esp32.rs b/esp-hal/src/rsa/esp32.rs index 22fad29f1a3..6cf1efde639 100644 --- a/esp-hal/src/rsa/esp32.rs +++ b/esp-hal/src/rsa/esp32.rs @@ -25,28 +25,35 @@ impl<'d, DM: crate::Mode> Rsa<'d, DM> { Ok(()) } + /// Writes the multi-mode configuration to the RSA hardware. pub(super) fn write_multi_mode(&mut self, mode: u32) { self.rsa.mult_mode().write(|w| unsafe { w.bits(mode) }); } + /// Writes the modular exponentiation mode configuration to the RSA + /// hardware. pub(super) fn write_modexp_mode(&mut self, mode: u32) { self.rsa.modexp_mode().write(|w| unsafe { w.bits(mode) }); } + /// Starts the modular exponentiation operation. pub(super) fn write_modexp_start(&mut self) { self.rsa .modexp_start() .write(|w| w.modexp_start().set_bit()); } + /// Starts the multiplication operation. pub(super) fn write_multi_start(&mut self) { self.rsa.mult_start().write(|w| w.mult_start().set_bit()); } + /// Clears the RSA interrupt flag. pub(super) fn clear_interrupt(&mut self) { self.rsa.interrupt().write(|w| w.interrupt().set_bit()); } + /// Checks if the RSA peripheral is idle. pub(super) fn is_idle(&mut self) -> bool { self.rsa.interrupt().read().bits() == 1 } @@ -62,6 +69,7 @@ impl<'d, DM: crate::Mode> Rsa<'d, DM> { } } +/// Module defining marker types for various RSA operand sizes. pub mod operand_sizes { //! Marker types for the operand sizes use paste::paste; @@ -165,10 +173,12 @@ where } } + /// Sets the modular exponentiation mode for the RSA hardware. pub(super) fn set_mode(rsa: &mut Rsa<'d, DM>) { rsa.write_modexp_mode((N / 16 - 1) as u32) } + /// Starts the modular exponentiation operation on the RSA hardware. pub(super) fn set_start(&mut self) { self.rsa.write_modexp_start(); } @@ -196,10 +206,12 @@ where self.set_start(); } + /// Sets the multiplication mode for the RSA hardware. pub(super) fn set_mode(rsa: &mut Rsa<'d, DM>) { rsa.write_multi_mode(((N * 2) / 16 + 7) as u32) } + /// Starts the multiplication operation on the RSA hardware. pub(super) fn set_start(&mut self) { self.rsa.write_multi_start(); } diff --git a/esp-hal/src/rsa/esp32cX.rs b/esp-hal/src/rsa/esp32cX.rs index e89edadaac6..b84135e2159 100644 --- a/esp-hal/src/rsa/esp32cX.rs +++ b/esp-hal/src/rsa/esp32cX.rs @@ -51,10 +51,12 @@ impl<'d, DM: crate::Mode> Rsa<'d, DM> { } } + /// Checks if the search functionality is enabled in the RSA hardware. pub(super) fn is_search_enabled(&mut self) -> bool { self.rsa.search_enable().read().search_enable().bit_is_set() } + /// Sets the search position in the RSA hardware. pub(super) fn write_search_position(&mut self, search_position: u32) { self.rsa .search_pos() @@ -79,28 +81,33 @@ impl<'d, DM: crate::Mode> Rsa<'d, DM> { } } + /// Starts the modular exponentiation operation. pub(super) fn write_modexp_start(&mut self) { self.rsa .set_start_modexp() .write(|w| w.set_start_modexp().set_bit()); } + /// Starts the multiplication operation. pub(super) fn write_multi_start(&mut self) { self.rsa .set_start_mult() .write(|w| w.set_start_mult().set_bit()); } + /// Starts the modular multiplication operation. fn write_modmulti_start(&mut self) { self.rsa .set_start_modmult() .write(|w| w.set_start_modmult().set_bit()); } + /// Clears the RSA interrupt flag. pub(super) fn clear_interrupt(&mut self) { self.rsa.int_clr().write(|w| w.clear_interrupt().set_bit()); } + /// Checks if the RSA peripheral is idle. pub(super) fn is_idle(&mut self) -> bool { self.rsa.query_idle().read().query_idle().bit_is_set() } @@ -110,6 +117,7 @@ impl<'d, DM: crate::Mode> Rsa<'d, DM> { } } +/// Module defining marker types for various RSA operand sizes. pub mod operand_sizes { //! Marker types for the operand sizes use paste::paste; @@ -255,10 +263,12 @@ where 0 } + /// Sets the modular exponentiation mode for the RSA hardware. pub(super) fn set_mode(rsa: &mut Rsa<'d, DM>) { rsa.write_mode((N - 1) as u32) } + /// Starts the modular exponentiation operation on the RSA hardware. pub(super) fn set_start(&mut self) { self.rsa.write_modexp_start(); } @@ -335,10 +345,12 @@ where self.set_start(); } + /// Sets the multiplication mode for the RSA hardware. pub(super) fn set_mode(rsa: &mut Rsa<'d, DM>) { rsa.write_mode((N * 2 - 1) as u32) } + /// Starts the multiplication operation on the RSA hardware. pub(super) fn set_start(&mut self) { self.rsa.write_multi_start(); } diff --git a/esp-hal/src/rsa/esp32sX.rs b/esp-hal/src/rsa/esp32sX.rs index 31120033570..bc521333e8e 100644 --- a/esp-hal/src/rsa/esp32sX.rs +++ b/esp-hal/src/rsa/esp32sX.rs @@ -57,10 +57,12 @@ impl<'d, DM: crate::Mode> Rsa<'d, DM> { } } + /// Checks if the search functionality is enabled in the RSA hardware. pub(super) fn is_search_enabled(&mut self) -> bool { self.rsa.search_enable().read().search_enable().bit_is_set() } + /// Sets the search position in the RSA hardware. pub(super) fn write_search_position(&mut self, search_position: u32) { self.rsa .search_pos() @@ -85,28 +87,33 @@ impl<'d, DM: crate::Mode> Rsa<'d, DM> { } } + /// Starts the modular exponentiation operation. pub(super) fn write_modexp_start(&mut self) { self.rsa .modexp_start() .write(|w| w.modexp_start().set_bit()); } + /// Starts the multiplication operation. pub(super) fn write_multi_start(&mut self) { self.rsa.mult_start().write(|w| w.mult_start().set_bit()); } + /// Starts the modular multiplication operation. fn write_modmulti_start(&mut self) { self.rsa .modmult_start() .write(|w| w.modmult_start().set_bit()); } + /// Clears the RSA interrupt flag. pub(super) fn clear_interrupt(&mut self) { self.rsa .clear_interrupt() .write(|w| w.clear_interrupt().set_bit()); } + /// Checks if the RSA peripheral is idle. pub(super) fn is_idle(&mut self) -> bool { self.rsa.idle().read().idle().bit_is_set() } @@ -296,10 +303,12 @@ where 0 } + /// Sets the modular exponentiation mode for the RSA hardware. pub(super) fn set_mode(rsa: &mut Rsa<'d, DM>) { rsa.write_mode((N - 1) as u32) } + /// Starts the modular exponentiation operation on the RSA hardware. pub(super) fn set_start(&mut self) { self.rsa.write_modexp_start(); } @@ -376,10 +385,12 @@ where self.set_start(); } + /// Sets the multiplication mode for the RSA hardware. pub(super) fn set_mode(rsa: &mut Rsa<'d, DM>) { rsa.write_mode((N * 2 - 1) as u32) } + /// Starts the multiplication operation on the RSA hardware. pub(super) fn set_start(&mut self) { self.rsa.write_multi_start(); } diff --git a/esp-hal/src/rsa/mod.rs b/esp-hal/src/rsa/mod.rs index a9496b41d28..41139cf8e7f 100644 --- a/esp-hal/src/rsa/mod.rs +++ b/esp-hal/src/rsa/mod.rs @@ -34,8 +34,6 @@ //! [nb]: https://docs.rs/nb/1.1.0/nb/ //! [the repository with corresponding example]: https://github.com/esp-rs/esp-hal/blob/main/hil-test/tests/rsa.rs -#![allow(missing_docs)] // TODO: Remove when able - use core::{marker::PhantomData, ptr::copy_nonoverlapping}; use crate::{ @@ -141,38 +139,52 @@ impl<'d, DM: crate::Mode> Rsa<'d, DM> { } } +/// Defines an RSA operation mode. pub trait RsaMode: crate::private::Sealed { + /// The input data type used for the RSA operation. type InputType; } + +/// A trait for RSA operations that involve multiple inputs and outputs. pub trait Multi: RsaMode { + /// The type of the output produced by the RSA operation. type OutputType; } macro_rules! implement_op { (($x:literal, multi)) => { - paste! {pub struct [];} - paste! { - impl Multi for [] { - type OutputType = [u32; $x*2 / 32]; - }} - paste! { - impl crate::private::Sealed for [] {} - } - paste! { - impl RsaMode for [] { - type InputType = [u32; $x / 32]; - }} + paste! { + /// Represents an RSA operation for the given bit size with multi-output. + pub struct []; + } + paste! { + impl Multi for [] { + type OutputType = [u32; $x * 2 / 32]; + } + } + paste! { + impl crate::private::Sealed for [] {} + } + paste! { + impl RsaMode for [] { + type InputType = [u32; $x / 32]; + } + } }; (($x:literal)) => { - paste! {pub struct [];} + paste! { + /// Represents an RSA operation for the given bit size. + pub struct []; + } paste! { impl crate::private::Sealed for [] {} } - paste!{ - impl RsaMode for [] { - type InputType = [u32; $x / 32]; - }} + paste! { + impl RsaMode for [] { + type InputType = [u32; $x / 32]; + } + } }; ($x:tt, $($y:tt),+) => { @@ -286,6 +298,7 @@ where } } +/// Async functionality #[cfg(feature = "async")] pub(crate) mod asynch { use core::task::Poll; @@ -303,11 +316,13 @@ pub(crate) mod asynch { static WAKER: AtomicWaker = AtomicWaker::new(); + /// `Future` that waits for the RSA operation to complete. pub(crate) struct RsaFuture<'d> { instance: &'d crate::peripherals::RSA, } impl<'d> RsaFuture<'d> { + /// Asynchronously initializes the RSA peripheral. pub async fn new(instance: &'d crate::peripherals::RSA) -> Self { #[cfg(not(any(esp32, esp32s2, esp32s3)))] instance.int_ena().modify(|_, w| w.int_ena().set_bit()); @@ -360,6 +375,7 @@ pub(crate) mod asynch { where T: RsaMode, { + /// Asynchronously performs an RSA modular exponentiation operation. pub async fn exponentiation( &mut self, base: &T::InputType, @@ -377,6 +393,7 @@ pub(crate) mod asynch { T: RsaMode, { #[cfg(not(esp32))] + /// Asynchronously performs an RSA modular multiplication operation. pub async fn modular_multiplication( &mut self, r: &T::InputType, @@ -388,6 +405,7 @@ pub(crate) mod asynch { } #[cfg(esp32)] + /// Asynchronously performs an RSA modular multiplication operation. pub async fn modular_multiplication( &mut self, operand_a: &T::InputType, @@ -407,6 +425,7 @@ pub(crate) mod asynch { T: RsaMode, { #[cfg(not(esp32))] + /// Asynchronously performs an RSA multiplication operation. pub async fn multiplication<'b, const O: usize>( &mut self, operand_b: &T::InputType, @@ -420,6 +439,7 @@ pub(crate) mod asynch { } #[cfg(esp32)] + /// Asynchronously performs an RSA multiplication operation. pub async fn multiplication<'b, const O: usize>( &mut self, operand_a: &T::InputType, @@ -435,6 +455,7 @@ pub(crate) mod asynch { } #[handler] + /// Interrupt handler for RSA. pub(super) fn rsa_interrupt_handler() { #[cfg(not(any(esp32, esp32s2, esp32s3)))] unsafe { &*crate::peripherals::RSA::ptr() } diff --git a/esp-hal/src/rtc_cntl/mod.rs b/esp-hal/src/rtc_cntl/mod.rs index db6a056361f..505e2cbe4e2 100644 --- a/esp-hal/src/rtc_cntl/mod.rs +++ b/esp-hal/src/rtc_cntl/mod.rs @@ -69,8 +69,6 @@ //! } //! ``` -#![allow(missing_docs)] // TODO: Remove when able - #[cfg(not(any(esp32c6, esp32h2)))] use fugit::HertzU32; use fugit::MicrosDurationU64; @@ -186,8 +184,10 @@ pub(crate) enum RtcCalSel { /// Low-power Management pub struct Rtc<'d> { _inner: PeripheralRef<'d, crate::peripherals::LPWR>, + /// Reset Watchdog Timer. pub rwdt: Rwdt, #[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2, esp32s3))] + /// Super Watchdog pub swd: Swd, } diff --git a/esp-hal/src/rtc_cntl/rtc/esp32.rs b/esp-hal/src/rtc_cntl/rtc/esp32.rs index 59fe4a85980..77a900dbaee 100644 --- a/esp-hal/src/rtc_cntl/rtc/esp32.rs +++ b/esp-hal/src/rtc_cntl/rtc/esp32.rs @@ -34,6 +34,7 @@ pub(crate) fn configure_clock() { // Chip Reset: Reset the whole chip, including the analog part #[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)] +/// SOC Reset Reason. pub enum SocResetReason { /// Power on reset ChipPowerOn = 0x01, diff --git a/esp-hal/src/rtc_cntl/rtc/esp32c2.rs b/esp-hal/src/rtc_cntl/rtc/esp32c2.rs index ab9c7efc870..75eba0d45c2 100644 --- a/esp-hal/src/rtc_cntl/rtc/esp32c2.rs +++ b/esp-hal/src/rtc_cntl/rtc/esp32c2.rs @@ -201,6 +201,7 @@ fn rtc_sleep_pu() { // Chip Reset: Reset the whole chip, including the analog part #[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)] +/// SOC Reset Reason. pub enum SocResetReason { /// Power on reset ChipPowerOn = 0x01, diff --git a/esp-hal/src/rtc_cntl/rtc/esp32c3.rs b/esp-hal/src/rtc_cntl/rtc/esp32c3.rs index 0c795e9bab4..8fc81c9e279 100644 --- a/esp-hal/src/rtc_cntl/rtc/esp32c3.rs +++ b/esp-hal/src/rtc_cntl/rtc/esp32c3.rs @@ -259,6 +259,7 @@ fn rtc_sleep_pu() { // System Reset: Reset the whole digital system, including RTC sub-system // Chip Reset: Reset the whole chip, including the analog part +/// SOC Reset Reason. #[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)] pub enum SocResetReason { /// Power on reset diff --git a/esp-hal/src/rtc_cntl/rtc/esp32c6.rs b/esp-hal/src/rtc_cntl/rtc/esp32c6.rs index 2f888ed299b..456701a936c 100644 --- a/esp-hal/src/rtc_cntl/rtc/esp32c6.rs +++ b/esp-hal/src/rtc_cntl/rtc/esp32c6.rs @@ -1305,6 +1305,7 @@ fn modem_clk_domain_active_state_icg_map_preinit() { // System Reset: Reset the whole digital system, including RTC sub-system // Chip Reset: Reset the whole chip, including the analog part +/// SOC Reset Reason. #[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)] pub enum SocResetReason { /// Power on reset diff --git a/esp-hal/src/rtc_cntl/rtc/esp32h2.rs b/esp-hal/src/rtc_cntl/rtc/esp32h2.rs index 22f6989f2a8..67bf9c39387 100644 --- a/esp-hal/src/rtc_cntl/rtc/esp32h2.rs +++ b/esp-hal/src/rtc_cntl/rtc/esp32h2.rs @@ -149,6 +149,7 @@ pub(crate) fn configure_clock() { // System Reset: Reset the whole digital system, including RTC sub-system // Chip Reset: Reset the whole chip, including the analog part +/// SOC Reset Reason. #[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)] pub enum SocResetReason { /// Power on reset diff --git a/esp-hal/src/rtc_cntl/rtc/esp32s2.rs b/esp-hal/src/rtc_cntl/rtc/esp32s2.rs index e27462d8376..51250e35e05 100644 --- a/esp-hal/src/rtc_cntl/rtc/esp32s2.rs +++ b/esp-hal/src/rtc_cntl/rtc/esp32s2.rs @@ -39,6 +39,7 @@ pub(crate) fn configure_clock() { // System Reset: Reset the whole digital system, including RTC sub-system // Chip Reset: Reset the whole chip, including the analog part +/// SOC Reset Reason. #[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)] pub enum SocResetReason { /// Power on reset diff --git a/esp-hal/src/rtc_cntl/rtc/esp32s3.rs b/esp-hal/src/rtc_cntl/rtc/esp32s3.rs index 53364bafc09..35c12f8bde3 100644 --- a/esp-hal/src/rtc_cntl/rtc/esp32s3.rs +++ b/esp-hal/src/rtc_cntl/rtc/esp32s3.rs @@ -39,6 +39,7 @@ pub(crate) fn configure_clock() { // System Reset: Reset the whole digital system, including RTC sub-system // Chip Reset: Reset the whole chip, including the analog part +/// SOC Reset Reason. #[derive(Debug, Clone, Copy, PartialEq, Eq, FromRepr)] pub enum SocResetReason { /// Power on reset diff --git a/esp-hal/src/rtc_cntl/sleep/esp32.rs b/esp-hal/src/rtc_cntl/sleep/esp32.rs index cfc70e67e2c..77435035172 100644 --- a/esp-hal/src/rtc_cntl/sleep/esp32.rs +++ b/esp-hal/src/rtc_cntl/sleep/esp32.rs @@ -7,38 +7,66 @@ use crate::{ // Approximate mapping of voltages to RTC_CNTL_DBIAS_WAK, RTC_CNTL_DBIAS_SLP, // RTC_CNTL_DIG_DBIAS_WAK, RTC_CNTL_DIG_DBIAS_SLP values. // Valid if RTC_CNTL_DBG_ATTEN is 0. +/// RTC digital bias setting corresponding to 0.90V. pub const RTC_CNTL_DBIAS_0V90: u8 = 0; +/// RTC digital bias setting corresponding to 0.95V. pub const RTC_CNTL_DBIAS_0V95: u8 = 1; +/// RTC digital bias setting corresponding to 1.00V. pub const RTC_CNTL_DBIAS_1V00: u8 = 2; +/// RTC digital bias setting corresponding to 1.05V. pub const RTC_CNTL_DBIAS_1V05: u8 = 3; +/// RTC digital bias setting corresponding to 1.10V. pub const RTC_CNTL_DBIAS_1V10: u8 = 4; +/// RTC digital bias setting corresponding to 1.15V. pub const RTC_CNTL_DBIAS_1V15: u8 = 5; +/// RTC digital bias setting corresponding to 1.20V. pub const RTC_CNTL_DBIAS_1V20: u8 = 6; +/// RTC digital bias setting corresponding to 1.25V. pub const RTC_CNTL_DBIAS_1V25: u8 = 7; + // Various delays to be programmed into power control state machines +/// Time (in microseconds) for waiting the XTL buffer to stabilize during sleep. pub const RTC_CNTL_XTL_BUF_WAIT_SLP_US: u32 = 1000; +/// Cycles to wait for PLL buffer stabilization. pub const RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES: u8 = 1; +/// Cycles to wait for the 8MHz clock to stabilize. pub const RTC_CNTL_CK8M_WAIT_SLP_CYCLES: u8 = 4; +/// Delay in cycles for wakeup signal to be applied. pub const RTC_CNTL_WAKEUP_DELAY_CYCLES: u8 = 7; +/// Power-up cycles for other blocks. pub const RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES: u8 = 1; +/// Wait cycles for other blocks. pub const RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES: u16 = 1; +/// Minimum sleep value (in cycles). pub const RTC_CNTL_MIN_SLP_VAL_MIN: u8 = 128; +/// Default debug attenuation value. pub const RTC_CNTL_DBG_ATTEN_DEFAULT: u8 = 3; +/// Power-up cycles for RTC memory. pub const RTC_MEM_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES; +/// Wait cycles for RTC memory. pub const RTC_MEM_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES; +/// Power-up cycles for ROM and RAM. pub const ROM_RAM_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES; +/// Wait cycles for ROM and RAM. pub const ROM_RAM_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES; +/// Power-up cycles for Wi-Fi. pub const WIFI_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES; +/// Wait cycles for Wi-Fi. pub const WIFI_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES; +/// Power-up cycles for RTC components. pub const RTC_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES; +/// Wait cycles for RTC components. pub const RTC_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES; +/// Power-up cycles for the digital wrap components. pub const DG_WRAP_POWERUP_CYCLES: u8 = RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES; +/// Wait cycles for the digital wrap components. pub const DG_WRAP_WAIT_CYCLES: u16 = RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES; +/// Default wait cycles for the 8MHz clock. pub const RTC_CNTL_CK8M_WAIT_DEFAULT: u8 = 20; +/// Default wait cycles to enable the 8MHz clock. pub const RTC_CK8M_ENABLE_WAIT_DEFAULT: u8 = 5; - impl WakeSource for TimerWakeupSource { fn apply( &self, @@ -162,6 +190,7 @@ impl Drop for Ext1WakeupSource<'_, '_> { bitfield::bitfield! { #[derive(Clone, Copy)] + /// Configuration for the RTC sleep behavior. pub struct RtcSleepConfig(u32); impl Debug; /// force normal voltage in sleep mode (digital domain memory) @@ -221,6 +250,7 @@ impl Default for RtcSleepConfig { } impl RtcSleepConfig { + /// Configures the RTC for deep sleep mode. pub fn deep() -> Self { let mut cfg = Self::default(); cfg.set_deep_slp(true); diff --git a/esp-hal/src/rtc_cntl/sleep/esp32c3.rs b/esp-hal/src/rtc_cntl/sleep/esp32c3.rs index e5a0c89eff6..5c1cec90f5f 100644 --- a/esp-hal/src/rtc_cntl/sleep/esp32c3.rs +++ b/esp-hal/src/rtc_cntl/sleep/esp32c3.rs @@ -42,46 +42,83 @@ const I2C_ULP_HOSTID: u8 = 0; // Approximate mapping of voltages to RTC_CNTL_DBIAS_WAK, RTC_CNTL_DBIAS_SLP, // RTC_CNTL_DIG_DBIAS_WAK, RTC_CNTL_DIG_DBIAS_SLP values. // Valid if RTC_CNTL_DBG_ATTEN is 0. +/// Digital bias voltage level of 0.90V. pub const RTC_CNTL_DBIAS_0V90: u32 = 13; +/// Digital bias voltage level of 0.95V. pub const RTC_CNTL_DBIAS_0V95: u32 = 16; +/// Digital bias voltage level of 1.00V. pub const RTC_CNTL_DBIAS_1V00: u32 = 18; +/// Digital bias voltage level of 1.05V. pub const RTC_CNTL_DBIAS_1V05: u32 = 20; +/// Digital bias voltage level of 1.10V. pub const RTC_CNTL_DBIAS_1V10: u32 = 23; +/// Digital bias voltage level of 1.15V. pub const RTC_CNTL_DBIAS_1V15: u32 = 25; +/// Digital bias voltage level of 1.20V. pub const RTC_CNTL_DBIAS_1V20: u32 = 28; +/// Digital bias voltage level of 1.25V. pub const RTC_CNTL_DBIAS_1V25: u32 = 30; -pub const RTC_CNTL_DBIAS_1V30: u32 = 31; //< voltage is about 1.34v in fact +/// Digital bias voltage level of approximately 1.34V. +pub const RTC_CNTL_DBIAS_1V30: u32 = 31; +/// Default attenuation setting during light sleep, with a voltage drop. pub const RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT: u8 = 5; +/// No attenuation (no voltage drop) during light sleep. pub const RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP: u8 = 0; +/// Default attenuation setting during deep sleep, with maximum voltage drop. pub const RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT: u8 = 15; +/// No attenuation (no voltage drop) during deep sleep. pub const RTC_CNTL_DBG_ATTEN_DEEPSLEEP_NODROP: u8 = 0; + +/// Default bias setting during sleep mode. pub const RTC_CNTL_BIASSLP_SLEEP_DEFAULT: u8 = 1; +/// Keeps the bias for ultra-low power sleep mode always on. pub const RTC_CNTL_BIASSLP_SLEEP_ON: u8 = 0; + +/// Default power-down current setting during sleep mode. pub const RTC_CNTL_PD_CUR_SLEEP_DEFAULT: u8 = 1; +/// Keeps the power-down current setting for sleep mode always on. pub const RTC_CNTL_PD_CUR_SLEEP_ON: u8 = 0; + +/// Default driver bias setting for the digital domain during sleep mode. pub const RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT: u8 = 254; +/// Default debug attenuation setting for the monitor mode. pub const RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT: u8 = 0; +/// Default bias setting for sleep mode in the monitor mode. pub const RTC_CNTL_BIASSLP_MONITOR_DEFAULT: bool = false; +/// Default power-down current setting for the monitor mode. pub const RTC_CNTL_PD_CUR_MONITOR_DEFAULT: bool = false; +/// Default number of cycles to wait for the PLL buffer to stabilize. pub const RTC_CNTL_PLL_BUF_WAIT_DEFAULT: u8 = 20; +/// Default number of cycles to wait for the XTL buffer to stabilize. pub const RTC_CNTL_XTL_BUF_WAIT_DEFAULT: u8 = 100; +/// Default number of cycles to wait for the internal 8MHz clock to stabilize. pub const RTC_CNTL_CK8M_WAIT_DEFAULT: u8 = 20; +/// Default number of cycles required to enable the internal 8MHz clock. pub const RTC_CK8M_ENABLE_WAIT_DEFAULT: u8 = 5; +/// Minimum number of cycles for sleep duration. pub const RTC_CNTL_MIN_SLP_VAL_MIN: u8 = 2; +/// Power-up cycles for other hardware blocks. pub const OTHER_BLOCKS_POWERUP: u8 = 1; +/// Wait cycles for other hardware blocks to stabilize. pub const OTHER_BLOCKS_WAIT: u16 = 1; +/// Disables GPIO interrupt. pub const GPIO_INTR_DISABLE: u8 = 0; +/// Sets GPIO interrupt to trigger on a low level signal. pub const GPIO_INTR_LOW_LEVEL: u8 = 4; +/// Sets GPIO interrupt to trigger on a high level signal. pub const GPIO_INTR_HIGH_LEVEL: u8 = 5; +/// Specifies the function configuration for GPIO pins. pub const PIN_FUNC_GPIO: u8 = 1; +/// Index for signaling GPIO output. pub const SIG_GPIO_OUT_IDX: u32 = 128; +/// Maximum number of GPIO pins supported. pub const GPIO_NUM_MAX: usize = 22; impl WakeSource for TimerWakeupSource { @@ -256,6 +293,7 @@ impl WakeSource for RtcioWakeupSource<'_, '_> { bitfield::bitfield! { #[derive(Clone, Copy)] + /// RTC Configuration. pub struct RtcConfig(u32); impl Debug; /// Number of rtc_fast_clk cycles to wait for 8M clock to be ready @@ -264,16 +302,19 @@ bitfield::bitfield! { pub u8, xtal_wait, set_xtal_wait: 15, 8; /// Number of rtc_fast_clk cycles to wait for PLL clock to be ready pub u8, pll_wait, set_pll_wait: 23, 16; - // Perform clock control related initialization. + /// Perform clock control related initialization. pub clkctl_init, set_clkctl_init: 24; - // Perform power control related initialization. + /// Perform power control related initialization. pub pwrctl_init, set_pwrctl_init: 25; - // Force power down RTC_DBOOST + /// Force power down `RTC_DBOOST`. pub rtc_dboost_fpd, set_rtc_dboost_fpd: 26; + /// Keep the XTAL oscillator powered up in sleep. pub xtal_fpu, set_xtal_fpu: 27; + /// Keep the BBPLL oscillator powered up in sleep. pub bbpll_fpu, set_bbpll_fpu: 28; + /// Enable clock gating when the CPU is in wait-for-interrupt state. pub cpu_waiti_clk_gate, set_cpu_waiti_clk_gate: 29; - // Calibrate Ocode to make bandgap voltage more precise. + /// Calibrate Ocode to make bandgap voltage more precise. pub cali_ocode, set_cali_ocode: 30; } @@ -293,17 +334,28 @@ impl Default for RtcConfig { bitfield::bitfield! { #[derive(Clone, Copy)] + /// Configuration for RTC initialization. pub struct RtcInitConfig(u128); impl Debug; + /// Number of cycles required to power up WiFi pub u8, wifi_powerup_cycles, set_wifi_powerup_cycles: 6, 0; + /// Number of wait cycles for WiFi to stabilize pub u16, wifi_wait_cycles, set_wifi_wait_cycles: 15, 7; + /// Number of cycles required to power up Bluetooth pub u8, bt_powerup_cycles, set_bt_powerup_cycles: 22, 16; + /// Number of wait cycles for Bluetooth to stabilize pub u16, bt_wait_cycles, set_bt_wait_cycles: 31, 23; + /// Number of cycles required to power up the top CPU pub u8, cpu_top_powerup_cycles, set_cpu_top_powerup_cycles: 38, 32; + /// Number of wait cycles for the top CPU to stabilize pub u16, cpu_top_wait_cycles, set_cpu_top_wait_cycles: 47, 39; + /// Number of cycles required to power up the digital wrapper pub u8, dg_wrap_powerup_cycles, set_dg_wrap_powerup_cycles: 54, 48; + /// Number of wait cycles for the digital wrapper to stabilize pub u16, dg_wrap_wait_cycles, set_dg_wrap_wait_cycles: 63, 55; + /// Number of cycles required to power up the digital peripherals pub u8, dg_peri_powerup_cycles, set_dg_peri_powerup_cycles: 70, 64; + /// Number of wait cycles for the digital peripherals to stabilize pub u16, dg_peri_wait_cycles, set_dg_peri_wait_cycles: 79, 71; } @@ -326,6 +378,7 @@ impl Default for RtcInitConfig { bitfield::bitfield! { #[derive(Clone, Copy)] + /// Configuration for RTC sleep mode. pub struct RtcSleepConfig(u64); impl Debug; /// force normal voltage in sleep mode (digital domain memory) @@ -437,6 +490,7 @@ fn rtc_sleep_pu(val: bool) { } impl RtcSleepConfig { + /// Configures the RTC for deep sleep mode. pub fn deep() -> Self { // Set up for ultra-low power sleep. Wakeup sources may modify these settings. let mut cfg = Self::default(); diff --git a/esp-hal/src/rtc_cntl/sleep/esp32c6.rs b/esp-hal/src/rtc_cntl/sleep/esp32c6.rs index 3336bc34372..fb052aed945 100644 --- a/esp-hal/src/rtc_cntl/sleep/esp32c6.rs +++ b/esp-hal/src/rtc_cntl/sleep/esp32c6.rs @@ -160,11 +160,14 @@ impl WakeSource for WakeFromLpCoreWakeupSource { } } +/// Configuration for controlling the behavior during sleep modes. #[derive(Clone, Copy)] // pmu_sleep_analog_config_t pub struct AnalogSleepConfig { + /// High-power system configuration. pub hp_sys: HpAnalog, // pub lp_sys_active: LpAnalog, // unused + /// Low-power system analog configuration. pub lp_sys_sleep: LpAnalog, } @@ -298,9 +301,12 @@ impl AnalogSleepConfig { } } +/// Configuration for controlling the behavior of digital peripherals during +/// sleep modes. #[derive(Clone, Copy)] // pmu_sleep_digital_config_t pub struct DigitalSleepConfig { + /// High-power system control register configuration. pub syscntl: HpSysCntlReg, } @@ -329,11 +335,16 @@ impl DigitalSleepConfig { } } +/// Configuration for controlling the power settings of high-power and low-power +/// systems during sleep modes. #[derive(Clone, Copy)] // pmu_sleep_power_config_t pub struct PowerSleepConfig { + /// Power configuration for the high-power system during sleep. pub hp_sys: HpSysPower, + /// Power configuration for the low-power system when it is active. pub lp_sys_active: LpSysPower, + /// Power configuration for the low-power system when it is in sleep mode. pub lp_sys_sleep: LpSysPower, } @@ -424,42 +435,64 @@ impl PowerSleepConfig { } } +/// Parameters for high-power system configurations during sleep modes. #[derive(Clone, Copy)] // pmu_hp_param_t pub struct HpParam { + /// Number of cycles to wait for the modem to wake up. pub modem_wakeup_wait_cycle: u32, + /// Number of cycles to wait for the analog component stabilization. pub analog_wait_target_cycle: u16, + /// Number of cycles to wait for the digital power-down sequence. pub digital_power_down_wait_cycle: u16, + /// Number of cycles to wait for the digital power supply to stabilize. pub digital_power_supply_wait_cycle: u16, + /// Number of cycles to wait for the digital power-up sequence. pub digital_power_up_wait_cycle: u16, + /// Number of cycles to wait for the PLL to stabilize. pub pll_stable_wait_cycle: u16, + /// Number of cycles to wait for modifying the ICG control. pub modify_icg_cntl_wait_cycle: u8, + /// Number of cycles to wait for switching the ICG coйntrol. pub switch_icg_cntl_wait_cycle: u8, + /// Minimum sleep time measured in slow clock cycles. pub min_slp_slow_clk_cycle: u8, } +/// Parameters for low-power system configurations during sleep modes. #[derive(Clone, Copy)] // pmu_lp_param_t pub struct LpParam { + /// Number of cycles to wait for the digital power supply to stabilize. pub digital_power_supply_wait_cycle: u16, + /// Minimum sleep time measured in slow clock cycles. pub min_slp_slow_clk_cycle: u8, + /// Number of cycles to wait for the analog component stabilization. pub analog_wait_target_cycle: u8, + /// Number of cycles to wait for the digital power-down sequence. pub digital_power_down_wait_cycle: u8, + /// Number of cycles to wait for the digital power-up sequence. pub digital_power_up_wait_cycle: u8, } +/// Parameters for high-power and low-power system configurations during sleep +/// modes. #[derive(Clone, Copy)] // pmu_hp_lp_param_t pub struct HpLpParam { - // union of two u16 variants, I've elected to not complicate things... + /// Union of two u16 variants pub xtal_stable_wait_cycle: u16, } +/// Configuration of parameters for sleep modes #[derive(Clone, Copy)] // pmu_sleep_param_config_t pub struct ParamSleepConfig { + /// Configuration of high-power system parameters. pub hp_sys: HpParam, + /// Configuration of low-power system parameters. pub lp_sys: LpParam, + /// Shared configuration parameters for high-power and low-power systems. pub hp_lp: HpLpParam, } impl ParamSleepConfig { @@ -729,10 +762,13 @@ impl SleepTimeConfig { } } +/// Configuration for the RTC sleep behavior. #[derive(Clone, Copy)] // pmu_sleep_config_t + deep sleep flag + pd flags pub struct RtcSleepConfig { + /// Deep Sleep flag pub deep: bool, + /// Power Down flags pub pd_flags: PowerDownFlags, } @@ -761,28 +797,46 @@ bitfield::bitfield! { /// Power domains to be powered down during sleep pub struct PowerDownFlags(u32); + /// Controls the power-down status of the top power domain. pub u32, pd_top , set_pd_top : 0; + /// Controls the power-down status of the VDD_SDIO power domain. pub u32, pd_vddsdio , set_pd_vddsdio : 1; + /// Controls the power-down status of the modem power domain. pub u32, pd_modem , set_pd_modem : 2; + /// Controls the power-down status of the high-performance peripheral power domain. pub u32, pd_hp_periph, set_pd_hp_periph: 3; + /// Controls the power-down status of the CPU power domain. pub u32, pd_cpu , set_pd_cpu : 4; + /// Controls the power-down status of the high-performance always-on domain. pub u32, pd_hp_aon , set_pd_hp_aon : 5; + /// Controls the power-down status of memory group 0. pub u32, pd_mem_g0 , set_pd_mem_g0 : 6; + /// Controls the power-down status of memory group 1. pub u32, pd_mem_g1 , set_pd_mem_g1 : 7; + /// Controls the power-down status of memory group 2. pub u32, pd_mem_g2 , set_pd_mem_g2 : 8; + /// Controls the power-down status of memory group 3. pub u32, pd_mem_g3 , set_pd_mem_g3 : 9; + /// Controls the power-down status of the crystal oscillator. pub u32, pd_xtal , set_pd_xtal : 10; + /// Controls the power-down status of the fast RC oscillator. pub u32, pd_rc_fast , set_pd_rc_fast : 11; + /// Controls the power-down status of the 32kHz crystal oscillator. pub u32, pd_xtal32k , set_pd_xtal32k : 12; + /// Controls the power-down status of the 32kHz RC oscillator. pub u32, pd_rc32k , set_pd_rc32k : 13; + /// Controls the power-down status of the low-power peripheral domain. pub u32, pd_lp_periph, set_pd_lp_periph: 14; } impl PowerDownFlags { + /// Checks whether all memory groups (G0, G1, G2, G3) are powered down. pub fn pd_mem(self) -> bool { self.pd_mem_g0() && self.pd_mem_g1() && self.pd_mem_g2() && self.pd_mem_g3() } + /// Sets the power-down status for all memory groups (G0, G1, G2, G3) at + /// once. pub fn set_pd_mem(&mut self, value: bool) { self.set_pd_mem_g0(value); self.set_pd_mem_g1(value); @@ -826,10 +880,12 @@ impl MachineConstants { } impl RtcSleepConfig { + /// Returns whether the device is in deep sleep mode. pub fn deep_slp(&self) -> bool { self.deep } + /// Configures the device for deep sleep mode with ultra-low power settings. pub fn deep() -> Self { // Set up for ultra-low power sleep. Wakeup sources may modify these settings. Self { diff --git a/esp-hal/src/rtc_cntl/sleep/esp32s3.rs b/esp-hal/src/rtc_cntl/sleep/esp32s3.rs index 23a9585825e..ea97060daaf 100644 --- a/esp-hal/src/rtc_cntl/sleep/esp32s3.rs +++ b/esp-hal/src/rtc_cntl/sleep/esp32s3.rs @@ -42,41 +42,69 @@ const I2C_DIG_REG_XPD_DIG_REG_LSB: u32 = 3; // Approximate mapping of voltages to RTC_CNTL_DBIAS_WAK, RTC_CNTL_DBIAS_SLP, // RTC_CNTL_DIG_DBIAS_WAK, RTC_CNTL_DIG_DBIAS_SLP values. // Valid if RTC_CNTL_DBG_ATTEN is 0. +/// Digital bias setting for 0.90V. pub const RTC_CNTL_DBIAS_0V90: u32 = 13; +/// Digital bias setting for 0.95V. pub const RTC_CNTL_DBIAS_0V95: u32 = 16; +/// Digital bias setting for 1.00V. pub const RTC_CNTL_DBIAS_1V00: u32 = 18; +/// Digital bias setting for 1.05V. pub const RTC_CNTL_DBIAS_1V05: u32 = 20; +/// Digital bias setting for 1.10V. pub const RTC_CNTL_DBIAS_1V10: u32 = 23; +/// Digital bias setting for 1.15V. pub const RTC_CNTL_DBIAS_1V15: u32 = 25; +/// Digital bias setting for 1.20V. pub const RTC_CNTL_DBIAS_1V20: u32 = 28; +/// Digital bias setting for 1.25V. pub const RTC_CNTL_DBIAS_1V25: u32 = 30; -pub const RTC_CNTL_DBIAS_1V30: u32 = 31; //< voltage is about 1.34v in fact - +/// Digital bias setting for 1.30V. Voltage is approximately 1.34V in practice. +pub const RTC_CNTL_DBIAS_1V30: u32 = 31; +/// Default monitor debug attenuation value. pub const RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT: u8 = 0; +/// ULP co-processor touch start wait time during sleep, set to maximum. pub const RTC_CNTL_ULPCP_TOUCH_START_WAIT_IN_SLEEP: u16 = 0xFF; +/// ULP co-processor touch start wait time default value. pub const RTC_CNTL_ULPCP_TOUCH_START_WAIT_DEFAULT: u16 = 0x10; - +/// Default wait time for PLL buffer during startup. pub const RTC_CNTL_PLL_BUF_WAIT_DEFAULT: u8 = 20; +/// Default wait time for CK8M during startup. pub const RTC_CNTL_CK8M_WAIT_DEFAULT: u8 = 20; +/// Minimum sleep value. pub const RTC_CNTL_MIN_SLP_VAL_MIN: u8 = 2; +/// Deep sleep debug attenuation setting for ultra-low power mode. pub const RTC_CNTL_DBG_ATTEN_DEEPSLEEP_ULTRA_LOW: u8 = 15; - +/// Power-up setting for other blocks. pub const OTHER_BLOCKS_POWERUP: u8 = 1; +/// Wait cycles for other blocks. pub const OTHER_BLOCKS_WAIT: u16 = 1; - +/// WiFi power-up cycles. pub const WIFI_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP; +/// WiFi wait cycles. pub const WIFI_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT; +/// Bluetooth power-up cycles. pub const BT_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP; +/// Bluetooth wait cycles. pub const BT_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT; +/// RTC power-up cycles. pub const RTC_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP; +/// RTC wait cycles. pub const RTC_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT; +/// CPU top power-up cycles. pub const CPU_TOP_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP; +/// CPU top wait cycles. pub const CPU_TOP_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT; +/// DG wrap power-up cycles. pub const DG_WRAP_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP; +/// DG wrap wait cycles. pub const DG_WRAP_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT; +/// DG peripheral power-up cycles. pub const DG_PERI_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP; +/// DG peripheral wait cycles. pub const DG_PERI_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT; +/// RTC memory power-up cycles. pub const RTC_MEM_POWERUP_CYCLES: u8 = OTHER_BLOCKS_POWERUP; +/// RTC memory wait cycles. pub const RTC_MEM_WAIT_CYCLES: u16 = OTHER_BLOCKS_WAIT; impl WakeSource for TimerWakeupSource { @@ -266,6 +294,7 @@ impl Drop for RtcioWakeupSource<'_, '_> { } bitfield::bitfield! { + /// Configuration for the RTC sleep behavior. #[derive(Clone, Copy)] pub struct RtcSleepConfig(u64); impl Debug; @@ -382,6 +411,7 @@ fn rtc_sleep_pu(val: bool) { } impl RtcSleepConfig { + /// Configures the RTC for deep sleep mode. pub fn deep() -> Self { // Set up for ultra-low power sleep. Wakeup sources may modify these settings. let mut cfg = Self::default(); diff --git a/esp-hal/src/rtc_cntl/sleep/mod.rs b/esp-hal/src/rtc_cntl/sleep/mod.rs index 71ee0712a24..1390ed437cb 100644 --- a/esp-hal/src/rtc_cntl/sleep/mod.rs +++ b/esp-hal/src/rtc_cntl/sleep/mod.rs @@ -33,41 +33,56 @@ mod sleep_impl; pub use sleep_impl::*; #[derive(Debug, Default, Clone, Copy, PartialEq)] +/// Level at which a wake-up event is triggered pub enum WakeupLevel { + /// The wake-up event is triggered when the pin is low. Low, #[default] + /// The wake-up event is triggered when the pin is high. High, } +/// Represents a timer wake-up source, triggering an event after a specified +/// duration. #[derive(Debug, Default, Clone, Copy)] #[cfg(any(esp32, esp32c3, esp32s3, esp32c6))] pub struct TimerWakeupSource { + /// The duration after which the wake-up event is triggered. duration: Duration, } #[cfg(any(esp32, esp32c3, esp32s3, esp32c6))] impl TimerWakeupSource { + /// Creates a new timer wake-up source with the specified duration. pub fn new(duration: Duration) -> Self { Self { duration } } } +/// Errors that can occur when configuring RTC wake-up sources. #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { + /// The selected pin is not a valid RTC pin. NotRtcPin, + /// The maximum number of wake-up sources has been exceeded. TooManyWakeupSources, } +/// External wake-up source (Ext0). #[derive(Debug)] #[cfg(any(esp32, esp32s3))] pub struct Ext0WakeupSource<'a, P: RtcIoWakeupPinType> { + /// The pin used as the wake-up source. pin: RefCell<&'a mut P>, + /// The level at which the wake-up event is triggered. level: WakeupLevel, } #[cfg(any(esp32, esp32s3))] impl<'a, P: RtcIoWakeupPinType> Ext0WakeupSource<'a, P> { + /// Creates a new external wake-up source (Ext0``) with the specified pin + /// and wake-up level. pub fn new(pin: &'a mut P, level: WakeupLevel) -> Self { Self { pin: RefCell::new(pin), @@ -76,14 +91,19 @@ impl<'a, P: RtcIoWakeupPinType> Ext0WakeupSource<'a, P> { } } +/// External wake-up source (Ext1). #[cfg(any(esp32, esp32s3))] pub struct Ext1WakeupSource<'a, 'b> { + /// A collection of pins used as wake-up sources. pins: RefCell<&'a mut [&'b mut dyn RtcIoWakeupPinType]>, + /// The level at which the wake-up event is triggered across all pins. level: WakeupLevel, } #[cfg(any(esp32, esp32s3))] impl<'a, 'b> Ext1WakeupSource<'a, 'b> { + /// Creates a new external wake-up source (Ext1) with the specified pins and + /// wake-up level. pub fn new(pins: &'a mut [&'b mut dyn RtcIoWakeupPinType], level: WakeupLevel) -> Self { Self { pins: RefCell::new(pins), @@ -92,6 +112,7 @@ impl<'a, 'b> Ext1WakeupSource<'a, 'b> { } } +/// External wake-up source (Ext1). #[cfg(esp32c6)] pub struct Ext1WakeupSource<'a, 'b> { pins: RefCell<&'a mut [(&'b mut dyn RtcIoWakeupPinType, WakeupLevel)]>, @@ -99,6 +120,8 @@ pub struct Ext1WakeupSource<'a, 'b> { #[cfg(esp32c6)] impl<'a, 'b> Ext1WakeupSource<'a, 'b> { + /// Creates a new external wake-up source (Ext1) with the specified pins and + /// wake-up level. pub fn new(pins: &'a mut [(&'b mut dyn RtcIoWakeupPinType, WakeupLevel)]) -> Self { Self { pins: RefCell::new(pins), @@ -118,6 +141,7 @@ pub struct RtcioWakeupSource<'a, 'b> { #[cfg(any(esp32c3, esp32s3))] impl<'a, 'b> RtcioWakeupSource<'a, 'b> { + /// Creates a new external wake-up source (Ext1). pub fn new(pins: &'a mut [(&'b mut dyn RtcIoWakeupPinType, WakeupLevel)]) -> Self { Self { pins: RefCell::new(pins), @@ -247,6 +271,7 @@ uart_wakeup_impl!(1); #[cfg(not(pmu))] bitfield::bitfield! { + /// Represents the wakeup triggers. #[derive(Default, Clone, Copy)] pub struct WakeTriggers(u16); impl Debug; @@ -276,6 +301,7 @@ bitfield::bitfield! { #[cfg(pmu)] bitfield::bitfield! { + /// Represents the wakeup triggers. #[derive(Default, Clone, Copy)] pub struct WakeTriggers(u16); impl Debug; @@ -306,6 +332,8 @@ bitfield::bitfield! { pub usb, set_usb: 14; } +/// Trait representing a wakeup source. pub trait WakeSource { + /// Configures the RTC and applies the wakeup triggers. fn apply(&self, rtc: &Rtc<'_>, triggers: &mut WakeTriggers, sleep_config: &mut RtcSleepConfig); } diff --git a/esp-hal/src/sha.rs b/esp-hal/src/sha.rs index 2213cb68e46..20861a53951 100644 --- a/esp-hal/src/sha.rs +++ b/esp-hal/src/sha.rs @@ -57,8 +57,6 @@ //! ## Implementation State //! - DMA-SHA Mode is not supported. -#![allow(missing_docs)] // TODO: Remove when able - use core::{convert::Infallible, marker::PhantomData}; /// Re-export digest for convenience @@ -99,10 +97,17 @@ impl crate::InterruptConfigurable for Context { } impl Context { + /// Indicates if the SHA context is in the first run. + /// + /// Returns `true` if this is the first time processing data with the SHA + /// instance, otherwise returns `false`. pub fn first_run(&self) -> bool { self.first_run } + /// Indicates if the SHA context has finished processing the data. + /// + /// Returns `true` if the SHA calculation is complete, otherwise returns. pub fn finished(&self) -> bool { self.finished } @@ -122,8 +127,14 @@ impl Context { // - This means that we need to buffer bytes coming in up to 4 u8's in order // to create a full u32 -// This implementation might fail after u32::MAX/8 bytes, to increase please see -// ::finish() length/self.cursor usage +/// Trait for defining the behavior of a SHA algorithm instance. +/// +/// This trait encapsulates the operations and configuration for a specific SHA +/// algorithm and provides methods for processing data buffers and calculating +/// the final hash. +/// +/// This implementation might fail after u32::MAX/8 bytes, to increase please +/// see ::finish() length/self.cursor usage pub trait Sha: core::ops::DerefMut> { /// Constant containing the name of the algorithm as a string. const ALGORITHM: &'static str; @@ -132,8 +143,14 @@ pub trait Sha: core::ops::DerefMut> { #[cfg(not(esp32))] fn mode_as_bits() -> u8; + /// Returns the length of the chunk that the algorithm processes at a time. + /// + /// For example, in SHA-256, this would typically return 64 bytes. fn chunk_length(&self) -> usize; + /// Returns the length of the resulting digest produced by the algorithm. + /// + /// For example, in SHA-256, this would return 32 bytes. fn digest_length(&self) -> usize; /// ESP32 requires that a control register to be written to calculate the @@ -141,10 +158,16 @@ pub trait Sha: core::ops::DerefMut> { #[cfg(esp32)] fn load_reg(&self); + /// Checks if the SHA peripheral is busy processing data. + /// + /// Returns `true` if the SHA peripheral is busy, `false` otherwise. /// ESP32 uses a different register per hash mode. #[cfg(esp32)] fn is_busy(&self) -> bool; + /// Checks if the SHA peripheral is busy processing data. + /// + /// Returns `true` if the SHA peripheral is busy, `false` otherwise. #[cfg(not(esp32))] fn is_busy(&self) -> bool { // Safety: This is safe because we only read `SHA_BUSY_REG` @@ -152,9 +175,17 @@ pub trait Sha: core::ops::DerefMut> { sha.busy().read().bits() != 0 } + /// Processes the data buffer and updates the hash state. + /// + /// This method is platform-specific and differs for ESP32 and non-ESP32 + /// platforms. #[cfg(esp32)] fn process_buffer(&mut self); + /// Processes the data buffer and updates the hash state. + /// + /// This method is platform-specific and differs for ESP32 and non-ESP32 + /// platforms. #[cfg(not(esp32))] fn process_buffer(&mut self) { // Safety: This is safe because digest state is restored and saved between @@ -193,6 +224,11 @@ pub trait Sha: core::ops::DerefMut> { self.saved_digest.replace(saved_digest); } + /// Flushes any remaining data from the internal buffer to the SHA + /// peripheral. + /// + /// Returns a `Result` indicating whether the flush was successful or if the + /// operation would block. fn flush_data(&mut self) -> nb::Result<(), Infallible> { if self.is_busy() { return Err(nb::Error::WouldBlock); @@ -234,8 +270,9 @@ pub trait Sha: core::ops::DerefMut> { Ok(()) } - // This function ensures that incoming data is aligned to u32 (due to issues - // with cpy_mem) + /// Writes data into the SHA buffer. + /// This function ensures that incoming data is aligned to u32 (due to + /// issues with `cpy_mem`) fn write_data<'a>(&mut self, incoming: &'a [u8]) -> nb::Result<&'a [u8], Infallible> { let mod_cursor = self.cursor % self.chunk_length(); @@ -273,6 +310,7 @@ pub trait Sha: core::ops::DerefMut> { Ok(remaining) } + /// Updates the SHA context with the provided data buffer. fn update<'a>(&mut self, buffer: &'a [u8]) -> nb::Result<&'a [u8], Infallible> { if self.is_busy() { return Err(nb::Error::WouldBlock); @@ -285,12 +323,12 @@ pub trait Sha: core::ops::DerefMut> { Ok(remaining) } - // Finish of the calculation (if not alreaedy) and copy result to output - // After `finish()` is called `update()`s will contribute to a new hash which - // can be calculated again with `finish()`. - // - // Typically output is expected to be the size of digest_length(), but smaller - // inputs can be given to get a "short hash" + /// Finish of the calculation (if not already) and copy result to output + /// After `finish()` is called `update()`s will contribute to a new hash + /// which can be calculated again with `finish()`. + /// + /// Typically output is expected to be the size of digest_length(), but + /// smaller inputs can be given to get a "short hash" fn finish(&mut self, output: &mut [u8]) -> nb::Result<(), Infallible> { // The main purpose of this function is to dynamically generate padding for the // input. Padding: Append "1" bit, Pad zeros until 512/1024 filled @@ -393,6 +431,15 @@ pub trait Sha: core::ops::DerefMut> { /// and a set of parameters macro_rules! impl_sha { ($name: ident, $mode_bits: tt, $digest_length: tt, $chunk_length: tt) => { + /// A SHA implementation struct. + /// + /// This struct is generated by the macro and represents a specific SHA hashing + /// algorithm (e.g., SHA-256, SHA-1). It manages the context and state required + /// for processing data using the selected hashing algorithm. + /// + /// The struct provides various functionalities such as initializing the hashing + /// process, updating the internal state with new data, and finalizing the + /// hashing operation to generate the final digest. pub struct $name(Context); impl $name { diff --git a/esp-hal/src/soc/esp32/cpu_control.rs b/esp-hal/src/soc/esp32/cpu_control.rs index 7319639379a..0bf03828969 100644 --- a/esp-hal/src/soc/esp32/cpu_control.rs +++ b/esp-hal/src/soc/esp32/cpu_control.rs @@ -99,14 +99,17 @@ impl Stack { } } + /// Returns the size of the stack. pub const fn len(&self) -> usize { SIZE } + /// Provides a mutable pointer to the bottom of the stack. pub fn bottom(&mut self) -> *mut u32 { self.mem.as_mut_ptr() as *mut u32 } + /// Provides a mutable pointer to the top of the stack. pub fn top(&mut self) -> *mut u32 { unsafe { self.bottom().add(SIZE / 4) } } @@ -132,9 +135,11 @@ impl<'a> Drop for AppCoreGuard<'a> { } } +/// Represents errors that can occur while working with the core. #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { + /// The core is already running. CoreAlreadyRunning, } @@ -168,6 +173,7 @@ unsafe fn internal_park_core(core: Cpu) { } impl<'d> CpuControl<'d> { + /// Creates a new instance of `CpuControl`. pub fn new(cpu_control: impl Peripheral

+ 'd) -> CpuControl<'d> { crate::into_ref!(cpu_control); diff --git a/esp-hal/src/soc/esp32/efuse/mod.rs b/esp-hal/src/soc/esp32/efuse/mod.rs index 0a6de1bac83..bf16993fc9e 100644 --- a/esp-hal/src/soc/esp32/efuse/mod.rs +++ b/esp-hal/src/soc/esp32/efuse/mod.rs @@ -47,20 +47,30 @@ use crate::peripherals::EFUSE; mod fields; +/// A struct representing the eFuse functionality of the chip. pub struct Efuse; +/// Representing different types of ESP32 chips. #[derive(PartialEq, Eq, Copy, Clone, Debug)] pub enum ChipType { + /// Represents the ESP32 D0WDQ6 chip variant. Esp32D0wdq6, + /// Represents the ESP32 D0WDQ5 chip variant. Esp32D0wdq5, + /// Represents the ESP32 D2WDQ5 chip variant. Esp32D2wdq5, + /// Represents the ESP32 Pico D2 chip variant. Esp32Picod2, + /// Represents the ESP32 Pico D4 chip variant. Esp32Picod4, + /// Represents the ESP32 Pico v3.02 chip variant. Esp32Picov302, + /// Represents an unknown or unsupported chip variant. Unknown, } impl Efuse { + /// Reads the base MAC address from the eFuse memory. pub fn read_base_mac_address() -> [u8; 6] { Self::read_field_be(MAC) } diff --git a/esp-hal/src/soc/esp32/gpio.rs b/esp-hal/src/soc/esp32/gpio.rs index fb8b29ed161..e354aae23d2 100644 --- a/esp-hal/src/soc/esp32/gpio.rs +++ b/esp-hal/src/soc/esp32/gpio.rs @@ -58,6 +58,7 @@ use crate::{ Cpu, }; +/// The total number of GPIO pins available. pub const NUM_PINS: usize = 40; pub(crate) const FUNC_IN_SEL_OFFSET: usize = 0; diff --git a/esp-hal/src/soc/esp32/mod.rs b/esp-hal/src/soc/esp32/mod.rs index be3b74f9ab3..c50c937af8c 100644 --- a/esp-hal/src/soc/esp32/mod.rs +++ b/esp-hal/src/soc/esp32/mod.rs @@ -33,15 +33,19 @@ macro_rules! chip { pub use chip; pub(crate) mod constants { + /// The base clock frequency for the I2S peripheral (Hertz). pub const I2S_SCLK: u32 = 160_000_000; + /// The default clock source for I2S operations. pub const I2S_DEFAULT_CLK_SRC: u32 = 2; - + /// The starting address of the Remote Control (RMT) module's RAM. pub const RMT_RAM_START: usize = 0x3ff56800; + /// The size, in bytes, of each RMT channel's dedicated RAM. pub const RMT_CHANNEL_RAM_SIZE: usize = 64; - + /// The lower bound of the system's DRAM (Data RAM) address space. pub const SOC_DRAM_LOW: u32 = 0x3FFA_E000; + /// The upper bound of the system's DRAM (Data RAM) address space. pub const SOC_DRAM_HIGH: u32 = 0x4000_0000; - + /// A reference clock tick of 1 MHz. pub const REF_TICK: fugit::HertzU32 = fugit::HertzU32::MHz(1); } diff --git a/esp-hal/src/soc/esp32/psram.rs b/esp-hal/src/soc/esp32/psram.rs index 83c684e3882..0ad25216335 100644 --- a/esp-hal/src/soc/esp32/psram.rs +++ b/esp-hal/src/soc/esp32/psram.rs @@ -18,8 +18,12 @@ //! //! NOTE: If you want to use `PSRAM` on `ESP32` or `ESP32-S3`, it'll work only //! in `release` mode. + +/// The starting virtual address of the PSRAM (Pseudo-SRAM) region in memory. pub const PSRAM_VADDR_START: usize = 0x3F800000; +/// Retrieves the starting virtual address of the PSRAM (Pseudo-SRAM) region in +/// memory. pub fn psram_vaddr_start() -> usize { PSRAM_VADDR_START } @@ -36,8 +40,10 @@ cfg_if::cfg_if! { } } +/// The total size of the PSRAM (Pseudo-SRAM) in bytes. pub const PSRAM_BYTES: usize = PSRAM_SIZE as usize * 1024 * 1024; +/// Initializes the PSRAM memory on supported devices. #[cfg(any(feature = "psram-2m", feature = "psram-4m", feature = "psram-8m"))] pub fn init_psram(_peripheral: impl crate::peripheral::Peripheral

) { utils::psram_init(); diff --git a/esp-hal/src/soc/esp32/trng.rs b/esp-hal/src/soc/esp32/trng.rs index f8bf24a4c83..aeb55fcab16 100644 --- a/esp-hal/src/soc/esp32/trng.rs +++ b/esp-hal/src/soc/esp32/trng.rs @@ -1,6 +1,8 @@ //! Helper functions for TRNG functionality -pub fn ensure_randomness() { +/// Enable true randomness by enabling the entropy source. +/// Blocks `ADC` usage. +pub(crate) fn ensure_randomness() { let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; let sens = unsafe { &*crate::peripherals::SENS::ptr() }; let dport = unsafe { &*crate::peripherals::DPORT::ptr() }; @@ -104,7 +106,8 @@ pub fn ensure_randomness() { } } -pub fn revert_trng() { +/// Disable true randomness. Unlocks `ADC` peripheral. +pub(crate) fn revert_trng() { let sens = unsafe { &*crate::peripherals::SENS::ptr() }; let i2s0 = unsafe { &*crate::peripherals::I2S0::ptr() }; let apb_ctrl = unsafe { &*crate::peripherals::APB_CTRL::ptr() }; diff --git a/esp-hal/src/soc/esp32c2/efuse/mod.rs b/esp-hal/src/soc/esp32c2/efuse/mod.rs index 257ceef3639..7ead2a94903 100644 --- a/esp-hal/src/soc/esp32c2/efuse/mod.rs +++ b/esp-hal/src/soc/esp32c2/efuse/mod.rs @@ -45,6 +45,7 @@ use crate::{analog::adc::Attenuation, peripherals::EFUSE}; mod fields; +/// A struct representing the eFuse functionality of the chip. pub struct Efuse; impl Efuse { diff --git a/esp-hal/src/soc/esp32c2/gpio.rs b/esp-hal/src/soc/esp32c2/gpio.rs index 103f97f6c3f..c50f33cf2d0 100644 --- a/esp-hal/src/soc/esp32c2/gpio.rs +++ b/esp-hal/src/soc/esp32c2/gpio.rs @@ -50,6 +50,7 @@ use crate::{ peripherals::GPIO, }; +/// The total number of GPIO pins available. pub const NUM_PINS: usize = 21; pub(crate) const FUNC_IN_SEL_OFFSET: usize = 0; diff --git a/esp-hal/src/soc/esp32c2/mod.rs b/esp-hal/src/soc/esp32c2/mod.rs index 71a0f469765..c8fcaa96da9 100644 --- a/esp-hal/src/soc/esp32c2/mod.rs +++ b/esp-hal/src/soc/esp32c2/mod.rs @@ -30,9 +30,12 @@ pub(crate) mod registers { } pub(crate) mod constants { + /// The lower bound of the system's DRAM (Data RAM) address space. pub const SOC_DRAM_LOW: u32 = 0x3FCA_0000; + /// The upper bound of the system's DRAM (Data RAM) address space. pub const SOC_DRAM_HIGH: u32 = 0x3FCE_0000; + /// RC FAST Clock value (Hertz). pub const RC_FAST_CLK: fugit::HertzU32 = fugit::HertzU32::kHz(17500); } diff --git a/esp-hal/src/soc/esp32c2/trng.rs b/esp-hal/src/soc/esp32c2/trng.rs index 88c5db4b23f..92a565ae665 100644 --- a/esp-hal/src/soc/esp32c2/trng.rs +++ b/esp-hal/src/soc/esp32c2/trng.rs @@ -15,6 +15,8 @@ const ADC_SARADC_ENT_TSENS_ADDR_LSB: u8 = 2; use crate::regi2c_write_mask; +/// Enable true randomness by enabling the entropy source. +/// Blocks `ADC` usage. pub(crate) fn ensure_randomness() { let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; let system = unsafe { &*crate::peripherals::SYSTEM::ptr() }; @@ -100,6 +102,7 @@ pub(crate) fn ensure_randomness() { } } +/// Disable true randomness. Unlocks `ADC` peripheral. pub(crate) fn revert_trng() { let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; diff --git a/esp-hal/src/soc/esp32c3/efuse/mod.rs b/esp-hal/src/soc/esp32c3/efuse/mod.rs index cf4463bbabf..2d326c6aa16 100644 --- a/esp-hal/src/soc/esp32c3/efuse/mod.rs +++ b/esp-hal/src/soc/esp32c3/efuse/mod.rs @@ -45,6 +45,7 @@ use crate::{analog::adc::Attenuation, peripherals::EFUSE}; mod fields; +/// A struct representing the eFuse functionality of the chip. pub struct Efuse; impl Efuse { diff --git a/esp-hal/src/soc/esp32c3/gpio.rs b/esp-hal/src/soc/esp32c3/gpio.rs index aca0ebe4878..4c6a3091301 100644 --- a/esp-hal/src/soc/esp32c3/gpio.rs +++ b/esp-hal/src/soc/esp32c3/gpio.rs @@ -51,6 +51,7 @@ use crate::{ peripherals::GPIO, }; +/// The total number of GPIO pins available. pub const NUM_PINS: usize = 22; pub(crate) const FUNC_IN_SEL_OFFSET: usize = 0; diff --git a/esp-hal/src/soc/esp32c3/mod.rs b/esp-hal/src/soc/esp32c3/mod.rs index b4e9fc23dd1..b74aa9a4460 100644 --- a/esp-hal/src/soc/esp32c3/mod.rs +++ b/esp-hal/src/soc/esp32c3/mod.rs @@ -34,17 +34,26 @@ pub(crate) mod registers { } pub(crate) mod constants { + /// The base clock frequency for the I2S peripheral (Hertz). pub const I2S_SCLK: u32 = 160_000_000; + /// The default clock source for I2S operations. pub const I2S_DEFAULT_CLK_SRC: u8 = 2; + /// The starting address of the Remote Control (RMT) module's RAM. pub const RMT_RAM_START: usize = 0x60016400; + /// The size, in bytes, of each RMT channel's dedicated RAM. pub const RMT_CHANNEL_RAM_SIZE: usize = 48; + /// RMT Clock source value. pub const RMT_CLOCK_SRC: u8 = 1; + /// RMT Clock source frequence. pub const RMT_CLOCK_SRC_FREQ: fugit::HertzU32 = fugit::HertzU32::MHz(80); + /// The lower bound of the system's DRAM (Data RAM) address space. pub const SOC_DRAM_LOW: u32 = 0x3FC8_0000; + /// The upper bound of the system's DRAM (Data RAM) address space. pub const SOC_DRAM_HIGH: u32 = 0x3FCE_0000; + /// RC FAST Clock value (Hertz). pub const RC_FAST_CLK: fugit::HertzU32 = fugit::HertzU32::kHz(17500); } diff --git a/esp-hal/src/soc/esp32c3/trng.rs b/esp-hal/src/soc/esp32c3/trng.rs index b78ed8d49a4..a1e7f5d281b 100644 --- a/esp-hal/src/soc/esp32c3/trng.rs +++ b/esp-hal/src/soc/esp32c3/trng.rs @@ -15,6 +15,8 @@ const ADC_SARADC_ENT_TSENS_ADDR_LSB: u8 = 2; use crate::regi2c_write_mask; +/// Enable true randomness by enabling the entropy source. +/// Blocks `ADC` usage. pub(crate) fn ensure_randomness() { let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; let system = unsafe { &*crate::peripherals::SYSTEM::ptr() }; @@ -100,6 +102,7 @@ pub(crate) fn ensure_randomness() { } } +/// Disable true randomness. Unlocks `ADC` peripheral. pub(crate) fn revert_trng() { let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; diff --git a/esp-hal/src/soc/esp32c6/efuse/mod.rs b/esp-hal/src/soc/esp32c6/efuse/mod.rs index 97711a5a3e4..e56293ba3cc 100644 --- a/esp-hal/src/soc/esp32c6/efuse/mod.rs +++ b/esp-hal/src/soc/esp32c6/efuse/mod.rs @@ -45,6 +45,7 @@ use crate::{analog::adc::Attenuation, peripherals::EFUSE}; mod fields; +/// A struct representing the eFuse functionality of the chip. pub struct Efuse; impl Efuse { diff --git a/esp-hal/src/soc/esp32c6/gpio.rs b/esp-hal/src/soc/esp32c6/gpio.rs index 74d524f10d5..4e688237e06 100644 --- a/esp-hal/src/soc/esp32c6/gpio.rs +++ b/esp-hal/src/soc/esp32c6/gpio.rs @@ -51,6 +51,7 @@ use crate::{ peripherals::GPIO, }; +/// The total number of GPIO pins available. pub const NUM_PINS: usize = 31; pub(crate) const FUNC_IN_SEL_OFFSET: usize = 0; diff --git a/esp-hal/src/soc/esp32c6/lp_core.rs b/esp-hal/src/soc/esp32c6/lp_core.rs index 24330a3492f..151e47268f1 100644 --- a/esp-hal/src/soc/esp32c6/lp_core.rs +++ b/esp-hal/src/soc/esp32c6/lp_core.rs @@ -23,8 +23,10 @@ use esp32c6 as pac; use crate::peripheral::{Peripheral, PeripheralRef}; +/// Represents the possible wakeup sources for the LP (Low Power) core. #[derive(Debug, Clone, Copy)] pub enum LpCoreWakeupSource { + /// Wakeup source from the HP (High Performance) CPU. HpCpu, } @@ -39,6 +41,7 @@ pub enum LpCoreClockSource { XtalD2Clk, } +/// Represents the Low Power (LP) core peripheral. pub struct LpCore<'d> { _lp_core: PeripheralRef<'d, crate::soc::peripherals::LP_CORE>, } diff --git a/esp-hal/src/soc/esp32c6/mod.rs b/esp-hal/src/soc/esp32c6/mod.rs index 2f7d2138554..d57051c7990 100644 --- a/esp-hal/src/soc/esp32c6/mod.rs +++ b/esp-hal/src/soc/esp32c6/mod.rs @@ -36,22 +36,33 @@ pub(crate) mod registers { } pub(crate) mod constants { + /// The default clock source for the timer group. pub const TIMG_DEFAULT_CLK_SRC: u8 = 1; + /// The clock frequency for the I2S peripheral in Hertz. pub const I2S_SCLK: u32 = 160_000_000; + /// The default clock source for the I2S peripheral. pub const I2S_DEFAULT_CLK_SRC: u8 = 2; + /// The starting address of the RMT (Remote Control) peripheral's RAM. pub const RMT_RAM_START: usize = 0x60006400; + /// The size of each RMT channel's RAM in bytes. pub const RMT_CHANNEL_RAM_SIZE: usize = 48; + /// The default clock source for the RMT peripheral. pub const RMT_CLOCK_SRC: u8 = 1; + /// The frequency of the RMT clock source in Hertz. pub const RMT_CLOCK_SRC_FREQ: fugit::HertzU32 = fugit::HertzU32::MHz(80); + /// The clock frequency for the Parallel IO peripheral in Hertz. pub const PARL_IO_SCLK: u32 = 240_000_000; + /// The lower address boundary for system DRAM. pub const SOC_DRAM_LOW: u32 = 0x4080_0000; + /// The upper address boundary for system DRAM. pub const SOC_DRAM_HIGH: u32 = 0x4088_0000; - pub const RC_FAST_CLK: fugit::HertzU32 = fugit::HertzU32::kHz(17500); + /// RC FAST Clock value (Hertz). + pub const RC_FAST_CLK: fugit::HertzU32 = fugit::HertzU32::kHz(17_500); } #[export_name = "__post_init"] diff --git a/esp-hal/src/soc/esp32c6/trng.rs b/esp-hal/src/soc/esp32c6/trng.rs index cfe6e75daf7..576f5c0442b 100644 --- a/esp-hal/src/soc/esp32c6/trng.rs +++ b/esp-hal/src/soc/esp32c6/trng.rs @@ -60,6 +60,8 @@ const ADC_SARADC2_ENCAL_REF_ADDR: u8 = 0x7; const ADC_SARADC2_ENCAL_REF_ADDR_MSB: u8 = 6; const ADC_SARADC2_ENCAL_REF_ADDR_LSB: u8 = 6; +/// Enable true randomness by enabling the entropy source. +/// Blocks `ADC` usage. pub(crate) fn ensure_randomness() { let pcr = unsafe { &*crate::peripherals::PCR::ptr() }; let pmu = unsafe { &*crate::peripherals::PMU::ptr() }; @@ -190,10 +192,9 @@ pub(crate) fn ensure_randomness() { } } -#[allow(unused)] +/// Disable true randomness. Unlocks `ADC` peripheral. pub(crate) fn revert_trng() { let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; - let pmu = unsafe { &*crate::peripherals::PMU::ptr() }; let pcr = unsafe { &*crate::peripherals::PCR::ptr() }; unsafe { diff --git a/esp-hal/src/soc/esp32h2/efuse/mod.rs b/esp-hal/src/soc/esp32h2/efuse/mod.rs index 81df45fad38..131a9287470 100644 --- a/esp-hal/src/soc/esp32h2/efuse/mod.rs +++ b/esp-hal/src/soc/esp32h2/efuse/mod.rs @@ -45,6 +45,7 @@ use crate::peripherals::EFUSE; mod fields; +/// A struct representing the eFuse functionality of the chip. pub struct Efuse; impl Efuse { diff --git a/esp-hal/src/soc/esp32h2/gpio.rs b/esp-hal/src/soc/esp32h2/gpio.rs index d6f2710eec1..519b6f56b6a 100644 --- a/esp-hal/src/soc/esp32h2/gpio.rs +++ b/esp-hal/src/soc/esp32h2/gpio.rs @@ -52,6 +52,7 @@ use crate::{ }; // https://github.com/espressif/esp-idf/blob/df9310a/components/soc/esp32h2/gpio_periph.c#L42 +/// The total number of GPIO pins available. pub const NUM_PINS: usize = 28; pub(crate) const FUNC_IN_SEL_OFFSET: usize = 0; diff --git a/esp-hal/src/soc/esp32h2/mod.rs b/esp-hal/src/soc/esp32h2/mod.rs index 457e0ff9f15..225a2ca93d5 100644 --- a/esp-hal/src/soc/esp32h2/mod.rs +++ b/esp-hal/src/soc/esp32h2/mod.rs @@ -35,21 +35,33 @@ pub(crate) mod registers { } pub(crate) mod constants { + /// Default clock source for the timer group (TIMG) peripheral. pub const TIMG_DEFAULT_CLK_SRC: u8 = 2; + /// Default clock source for the I2S peripheral. pub const I2S_DEFAULT_CLK_SRC: u8 = 1; + /// Clock frequency for the I2S peripheral, in Hertz. pub const I2S_SCLK: u32 = 96_000_000; + /// Start address of the RMT (Remote Control) peripheral's RAM. pub const RMT_RAM_START: usize = 0x60007400; + /// Size of the RAM allocated per RMT channel, in bytes. pub const RMT_CHANNEL_RAM_SIZE: usize = 48; + /// Clock source for the RMT peripheral (false = default source). pub const RMT_CLOCK_SRC: bool = false; + /// Frequency of the RMT clock source, in Hertz. pub const RMT_CLOCK_SRC_FREQ: fugit::HertzU32 = fugit::HertzU32::MHz(32); + /// System clock frequency for the parallel I/O (PARL IO) peripheral, in + /// Hertz. pub const PARL_IO_SCLK: u32 = 96_000_000; + /// Start address of the system's DRAM (low range). pub const SOC_DRAM_LOW: u32 = 0x4080_0000; + /// End address of the system's DRAM (high range). pub const SOC_DRAM_HIGH: u32 = 0x4085_0000; + /// RC FAST Clock value (Hertz). pub const RC_FAST_CLK: fugit::HertzU32 = fugit::HertzU32::kHz(17500); } diff --git a/esp-hal/src/soc/esp32h2/trng.rs b/esp-hal/src/soc/esp32h2/trng.rs index 0b1e25e1188..e0c3aab93c5 100644 --- a/esp-hal/src/soc/esp32h2/trng.rs +++ b/esp-hal/src/soc/esp32h2/trng.rs @@ -56,6 +56,8 @@ const REGI2C_RTC_WR_CNTL_S: u8 = 24; const REGI2C_RTC_DATA_V: u8 = 0xFF; const REGI2C_RTC_DATA_S: u8 = 16; +/// Enable true randomness by enabling the entropy source. +/// Blocks `ADC` usage. pub(crate) fn ensure_randomness() { let pcr = unsafe { &*crate::peripherals::PCR::ptr() }; let pmu = unsafe { &*crate::peripherals::PMU::ptr() }; @@ -177,6 +179,7 @@ pub(crate) fn ensure_randomness() { } } +/// Disable true randomness. Unlocks `ADC` peripheral. pub(crate) fn revert_trng() { let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; let pcr = unsafe { &*crate::peripherals::PCR::ptr() }; diff --git a/esp-hal/src/soc/esp32s2/efuse/mod.rs b/esp-hal/src/soc/esp32s2/efuse/mod.rs index e93849c107b..61d2975344e 100644 --- a/esp-hal/src/soc/esp32s2/efuse/mod.rs +++ b/esp-hal/src/soc/esp32s2/efuse/mod.rs @@ -45,6 +45,7 @@ use crate::peripherals::EFUSE; mod fields; +/// A struct representing the eFuse functionality of the chip. pub struct Efuse; impl Efuse { diff --git a/esp-hal/src/soc/esp32s2/gpio.rs b/esp-hal/src/soc/esp32s2/gpio.rs index 78cd541c23e..bdb53bc9423 100644 --- a/esp-hal/src/soc/esp32s2/gpio.rs +++ b/esp-hal/src/soc/esp32s2/gpio.rs @@ -64,6 +64,7 @@ use crate::{ peripherals::GPIO, }; +/// The total number of GPIO pins available. pub const NUM_PINS: usize = 47; pub(crate) const FUNC_IN_SEL_OFFSET: usize = 0; diff --git a/esp-hal/src/soc/esp32s2/mod.rs b/esp-hal/src/soc/esp32s2/mod.rs index a19d919f8f2..e6b4d10add5 100644 --- a/esp-hal/src/soc/esp32s2/mod.rs +++ b/esp-hal/src/soc/esp32s2/mod.rs @@ -38,15 +38,19 @@ macro_rules! chip { pub use chip; pub(crate) mod constants { + /// System clock frequency for the I2S peripheral, in Hertz. pub const I2S_SCLK: u32 = 160_000_000; + /// Default clock source for the I2S peripheral. pub const I2S_DEFAULT_CLK_SRC: u32 = 2; - + /// Start address of the RMT (Remote Control) peripheral's RAM. pub const RMT_RAM_START: usize = 0x3f416400; + /// Size of the RAM allocated per RMT channel, in bytes. pub const RMT_CHANNEL_RAM_SIZE: usize = 64; - + /// Start address of the system's DRAM (low range). pub const SOC_DRAM_LOW: u32 = 0x3FFB_0000; + /// End address of the system's DRAM (high range). pub const SOC_DRAM_HIGH: u32 = 0x4000_0000; - + /// Reference clock tick frequency, set to 1 MHz. pub const REF_TICK: fugit::HertzU32 = fugit::HertzU32::MHz(1); } diff --git a/esp-hal/src/soc/esp32s2/psram.rs b/esp-hal/src/soc/esp32s2/psram.rs index a47fcbd6d2d..54fbb2ec2e0 100644 --- a/esp-hal/src/soc/esp32s2/psram.rs +++ b/esp-hal/src/soc/esp32s2/psram.rs @@ -17,6 +17,7 @@ //! `4MB`, and `8MB`. const PSRAM_VADDR: u32 = 0x3f500000; +/// Returns the start address of the PSRAM virtual address space. pub fn psram_vaddr_start() -> usize { PSRAM_VADDR_START } @@ -33,10 +34,14 @@ cfg_if::cfg_if! { } } +/// The total size of the PSRAM in bytes, calculated from the PSRAM size +/// constant. pub const PSRAM_BYTES: usize = PSRAM_SIZE as usize * 1024 * 1024; +/// The start address of the PSRAM virtual address space. pub const PSRAM_VADDR_START: usize = PSRAM_VADDR as usize; +/// Initialize PSRAM to be used for data. #[cfg(any(feature = "psram-2m", feature = "psram-4m", feature = "psram-8m"))] pub fn init_psram(_peripheral: impl crate::peripheral::Peripheral

) { #[allow(unused)] diff --git a/esp-hal/src/soc/esp32s2/trng.rs b/esp-hal/src/soc/esp32s2/trng.rs index 2999ac1d339..48eeb6f9d33 100644 --- a/esp-hal/src/soc/esp32s2/trng.rs +++ b/esp-hal/src/soc/esp32s2/trng.rs @@ -45,6 +45,8 @@ const I2C_RTC_BBPLL_MASK: u32 = 1 << 17; const I2C_RTC_SAR_MASK: u32 = 1 << 18; const I2C_RTC_BOD_MASK: u32 = 1 << 22; +/// Enable true randomness by enabling the entropy source. +/// Blocks `ADC` usage. pub(crate) fn ensure_randomness() { let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; let dport = unsafe { &*crate::peripherals::SYSTEM::ptr() }; @@ -157,7 +159,8 @@ pub(crate) fn ensure_randomness() { } } -pub fn revert_trng() { +/// Disable true randomness. Unlocks `ADC` peripheral. +pub(crate) fn revert_trng() { let dport = unsafe { &*crate::peripherals::SYSTEM::ptr() }; let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; let sens = unsafe { &*crate::peripherals::SENS::ptr() }; diff --git a/esp-hal/src/soc/esp32s2/ulp_core.rs b/esp-hal/src/soc/esp32s2/ulp_core.rs index cedfef686e0..579317b2a8f 100644 --- a/esp-hal/src/soc/esp32s2/ulp_core.rs +++ b/esp-hal/src/soc/esp32s2/ulp_core.rs @@ -42,16 +42,20 @@ use esp32s2 as pac; use crate::peripheral::{Peripheral, PeripheralRef}; +/// Enum representing the possible wakeup sources for the ULP core. #[derive(Debug, Clone, Copy)] pub enum UlpCoreWakeupSource { + /// Wakeup source from the HP (High Performance) CPU. HpCpu, } +/// Structure representing the ULP (Ultra-Low Power) core. pub struct UlpCore<'d> { _lp_core: PeripheralRef<'d, crate::soc::peripherals::ULP_RISCV_CORE>, } impl<'d> UlpCore<'d> { + /// Creates a new instance of the `UlpCore` struct. pub fn new(lp_core: impl Peripheral

+ 'd) -> Self { crate::into_ref!(lp_core); @@ -70,6 +74,7 @@ impl<'d> UlpCore<'d> { // ulp_stop(); // } + /// Runs the ULP core with the specified wakeup source. pub fn run(&mut self, wakeup_src: UlpCoreWakeupSource) { ulp_run(wakeup_src); } diff --git a/esp-hal/src/soc/esp32s3/cpu_control.rs b/esp-hal/src/soc/esp32s3/cpu_control.rs index efe7397681b..403ddd98887 100644 --- a/esp-hal/src/soc/esp32s3/cpu_control.rs +++ b/esp-hal/src/soc/esp32s3/cpu_control.rs @@ -100,14 +100,17 @@ impl Stack { } } + /// Returns the length of the stack in bytes. pub const fn len(&self) -> usize { SIZE } + /// Returns a mutable pointer to the bottom of the stack. pub fn bottom(&mut self) -> *mut u32 { self.mem.as_mut_ptr() as *mut u32 } + /// Returns a mutable pointer to the top of the stack. pub fn top(&mut self) -> *mut u32 { unsafe { self.bottom().add(SIZE / 4) } } @@ -132,9 +135,11 @@ impl<'a> Drop for AppCoreGuard<'a> { } } +/// Represents errors that can occur while working with the core. #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { + /// The core is already running. CoreAlreadyRunning, } @@ -168,6 +173,7 @@ unsafe fn internal_park_core(core: Cpu) { } impl<'d> CpuControl<'d> { + /// Creates a new instance of `CpuControl`. pub fn new(cpu_control: impl Peripheral

+ 'd) -> CpuControl<'d> { crate::into_ref!(cpu_control); diff --git a/esp-hal/src/soc/esp32s3/efuse/mod.rs b/esp-hal/src/soc/esp32s3/efuse/mod.rs index 8acdc754326..72fc1d2c37e 100644 --- a/esp-hal/src/soc/esp32s3/efuse/mod.rs +++ b/esp-hal/src/soc/esp32s3/efuse/mod.rs @@ -45,6 +45,7 @@ use crate::{analog::adc::Attenuation, peripherals::EFUSE}; mod fields; +/// A struct representing the eFuse functionality of the chip. pub struct Efuse; impl Efuse { diff --git a/esp-hal/src/soc/esp32s3/gpio.rs b/esp-hal/src/soc/esp32s3/gpio.rs index 96f0c6a3658..5ee417e4e57 100644 --- a/esp-hal/src/soc/esp32s3/gpio.rs +++ b/esp-hal/src/soc/esp32s3/gpio.rs @@ -52,6 +52,7 @@ use crate::{ peripherals::GPIO, }; +/// The total number of GPIO pins available. pub const NUM_PINS: usize = 49; pub(crate) const FUNC_IN_SEL_OFFSET: usize = 0; diff --git a/esp-hal/src/soc/esp32s3/mod.rs b/esp-hal/src/soc/esp32s3/mod.rs index f711304123c..0cf538d17c2 100644 --- a/esp-hal/src/soc/esp32s3/mod.rs +++ b/esp-hal/src/soc/esp32s3/mod.rs @@ -39,17 +39,26 @@ macro_rules! chip { pub use chip; pub(crate) mod constants { + /// The base clock frequency for the I2S peripheral (Hertz). pub const I2S_SCLK: u32 = 160_000_000; + /// The default clock source for I2S operations. pub const I2S_DEFAULT_CLK_SRC: u8 = 2; + /// The starting address of the Remote Control (RMT) module's RAM. pub const RMT_RAM_START: usize = 0x60016800; + /// The size, in bytes, of each RMT channel's dedicated RAM. pub const RMT_CHANNEL_RAM_SIZE: usize = 48; + /// RMT Clock source value. pub const RMT_CLOCK_SRC: u8 = 1; + /// RMT Clock source frequence. pub const RMT_CLOCK_SRC_FREQ: fugit::HertzU32 = fugit::HertzU32::MHz(80); + /// The lower bound of the system's DRAM (Data RAM) address space. pub const SOC_DRAM_LOW: u32 = 0x3FC8_8000; + /// The upper bound of the system's DRAM (Data RAM) address space. pub const SOC_DRAM_HIGH: u32 = 0x3FD0_0000; + /// A reference clock tick of 1 MHz. pub const RC_FAST_CLK: fugit::HertzU32 = fugit::HertzU32::kHz(17500); } @@ -171,6 +180,7 @@ unsafe fn post_init() { Wdt::::set_wdt_enabled(false); } +/// Write back a specific range of data in the cache. #[doc(hidden)] #[link_section = ".rwtext"] pub unsafe fn cache_writeback_addr(addr: u32, size: u32) { @@ -185,6 +195,7 @@ pub unsafe fn cache_writeback_addr(addr: u32, size: u32) { Cache_Resume_DCache_Autoload(autoload); } +/// Invalidate a specific range of addresses in the cache. #[doc(hidden)] #[link_section = ".rwtext"] pub unsafe fn cache_invalidate_addr(addr: u32, size: u32) { @@ -194,6 +205,7 @@ pub unsafe fn cache_invalidate_addr(addr: u32, size: u32) { Cache_Invalidate_Addr(addr, size); } +/// Get the size of a cache line in the DCache. #[doc(hidden)] #[link_section = ".rwtext"] pub unsafe fn cache_get_dcache_line_size() -> u32 { diff --git a/esp-hal/src/soc/esp32s3/psram.rs b/esp-hal/src/soc/esp32s3/psram.rs index f9f986af9de..59aa01d16e4 100644 --- a/esp-hal/src/soc/esp32s3/psram.rs +++ b/esp-hal/src/soc/esp32s3/psram.rs @@ -18,6 +18,7 @@ static mut PSRAM_VADDR: u32 = 0x3C000000; +/// Returns the start address of the PSRAM virtual address space. pub fn psram_vaddr_start() -> usize { unsafe { PSRAM_VADDR as usize } } @@ -42,6 +43,8 @@ cfg_if::cfg_if! { } } +/// The total size of the PSRAM in bytes, calculated from the PSRAM size +/// constant. pub const PSRAM_BYTES: usize = PSRAM_SIZE as usize * 1024 * 1024; /// Initialize PSRAM to be used for data. @@ -862,14 +865,21 @@ pub(crate) mod utils { fn esp_rom_opiflash_pin_config(); } + /// Represents the operational mode registers of an OPI PSRAM. #[derive(Default)] #[repr(C)] struct OpiPsramModeReg { + // Mode register 0 (MR0). pub mr0: u8, + // Mode register 1 (MR1). pub mr1: u8, + // Mode register 2 (MR2). pub mr2: u8, + // Mode register 3 (MR3). pub mr3: u8, + // Mode register 4 (MR4). pub mr4: u8, + // Mode register 8 (MR8). pub mr8: u8, } diff --git a/esp-hal/src/soc/esp32s3/trng.rs b/esp-hal/src/soc/esp32s3/trng.rs index c67933c8f5c..fc98ddda813 100644 --- a/esp-hal/src/soc/esp32s3/trng.rs +++ b/esp-hal/src/soc/esp32s3/trng.rs @@ -17,6 +17,8 @@ const ADC_SARADC_DTEST_RTC_ADDR_LSB: u32 = 0; use crate::regi2c_write_mask; +/// Enable true randomness by enabling the entropy source. +/// Blocks `ADC` usage. pub(crate) fn ensure_randomness() { unsafe { let rtc_cntl = &*crate::peripherals::RTC_CNTL::ptr(); @@ -117,7 +119,8 @@ pub(crate) fn ensure_randomness() { } } -pub fn revert_trng() { +/// Disable true randomness. Unlocks `ADC` peripheral. +pub(crate) fn revert_trng() { let system = unsafe { &*crate::peripherals::SYSTEM::ptr() }; let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; let sens = unsafe { &*crate::peripherals::SENS::ptr() }; diff --git a/esp-hal/src/soc/esp32s3/ulp_core.rs b/esp-hal/src/soc/esp32s3/ulp_core.rs index f704a2a171b..865387bcb15 100644 --- a/esp-hal/src/soc/esp32s3/ulp_core.rs +++ b/esp-hal/src/soc/esp32s3/ulp_core.rs @@ -42,16 +42,20 @@ use esp32s3 as pac; use crate::peripheral::{Peripheral, PeripheralRef}; +/// Enum representing the possible wakeup sources for the ULP core. #[derive(Debug, Clone, Copy)] pub enum UlpCoreWakeupSource { + /// Wakeup source from the HP (High Performance) CPU. HpCpu, } +/// Structure representing the ULP (Ultra-Low Power) core. pub struct UlpCore<'d> { _lp_core: PeripheralRef<'d, crate::soc::peripherals::ULP_RISCV_CORE>, } impl<'d> UlpCore<'d> { + /// Creates a new instance of the `UlpCore` struct. pub fn new(lp_core: impl Peripheral

+ 'd) -> Self { crate::into_ref!(lp_core); @@ -66,10 +70,12 @@ impl<'d> UlpCore<'d> { this } + /// Stops the ULP core. pub fn stop(&mut self) { ulp_stop(); } + /// Runs the ULP core with the specified wakeup source. pub fn run(&mut self, wakeup_src: UlpCoreWakeupSource) { ulp_run(wakeup_src); } diff --git a/esp-hal/src/soc/mod.rs b/esp-hal/src/soc/mod.rs index 47d00c33452..d364895a771 100644 --- a/esp-hal/src/soc/mod.rs +++ b/esp-hal/src/soc/mod.rs @@ -1,5 +1,3 @@ -#![allow(missing_docs)] // TODO: Remove when able - use portable_atomic::{AtomicU8, Ordering}; pub use self::implementation::*; @@ -26,8 +24,10 @@ mod efuse_field; static MAC_OVERRIDE_STATE: AtomicU8 = AtomicU8::new(0); static mut MAC_OVERRIDE: [u8; 6] = [0; 6]; +/// Error indicating issues with setting the MAC address. #[derive(PartialEq, Eq, Copy, Clone, Debug)] pub enum SetMacError { + /// The MAC address has already been set and cannot be changed. AlreadySet, } diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index a155bbf6c2b..1c479a532d2 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -96,9 +96,14 @@ pub mod prelude { }; } +/// Enumeration of possible SPI interrupt events. #[cfg(not(any(esp32, esp32s2)))] #[derive(EnumSetType)] pub enum SpiInterrupt { + /// Indicates that the SPI transaction has completed successfully. + /// + /// This interrupt is triggered when an SPI transaction has finished + /// transmitting and receiving data. TransDone, } @@ -114,26 +119,44 @@ const EMPTY_WRITE_PAD: u8 = 0x00u8; #[allow(unused)] const MAX_DMA_SIZE: usize = 32736; -/// SPI command, 1 to 16 bits. +/// SPI commands, each consisting of a 16-bit command value and a data mode. /// +/// Used to define specific commands sent over the SPI bus. /// Can be [Command::None] if command phase should be suppressed. pub enum Command { + /// No command is sent. None, + /// Command1. Command1(u16, SpiDataMode), + /// Command2. Command2(u16, SpiDataMode), + /// Command3. Command3(u16, SpiDataMode), + /// Command4. Command4(u16, SpiDataMode), + /// Command5. Command5(u16, SpiDataMode), + /// Command6. Command6(u16, SpiDataMode), + /// Command7. Command7(u16, SpiDataMode), + /// Command8. Command8(u16, SpiDataMode), + /// Command9. Command9(u16, SpiDataMode), + /// Command10. Command10(u16, SpiDataMode), + /// Command11. Command11(u16, SpiDataMode), + /// Command12. Command12(u16, SpiDataMode), + /// Command13. Command13(u16, SpiDataMode), + /// Command14. Command14(u16, SpiDataMode), + /// Command15. Command15(u16, SpiDataMode), + /// Command16. Command16(u16, SpiDataMode), } @@ -209,42 +232,76 @@ impl Command { } } -/// SPI address, 1 to 32 bits. +/// SPI address, ranging from 1 to 32 bits, paired with a data mode. /// +/// This can be used to specify the address phase of SPI transactions. /// Can be [Address::None] if address phase should be suppressed. pub enum Address { + /// No address phase. None, + /// Address with 1-bit. Address1(u32, SpiDataMode), + /// Address with 2-bit. Address2(u32, SpiDataMode), + /// Address with 3-bit. Address3(u32, SpiDataMode), + /// Address with 4-bit. Address4(u32, SpiDataMode), + /// Address with 5-bit. Address5(u32, SpiDataMode), + /// Address with 6-bit. Address6(u32, SpiDataMode), + /// Address with 7-bit. Address7(u32, SpiDataMode), + /// Address with 8-bit. Address8(u32, SpiDataMode), + /// Address with 9-bit. Address9(u32, SpiDataMode), + /// Address with 10-bit. Address10(u32, SpiDataMode), + /// Address with 11-bit. Address11(u32, SpiDataMode), + /// Address with 12-bit. Address12(u32, SpiDataMode), + /// Address with 13-bit. Address13(u32, SpiDataMode), + /// Address with 14-bit. Address14(u32, SpiDataMode), + /// Address with 15-bit. Address15(u32, SpiDataMode), + /// Address with 16-bit. Address16(u32, SpiDataMode), + /// Address with 17-bit. Address17(u32, SpiDataMode), + /// Address with 18-bit. Address18(u32, SpiDataMode), + /// Address with 19-bit. Address19(u32, SpiDataMode), + /// Address with 20-bit. Address20(u32, SpiDataMode), + /// Address with 21-bit. Address21(u32, SpiDataMode), + /// Address with 22-bit. Address22(u32, SpiDataMode), + /// Address with 23-bit. Address23(u32, SpiDataMode), + /// Address with 24-bit. Address24(u32, SpiDataMode), + /// Address with 25-bit. Address25(u32, SpiDataMode), + /// Address with 26-bit. Address26(u32, SpiDataMode), + /// Address with 27-bit. Address27(u32, SpiDataMode), + /// Address with 28-bit. Address28(u32, SpiDataMode), + /// Address with 29-bit. Address29(u32, SpiDataMode), + /// Address with 30-bit. Address30(u32, SpiDataMode), + /// Address with 31-bit. Address31(u32, SpiDataMode), + /// Address with 32-bit. Address32(u32, SpiDataMode), } @@ -370,6 +427,8 @@ impl Address { /// Read and Write in half duplex mode. pub trait HalfDuplexReadWrite { + /// The associated error type that will be returned in the event of a + /// failure. type Error; /// Half-duplex read. @@ -457,6 +516,10 @@ where Self::new_internal(spi, frequency, mode, clocks) } + /// Assign the SCK (Serial Clock) pin for the SPI instance. + /// + /// Sets the specified pin to push-pull output and connects it to the SPI + /// clock signal. pub fn with_sck(self, sck: impl Peripheral

+ 'd) -> Self { crate::into_ref!(sck); sck.set_to_push_pull_output(private::Internal); @@ -465,6 +528,10 @@ where self } + /// Assign the MOSI (Master Out Slave In) pin for the SPI instance. + /// + /// Sets the specified pin to push-pull output and connects it to the SPI + /// MOSI signal. pub fn with_mosi(self, mosi: impl Peripheral

+ 'd) -> Self { crate::into_ref!(mosi); mosi.set_to_push_pull_output(private::Internal); @@ -473,6 +540,9 @@ where self } + /// Assign the MISO (Master In Slave Out) pin for the SPI instance. + /// + /// Sets the specified pin to input and connects it to the SPI MISO signal. pub fn with_miso(self, miso: impl Peripheral

+ 'd) -> Self { crate::into_ref!(miso); miso.set_to_input(private::Internal); @@ -481,6 +551,10 @@ where self } + /// Assign the CS (Chip Select) pin for the SPI instance. + /// + /// Sets the specified pin to push-pull output and connects it to the SPI CS + /// signal. pub fn with_cs(self, cs: impl Peripheral

+ 'd) -> Self { crate::into_ref!(cs); cs.set_to_push_pull_output(private::Internal); @@ -555,6 +629,10 @@ where spi } + /// Change the bus frequency of the SPI instance. + /// + /// This method allows user to update the bus frequency for the SPI + /// communication after the instance has been created. pub fn change_bus_frequency(&mut self, frequency: HertzU32, clocks: &Clocks<'d>) { self.spi.ch_bus_freq(frequency, clocks); } @@ -578,6 +656,10 @@ where Self::new_internal(spi, frequency, mode, clocks) } + /// Assign the SCK (Serial Clock) pin for the SPI instance. + /// + /// Sets the specified pin to push-pull output and connects it to the SPI + /// clock signal. pub fn with_sck(self, sck: impl Peripheral

+ 'd) -> Self { crate::into_ref!(sck); sck.set_to_push_pull_output(private::Internal); @@ -586,6 +668,11 @@ where self } + /// Assign the MOSI (Master Out Slave In) pin for the SPI instance in + /// half-duplex mode. + /// + /// Enables both input and output functionality for the pin, and connects it + /// to the MOSI signal and SIO0 input signal. pub fn with_mosi( self, mosi: impl Peripheral

+ 'd, @@ -599,6 +686,11 @@ where self } + /// Assign the MISO (Master In Slave Out) pin for the SPI instance in + /// half-duplex mode. + /// + /// Enables both input and output functionality for the pin, and connects it + /// to the MISO signal and SIO1 input signal. pub fn with_miso( self, miso: impl Peripheral

+ 'd, @@ -612,6 +704,10 @@ where self } + /// Assign the SIO2 pin for the SPI instance. + /// + /// Enables both input and output functionality for the pin, and connects it + /// to the SIO2 output and input signals. pub fn with_sio2( self, sio2: impl Peripheral

+ 'd, @@ -625,6 +721,10 @@ where self } + /// Assign the SIO3 pin for the SPI instance. + /// + /// Enables both input and output functionality for the pin, and connects it + /// to the SIO3 output and input signals. pub fn with_sio3( self, sio3: impl Peripheral

+ 'd, @@ -638,6 +738,10 @@ where self } + /// Assign the CS (Chip Select) pin for the SPI instance. + /// + /// Sets the specified pin to push-pull output and connects it to the SPI CS + /// signal. pub fn with_cs(self, cs: impl Peripheral

+ 'd) -> Self { crate::into_ref!(cs); cs.set_to_push_pull_output(private::Internal); @@ -733,6 +837,10 @@ where spi } + /// Change the bus frequency of the SPI instance in half-duplex mode. + /// + /// This method allows you to update the bus frequency for the SPI + /// communication after the instance has been created. pub fn change_bus_frequency(&mut self, frequency: HertzU32, clocks: &Clocks<'d>) { self.spi.ch_bus_freq(frequency, clocks); } @@ -837,6 +945,7 @@ where } } +/// DMA (Direct Memory Access) funtionality (Master). pub mod dma { use core::{ cmp::min, @@ -868,6 +977,11 @@ pub mod dma { where M: DuplexMode, { + /// Configures the SPI instance to use DMA with the specified channel. + /// + /// This method prepares the SPI instance for DMA transfers. It + /// initializes the DMA channel for transmission and returns an + /// instance of `SpiDma` that supports DMA operations. pub fn with_dma( self, mut channel: Channel<'d, C, DmaMode>, @@ -892,6 +1006,11 @@ pub mod dma { where M: DuplexMode, { + /// Configures the SPI3 instance to use DMA with the specified channel. + /// + /// This method prepares the SPI instance for DMA transfers using SPI3 + /// and returns an instance of `SpiDma` that supports DMA + /// operations. pub fn with_dma( self, mut channel: Channel<'d, C, DmaMode>, @@ -931,6 +1050,10 @@ pub mod dma { M: DuplexMode, DmaMode: Mode, { + /// Formats the `SpiDma` instance for debugging purposes. + /// + /// This method returns a debug struct with the name "SpiDma" without + /// exposing internal details. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("SpiDma").finish() } @@ -994,6 +1117,7 @@ pub mod dma { M: DuplexMode, DmaMode: Mode, { + /// Configures the interrupt handler for the DMA-enabled SPI instance. fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) { SpiDma::set_interrupt_handler(self, handler); } @@ -1007,6 +1131,7 @@ pub mod dma { M: DuplexMode, DmaMode: Mode, { + /// Changes the SPI bus frequency for the DMA-enabled SPI instance. pub fn change_bus_frequency(&mut self, frequency: HertzU32, clocks: &Clocks<'d>) { self.spi.ch_bus_freq(frequency, clocks); } @@ -1018,6 +1143,11 @@ pub mod dma { C: DmaChannel, C::P: SpiPeripheral, { + /// Configures the DMA buffers for the SPI instance. + /// + /// This method sets up both TX and RX buffers for DMA transfers. + /// It returns an instance of `SpiDmaBus` that can be used for SPI + /// communication. pub fn with_buffers( self, dma_tx_buf: DmaTxBuf, @@ -1034,6 +1164,11 @@ pub mod dma { C: DmaChannel, C::P: SpiPeripheral, { + /// Configures the DMA buffers for asynchronous SPI communication. + /// + /// This method sets up both TX and RX buffers for DMA transfers. + /// It eturns an instance of `SpiDmaAsyncBus` to be used for + /// asynchronous SPI operations. pub fn with_buffers( self, dma_tx_buf: DmaTxBuf, @@ -1043,6 +1178,10 @@ pub mod dma { } } + /// A structure representing a DMA transfer for SPI. + /// + /// This structure holds references to the SPI instance, DMA buffers, and + /// transfer status. pub struct SpiDmaTransfer<'d, T, C, M, DmaMode, Buf> where C: DmaChannel, @@ -1083,6 +1222,10 @@ pub mod dma { } } + /// Checks if the DMA transfer is complete. + /// + /// This method returns `true` if both TX and RX operations are done, + /// and the SPI instance is no longer busy. pub fn is_done(&self) -> bool { if self.is_tx && !self.tx_future_awaited && !self.spi_dma.channel.tx.is_done() { return false; @@ -1107,6 +1250,10 @@ pub mod dma { true } + /// Waits for the DMA transfer to complete. + /// + /// This method blocks until the transfer is finished and returns the + /// `SpiDma` instance and the associated buffer. pub fn wait(mut self) -> (SpiDma<'d, T, C, M, DmaMode>, Buf) { self.spi_dma.spi.flush().ok(); fence(Ordering::Acquire); @@ -1122,6 +1269,9 @@ pub mod dma { C::P: SpiPeripheral, M: DuplexMode, { + /// Waits for the DMA transfer to complete asynchronously. + /// + /// This method awaits the completion of both TX and RX operations. pub async fn wait_for_done(&mut self) { if self.is_tx && !self.tx_future_awaited { let _ = DmaTxFuture::new(&mut self.spi_dma.channel.tx).await; @@ -1258,6 +1408,7 @@ pub mod dma { M: IsHalfDuplex, DmaMode: Mode, { + /// Perform a half-duplex read operation using DMA. #[allow(clippy::type_complexity)] #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] pub fn read( @@ -1335,6 +1486,7 @@ pub mod dma { Ok(SpiDmaTransfer::new(self, buffer, bytes_to_read > 0, false)) } + /// Perform a half-duplex write operation using DMA. #[allow(clippy::type_complexity)] #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] pub fn write( @@ -1413,6 +1565,10 @@ pub mod dma { } } + /// A DMA-capable SPI bus that handles full-duplex transfers. + /// + /// This structure is responsible for managing SPI transfers using DMA + /// buffers. pub struct SpiDmaBus<'d, T, C> where T: InstanceDma, @@ -1429,6 +1585,8 @@ pub mod dma { C: DmaChannel, C::P: SpiPeripheral, { + /// Creates a new `SpiDmaBus` with the specified SPI instance and DMA + /// buffers. pub fn new( spi_dma: SpiDma<'d, T, C, FullDuplexMode, crate::Blocking>, tx_buffer: DmaTxBuf, @@ -1440,6 +1598,7 @@ pub mod dma { } } + /// Reads data from the SPI bus using DMA. pub fn read(&mut self, words: &mut [u8]) -> Result<(), Error> { let mut spi_dma = self.spi_dma.take().unwrap(); let (tx_buf, mut rx_buf) = self.buffers.take().unwrap(); @@ -1467,6 +1626,7 @@ pub mod dma { Ok(()) } + /// Writes data to the SPI bus using DMA. pub fn write(&mut self, words: &[u8]) -> Result<(), Error> { let mut spi_dma = self.spi_dma.take().unwrap(); let (mut tx_buf, rx_buf) = self.buffers.take().unwrap(); @@ -1491,6 +1651,7 @@ pub mod dma { Ok(()) } + /// Transfers data to and from the SPI bus simultaneously using DMA. pub fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> { let mut spi_dma = self.spi_dma.take().unwrap(); let (mut tx_buf, mut rx_buf) = self.buffers.take().unwrap(); @@ -1534,6 +1695,7 @@ pub mod dma { } } + /// Transfers data in place on the SPI bus using DMA. pub fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Error> { let mut spi_dma = self.spi_dma.take().unwrap(); let (mut tx_buf, mut rx_buf) = self.buffers.take().unwrap(); @@ -1595,6 +1757,7 @@ pub mod dma { } } + /// Async functionality #[cfg(feature = "async")] pub mod asynch { use core::{cmp::min, mem::take}; @@ -1630,6 +1793,10 @@ pub mod dma { InUse, } + /// An asynchronous DMA-capable SPI bus for full-duplex operations. + /// + /// This struct provides an interface for SPI operations using DMA in an + /// asynchronous way. pub struct SpiDmaAsyncBus<'d, T, C> where T: InstanceDma, @@ -1645,6 +1812,10 @@ pub mod dma { C: DmaChannel, C::P: SpiPeripheral, { + /// Creates a new asynchronous DMA SPI bus instance. + /// + /// Initializes the bus with the provided SPI instance and DMA + /// buffers for transmit and receive operations. pub fn new( spi: SpiDma<'d, T, C, FullDuplexMode, crate::Async>, dma_tx_buf: DmaTxBuf, @@ -1655,6 +1826,8 @@ pub mod dma { } } + /// Waits for the current SPI DMA transfer to complete, ensuring the + /// bus is idle. async fn wait_for_idle( &mut self, ) -> ( @@ -1703,6 +1876,8 @@ pub mod dma { C: DmaChannel, C::P: SpiPeripheral, { + /// Asynchronously reads data from the SPI bus into the provided + /// buffer. async fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { // Get previous transfer. let (mut spi_dma, mut tx_buf, mut rx_buf) = self.wait_for_idle().await; @@ -1741,6 +1916,8 @@ pub mod dma { Ok(()) } + /// Asynchronously writes data to the SPI bus from the provided + /// buffer. async fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { // Get previous transfer. let (mut spi_dma, mut tx_buf, mut rx_buf) = self.wait_for_idle().await; @@ -1777,6 +1954,12 @@ pub mod dma { Ok(()) } + /// Asynchronously performs a full-duplex transfer over the SPI bus. + /// + /// This method splits the transfer operation into chunks and + /// processes it asynchronously. It simultaneously + /// writes data from the `write` buffer and reads data into the + /// `read` buffer. async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { // Get previous transfer. let (mut spi_dma, mut tx_buf, mut rx_buf) = self.wait_for_idle().await; @@ -1832,6 +2015,8 @@ pub mod dma { } } + /// Asynchronously performs an in-place full-duplex transfer over + /// the SPI bus. async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { // Get previous transfer. let (mut spi_dma, mut tx_buf, mut rx_buf) = self.wait_for_idle().await; diff --git a/esp-hal/src/spi/mod.rs b/esp-hal/src/spi/mod.rs index c3da24442b2..9f30272438a 100644 --- a/esp-hal/src/spi/mod.rs +++ b/esp-hal/src/spi/mod.rs @@ -9,8 +9,6 @@ //! more information on these modes, please refer to the documentation in their //! respective modules. -#![allow(missing_docs)] // TODO: Remove when able - use crate::dma::DmaError; pub mod master; @@ -21,10 +19,17 @@ pub mod slave; #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { + /// Error occurred due to a DMA-related issue. DmaError(DmaError), + /// Error indicating that the maximum DMA transfer size was exceeded. MaxDmaTransferSizeExceeded, + /// Error indicating that the FIFO size was exceeded during SPI + /// communication. FifoSizeExeeded, + /// Error indicating that the operation is unsupported by the current + /// implementation. Unsupported, + /// An unknown error occurred during SPI communication. Unknown, } @@ -41,13 +46,25 @@ impl embedded_hal::spi::Error for Error { } } -/// SPI modes +/// SPI communication modes, defined by clock polarity (CPOL) and clock phase +/// (CPHA). +/// +/// These modes control the clock signal's idle state and when data is sampled +/// and shifted. #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SpiMode { + /// Mode 0 (CPOL = 0, CPHA = 0): Clock is low when idle, data is captured on + /// the rising edge and propagated on the falling edge. Mode0, + /// Mode 1 (CPOL = 0, CPHA = 1): Clock is low when idle, data is captured on + /// the falling edge and propagated on the rising edge. Mode1, + /// Mode 2 (CPOL = 1, CPHA = 0): Clock is high when idle, data is captured + /// on the falling edge and propagated on the rising edge. Mode2, + /// Mode 3 (CPOL = 1, CPHA = 1): Clock is high when idle, data is captured + /// on the rising edge and propagated on the falling edge. Mode3, } @@ -55,24 +72,28 @@ pub enum SpiMode { #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SpiBitOrder { + /// Most Significant Bit (MSB) is transmitted first. MSBFirst, + /// Least Significant Bit (LSB) is transmitted first. LSBFirst, } +/// Trait marker for defining SPI duplex modes. pub trait DuplexMode {} +/// Trait marker for SPI full-duplex mode. pub trait IsFullDuplex: DuplexMode {} +/// Trait marker for SPI half-duplex mode. pub trait IsHalfDuplex: DuplexMode {} /// SPI data mode -/// -/// Single = 1 bit, 2 wires -/// Dual = 2 bit, 2 wires -/// Quad = 4 bit, 4 wires #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum SpiDataMode { + /// `Single` Data Mode - 1 bit, 2 wires. Single, + /// `Dual` Data Mode - 2 bit, 2 wires Dual, + /// `Quad` Data Mode - 4 bit, 4 wires Quad, } diff --git a/esp-hal/src/spi/slave.rs b/esp-hal/src/spi/slave.rs index 748e0365ee2..d001d0d3e3e 100644 --- a/esp-hal/src/spi/slave.rs +++ b/esp-hal/src/spi/slave.rs @@ -143,6 +143,7 @@ where } } +/// DMA (Direct Memory Access) funtionality (Slave). pub mod dma { use super::*; #[cfg(spi3)] @@ -169,12 +170,15 @@ pub mod dma { Mode, }; + /// Trait for configuring DMA with SPI2 peripherals in slave mode. pub trait WithDmaSpi2<'d, C, DmaMode> where C: DmaChannel, C::P: SpiPeripheral, DmaMode: Mode, { + /// Configures the SPI2 peripheral with the provided DMA channel and + /// descriptors. fn with_dma( self, channel: Channel<'d, C, DmaMode>, @@ -183,6 +187,7 @@ pub mod dma { ) -> SpiDma<'d, crate::peripherals::SPI2, C, DmaMode>; } + /// Trait for configuring DMA with SPI3 peripherals in slave mode. #[cfg(spi3)] pub trait WithDmaSpi3<'d, C, DmaMode> where @@ -190,6 +195,8 @@ pub mod dma { C::P: SpiPeripheral, DmaMode: Mode, { + /// Configures the SPI3 peripheral with the provided DMA channel and + /// descriptors. fn with_dma( self, channel: Channel<'d, C, DmaMode>, diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index da49a3e2196..96e80b87a3f 100755 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -29,8 +29,6 @@ //! # } //! ``` -#![allow(missing_docs)] // TODO: Remove when able - use crate::{ interrupt::InterruptHandler, peripheral::PeripheralRef, @@ -38,72 +36,109 @@ use crate::{ InterruptConfigurable, }; -/// Peripherals which can be enabled via `PeripheralClockControl` +/// Peripherals which can be enabled via `PeripheralClockControl`. +/// +/// This enum represents various hardware peripherals that can be enabled +/// by the system's clock control. Depending on the target device, different +/// peripherals will be available for enabling. pub enum Peripheral { + /// SPI2 peripheral. #[cfg(spi2)] Spi2, + /// SPI3 peripheral. #[cfg(spi3)] Spi3, + /// External I2C0 peripheral. #[cfg(i2c0)] I2cExt0, + /// External I2C1 peripheral. #[cfg(i2c1)] I2cExt1, + /// RMT peripheral (Remote Control). #[cfg(rmt)] Rmt, + /// LEDC peripheral (LED PWM Controller). #[cfg(ledc)] Ledc, + /// MCPWM0 peripheral (Motor Control PWM 0). #[cfg(mcpwm0)] Mcpwm0, + /// MCPWM1 peripheral (Motor Control PWM 1). #[cfg(mcpwm1)] Mcpwm1, + /// PCNT peripheral (Pulse Counter). #[cfg(pcnt)] Pcnt, + /// APB SAR ADC peripheral. #[cfg(apb_saradc)] ApbSarAdc, + /// General DMA (GDMA) peripheral. #[cfg(gdma)] Gdma, + /// Peripheral DMA (PDMA) peripheral. #[cfg(pdma)] Dma, + /// I2S0 peripheral (Inter-IC Sound). #[cfg(i2s0)] I2s0, + /// I2S1 peripheral (Inter-IC Sound). #[cfg(i2s1)] I2s1, + /// USB0 peripheral. #[cfg(usb0)] Usb, + /// AES peripheral (Advanced Encryption Standard). #[cfg(aes)] Aes, + /// TWAI0 peripheral. #[cfg(twai0)] Twai0, + /// TWAI1 peripheral. #[cfg(twai1)] Twai1, + /// Timer Group 0 peripheral. #[cfg(timg0)] Timg0, + /// Timer Group 1 peripheral. #[cfg(timg1)] Timg1, + /// Low-power watchdog timer (WDT) peripheral. #[cfg(lp_wdt)] Wdt, + /// SHA peripheral (Secure Hash Algorithm). #[cfg(sha)] Sha, + /// USB Device peripheral. #[cfg(usb_device)] UsbDevice, + /// UART0 peripheral. #[cfg(uart0)] Uart0, + /// UART1 peripheral. #[cfg(uart1)] Uart1, + /// UART2 peripheral. #[cfg(uart2)] Uart2, + /// RSA peripheral (Rivest-Shamir-Adleman encryption). #[cfg(rsa)] Rsa, + /// Parallel IO peripheral. #[cfg(parl_io)] ParlIo, + /// HMAC peripheral (Hash-based Message Authentication Code). #[cfg(hmac)] Hmac, + /// ECC peripheral (Elliptic Curve Cryptography). #[cfg(ecc)] Ecc, + /// SOC ETM peripheral (Event Task Manager). #[cfg(soc_etm)] Etm, + /// TRACE0 peripheral (Debug trace). #[cfg(trace0)] Trace0, + /// LCD Camera peripheral. #[cfg(lcd_cam)] LcdCam, } @@ -111,8 +146,11 @@ pub enum Peripheral { /// The `DPORT`/`PCR`/`SYSTEM` peripheral split into its different logical /// components. pub struct SystemControl<'d> { + /// Inner reference to the SYSTEM peripheral. _inner: PeripheralRef<'d, SYSTEM>, + /// Controls the system's clock settings and configurations. pub clock_control: SystemClockControl, + /// Controls the system's software interrupt settings. pub software_interrupt_control: SoftwareInterruptControl, } @@ -244,6 +282,10 @@ impl InterruptConfigurable for SoftwareInterrupt { } /// This gives access to the available software interrupts. +/// +/// This struct contains several instances of software interrupts that can be +/// used for signaling between different parts of a program or system. Each +/// interrupt is identified by an index (0 to 3). #[cfg_attr( multi_core, doc = r#" @@ -253,9 +295,14 @@ feature is enabled."# )] #[non_exhaustive] pub struct SoftwareInterruptControl { + /// Software interrupt 0. pub software_interrupt0: SoftwareInterrupt<0>, + /// Software interrupt 1. pub software_interrupt1: SoftwareInterrupt<1>, + /// Software interrupt 2. pub software_interrupt2: SoftwareInterrupt<2>, + /// Software interrupt 3 (only available when not running on a multi-core + /// system with the `embassy` feature enabled). #[cfg(not(all(feature = "embassy", multi_core)))] pub software_interrupt3: SoftwareInterrupt<3>, } @@ -1117,6 +1164,7 @@ pub struct SystemClockControl { } impl SystemClockControl { + /// Creates new instance of `SystemClockControl`. pub fn new() -> Self { Self { _private: () } } @@ -1142,12 +1190,16 @@ impl crate::private::Sealed for SystemClockControl {} /// Enumeration of the available radio peripherals for this chip. #[cfg(any(bt, ieee802154, wifi))] pub enum RadioPeripherals { + /// Represents the PHY (Physical Layer) peripheral. #[cfg(phy)] Phy, + /// Represents the Bluetooth peripheral. #[cfg(bt)] Bt, + /// Represents the WiFi peripheral. #[cfg(wifi)] Wifi, + /// Represents the IEEE 802.15.4 peripheral. #[cfg(ieee802154)] Ieee802154, } @@ -1170,5 +1222,6 @@ pub trait RadioClockController { /// Initialize BLE RTC clocks fn ble_rtc_clk_init(&mut self); + /// Reset the Resolvable Private Address (RPA). fn reset_rpa(&mut self); } diff --git a/esp-hal/src/timer/mod.rs b/esp-hal/src/timer/mod.rs index 99efaf8838e..f72fc16b932 100644 --- a/esp-hal/src/timer/mod.rs +++ b/esp-hal/src/timer/mod.rs @@ -364,17 +364,22 @@ impl<'d, T> embedded_hal_02::timer::Periodic for PeriodicTimer<'d, T> where T: T /// A type-erased timer /// /// You can create an instance of this by just calling `.into()` on a timer. -#[allow(missing_docs)] pub enum ErasedTimer { + /// Timer 0 of the TIMG0 peripheral in blocking mode. Timg0Timer0(timg::Timer, Blocking>), + /// Timer 1 of the TIMG0 peripheral in blocking mode. #[cfg(timg_timer1)] Timg0Timer1(timg::Timer, Blocking>), + /// Timer 0 of the TIMG1 peripheral in blocking mode. #[cfg(timg1)] Timg1Timer0(timg::Timer, Blocking>), + /// Timer 1 of the TIMG1 peripheral in blocking mode. #[cfg(all(timg1, timg_timer1))] Timg1Timer1(timg::Timer, Blocking>), + /// Systimer Alarm in periodic mode with blocking behavior. #[cfg(systimer)] SystimerAlarmPeriodic(systimer::Alarm<'static, systimer::Periodic, Blocking>), + /// Systimer Target in periodic mode with blocking behavior. #[cfg(systimer)] SystimerAlarmTarget(systimer::Alarm<'static, systimer::Target, Blocking>), } diff --git a/esp-hal/src/twai/filter.rs b/esp-hal/src/twai/filter.rs index bbdf2780351..2d0494f20a0 100644 --- a/esp-hal/src/twai/filter.rs +++ b/esp-hal/src/twai/filter.rs @@ -14,8 +14,15 @@ use super::{ExtendedId, StandardId}; #[derive(Debug, PartialEq, Eq)] +/// Represents the type of filtering to be applied to incoming TWAI frames. pub enum FilterType { + /// Uses the acceptance code and mask to define a single filter, which + /// allows for the first two data bytes of a standard frame to be filtered, + /// or the entirety of an extended frame's 29-bit ID. Single, + /// Uses the acceptance code and mask to define two separate filters + /// allowing for increased flexibility of ID's to accept, but does not allow + /// for all 29-bits of an extended ID to be filtered. Dual, } @@ -32,6 +39,7 @@ pub enum FilterType { pub trait Filter { /// The type of the filter. const FILTER_TYPE: FilterType; + /// Returns filter type. fn filter_type(&self) -> FilterType { Self::FILTER_TYPE } @@ -40,6 +48,7 @@ pub trait Filter { fn to_registers(&self) -> [u8; 8]; } +/// A type representing the bitmask used to filter incoming TWAI frames. pub type BitFilter = [u8; N]; // Convert a byte from a bytestring into a bit inside a given code and mask. diff --git a/esp-hal/src/twai/mod.rs b/esp-hal/src/twai/mod.rs index 0953b543414..2a5ab3fbd95 100644 --- a/esp-hal/src/twai/mod.rs +++ b/esp-hal/src/twai/mod.rs @@ -14,7 +14,7 @@ //! up the timing 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 +//! This driver manages the ISO 11898-1 compatible TWAI //! controllers. It supports Standard Frame Format (11-bit) and Extended Frame //! Format (29-bit) frame identifiers. //! @@ -34,13 +34,13 @@ //! # use core::option::Option::None; //! # use nb::block; //! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); -//! // Use GPIO pins 2 and 3 to connect to the respective pins on the CAN +//! // Use GPIO pins 2 and 3 to connect to the respective pins on the TWAI //! // 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 = BaudRate::B1000K; +//! // The speed of the TWAI bus. +//! const TWAI_BAUDRATE: twai::BaudRate = BaudRate::B1000K; //! //! // Begin configuring the TWAI peripheral. The peripheral is in a reset like //! // state that prevents transmission but allows configuration. @@ -49,7 +49,7 @@ //! can_tx_pin, //! can_rx_pin, //! &clocks, -//! CAN_BAUDRATE, +//! TWAI_BAUDRATE, //! TwaiMode::Normal //! ); //! @@ -90,13 +90,13 @@ //! # use core::option::Option::None; //! # use nb::block; //! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); -//! // Use GPIO pins 2 and 3 to connect to the respective pins on the CAN +//! // Use GPIO pins 2 and 3 to connect to the respective pins on the TWAI //! // 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 = BaudRate::B1000K; +//! // The speed of the TWAI bus. +//! const TWAI_BAUDRATE: twai::BaudRate = BaudRate::B1000K; //! //! // Begin configuring the TWAI peripheral. //! let mut can_config = twai::TwaiConfiguration::new( @@ -104,7 +104,7 @@ //! can_tx_pin, //! can_rx_pin, //! &clocks, -//! CAN_BAUDRATE, +//! TWAI_BAUDRATE, //! TwaiMode::SelfTest //! ); //! @@ -129,8 +129,6 @@ //! # } //! ``` -#![allow(missing_docs)] // TODO: Remove when able - use core::marker::PhantomData; use self::filter::{Filter, FilterType}; @@ -146,12 +144,12 @@ use crate::{ pub mod filter; -/// CAN error kind +/// TWAI error kind /// -/// This represents a common set of CAN operation errors. HAL implementations +/// This represents a common set of TWAI operation errors. HAL implementations /// are free to define more specific or additional error types. However, by -/// providing a mapping to these common CAN errors, generic code can still react -/// to them. +/// providing a mapping to these common TWAI errors, generic code can still +/// react to them. #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[non_exhaustive] pub enum ErrorKind { @@ -256,15 +254,15 @@ pub enum TwaiMode { ListenOnly, } -/// Standard 11-bit CAN Identifier (`0..=0x7FF`). +/// Standard 11-bit TWAI Identifier (`0..=0x7FF`). #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub struct StandardId(u16); impl StandardId { - /// CAN ID `0`, the highest priority. + /// TWAI ID `0`, the highest priority. pub const ZERO: Self = StandardId(0); - /// CAN ID `0x7FF`, the lowest priority. + /// TWAI ID `0x7FF`, the lowest priority. pub const MAX: Self = StandardId(0x7FF); /// Tries to create a `StandardId` from a raw 16-bit integer. @@ -290,7 +288,7 @@ impl StandardId { StandardId(raw) } - /// Returns this CAN Identifier as a raw 16-bit integer. + /// Returns TWAI Identifier as a raw 16-bit integer. #[inline] pub fn as_raw(&self) -> u16 { self.0 @@ -325,15 +323,15 @@ impl From for StandardId { } } -/// Extended 29-bit CAN Identifier (`0..=1FFF_FFFF`). +/// Extended 29-bit TWAI Identifier (`0..=1FFF_FFFF`). #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub struct ExtendedId(u32); impl ExtendedId { - /// CAN ID `0`, the highest priority. + /// TWAI ID `0`, the highest priority. pub const ZERO: Self = ExtendedId(0); - /// CAN ID `0x1FFFFFFF`, the lowest priority. + /// TWAI ID `0x1FFFFFFF`, the lowest priority. pub const MAX: Self = ExtendedId(0x1FFF_FFFF); /// Tries to create a `ExtendedId` from a raw 32-bit integer. @@ -359,7 +357,7 @@ impl ExtendedId { ExtendedId(raw) } - /// Returns this CAN Identifier as a raw 32-bit integer. + /// Returns TWAI Identifier as a raw 32-bit integer. #[inline] pub fn as_raw(&self) -> u32 { self.0 @@ -400,7 +398,7 @@ impl From for ExtendedId { } } -/// A CAN Identifier (standard or extended). +/// A TWAI Identifier (standard or extended). #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum Id { /// Standard 11-bit Identifier (`0..=0x7FF`). @@ -474,8 +472,9 @@ pub struct EspTwaiFrame { } impl EspTwaiFrame { + /// Creates a new `EspTwaiFrame` with the specified ID and data payload. pub fn new(id: Id, data: &[u8]) -> Option { - // CAN2.0 frames cannot contain more than 8 bytes of data. + // TWAI frames cannot contain more than 8 bytes of data. if data.len() > 8 { return None; } @@ -493,8 +492,10 @@ impl EspTwaiFrame { }) } + /// Creates a new `EspTwaiFrame` for a transmission request with the + /// specified ID and data length (DLC). pub fn new_remote(id: Id, dlc: usize) -> Option { - // CAN2.0 frames cannot have more than 8 bytes. + // TWAI frames cannot have more than 8 bytes. if dlc > 8 { return None; } @@ -508,6 +509,8 @@ impl EspTwaiFrame { }) } + /// Creates a new `EspTwaiFrame` ready for self-reception with the specified + /// ID and data payload. pub fn new_self_reception(id: Id, data: &[u8]) -> Option { if data.len() > 8 { return None; @@ -635,10 +638,23 @@ impl embedded_can::Frame for EspTwaiFrame { /// The underlying timings for the TWAI peripheral. pub struct TimingConfig { + /// The baudrate prescaler is used to determine the period of each time + /// quantum by dividing the TWAI controller's source clock. pub baud_rate_prescaler: u16, + + /// The synchronization jump width is used to determine the maximum number + /// of time quanta a single bit time can be lengthened/shortened for + /// synchronization purposes. pub sync_jump_width: u8, + + /// Timing segment 1 consists of 1 to 16 time quanta before sample point. pub tseg_1: u8, + + /// Timing Segment 2 consists of 1 to 8 time quanta after sample point. pub tseg_2: u8, + + /// Enabling triple sampling causes 3 time quanta to be sampled per bit + /// instead of 1. pub triple_sample: bool, } @@ -646,33 +662,24 @@ pub struct TimingConfig { /// Currently these timings are sourced from the ESP IDF C driver which assumes /// an APB clock of 80MHz. pub enum BaudRate { + /// A baud rate of 125 Kbps. B125K, + /// A baud rate of 250 Kbps. B250K, + /// A baud rate of 500 Kbps. B500K, + /// A baud rate of 1 Mbps. B1000K, + /// A custom baud rate defined by the user. + /// + /// This variant allows users to specify their own timing configuration + /// using a `TimingConfig` struct. Custom(TimingConfig), } impl BaudRate { /// Convert the BaudRate into the timings that the peripheral needs. - // These timings are copied from the ESP IDF C driver. - // #define TWAI_TIMING_CONFIG_25KBITS() {.brp = 128, .tseg_1 = 16, .tseg_2 = - // 8, .sjw = 3, .triple_sampling = false} - // #define TWAI_TIMING_CONFIG_50KBITS() {.brp = 80, .tseg_1 = 15, .tseg_2 = - // 4, .sjw = 3, .triple_sampling = false} - // #define TWAI_TIMING_CONFIG_100KBITS() {.brp = 40, .tseg_1 = 15, .tseg_2 = - // 4, .sjw = 3, .triple_sampling = false} - // #define TWAI_TIMING_CONFIG_125KBITS() {.brp = 32, .tseg_1 = 15, .tseg_2 = - // 4, .sjw = 3, .triple_sampling = false} - // #define TWAI_TIMING_CONFIG_250KBITS() {.brp = 16, .tseg_1 = 15, .tseg_2 = - // 4, .sjw = 3, .triple_sampling = false} - // #define TWAI_TIMING_CONFIG_500KBITS() {.brp = 8, .tseg_1 = 15, .tseg_2 = 4, - // .sjw = 3, .triple_sampling = false} #define TWAI_TIMING_CONFIG_800KBITS() - // {.brp = 4, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false} - // #define TWAI_TIMING_CONFIG_1MBITS() {.brp = 4, .tseg_1 = 15, .tseg_2 = 4, - // .sjw = 3, .triple_sampling = false} - // - // see https://github.com/espressif/esp-idf/tree/master/components/hal/include/hal/twai_types.h + // See: https://github.com/espressif/esp-idf/tree/master/components/hal/include/hal/twai_types.h const fn timing(self) -> TimingConfig { #[allow(unused_mut)] let mut timing = match self { @@ -1024,10 +1031,12 @@ where } } + /// Returns the value of the receive error counter. pub fn receive_error_count(&self) -> u8 { T::register_block().rx_err_cnt().read().rx_err_cnt().bits() } + /// Returns the value of the transmit error counter. pub fn transmit_error_count(&self) -> u8 { T::register_block().tx_err_cnt().read().tx_err_cnt().bits() } @@ -1067,10 +1076,12 @@ where } } + /// Sends the specified `EspTwaiFrame` over the TWAI bus. pub fn transmit(&mut self, frame: &EspTwaiFrame) -> nb::Result<(), EspTwaiError> { self.tx.transmit(frame) } + /// Receives a TWAI frame from the TWAI bus. pub fn receive(&mut self) -> nb::Result { self.rx.receive() } @@ -1082,7 +1093,7 @@ where } } -/// Interface to the CAN transmitter part. +/// Interface to the TWAI transmitter part. pub struct TwaiTx<'d, T, DM: crate::Mode> { _peripheral: PhantomData<&'d T>, phantom: PhantomData, @@ -1124,7 +1135,7 @@ where } } -/// Interface to the CAN receiver part. +/// Interface to the TWAI receiver part. pub struct TwaiRx<'d, T, DM: crate::Mode> { _peripheral: PhantomData<&'d T>, phantom: PhantomData, @@ -1135,7 +1146,7 @@ where T: OperationInstance, DM: crate::Mode, { - // Receive a frame + /// Receive a frame pub fn receive(&mut self) -> nb::Result { let register_block = T::register_block(); let status = register_block.status().read(); @@ -1166,9 +1177,14 @@ where } } +/// Represents errors that can occur in the TWAI driver. +/// This enum defines the possible errors that can be encountered when +/// interacting with the TWAI peripheral. #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum EspTwaiError { + /// TWAI peripheral has entered a bus-off state. BusOff, + /// Encapsulates errors defined by the embedded-hal crate. EmbeddedHAL(ErrorKind), } @@ -1274,28 +1290,41 @@ where } } +/// TWAI peripheral instance. pub trait Instance: crate::private::Sealed { + /// The system peripheral associated with this TWAI instance. const SYSTEM_PERIPHERAL: system::Peripheral; + /// The identifier number for this TWAI instance. const NUMBER: usize; + /// Input signal. const INPUT_SIGNAL: InputSignal; + /// Output signal. const OUTPUT_SIGNAL: OutputSignal; - + /// The interrupt associated with this TWAI instance. const INTERRUPT: crate::peripherals::Interrupt; #[cfg(feature = "async")] + /// Provides an asynchronous interrupt handler for TWAI instance. fn async_handler() -> InterruptHandler; + /// Returns a reference to the register block for TWAI instance. fn register_block() -> &'static RegisterBlock; + /// Enables the TWAI peripheral. fn enable_peripheral(); + /// Resets the TWAI peripheral. fn reset_peripheral(); + /// Enables interrupts for the TWAI peripheral. fn enable_interrupts(); } +/// An extension of the `Instance` trait that provides additional operations +/// for managing and interacting with the TWAI peripheral. pub trait OperationInstance: Instance { #[cfg(feature = "async")] + /// Returns a reference to the asynchronous state for this TWAI instance. fn async_state() -> &'static asynch::TwaiAsyncState { &asynch::TWAI_STATE[Self::NUMBER] } @@ -1652,10 +1681,11 @@ mod asynch { where T: OperationInstance, { + /// Transmits an `EspTwaiFrame` asynchronously over the TWAI bus. pub async fn transmit_async(&mut self, frame: &EspTwaiFrame) -> Result<(), EspTwaiError> { self.tx.transmit_async(frame).await } - + /// Receives an `EspTwaiFrame` asynchronously over the TWAI bus. pub async fn receive_async(&mut self) -> Result { self.rx.receive_async().await } @@ -1665,6 +1695,7 @@ mod asynch { where T: OperationInstance, { + /// Transmits an `EspTwaiFrame` asynchronously over the TWAI bus. pub async fn transmit_async(&mut self, frame: &EspTwaiFrame) -> Result<(), EspTwaiError> { T::enable_interrupts(); poll_fn(|cx| { @@ -1694,6 +1725,7 @@ mod asynch { where T: OperationInstance, { + /// Receives an `EspTwaiFrame` asynchronously over the TWAI bus. pub async fn receive_async(&mut self) -> Result { T::enable_interrupts(); poll_fn(|cx| { diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index 2d15d321c89..8965db86e21 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -118,8 +118,6 @@ //! [embedded-hal-async]: https://docs.rs/embedded-hal-async/latest/embedded_hal_async/ //! [embedded-io-async]: https://docs.rs/embedded-io-async/latest/embedded_io_async/ -#![allow(missing_docs)] // TODO: Remove when able - use core::marker::PhantomData; use self::config::Config; @@ -150,25 +148,60 @@ use crate::soc::constants::REF_TICK; // Default TX and RX pins for Uart/Serial communication (UART0) cfg_if::cfg_if! { if #[cfg(esp32)] { + /// Default TX pin for UART0 on ESP32. + /// Corresponds to GPIO1. pub type DefaultTxPin = crate::gpio::Gpio1; + + /// Default RX pin for UART0 on ESP32. + /// Corresponds to GPIO3. pub type DefaultRxPin = crate::gpio::Gpio3; } else if #[cfg(esp32c2)] { + /// Default TX pin for UART0 on ESP32-C2. + /// Corresponds to GPIO20. pub type DefaultTxPin = crate::gpio::Gpio20; + + /// Default RX pin for UART0 on ESP32-C2. + /// Corresponds to GPIO19. pub type DefaultRxPin = crate::gpio::Gpio19; } else if #[cfg(esp32c3)] { + /// Default TX pin for UART0 on ESP32-C3. + /// Corresponds to GPIO21. pub type DefaultTxPin = crate::gpio::Gpio21; + + /// Default RX pin for UART0 on ESP32-C3. + /// Corresponds to GPIO20. pub type DefaultRxPin = crate::gpio::Gpio20; }else if #[cfg(esp32c6)] { + /// Default TX pin for UART0 on ESP32-C6. + /// Corresponds to GPIO16. pub type DefaultTxPin = crate::gpio::Gpio16; + + /// Default RX pin for UART0 on ESP32-C6. + /// Corresponds to GPIO17. pub type DefaultRxPin = crate::gpio::Gpio17; }else if #[cfg(esp32h2)] { + /// Default TX pin for UART0 on ESP32-H2. + /// Corresponds to GPIO24. pub type DefaultTxPin = crate::gpio::Gpio24; + + /// Default RX pin for UART0 on ESP32-H2. + /// Corresponds to GPIO23. pub type DefaultRxPin = crate::gpio::Gpio23; } else if #[cfg(esp32s2)] { + /// Default TX pin for UART0 on ESP32-S2. + /// Corresponds to GPIO43. pub type DefaultTxPin = crate::gpio::Gpio43; + + /// Default RX pin for UART0 on ESP32-S2. + /// Corresponds to GPIO44. pub type DefaultRxPin = crate::gpio::Gpio44; } else if #[cfg(esp32s3)] { + /// Default TX pin for UART0 on ESP32-S3. + /// Corresponds to GPIO43. pub type DefaultTxPin = crate::gpio::Gpio43; + + /// Default RX pin for UART0 on ESP32-S3. + /// Corresponds to GPIO44. pub type DefaultRxPin = crate::gpio::Gpio44; } } @@ -177,15 +210,36 @@ cfg_if::cfg_if! { #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { - /// An invalid configuration argument was provided + /// An invalid configuration argument was provided. + /// + /// This error occurs when an incorrect or invalid argument is passed during + /// the configuration of the UART peripheral. InvalidArgument, - /// The RX FIFO overflowed + + /// The RX FIFO overflowed. #[cfg(feature = "async")] RxFifoOvf, + + /// A glitch was detected on the RX line. + /// + /// This error occurs when an unexpected or erroneous signal (glitch) is + /// detected on the UART RX line, which could lead to incorrect data + /// reception. #[cfg(feature = "async")] RxGlitchDetected, + + /// A framing error was detected on the RX line. + /// + /// This error occurs when the received data does not conform to the + /// expected UART frame format. #[cfg(feature = "async")] RxFrameError, + + /// A parity error was detected on the RX line. + /// + /// This error occurs when the parity bit in the received data does not + /// match the expected parity configuration. + /// with the `async` feature. #[cfg(feature = "async")] RxParityError, } @@ -233,33 +287,55 @@ pub mod config { const UART_TOUT_THRESH_DEFAULT: u8 = 10; /// Number of data bits + /// + /// This enum represents the various configurations for the number of data + /// bits used in UART communication. The number of data bits defines the + /// length of each transmitted or received data frame. #[derive(PartialEq, Eq, Copy, Clone, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum DataBits { + /// 5 data bits per frame. DataBits5 = 0, + /// 6 data bits per frame. DataBits6 = 1, + /// 7 data bits per frame. DataBits7 = 2, + /// 8 data bits per frame (most common). DataBits8 = 3, } /// Parity check + /// + /// Parity is a form of error detection in UART communication, used to + /// ensure that the data has not been corrupted during transmission. The + /// parity bit is added to the data bits to make the number of 1-bits + /// either even or odd. #[derive(PartialEq, Eq, Copy, Clone, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Parity { + /// No parity bit is used (most common). ParityNone, + /// Even parity: the parity bit is set to make the total number of + /// 1-bits even. ParityEven, + /// Odd parity: the parity bit is set to make the total number of 1-bits + /// odd. ParityOdd, } /// Number of stop bits + /// + /// The stop bit(s) signal the end of a data packet in UART communication. + /// This enum defines the possible configurations for the number of stop + /// bits. #[derive(PartialEq, Eq, Copy, Clone, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum StopBits { - /// 1 stop bit + /// 1 stop bit. STOP1 = 1, - /// 1.5 stop bits + /// 1.5 stop bits. STOP1P5 = 2, - /// 2 stop bits + /// 2 stop bits. STOP2 = 3, } @@ -267,51 +343,68 @@ pub mod config { #[derive(Debug, Copy, Clone)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Config { + /// The baud rate (speed) of the UART communication in bits per second + /// (bps). pub baudrate: u32, + /// Number of data bits in each frame (5, 6, 7, or 8 bits). pub data_bits: DataBits, + /// Parity setting (None, Even, or Odd). pub parity: Parity, + /// Number of stop bits in each frame (1, 1.5, or 2 bits). pub stop_bits: StopBits, + /// Clock source used by the UART peripheral. pub clock_source: super::ClockSource, + /// Threshold level at which the RX FIFO is considered full. pub rx_fifo_full_threshold: u16, + /// Optional timeout value for RX operations. pub rx_timeout: Option, } impl Config { + /// Sets the baud rate for the UART configuration. pub fn baudrate(mut self, baudrate: u32) -> Self { self.baudrate = baudrate; self } + /// Configures the UART to use no parity check. pub fn parity_none(mut self) -> Self { self.parity = Parity::ParityNone; self } + /// Configures the UART to use even parity check. pub fn parity_even(mut self) -> Self { self.parity = Parity::ParityEven; self } + /// Configures the UART to use odd parity check. pub fn parity_odd(mut self) -> Self { self.parity = Parity::ParityOdd; self } + /// Sets the number of data bits for the UART configuration. pub fn data_bits(mut self, data_bits: DataBits) -> Self { self.data_bits = data_bits; self } + /// Sets the number of stop bits for the UART configuration. pub fn stop_bits(mut self, stop_bits: StopBits) -> Self { self.stop_bits = stop_bits; self } + /// Sets the clock source for the UART configuration. pub fn clock_source(mut self, source: super::ClockSource) -> Self { self.clock_source = source; self } + /// Calculates the total symbol length in bits based on the configured + /// data bits, parity, and stop bits. pub fn symbol_length(&self) -> u8 { let mut length: u8 = 1; // start bit length += match self.data_bits { @@ -331,11 +424,13 @@ pub mod config { length } + /// Sets the RX FIFO full threshold for the UART configuration. pub fn rx_fifo_full_threshold(mut self, threshold: u16) -> Self { self.rx_fifo_full_threshold = threshold; self } + /// Sets the RX timeout for the UART configuration. pub fn rx_timeout(mut self, timeout: Option) -> Self { self.rx_timeout = timeout; self @@ -361,14 +456,27 @@ pub mod config { /// Configuration for the AT-CMD detection functionality pub struct AtCmdConfig { + /// Optional idle time before the AT command detection begins, in clock + /// cycles. pub pre_idle_count: Option, + /// Optional idle time after the AT command detection ends, in clock + /// cycles. pub post_idle_count: Option, + /// Optional timeout between characters in the AT command, in clock + /// cycles. pub gap_timeout: Option, + /// The character that triggers the AT command detection. pub cmd_char: u8, + /// Optional number of characters to detect as part of the AT command. pub char_num: Option, } impl AtCmdConfig { + /// Creates a new `AtCmdConfig` with the specified configuration. + /// + /// This function sets up the AT command detection parameters, including + /// pre- and post-idle times, a gap timeout, the triggering command + /// character, and the number of characters to detect. pub fn new( pre_idle_count: Option, post_idle_count: Option, @@ -1306,10 +1414,27 @@ where /// UART Peripheral Instance pub trait Instance: crate::private::Sealed { + /// Returns a reference to the UART register block for the specific + /// instance. + /// + /// # Safety + /// This function returns a reference to the raw hardware registers, so + /// direct interaction with the registers may require careful handling + /// to avoid unintended side effects. fn register_block() -> &'static RegisterBlock; + + /// Returns the UART number associated with this instance (e.g., UART0, + /// UART1, etc.). fn uart_number() -> usize; + + /// Returns the interrupt associated with this UART instance. fn interrupt() -> Interrupt; + /// Disables all TX-related interrupts for this UART instance. + /// + /// This function clears and disables the `transmit FIFO empty` interrupt, + /// `transmit break done`, `transmit break idle done`, and `transmit done` + /// interrupts. fn disable_tx_interrupts() { Self::register_block().int_clr().write(|w| { w.txfifo_empty() @@ -1334,6 +1459,11 @@ pub trait Instance: crate::private::Sealed { }); } + /// Disables all RX-related interrupts for this UART instance. + /// + /// This function clears and disables the `receive FIFO full` interrupt, + /// `receive FIFO overflow`, `receive FIFO timeout`, and `AT command + /// character detection` interrupts. fn disable_rx_interrupts() { Self::register_block().int_clr().write(|w| { w.rxfifo_full() @@ -1359,6 +1489,8 @@ pub trait Instance: crate::private::Sealed { } #[allow(clippy::useless_conversion)] + /// Returns the number of bytes currently in the TX FIFO for this UART + /// instance. fn get_tx_fifo_count() -> u16 { Self::register_block() .status() @@ -1368,6 +1500,8 @@ pub trait Instance: crate::private::Sealed { .into() } + /// Returns the number of bytes currently in the RX FIFO for this UART + /// instance. #[allow(clippy::useless_conversion)] fn get_rx_fifo_count() -> u16 { let fifo_cnt: u16 = Self::register_block() @@ -1408,6 +1542,10 @@ pub trait Instance: crate::private::Sealed { fifo_cnt } + /// Checks if the TX line is idle for this UART instance. + /// + /// Returns `true` if the transmit line is idle, meaning no data is + /// currently being transmitted. fn is_tx_idle() -> bool { #[cfg(esp32)] let idle = Self::register_block().status().read().st_utx_out().bits() == 0x0u8; @@ -1422,6 +1560,10 @@ pub trait Instance: crate::private::Sealed { idle } + /// Checks if the RX line is idle for this UART instance. + /// + /// Returns `true` if the receive line is idle, meaning no data is currently + /// being received. fn is_rx_idle() -> bool { #[cfg(esp32)] let idle = Self::register_block().status().read().st_urx_out().bits() == 0x0u8; @@ -1436,11 +1578,26 @@ pub trait Instance: crate::private::Sealed { idle } + /// Returns the output signal identifier for the TX pin of this UART + /// instance. fn tx_signal() -> OutputSignal; + + /// Returns the input signal identifier for the RX pin of this UART + /// instance. fn rx_signal() -> InputSignal; + + /// Returns the input signal identifier for the CTS (Clear to Send) pin of + /// this UART instance. fn cts_signal() -> InputSignal; + + /// Returns the output signal identifier for the RTS (Request to Send) pin + /// of this UART instance. fn rts_signal() -> OutputSignal; + + /// Enables the clock for this UART peripheral instance. fn enable_peripheral(); + + /// Resets the UART peripheral instance. fn reset_peripheral(); } @@ -2056,15 +2213,18 @@ mod asynch { where T: Instance, { - /// See [`UartRx::read_async`] + /// Asynchronously reads data from the UART receive buffer into the + /// provided buffer. pub async fn read_async(&mut self, buf: &mut [u8]) -> Result { self.rx.read_async(buf).await } + /// Asynchronously writes data to the UART transmit buffer. pub async fn write_async(&mut self, words: &[u8]) -> Result { self.tx.write_async(words).await } + /// Asynchronously flushes the UART transmit buffer. pub async fn flush_async(&mut self) -> Result<(), Error> { self.tx.flush_async().await } @@ -2111,6 +2271,12 @@ mod asynch { Ok(uart_tx) } + /// Asynchronously writes data to the UART transmit buffer in chunks. + /// + /// This function sends the contents of the provided buffer `words` over + /// the UART. Data is written in chunks to avoid overflowing the + /// transmit FIFO, and the function waits asynchronously when + /// necessary for space in the buffer to become available. pub async fn write_async(&mut self, words: &[u8]) -> Result { let mut count = 0; let mut offset: usize = 0; @@ -2136,6 +2302,11 @@ mod asynch { Ok(count) } + /// Asynchronously flushes the UART transmit buffer. + /// + /// This function ensures that all pending data in the transmit FIFO has + /// been sent over the UART. If the FIFO contains data, it waits + /// for the transmission to complete before returning. pub async fn flush_async(&mut self) -> Result<(), Error> { let count = T::get_tx_fifo_count(); if count > 0 { diff --git a/esp-riscv-rt/src/lib.rs b/esp-riscv-rt/src/lib.rs index 2283280c96d..a7f344327e3 100644 --- a/esp-riscv-rt/src/lib.rs +++ b/esp-riscv-rt/src/lib.rs @@ -71,44 +71,92 @@ pub unsafe extern "C" fn start_rust(a0: usize, a1: usize, a2: usize) -> ! { } /// Registers saved in trap handler -#[allow(missing_docs)] #[derive(Debug, Default, Clone, Copy)] #[repr(C)] pub struct TrapFrame { + /// Return address, stores the address to return to after a function call or + /// interrupt. pub ra: usize, + /// Temporary register t0, used for intermediate values. pub t0: usize, + /// Temporary register t1, used for intermediate values. pub t1: usize, + /// Temporary register t2, used for intermediate values. pub t2: usize, + /// Temporary register t3, used for intermediate values. pub t3: usize, + /// Temporary register t4, used for intermediate values. pub t4: usize, + /// Temporary register t5, used for intermediate values. pub t5: usize, + /// Temporary register t6, used for intermediate values. pub t6: usize, + /// Argument register a0, typically used to pass the first argument to a + /// function. pub a0: usize, + /// Argument register a1, typically used to pass the second argument to a + /// function. pub a1: usize, + /// Argument register a2, typically used to pass the third argument to a + /// function. pub a2: usize, + /// Argument register a3, typically used to pass the fourth argument to a + /// function. pub a3: usize, + /// Argument register a4, typically used to pass the fifth argument to a + /// function. pub a4: usize, + /// Argument register a5, typically used to pass the sixth argument to a + /// function. pub a5: usize, + /// Argument register a6, typically used to pass the seventh argument to a + /// function. pub a6: usize, + /// Argument register a7, typically used to pass the eighth argument to a + /// function. pub a7: usize, + /// Saved register s0, used to hold values across function calls. pub s0: usize, + /// Saved register s1, used to hold values across function calls. pub s1: usize, + /// Saved register s2, used to hold values across function calls. pub s2: usize, + /// Saved register s3, used to hold values across function calls. pub s3: usize, + /// Saved register s4, used to hold values across function calls. pub s4: usize, + /// Saved register s5, used to hold values across function calls. pub s5: usize, + /// Saved register s6, used to hold values across function calls. pub s6: usize, + /// Saved register s7, used to hold values across function calls. pub s7: usize, + /// Saved register s8, used to hold values across function calls. pub s8: usize, + /// Saved register s9, used to hold values across function calls. pub s9: usize, + /// Saved register s10, used to hold values across function calls. pub s10: usize, + /// Saved register s11, used to hold values across function calls. pub s11: usize, + /// Global pointer register, holds the address of the global data area. pub gp: usize, + /// Thread pointer register, holds the address of the thread-local storage + /// area. pub tp: usize, + /// Stack pointer register, holds the address of the top of the stack. pub sp: usize, + /// Program counter, stores the address of the next instruction to be + /// executed. pub pc: usize, + /// Machine status register, holds the current status of the processor, + /// including interrupt enable bits and privilege mode. pub mstatus: usize, + /// Machine cause register, contains the reason for the trap (e.g., + /// exception or interrupt number). pub mcause: usize, + /// Machine trap value register, contains additional information about the + /// trap (e.g., faulting address). pub mtval: usize, }