esp-hal: Add runnable doctests to peripheral drivers (#1663)

* Check docs examples II

* rebase and update

* fix root crate macro expansion in doctest snippets

* clean up and fmt

* add xtask run-doc-test subcommand and check in CI

* address review comments

* remove commented printlns

* fix the host target check

* rebase and update

* hide docs for before_snippet macro and remove commented block code in twai
This commit is contained in:
Juraj Sadel 2024-06-11 12:18:09 +02:00 committed by GitHub
parent b8af24071e
commit 4c5e493b1b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
65 changed files with 965 additions and 732 deletions

View File

@ -104,6 +104,15 @@ jobs:
# Build all supported examples for the specified device: # Build all supported examples for the specified device:
- name: Build (examples) - name: Build (examples)
run: cargo xtask build-examples esp-hal ${{ matrix.device.soc }} run: cargo xtask build-examples esp-hal ${{ matrix.device.soc }}
# Check doc-tests
- if: ${{ !contains(fromJson('["esp32", "esp32s2", "esp32s3"]'), matrix.device.soc) }}
uses: dtolnay/rust-toolchain@v1
with:
target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf
toolchain: nightly
components: rust-src
- name: Check doc-tests
run: cargo xtask run-doc-test esp-hal ${{ matrix.device.soc }}
esp-lp-hal: esp-lp-hal:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -345,4 +354,4 @@ jobs:
ldproxy: false ldproxy: false
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- run: cargo xtask build-tests ${{ matrix.target.soc }} - run: cargo xtask build-tests ${{ matrix.target.soc }}

View File

@ -23,7 +23,7 @@ macro_rules! heap_allocator {
/// and the psram module path. /// and the psram module path.
/// ///
/// # Usage /// # Usage
/// ```no_run /// ```rust, no_run
/// esp_alloc::psram_allocator!(peripherals.PSRAM, hal::psram); /// esp_alloc::psram_allocator!(peripherals.PSRAM, hal::psram);
/// ``` /// ```
#[macro_export] #[macro_export]

View File

@ -39,7 +39,7 @@
//! //!
//! Requires the `embassy` feature to be enabled. //! Requires the `embassy` feature to be enabled.
//! //!
//! ```no_run //! ```rust, no_run
//! #[main] //! #[main]
//! async fn main(spawner: Spawner) { //! async fn main(spawner: Spawner) {
//! // Your application's entry point //! // Your application's entry point
@ -50,7 +50,7 @@
//! //!
//! Requires the `ram` feature to be enabled. //! Requires the `ram` feature to be enabled.
//! //!
//! ```no_run //! ```rust, no_run
//! #[ram(rtc_fast)] //! #[ram(rtc_fast)]
//! static mut SOME_INITED_DATA: [u8; 2] = [0xaa, 0xbb]; //! static mut SOME_INITED_DATA: [u8; 2] = [0xaa, 0xbb];
//! //!
@ -316,7 +316,7 @@ pub fn make_gpio_enum_dispatch_macro(input: TokenStream) -> TokenStream {
/// Load code to be run on the LP/ULP core. /// Load code to be run on the LP/ULP core.
/// ///
/// ## Example /// ## Example
/// ```no_run /// ```rust, no_run
/// let lp_core_code = load_lp_code!("path.elf"); /// let lp_core_code = load_lp_code!("path.elf");
/// lp_core_code.run(&mut lp_core, lp_core::LpCoreWakeupSource::HpCpu, lp_pin); /// lp_core_code.run(&mut lp_core, lp_core::LpCoreWakeupSource::HpCpu, lp_pin);
/// ```` /// ````

View File

@ -117,6 +117,12 @@ fn main() -> Result<(), Box<dyn Error>> {
)?; )?;
} }
// needed for before_snippet! macro
let host = env::var_os("HOST").expect("HOST not set");
if let Some("windows") = host.to_str().unwrap().split('-').nth(2) {
println!("cargo:rustc-cfg=host_os=\"windows\"");
}
// With the architecture-specific linker scripts taken care of, we can copy all // With the architecture-specific linker scripts taken care of, we can copy all
// remaining linker scripts which are common to all devices: // remaining linker scripts which are common to all devices:
copy_dir_all(&config_symbols, "ld/sections", &out)?; copy_dir_all(&config_symbols, "ld/sections", &out)?;

12
esp-hal/doc-helper/before Normal file
View File

@ -0,0 +1,12 @@
# #![no_std]
# use esp_hal::peripherals::Peripherals;
# use esp_hal::clock::ClockControl;
# use esp_hal::system::SystemControl;
# #[panic_handler]
# fn panic(_ : &core::panic::PanicInfo) -> ! {
# loop {}
# }
# fn main() {
# let peripherals = Peripherals::take();
# let system = SystemControl::new(peripherals.SYSTEM);
# let mut clocks = ClockControl::boot_defaults(system.clock_control).freeze();

View File

@ -12,53 +12,26 @@
//! //!
//! ## Example //! ## Example
//! //!
//! ### Initialization //! ```rust, no_run
//! #![doc = crate::before_snippet!()]
//! ```no_run //! # use esp_hal::aes::{Aes, Mode};
//! let mut aes = Aes::new(peripherals.AES); //! # let keytext = "SUp4SeCp@sSw0rd".as_bytes();
//! ``` //! # let plaintext = "message".as_bytes();
//! //! # let mut keybuf = [0_u8; 16];
//! ### Creating key and block Buffer //! # keybuf[..keytext.len()].copy_from_slice(keytext);
//!
//! ```no_run
//! let keytext = "SUp4SeCp@sSw0rd".as_bytes();
//! let plaintext = "message".as_bytes();
//!
//! // create an array with aes128 key size
//! let mut keybuf = [0_u8; 16];
//! keybuf[..keytext.len()].copy_from_slice(keytext);
//!
//! // create an array with aes block size
//! let mut block_buf = [0_u8; 16]; //! let mut block_buf = [0_u8; 16];
//! block_buf[..plaintext.len()].copy_from_slice(plaintext); //! block_buf[..plaintext.len()].copy_from_slice(plaintext);
//! ```
//!
//! ### Encrypting and Decrypting (using hardware)
//!
//! ```no_run
//! let mut block = block_buf.clone(); //! let mut block = block_buf.clone();
//!
//! let mut aes = Aes::new(peripherals.AES);
//! aes.process(&mut block, Mode::Encryption128, keybuf); //! aes.process(&mut block, Mode::Encryption128, keybuf);
//! let hw_encrypted = block.clone(); //! let hw_encrypted = block.clone();
//! //!
//! aes.process(&mut block, Mode::Decryption128, keybuf); //! aes.process(&mut block, Mode::Decryption128, keybuf);
//! let hw_decrypted = block; //! let hw_decrypted = block;
//! # }
//! ``` //! ```
//! //!
//! ### Encrypting and Decrypting (using software)
//!
//! ```no_run
//! let key = GenericArray::from(keybuf);
//!
//! let mut block = GenericArray::from(block_buf);
//! let cipher = Aes128SW::new(&key);
//! cipher.encrypt_block(&mut block);
//!
//! let sw_encrypted = block.clone();
//! cipher.decrypt_block(&mut block);
//!
//! let sw_decrypted = block;
//! ```
//!
//! ### Implementation State //! ### Implementation State
//! //!
//! * DMA mode is currently not supported on ESP32 and ESP32S2 ⚠️ //! * DMA mode is currently not supported on ESP32 and ESP32S2 ⚠️
@ -69,39 +42,11 @@
//! //!
//! * Initialization vector (IV) is currently not supported ⚠️ //! * Initialization vector (IV) is currently not supported ⚠️
//! //!
//! ## Example //! ⚠️: The examples for AES with DMA peripheral are quite extensive, so for a more
//! detailed study of how to use this driver please visit [the repository
//! with corresponding example].
//! //!
//! ### Initialization //! [the repository with corresponding example]: https://github.com/esp-rs/esp-hal/blob/main/hil-test/tests/aes_dma.rs
//!
//! ```no_run
//! let dma = Gdma::new(peripherals.DMA);
//! let dma_channel = dma.channel0;
//!
//! let mut descriptors = [0u32; 8 * 3];
//! let mut rx_descriptors = [0u32; 8 * 3];
//!
//! let aes = Aes::new(peripherals.AES).with_dma(dma_channel.configure(
//! false,
//! &mut descriptors,
//! &mut rx_descriptors,
//! DmaPriority::Priority0,
//! ));
//! ```
//!
//! ### Operation
//!
//! ```no_run
//! let transfer = aes
//! .process(
//! plaintext,
//! hw_encrypted,
//! Mode::Encryption128,
//! CipherMode::Ecb,
//! keybuf,
//! )
//! .unwrap();
//! transfer.wait().unwrap();
//! ```
use crate::{ use crate::{
peripheral::{Peripheral, PeripheralRef}, peripheral::{Peripheral, PeripheralRef},

View File

@ -6,19 +6,36 @@
//! //!
//! ## Example //! ## Example
//! //!
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::analog::adc::AdcConfig;
//! # use esp_hal::peripherals::ADC1;
//! # use esp_hal::analog::adc::Attenuation;
//! # use esp_hal::analog::adc::Adc;
//! # use esp_hal::delay::Delay;
//! # use esp_hal::gpio::Io;
//! # use core::result::Result::Err;
//!
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
#![cfg_attr(esp32, doc = "let analog_pin = io.pins.gpio32;")]
#![cfg_attr(any(esp32s2, esp32s3), doc = "let analog_pin = io.pins.gpio3;")]
#![cfg_attr(
not(any(esp32, esp32s2, esp32s3)),
doc = "let analog_pin = io.pins.gpio2;"
)]
//! let mut adc1_config = AdcConfig::new(); //! let mut adc1_config = AdcConfig::new();
//! let mut adc1 = ADC::<ADC1>::new(peripherals.ADC1, adc1_config); //! let mut pin = adc1_config.enable_pin(analog_pin,
//! let mut pin = adc1_config.enable_pin(io.pins.gpio2, Attenuation::Attenuation11dB); //! Attenuation::Attenuation11dB); let mut adc1 = Adc::new(peripherals.ADC1,
//! adc1_config);
//! //!
//! let mut delay = Delay::new(&clocks); //! let mut delay = Delay::new(&clocks);
//! //!
//! loop { //! loop {
//! let pin_value: u16 = nb::block!(adc1.read(&mut pin)).unwrap(); //! let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut pin)).unwrap();
//! println!("PIN2 ADC reading = {}", pin_value);
//! //!
//! delay.delay_ms(1500u32); //! delay.delay_millis(1500);
//! } //! }
//! # }
//! ``` //! ```
use core::marker::PhantomData; use core::marker::PhantomData;

View File

@ -11,29 +11,30 @@
//! //!
//! ## Example //! ## Example
//! //!
//! ```no_run //! ```rust, no_run
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); #![doc = crate::before_snippet!()]
//! let gpio25 = io.pins.gpio25; //! # use esp_hal::gpio::Io;
//! let gpio26 = io.pins.gpio26; //! # use esp_hal::analog::dac::Dac;
//! # use esp_hal::delay::Delay;
//! # use embedded_hal::delay::DelayNs;
//! //!
//! let mut dac1 = Dac::new(peripherals.DAC1, gpio25); //! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! let mut dac2 = Dac::new(peripherals.DAC2, gpio26); #![cfg_attr(esp32, doc = "let dac1_pin = io.pins.gpio25;")]
#![cfg_attr(esp32s2, doc = "let dac1_pin = io.pins.gpio17;")]
//! let mut dac1 = Dac::new(peripherals.DAC1, dac1_pin);
//! //!
//! let mut delay = Delay::new(&clocks); //! let mut delay = Delay::new(&clocks);
//! //!
//! let mut voltage_dac1 = 200u8; //! let mut voltage_dac1 = 200u8;
//! let mut voltage_dac2 = 255u8;
//! //!
//! // Change voltage on the pins using write function: //! // Change voltage on the pins using write function:
//! loop { //! loop {
//! voltage_dac1 = voltage_dac1.wrapping_add(1); //! voltage_dac1 = voltage_dac1.wrapping_add(1);
//! dac1.write(voltage_dac1); //! dac1.write(voltage_dac1);
//! //!
//! voltage_dac2 = voltage_dac2.wrapping_sub(1);
//! dac2.write(voltage_dac2);
//!
//! delay.delay_ms(50u32); //! delay.delay_ms(50u32);
//! } //! }
//! # }
//! ``` //! ```
#![deny(missing_docs)] #![deny(missing_docs)]

View File

@ -40,19 +40,29 @@
//! ## Examples //! ## Examples
//! //!
//! #### Initialize with default clock frequency for this chip //! #### Initialize with default clock frequency for this chip
//! ```no_run //! ```rust, no_run
//! let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); //! # #![no_std]
//! ``` //! # use esp_hal::peripherals::Peripherals;
//! //! # use esp_hal::clock::ClockControl;
//! #### Initialize with the highest possible frequency for this chip //! # use esp_hal::system::SystemControl;
//! ```no_run //! # #[panic_handler]
//! # fn panic(_ : &core::panic::PanicInfo) -> ! {
//! # loop {}
//! # }
//! # fn main() {
//! # let peripherals = Peripherals::take();
//! # let system = SystemControl::new(peripherals.SYSTEM);
//! // Initialize with the highest possible frequency for this chip
//! let clocks = ClockControl::max(system.clock_control).freeze(); //! let clocks = ClockControl::max(system.clock_control).freeze();
//! ```
//! //!
//! #### Initialize with custom clock frequency //! // Initialize with custom clock frequency
//! ```no_run //! // let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock160MHz).freeze();
//! let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock160MHz).freeze(); //! //
//! // Initialize with default clock frequency for this chip
//! // let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
//! # }
//! ``` //! ```
use fugit::HertzU32; use fugit::HertzU32;
#[cfg(any(esp32, esp32c2))] #[cfg(any(esp32, esp32c2))]

View File

@ -11,13 +11,16 @@
//! affected by many factors, including interrupt usage. //! affected by many factors, including interrupt usage.
//! //!
//! ## Example //! ## Example
//! ```no_run //! ```rust, no_run
//! let mut clocks = ClockControl::boot_defaults(system.clock_control).freeze(); #![doc = crate::before_snippet!()]
//! # use esp_hal::delay::Delay;
//! # use embedded_hal::delay::DelayNs;
//! let mut delay = Delay::new(&clocks); //! let mut delay = Delay::new(&clocks);
//! //!
//! delay.delay_ms(1000 as u32); //! delay.delay_ms(1000 as u32);
//! # }
//! ``` //! ```
//! //!
//! [DelayMs]: embedded_hal_02::blocking::delay::DelayMs //! [DelayMs]: embedded_hal_02::blocking::delay::DelayMs
//! [DelayUs]: embedded_hal_02::blocking::delay::DelayUs //! [DelayUs]: embedded_hal_02::blocking::delay::DelayUs
//! [embedded-hal]: https://docs.rs/embedded-hal/0.2.7/embedded_hal/index.html //! [embedded-hal]: https://docs.rs/embedded-hal/0.2.7/embedded_hal/index.html

View File

@ -18,10 +18,6 @@
//! GDMA peripheral can be initializes using the `new` function, which requires //! GDMA peripheral can be initializes using the `new` function, which requires
//! a DMA peripheral instance and a clock control reference. //! a DMA peripheral instance and a clock control reference.
//! //!
//! ```no_run
//! let dma = Gdma::new(peripherals.DMA);
//! ```
//!
//! <em>PS: Note that the number of DMA channels is chip-specific.</em> //! <em>PS: Note that the number of DMA channels is chip-specific.</em>
use crate::{ use crate::{

View File

@ -15,31 +15,36 @@
//! //!
//! ### Initialize and utilize DMA controller in `SPI` //! ### Initialize and utilize DMA controller in `SPI`
//! //!
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::dma_buffers;
//! # use esp_hal::gpio::Io;
//! # use esp_hal::spi::{master::{Spi, prelude::*}, SpiMode};
//! # use esp_hal::dma::{Dma, DmaPriority};
//! # use crate::esp_hal::prelude::_fugit_RateExtU32;
//! let dma = Dma::new(peripherals.DMA); //! let dma = Dma::new(peripherals.DMA);
//! let dma_channel = dma.channel0; #![cfg_attr(any(esp32, esp32s2), doc = "let dma_channel = dma.spi2channel;")]
#![cfg_attr(not(any(esp32, esp32s2)), doc = "let dma_channel = dma.channel0;")]
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! let sclk = io.pins.gpio0;
//! let miso = io.pins.gpio2;
//! let mosi = io.pins.gpio4;
//! let cs = io.pins.gpio5;
//! //!
//! let mut descriptors = [DmaDescriptor::EMPTY; 8]; //! let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) =
//! let mut rx_descriptors = [DmaDescriptor::EMPTY; 8]; //! dma_buffers!(32000);
//! //!
//! let mut spi = Spi::new( //! let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
//! peripherals.SPI2, //! .with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
//! sclk,
//! mosi,
//! miso,
//! cs,
//! 100.kHz(),
//! SpiMode::Mode0,
//! &clocks,
//! )
//! .with_dma(dma_channel.configure( //! .with_dma(dma_channel.configure(
//! false, //! false,
//! &mut descriptors, //! &mut tx_descriptors,
//! &mut rx_descriptors, //! &mut rx_descriptors,
//! DmaPriority::Priority0, //! DmaPriority::Priority0,
//! )); //! ));
//! # }
//! ``` //! ```
//! //!
//! ⚠️ Note: Descriptors should be sized as `(CHUNK_SIZE + 4091) / 4092`. //! ⚠️ Note: Descriptors should be sized as `(CHUNK_SIZE + 4091) / 4092`.
//! I.e., to transfer buffers of size `1..=4092`, you need 1 descriptor. //! I.e., to transfer buffers of size `1..=4092`, you need 1 descriptor.
//! //!
@ -139,7 +144,7 @@ const CHUNK_SIZE: usize = 4092;
/// Convenience macro to create DMA buffers and descriptors /// Convenience macro to create DMA buffers and descriptors
/// ///
/// ## Usage /// ## Usage
/// ```rust,no_run /// ```rust,ignore
/// // TX and RX buffers are 32000 bytes - passing only one parameter makes TX and RX the same size /// // TX and RX buffers are 32000 bytes - passing only one parameter makes TX and RX the same size
/// let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) = dma_buffers!(32000, 32000); /// let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) = dma_buffers!(32000, 32000);
/// ``` /// ```
@ -179,7 +184,7 @@ macro_rules! dma_buffers {
/// Convenience macro to create circular DMA buffers and descriptors /// Convenience macro to create circular DMA buffers and descriptors
/// ///
/// ## Usage /// ## Usage
/// ```rust,no_run /// ```rust,ignore
/// // TX and RX buffers are 32000 bytes - passing only one parameter makes TX and RX the same size /// // TX and RX buffers are 32000 bytes - passing only one parameter makes TX and RX the same size
/// let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) = /// let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) =
/// dma_circular_buffers!(32000, 32000); /// dma_circular_buffers!(32000, 32000);
@ -240,7 +245,7 @@ macro_rules! dma_circular_buffers {
/// Convenience macro to create DMA descriptors /// Convenience macro to create DMA descriptors
/// ///
/// ## Usage /// ## Usage
/// ```rust,no_run /// ```rust,ignore
/// // Create TX and RX descriptors for transactions up to 32000 bytes - passing only one parameter assumes TX and RX are the same size /// // Create TX and RX descriptors for transactions up to 32000 bytes - passing only one parameter assumes TX and RX are the same size
/// let (mut tx_descriptors, mut rx_descriptors) = dma_descriptors!(32000, 32000); /// let (mut tx_descriptors, mut rx_descriptors) = dma_descriptors!(32000, 32000);
/// ``` /// ```
@ -262,7 +267,7 @@ macro_rules! dma_descriptors {
/// Convenience macro to create circular DMA descriptors /// Convenience macro to create circular DMA descriptors
/// ///
/// ## Usage /// ## Usage
/// ```rust,no_run /// ```rust,ignore
/// // Create TX and RX descriptors for transactions up to 32000 bytes - passing only one parameter assumes TX and RX are the same size /// // Create TX and RX descriptors for transactions up to 32000 bytes - passing only one parameter assumes TX and RX are the same size
/// let (mut tx_descriptors, mut rx_descriptors) = dma_circular_descriptors!(32000, 32000); /// let (mut tx_descriptors, mut rx_descriptors) = dma_circular_descriptors!(32000, 32000);
/// ``` /// ```

View File

@ -21,15 +21,33 @@
//! For more information, please refer to the //! For more information, please refer to the
#![doc = concat!("[ESP-IDF documentation](https://docs.espressif.com/projects/esp-idf/en/latest/", crate::soc::chip!(), "/api-reference/peripherals/etm.html)")] #![doc = concat!("[ESP-IDF documentation](https://docs.espressif.com/projects/esp-idf/en/latest/", crate::soc::chip!(), "/api-reference/peripherals/etm.html)")]
//! ## Example //! ## Example
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::gpio::Io;
//! # use esp_hal::gpio::etm::GpioEtmChannels;
//! # use esp_hal::etm::Etm;
//! # use esp_hal::gpio::etm::GpioEtmInputConfig;
//! # use esp_hal::gpio::etm::GpioEtmOutputConfig;
//! # use esp_hal::gpio::Pull;
//! # use esp_hal::gpio::Level;
//!
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); //! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! let mut led = io.pins.gpio1; //! let mut led = io.pins.gpio1;
//! let button = io.pins.gpio9; //! let button = io.pins.gpio9;
//! //!
//! // setup ETM //! // setup ETM
//! let gpio_ext = GpioEtmChannels::new(peripherals.GPIO_SD); //! let gpio_ext = GpioEtmChannels::new(peripherals.GPIO_SD);
//! let led_task = gpio_ext.channel0_task.toggle(&mut led); //! let led_task = gpio_ext.channel0_task.toggle(
//! let button_event = gpio_ext.channel0_event.falling_edge(button); //! &mut led,
//! GpioEtmOutputConfig {
//! open_drain: false,
//! pull: Pull::None,
//! initial_state: Level::Low,
//! },
//! );
//! let button_event = gpio_ext
//! .channel0_event
//! .falling_edge(button, GpioEtmInputConfig { pull: Pull::Down });
//! //!
//! let etm = Etm::new(peripherals.SOC_ETM); //! let etm = Etm::new(peripherals.SOC_ETM);
//! let channel0 = etm.channel0; //! let channel0 = etm.channel0;
@ -40,6 +58,7 @@
//! //!
//! // the LED is controlled by the button without involving the CPU //! // the LED is controlled by the button without involving the CPU
//! loop {} //! loop {}
//! # }
//! ``` //! ```
use crate::{ use crate::{

View File

@ -22,7 +22,21 @@
//! reversed //! reversed
//! //!
//! ## Example //! ## Example
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::gpio::Io;
//! # use esp_hal::gpio::etm::GpioEtmChannels;
//! # use esp_hal::etm::Etm;
//! # use esp_hal::gpio::etm::GpioEtmInputConfig;
//! # use esp_hal::gpio::etm::GpioEtmOutputConfig;
//! # use esp_hal::gpio::Pull;
//! # use esp_hal::gpio::Level;
//!
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! # let mut led = io.pins.gpio1;
//! # let button = io.pins.gpio9;
//!
//! let gpio_ext = GpioEtmChannels::new(peripherals.GPIO_SD);
//! let led_task = gpio_ext.channel0_task.toggle( //! let led_task = gpio_ext.channel0_task.toggle(
//! &mut led, //! &mut led,
//! GpioEtmOutputConfig { //! GpioEtmOutputConfig {
@ -34,6 +48,7 @@
//! let button_event = gpio_ext //! let button_event = gpio_ext
//! .channel0_event //! .channel0_event
//! .falling_edge(button, GpioEtmInputConfig { pull: Pull::Down }); //! .falling_edge(button, GpioEtmInputConfig { pull: Pull::Down });
//! # }
//! ``` //! ```
use crate::{ use crate::{

View File

@ -14,10 +14,14 @@
//! chip from Deep-sleep. //! chip from Deep-sleep.
//! //!
//! # Example //! # Example
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! use esp_hal::gpio::Io;
//! use esp_hal::gpio::lp_io::LowPowerOutput;
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); //! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! // configure GPIO 1 as LP output pin //! // configure GPIO 1 as LP output pin
//! let lp_pin = LowPowerOutput::new(io.pins.gpio1); //! let lp_pin: LowPowerOutput<'_, 1> = LowPowerOutput::new(io.pins.gpio1);
//! # }
//! ``` //! ```
use core::marker::PhantomData; use core::marker::PhantomData;

View File

@ -15,11 +15,14 @@
//! designed struct from the pac struct `GPIO` and `IO_MUX` using `Io::new`. //! designed struct from the pac struct `GPIO` and `IO_MUX` using `Io::new`.
//! //!
//! ## Example //! ## Example
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::gpio::{Io, Level, Output};
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); //! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! let mut led = Output::new(io.pins.gpio5); //! let mut led = Output::new(io.pins.gpio5, Level::High);
//! # }
//! ``` //! ```
//! //!
//! [embedded-hal]: https://docs.rs/embedded-hal/latest/embedded_hal/ //! [embedded-hal]: https://docs.rs/embedded-hal/latest/embedded_hal/
#![warn(missing_docs)] #![warn(missing_docs)]

View File

@ -14,7 +14,7 @@
//! chip from Deep-sleep. //! chip from Deep-sleep.
//! //!
//! # Example //! # Example
//! ```no_run //! ```rust, ignore
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); //! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! // configure GPIO 1 as ULP output pin //! // configure GPIO 1 as ULP output pin
//! let lp_pin = LowPowerOutput::new(io.pins.gpio1); //! let lp_pin = LowPowerOutput::new(io.pins.gpio1);

View File

@ -14,7 +14,13 @@
//! ## Example //! ## Example
//! Following code shows how to read data from a BMP180 sensor using I2C. //! Following code shows how to read data from a BMP180 sensor using I2C.
//! //!
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::i2c::I2C;
//! # use esp_hal::gpio::Io;
//! # use core::option::Option::None;
//! # use crate::esp_hal::prelude::_fugit_RateExtU32;
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! // Create a new peripheral object with the described wiring //! // Create a new peripheral object with the described wiring
//! // and standard I2C clock speed //! // and standard I2C clock speed
//! let mut i2c = I2C::new( //! let mut i2c = I2C::new(
@ -28,9 +34,8 @@
//! loop { //! loop {
//! let mut data = [0u8; 22]; //! let mut data = [0u8; 22];
//! i2c.write_read(0x77, &[0xaa], &mut data).ok(); //! i2c.write_read(0x77, &[0xaa], &mut data).ok();
//!
//! println!("{:02x?}", data);
//! } //! }
//! # }
//! ``` //! ```
use core::marker::PhantomData; use core::marker::PhantomData;

View File

@ -22,7 +22,25 @@
//! ## Examples //! ## Examples
//! //!
//! ### initialization //! ### initialization
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::i2s::I2s;
//! # use esp_hal::i2s::Standard;
//! # use esp_hal::i2s::DataFormat;
//! # use esp_hal::gpio::Io;
//! # use esp_hal::dma_buffers;
//! # use esp_hal::dma::{Dma, DmaPriority};
//! # use crate::esp_hal::prelude::_fugit_RateExtU32;
//! # use crate::esp_hal::peripherals::Peripherals;
//! # use crate::esp_hal::i2s::I2sReadDma;
//! # use core::ptr::addr_of_mut;
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! let dma = Dma::new(peripherals.DMA);
#![cfg_attr(any(esp32, esp32s2), doc = "let dma_channel = dma.i2s0channel;")]
#![cfg_attr(not(any(esp32, esp32s2)), doc = "let dma_channel = dma.channel0;")]
//! let (_, mut tx_descriptors, mut rx_buffer, mut rx_descriptors) =
//! dma_buffers!(0, 4 * 4092);
//!
//! let i2s = I2s::new( //! let i2s = I2s::new(
//! peripherals.I2S0, //! peripherals.I2S0,
//! Standard::Philips, //! Standard::Philips,
@ -35,24 +53,15 @@
//! DmaPriority::Priority0, //! DmaPriority::Priority0,
//! ), //! ),
//! &clocks, //! &clocks,
//! ) //! );
//! .with_mclk(io.pins.gpio4); #![cfg_attr(not(esp32), doc = "let i2s = i2s.with_mclk(io.pins.gpio0);")]
//! ``` //! let mut i2s_rx = i2s.i2s_rx
//!
//! ### Reading
//! ```no_run
//! let i2s_rx = i2s.i2s_rx.
//! .with_bclk(io.pins.gpio1) //! .with_bclk(io.pins.gpio1)
//! .with_ws(io.pins.gpio2) //! .with_ws(io.pins.gpio2)
//! .with_dout(io.pins.gpio5) //! .with_din(io.pins.gpio5)
//! .build(); //! .build();
//! //!
//! // Creating DMA buffer //! let mut transfer = i2s_rx.read_dma_circular(&mut rx_buffer).unwrap();
//! static mut BUFFER: [u8; 4092 * 4] = [0u8; 4092 * 4];
//! let buffer: &'static mut [u8; 4092 * 4] = unsafe { &mut BUFFER };
//!
//! let mut transfer = i2s_rx.read_dma_circular(buffer).unwrap();
//! println!("Started transfer");
//! //!
//! loop { //! loop {
//! let avail = transfer.available(); //! let avail = transfer.available();
@ -60,9 +69,9 @@
//! if avail > 0 { //! if avail > 0 {
//! let mut rcv = [0u8; 5000]; //! let mut rcv = [0u8; 5000];
//! transfer.pop(&mut rcv[..avail]).unwrap(); //! transfer.pop(&mut rcv[..avail]).unwrap();
//! println!("Received {:x?}...", &rcv[..30]);
//! } //! }
//! } //! }
//! # }
//! ``` //! ```
use core::marker::PhantomData; use core::marker::PhantomData;

View File

@ -8,38 +8,53 @@
//! This is the preferred way to register handlers. //! This is the preferred way to register handlers.
//! //!
//! ## Example using the peripheral driver to register an interrupt handler //! ## Example using the peripheral driver to register an interrupt handler
//! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use core::cell::RefCell;
//! //!
//! ```no_run //! # use critical_section::Mutex;
//! #[entry] //! # use esp_hal::{
//! fn main() -> ! { //! # prelude::*,
//! ... //! # system::{SoftwareInterrupt, SystemControl},
//! let mut sw_int = system.software_interrupt_control; //! # };
//! # use esp_hal::interrupt::Priority;
//! # use esp_hal::interrupt::InterruptHandler;
//!
//! static SWINT0: Mutex<RefCell<Option<SoftwareInterrupt<0>>>> =
//! Mutex::new(RefCell::new(None));
//!
//! let mut sw_int = system.software_interrupt_control;
//! critical_section::with(|cs| { //! critical_section::with(|cs| {
//! sw_int //! sw_int
//! .software_interrupt0 //! .software_interrupt0
//! .set_interrupt_handler(swint0_handler); //! .set_interrupt_handler(swint0_handler);
//! SWINT0 //! SWINT0
//! .borrow_ref_mut(cs) //! .borrow_ref_mut(cs)
//! .replace(sw_int.software_interrupt0); //! .replace(sw_int.software_interrupt0);
//! }); //! });
//! //!
//! // trigger the interrupt
//! critical_section::with(|cs| { //! critical_section::with(|cs| {
//! SWINT0.borrow_ref_mut(cs).as_mut().unwrap().raise(); //! SWINT0.borrow_ref(cs).as_ref().unwrap().raise();
//! }); //! });
//! ... //!
//! loop {}
//! } //! }
//! //!
//! // use the `handler` macro to define a handler, optionally you can set a priority //! # use procmacros::handler;
//! #[handler(priority = esp_hal::interrupt::Priority::Priority2)] //! # use esp_hal::interrupt;
//! # use critical_section::Mutex;
//! # use core::cell::RefCell;
//! # use esp_hal::system::SoftwareInterrupt;
//! # static SWINT0: Mutex<RefCell<Option<SoftwareInterrupt<0>>>> = Mutex::new(RefCell::new(None));
//! #[handler(priority = esp_hal::interrupt::Priority::Priority1)]
//! fn swint0_handler() { //! fn swint0_handler() {
//! esp_println::println!("SW interrupt0"); //! // esp_println::println!("SW interrupt0");
//! critical_section::with(|cs| { //! critical_section::with(|cs| {
//! SWINT0.borrow_ref_mut(cs).as_mut().unwrap().reset(); //! SWINT0.borrow_ref(cs).as_ref().unwrap().reset();
//! }); //! });
//! } //! }
//! ``` //! ```
//!
//! There are additional ways to register interrupt handlers which are generally //! There are additional ways to register interrupt handlers which are generally
//! only meant to be used in very special situations (mostly internal to the HAL //! only meant to be used in very special situations (mostly internal to the HAL
//! or the supporting libraries). Those are outside the scope of this //! or the supporting libraries). Those are outside the scope of this

View File

@ -5,7 +5,7 @@
//! //!
//! On chips with a PLIC CPU interrupts 1,2,5,6,9 .. 19 are used. //! On chips with a PLIC CPU interrupts 1,2,5,6,9 .. 19 are used.
//! //!
//! ```rust //! ```rust, ignore
//! interrupt1() => Priority::Priority1 //! interrupt1() => Priority::Priority1
//! interrupt2() => Priority::Priority2 //! interrupt2() => Priority::Priority2
//! ... //! ...

View File

@ -12,7 +12,27 @@
//! Following code shows how to receive some bytes from an 8 bit DVP stream in //! Following code shows how to receive some bytes from an 8 bit DVP stream in
//! master mode. //! master mode.
//! //!
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::gpio::Io;
//! # use esp_hal::lcd_cam::{cam::{Camera, RxEightBits}, LcdCam};
//! # use fugit::RateExtU32;
//! # use esp_hal::dma_buffers;
//! # use esp_hal::dma::{Dma, DmaPriority};
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//!
//! # let dma = Dma::new(peripherals.DMA);
//! # let channel = dma.channel0;
//!
//! # let (tx_buffer, mut tx_descriptors, _, mut rx_descriptors) = dma_buffers!(32678, 0);
//!
//! # let channel = channel.configure(
//! # false,
//! # &mut tx_descriptors,
//! # &mut rx_descriptors,
//! # DmaPriority::Priority0,
//! # );
//!
//! let mclk_pin = io.pins.gpio15; //! let mclk_pin = io.pins.gpio15;
//! let vsync_pin = io.pins.gpio6; //! let vsync_pin = io.pins.gpio6;
//! let href_pin = io.pins.gpio7; //! let href_pin = io.pins.gpio7;
@ -29,9 +49,11 @@
//! ); //! );
//! //!
//! let lcd_cam = LcdCam::new(peripherals.LCD_CAM); //! let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
//! let mut camera = Camera::new(lcd_cam.cam, channel.rx, data_pins, 20u32.MHz(), &clocks) //! let mut camera =
//! .with_master_clock(mclk_pin) // Remove this for slave mode. //! Camera::new(lcd_cam.cam, channel.rx, data_pins, 20u32.MHz(), &clocks)
//! .with_ctrl_pins(vsync_pin, href_pin, pclk_pin); //! .with_master_clock(mclk_pin) // Remove this for slave mode.
//! .with_ctrl_pins(vsync_pin, href_pin, pclk_pin);
//! # }
//! ``` //! ```
use core::mem::size_of; use core::mem::size_of;

View File

@ -9,7 +9,28 @@
//! Following code show how to send a command to a MIPI-DSI display over I8080 //! Following code show how to send a command to a MIPI-DSI display over I8080
//! protocol. //! protocol.
//! //!
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::gpio::Io;
//! # use esp_hal::lcd_cam::{LcdCam, lcd::i8080::{Config, I8080, TxEightBits}};
//! # use esp_hal::dma_buffers;
//! # use esp_hal::dma::{Dma, DmaPriority};
//! # use fugit::RateExtU32;
//!
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//!
//! # let dma = Dma::new(peripherals.DMA);
//! # let channel = dma.channel0;
//!
//! # let (tx_buffer, mut tx_descriptors, _, mut rx_descriptors) = dma_buffers!(32678, 0);
//!
//! # let channel = channel.configure(
//! # false,
//! # &mut tx_descriptors,
//! # &mut rx_descriptors,
//! # DmaPriority::Priority0,
//! # );
//!
//! let tx_pins = TxEightBits::new( //! let tx_pins = TxEightBits::new(
//! io.pins.gpio9, //! io.pins.gpio9,
//! io.pins.gpio46, //! io.pins.gpio46,
@ -33,6 +54,7 @@
//! .with_ctrl_pins(io.pins.gpio0, io.pins.gpio47); //! .with_ctrl_pins(io.pins.gpio0, io.pins.gpio47);
//! //!
//! i8080.send(0x3A, 0, &[0x55]).unwrap(); // RGB565 //! i8080.send(0x3A, 0, &[0x55]).unwrap(); // RGB565
//! # }
//! ``` //! ```
use core::{fmt::Formatter, mem::size_of}; use core::{fmt::Formatter, mem::size_of};

View File

@ -9,8 +9,22 @@
//! The following will configure the Low Speed Channel0 to 24kHz output with //! The following will configure the Low Speed Channel0 to 24kHz output with
//! 10% duty using the ABPClock //! 10% duty using the ABPClock
//! //!
//! ```no_run //! ```rust, no_run
//! let mut ledc = Ledc::new(peripherals.LEDC, &clock_control); #![doc = crate::before_snippet!()]
//! # use esp_hal::ledc::Ledc;
//! # use esp_hal::ledc::LSGlobalClkSource;
//! # use esp_hal::ledc::timer;
//! # use esp_hal::ledc::LowSpeed;
//! # use esp_hal::ledc::channel;
//! # use esp_hal::gpio::Io;
//! # use crate::esp_hal::prelude::_esp_hal_ledc_timer_TimerIFace;
//! # use crate::esp_hal::prelude::_fugit_RateExtU32;
//! # use crate::esp_hal::prelude::_esp_hal_ledc_channel_ChannelIFace;
//!
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! # let led = io.pins.gpio0;
//!
//! let mut ledc = Ledc::new(peripherals.LEDC, &clocks);
//! ledc.set_global_slow_clock(LSGlobalClkSource::APBClk); //! ledc.set_global_slow_clock(LSGlobalClkSource::APBClk);
//! //!
//! let mut lstimer0 = ledc.get_timer::<LowSpeed>(timer::Number::Timer0); //! let mut lstimer0 = ledc.get_timer::<LowSpeed>(timer::Number::Timer0);
@ -26,37 +40,13 @@
//! channel0 //! channel0
//! .configure(channel::config::Config { //! .configure(channel::config::Config {
//! timer: &lstimer0, //! timer: &lstimer0,
//! duty: 10, //! duty_pct: 10,
//! pin_config: channel::config::PinConfig::PushPull,
//! }) //! })
//! .unwrap(); //! .unwrap();
//! # }
//! ``` //! ```
//! //!
//! # HighSpeed Example (ESP32 only):
//!
//! The following will configure the High Speed Channel0 to 24kHz output with
//! 10% duty using the ABPClock
//!
//! ```no_run
//! let ledc = Ledc::new(peripherals.LEDC, &clock_control);
//!
//! let mut hstimer0 = ledc.get_timer::<HighSpeed>(timer::Number::Timer0);
//! hstimer0
//! .configure(timer::config::Config {
//! duty: timer::config::Duty::Duty5Bit,
//! clock_source: timer::HSClockSource::APBClk,
//! frequency: 24.kHz(),
//! })
//! .unwrap();
//!
//! let mut channel0 = ledc.get_channel(channel::Number::Channel0, led);
//! channel0
//! .configure(channel::config::Config {
//! timer: &hstimer0,
//! duty: 10,
//! })
//! .unwrap();
//! ```
//!
//! # Unsupported //! # Unsupported
//! - Source clock selection //! - Source clock selection
//! - Interrupts //! - Interrupts

View File

@ -32,7 +32,7 @@
//! Invoke the following command in the root of the esp-hal repository to get //! Invoke the following command in the root of the esp-hal repository to get
//! started. //! started.
//! //!
//! ```no_run //! ```bash
//! cargo xtask help //! cargo xtask help
//! ``` //! ```
//! //!
@ -45,7 +45,7 @@
//! We have a template for quick starting bare-metal projects, [esp-template]. //! We have a template for quick starting bare-metal projects, [esp-template].
//! The template uses [cargo-generate], so ensure that it is installed and run //! The template uses [cargo-generate], so ensure that it is installed and run
//! //!
//! ```no_run //! ```bash
//! cargo generate -a esp-rs/esp-template //! cargo generate -a esp-rs/esp-template
//! ``` //! ```
//! //!
@ -461,8 +461,8 @@ mod critical_section_impl {
/// often a `const` variable. /// often a `const` variable.
/// ///
/// Example usage using [`spi::master::dma::SpiDma`] /// Example usage using [`spi::master::dma::SpiDma`]
/// ```no_run /// ```rust, ignore
/// const ARRAY_IN_FLASH = [0xAA; 128] /// const ARRAY_IN_FLASH = [0xAA; 128];
/// ///
/// let spi = SpiDma::new(/* */); /// let spi = SpiDma::new(/* */);
/// ///
@ -525,3 +525,23 @@ fn hal_main(a0: usize, a1: usize, a2: usize) -> ! {
unsafe extern "C" fn stack_chk_fail() { unsafe extern "C" fn stack_chk_fail() {
panic!("Stack corruption detected"); panic!("Stack corruption detected");
} }
#[doc(hidden)]
/// Helper macro for checking doctest code snippets
#[cfg(not(host_os = "windows"))]
#[macro_export]
macro_rules! before_snippet {
() => {
core::include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/doc-helper/before"))
};
}
#[doc(hidden)]
/// Helper macro for checking doctest code snippets
#[cfg(host_os = "windows")]
#[macro_export]
macro_rules! before_snippet {
() => {
core::include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "\\doc-helper\\before"))
};
}

View File

@ -31,14 +31,26 @@
//! ## Example //! ## Example
//! Uses timer0 and operator0 of the MCPWM0 peripheral to output a 50% duty //! Uses timer0 and operator0 of the MCPWM0 peripheral to output a 50% duty
//! signal at 20 kHz. The signal will be output to the pin assigned to `pin`. //! signal at 20 kHz. The signal will be output to the pin assigned to `pin`.
//! //! ```rust, no_run
//! ```no_run #![doc = crate::before_snippet!()]
//! # use esp_hal::{mcpwm, prelude::*}; //! # use esp_hal::{mcpwm, prelude::*};
//! use mcpwm::{operator::PwmPinConfig, timer::PwmWorkingMode, McPwm, PeripheralClockConfig}; //! # use esp_hal::mcpwm::operator::{DeadTimeCfg, PWMStream};
//! # use mcpwm::{operator::PwmPinConfig, timer::PwmWorkingMode, McPwm, PeripheralClockConfig};
//! # use esp_hal::gpio::Io;
//!
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! # let pin = io.pins.gpio0;
//! //!
//! // initialize peripheral //! // initialize peripheral
//! let clock_cfg = PeripheralClockConfig::with_frequency(&clocks, 40.MHz()).unwrap(); #![cfg_attr(
//! let mut mcpwm = McPwm::new(peripherals.PWM0, clock_cfg); esp32h2,
doc = "let clock_cfg = PeripheralClockConfig::with_frequency(&clocks, 40.MHz()).unwrap();"
)]
#![cfg_attr(
not(esp32h2),
doc = "let clock_cfg = PeripheralClockConfig::with_frequency(&clocks, 32.MHz()).unwrap();"
)]
//! let mut mcpwm = McPwm::new(peripherals.MCPWM0, clock_cfg);
//! //!
//! // connect operator0 to timer0 //! // connect operator0 to timer0
//! mcpwm.operator0.set_timer(&mcpwm.timer0); //! mcpwm.operator0.set_timer(&mcpwm.timer0);
@ -47,7 +59,8 @@
//! .operator0 //! .operator0
//! .with_pin_a(pin, PwmPinConfig::UP_ACTIVE_HIGH); //! .with_pin_a(pin, PwmPinConfig::UP_ACTIVE_HIGH);
//! //!
//! // start timer with timestamp values in the range of 0..=99 and a frequency of 20 kHz //! // start timer with timestamp values in the range of 0..=99 and a frequency
//! // of 20 kHz
//! let timer_clock_cfg = clock_cfg //! let timer_clock_cfg = clock_cfg
//! .timer_clock_with_frequency(99, PwmWorkingMode::Increase, 20.kHz()) //! .timer_clock_with_frequency(99, PwmWorkingMode::Increase, 20.kHz())
//! .unwrap(); //! .unwrap();
@ -55,6 +68,7 @@
//! //!
//! // pin will be high 50% of the time //! // pin will be high 50% of the time
//! pwm_pin.set_timestamp(50); //! pwm_pin.set_timestamp(50);
//! # }
//! ``` //! ```
#![deny(missing_docs)] #![deny(missing_docs)]

View File

@ -480,17 +480,34 @@ impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool>
/// configured deadtime. /// configured deadtime.
/// ///
/// # H-Bridge example /// # H-Bridge example
/// ```no_run /// ```rust, no_run
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/doc-helper/before"))]
/// # use esp_hal::{mcpwm, prelude::*};
/// # use esp_hal::mcpwm::{McPwm, PeripheralClockConfig};
/// # use esp_hal::mcpwm::operator::{DeadTimeCfg, PwmPinConfig, PWMStream};
/// # use esp_hal::gpio::Io;
/// # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
/// // active high complementary using PWMA input /// // active high complementary using PWMA input
/// let bridge_active = DeadTimeCfg::new_ahc(); /// let bridge_active = DeadTimeCfg::new_ahc();
/// // use PWMB as input for both outputs /// // use PWMB as input for both outputs
/// let bridge_off = DeadTimeCfg::new_bypass().set_output_swap(PWMStream::PWMA, true); /// let bridge_off = DeadTimeCfg::new_bypass().set_output_swap(PWMStream::PWMA,
/// true);
#[cfg_attr(
esp32h2,
doc = "let clock_cfg = PeripheralClockConfig::with_frequency(&clocks, 40.MHz()).unwrap();"
)]
#[cfg_attr(
not(esp32h2),
doc = "let clock_cfg = PeripheralClockConfig::with_frequency(&clocks, 32.MHz()).unwrap();"
)]
/// let mut mcpwm = McPwm::new(peripherals.MCPWM0, clock_cfg);
///
/// let mut pins = mcpwm.operator0.with_linked_pins( /// let mut pins = mcpwm.operator0.with_linked_pins(
/// pin_a, /// io.pins.gpio0,
/// PwmPinConfig::UP_DOWN_ACTIVE_HIGH, // use PWMA as our main input /// PwmPinConfig::UP_DOWN_ACTIVE_HIGH, // use PWMA as our main input
/// pin_b, /// io.pins.gpio1,
/// PwmPinConfig::EMPTY, // keep PWMB "low" /// PwmPinConfig::EMPTY, // keep PWMB "low"
/// bride_off, /// bridge_off,
/// ); /// );
/// ///
/// pins.set_falling_edge_deadtime(5); /// pins.set_falling_edge_deadtime(5);
@ -501,6 +518,7 @@ impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool>
/// pins.set_deadtime_cfg(bridge_active); /// pins.set_deadtime_cfg(bridge_active);
/// // pin_a: _______-------_____________-------______ /// // pin_a: _______-------_____________-------______
/// // pin_b: ------_________-----------_________----- /// // pin_b: ------_________-----------_________-----
/// # }
/// ``` /// ```
pub struct LinkedPins<'d, PinA, PinB, PWM, const OP: u8> { pub struct LinkedPins<'d, PinA, PinB, PWM, const OP: u8> {
pin_a: PwmPin<'d, PinA, PWM, OP, true>, pin_a: PwmPin<'d, PinA, PWM, OP, true>,

View File

@ -12,9 +12,25 @@
//! ## Examples //! ## Examples
//! //!
//! ### Initialization for TX //! ### Initialization for TX
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::gpio::Io;
//! # use esp_hal::dma_buffers;
//! # use esp_hal::dma::{Dma, DmaPriority};
//! # use esp_hal::parl_io::{ClkOutPin, no_clk_pin, BitPackOrder, ParlIoTxOnly, SampleEdge, TxFourBits, TxPinConfigWithValidPin};
//! # use crate::esp_hal::prelude::_fugit_RateExtU32;
//!
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//!
//! # let dma = Dma::new(peripherals.DMA);
//! # let dma_channel = dma.channel0;
//!
//! let (tx_buffer, mut tx_descriptors, _, mut rx_descriptors) =
//! dma_buffers!(32000, 0); let buffer = tx_buffer;
//!
//! // configure the data pins to use //! // configure the data pins to use
//! let tx_pins = TxFourBits::new(io.pins.gpio1, io.pins.gpio2, io.pins.gpio3, io.pins.gpio4); //! let tx_pins = TxFourBits::new(io.pins.gpio1, io.pins.gpio2, io.pins.gpio3,
//! io.pins.gpio4);
//! //!
//! // configure the valid pin which will be driven high during a TX transfer //! // configure the valid pin which will be driven high during a TX transfer
//! let mut pin_conf = TxPinConfigWithValidPin::new(tx_pins, io.pins.gpio5); //! let mut pin_conf = TxPinConfigWithValidPin::new(tx_pins, io.pins.gpio5);
@ -45,18 +61,32 @@
//! BitPackOrder::Msb, //! BitPackOrder::Msb,
//! ) //! )
//! .unwrap(); //! .unwrap();
//! ```
//! //!
//! ### Start TX transfer //! let mut transfer = parl_io_tx.write_dma(&buffer).unwrap();
//! ```no_run
//! let mut transfer = parl_io_tx.write_dma(buffer).unwrap();
//! //!
//! transfer.wait().unwrap(); //! transfer.wait().unwrap();
//! # }
//! ``` //! ```
//! //!
//! ### Initialization for RX //! ### Initialization for RX
//! ```no_run //! ```rust, no_run
//! let mut rx_pins = RxFourBits::new(io.pins.gpio1, io.pins.gpio2, io.pins.gpio3, io.pins.gpio4); #![doc = crate::before_snippet!()]
//! # use esp_hal::gpio::Io;
//! # use esp_hal::dma_buffers;
//! # use esp_hal::dma::{Dma, DmaPriority};
//! # use esp_hal::parl_io::{no_clk_pin, BitPackOrder, ParlIoRxOnly, RxFourBits};
//! # use crate::esp_hal::prelude::_fugit_RateExtU32;
//!
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//!
//! # let dma = Dma::new(peripherals.DMA);
//! # let dma_channel = dma.channel0;
//!
//! let mut rx_pins = RxFourBits::new(io.pins.gpio1, io.pins.gpio2,
//! io.pins.gpio3, io.pins.gpio4);
//!
//! let (_, mut tx_descriptors, rx_buffer, mut rx_descriptors) = dma_buffers!(0,
//! 32000); let mut buffer = rx_buffer;
//! //!
//! let parl_io = ParlIoRxOnly::new( //! let parl_io = ParlIoRxOnly::new(
//! peripherals.PARL_IO, //! peripherals.PARL_IO,
@ -75,13 +105,12 @@
//! .rx //! .rx
//! .with_config(&mut rx_pins, no_clk_pin(), BitPackOrder::Msb, Some(0xfff)) //! .with_config(&mut rx_pins, no_clk_pin(), BitPackOrder::Msb, Some(0xfff))
//! .unwrap(); //! .unwrap();
//! ```
//! //!
//! ### Start RX transfer //! let mut transfer = parl_io_rx.read_dma(&mut buffer).unwrap();
//! ```no_run
//! let mut transfer = parl_io_rx.read_dma(buffer).unwrap();
//! transfer.wait().unwrap(); //! transfer.wait().unwrap();
//! # }
//! ``` //! ```
#![warn(missing_docs)] #![warn(missing_docs)]
use core::marker::PhantomData; use core::marker::PhantomData;

View File

@ -28,107 +28,13 @@
//! enables users to pause, resume, and clear the counter, as well as enable or //! enables users to pause, resume, and clear the counter, as well as enable or
//! disable interrupts for specific events associated with the unit. //! disable interrupts for specific events associated with the unit.
//! //!
//! ## Example //! ⚠️: The examples for PCNT peripheral are quite extensive, so for a more
//! ```no_run //! detailed study of how to use this driver please visit [the repository
//! let unit_number = unit::Number::Unit1; //! with corresponding example].
//!
//! // setup a pulse couter
//! println!("setup pulse counter unit 0");
//! let pcnt = Pcnt::new(peripherals.PCNT, Some(interrupt_handler));
//! let mut u0 = pcnt.get_unit(unit_number);
//! u0.configure(unit::Config {
//! low_limit: -100,
//! high_limit: 100,
//! filter: Some(min(10u16 * 80, 1023u16)),
//! ..Default::default()
//! })
//! .unwrap();
//!
//! println!("setup channel 0");
//! let mut ch0 = u0.get_channel(channel::Number::Channel0);
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! let mut pin_a = io.pins.gpio5;
//! let mut pin_b = io.pins.gpio6;
//!
//! ch0.configure(
//! PcntSource::from_pin(&mut pin_a, PcntInputConfig { pull: Pull::Up }),
//! PcntSource::from_pin(&mut pin_b, PcntInputConfig { pull: Pull::Up }),
//! channel::Config {
//! lctrl_mode: channel::CtrlMode::Reverse,
//! hctrl_mode: channel::CtrlMode::Keep,
//! pos_edge: channel::EdgeMode::Decrement,
//! neg_edge: channel::EdgeMode::Increment,
//! invert_ctrl: false,
//! invert_sig: false,
//! },
//! );
//!
//! println!("setup channel 1");
//! let mut ch1 = u0.get_channel(channel::Number::Channel1);
//! ch1.configure(
//! PcntSource::from_pin(&mut pin_b, PcntInputConfig { pull: Pull::Up }),
//! PcntSource::from_pin(&mut pin_a, PcntInputConfig { pull: Pull::Up }),
//! channel::Config {
//! lctrl_mode: channel::CtrlMode::Reverse,
//! hctrl_mode: channel::CtrlMode::Keep,
//! pos_edge: channel::EdgeMode::Increment,
//! neg_edge: channel::EdgeMode::Decrement,
//! invert_ctrl: false,
//! invert_sig: false,
//! },
//! );
//! println!("subscribing to events");
//! u0.events(unit::Events {
//! low_limit: true,
//! high_limit: true,
//! thresh0: false,
//! thresh1: false,
//! zero: false,
//! });
//!
//! println!("enabling interrupts");
//! u0.listen();
//! println!("resume pulse counter unit 0");
//! u0.resume();
//!
//! critical_section::with(|cs| UNIT0.borrow_ref_mut(cs).replace(u0));
//!
//! let mut last_value: i32 = 0;
//! loop {
//! critical_section::with(|cs| {
//! let mut u0 = UNIT0.borrow_ref_mut(cs);
//! let u0 = u0.as_mut().unwrap();
//! let value: i32 = u0.get_value() as i32 + VALUE.load(Ordering::SeqCst);
//! if value != last_value {
//! println!("value: {value}");
//! last_value = value;
//! }
//! });
//! }
//! ```
//!
//! Where the `PCNT` interrupt handler is defined as:
//! ```no_run
//! #[handler(priority = esp_hal::interrupt::Priority::Priority2)]
//! fn interrupt_handler() {
//! critical_section::with(|cs| {
//! let mut u0 = UNIT0.borrow_ref_mut(cs);
//! let u0 = u0.as_mut().unwrap();
//! if u0.interrupt_set() {
//! let events = u0.get_events();
//! if events.high_limit {
//! VALUE.fetch_add(100, Ordering::SeqCst);
//! } else if events.low_limit {
//! VALUE.fetch_add(-100, Ordering::SeqCst);
//! }
//! u0.reset_interrupt();
//! }
//! });
//! }
//! ```
//! //!
//! [channel]: channel/index.html //! [channel]: channel/index.html
//! [unit]: unit/index.html //! [unit]: unit/index.html
//! [the repository with corresponding example]: https://github.com/esp-rs/esp-hal/blob/main/examples/src/bin/pcnt_encoder.rs
use self::unit::Unit; use self::unit::Unit;
use crate::{ use crate::{

View File

@ -20,20 +20,6 @@
//! The module also includes a `peripheral_macros` module, which contains macros //! The module also includes a `peripheral_macros` module, which contains macros
//! for generating peripheral structs and associated traits based on //! for generating peripheral structs and associated traits based on
//! configuration options. //! configuration options.
//!
//! ## Examples
//!
//! ### Initialization
//! ```no_run
//! let peripherals = Peripherals::take();
//! ```
//! ### Accessing peripherals
//! ```no_run
//! let mut rtc = Rtc::new(peripherals.LPWR, None);
//! ```
//! ```no_run
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! ```
use core::{ use core::{
marker::PhantomData, marker::PhantomData,
@ -139,7 +125,7 @@ impl<'a, T> DerefMut for PeripheralRef<'a, T> {
/// ///
/// For example, if you have a driver with a constructor like this: /// For example, if you have a driver with a constructor like this:
/// ///
/// ```ignore /// ```rust, ignore
/// impl<'d, T: Instance> Twim<'d, T> { /// impl<'d, T: Instance> Twim<'d, T> {
/// pub fn new( /// pub fn new(
/// twim: impl Peripheral<P = T> + 'd, /// twim: impl Peripheral<P = T> + 'd,
@ -154,14 +140,14 @@ impl<'a, T> DerefMut for PeripheralRef<'a, T> {
/// You may call it with owned peripherals, which yields an instance that can /// You may call it with owned peripherals, which yields an instance that can
/// live forever (`'static`): /// live forever (`'static`):
/// ///
/// ```ignore /// ```rust, ignore
/// let mut twi: Twim<'static, ...> = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config); /// let mut twi: Twim<'static, ...> = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config);
/// ``` /// ```
/// ///
/// Or you may call it with borrowed peripherals, which yields an instance that /// Or you may call it with borrowed peripherals, which yields an instance that
/// can only live for as long as the borrows last: /// can only live for as long as the borrows last:
/// ///
/// ```ignore /// ```rust, ignore
/// let mut twi: Twim<'_, ...> = Twim::new(&mut p.TWISPI0, &mut irq, &mut p.P0_03, &mut p.P0_04, config); /// let mut twi: Twim<'_, ...> = Twim::new(&mut p.TWISPI0, &mut irq, &mut p.P0_03, &mut p.P0_04, config);
/// ``` /// ```
/// ///

View File

@ -40,8 +40,19 @@
//! //!
//! ### Initialization //! ### Initialization
//! //!
//! ```no_run //! ```rust, no_run
//! let rmt = Rmt::new(peripherals.RMT, 80.MHz(), &mut clock_control, &clocks).unwrap(); #![doc = crate::before_snippet!()]
//! # use esp_hal::peripherals::Peripherals;
//! # use esp_hal::rmt::TxChannelConfig;
//! # use esp_hal::rmt::Rmt;
//! # use esp_hal::gpio::Io;
//! # use esp_hal::clock::ClockControl;
//! # use crate::esp_hal::rmt::TxChannelCreator;
//! # use crate::esp_hal::prelude::_fugit_RateExtU32;
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
#![cfg_attr(esp32h2, doc = "let freq = 32.MHz();")]
#![cfg_attr(not(esp32h2), doc = "let freq = 80.MHz();")]
//! let rmt = Rmt::new(peripherals.RMT, freq, &clocks, None).unwrap();
//! let mut channel = rmt //! let mut channel = rmt
//! .channel0 //! .channel0
//! .configure( //! .configure(
@ -57,31 +68,11 @@
//! }, //! },
//! ) //! )
//! .unwrap(); //! .unwrap();
//! # }
//! ``` //! ```
//! (on ESP32 and ESP32-S2 you cannot specify a base frequency other than 80 //! (on ESP32 and ESP32-S2 you cannot specify a base frequency other than 80
//! MHz) //! MHz)
//!
//! ### Sending a pulse sequence
//!
//! ```no_run
//! let data = [
//! PulseCode {
//! level1: true,
//! length1: 100,
//! level2: false,
//! length2: 300,
//! },
//! PulseCode {
//! level1: true,
//! length1: 100,
//! level2: false,
//! length2: 0, // a zero-length pulse marks the end of the sequence
//! },
//! ];
//!
//! let transaction = channel.transmit(&data);
//! channel = transaction.wait().unwrap();
//! ```
#![warn(missing_docs)] #![warn(missing_docs)]
use core::marker::PhantomData; use core::marker::PhantomData;

View File

@ -41,26 +41,6 @@
//! //!
//! For more information, please refer to the //! For more information, please refer to the
#![doc = concat!("[ESP-IDF documentation](https://docs.espressif.com/projects/esp-idf/en/latest/", crate::soc::chip!(), "/api-reference/system/random.html)")] #![doc = concat!("[ESP-IDF documentation](https://docs.espressif.com/projects/esp-idf/en/latest/", crate::soc::chip!(), "/api-reference/system/random.html)")]
//! # Examples
//!
//! ## Initialization
//!
//! ```no_run
//! let mut rng = Rng::new(peripherals.RNG);
//! ```
//!
//! ## Generate a random word (u32)
//!
//! ```no_run
//! let random: u32 = rng.random();
//! ```
//!
//! ## Fill a buffer of arbitrary size with random bytes
//!
//! ```no_run
//! let mut buffer = [0u8; 32];
//! rng.read(&mut buffer).unwrap();
//! ```
use core::marker::PhantomData; use core::marker::PhantomData;

View File

@ -24,14 +24,20 @@
//! ongoing calculation over multiple buffers. To do this, the initial value //! ongoing calculation over multiple buffers. To do this, the initial value
//! passed in and the final value returned are one's complemented. //! passed in and the final value returned are one's complemented.
//! //!
//! ``` //! ```rust, no_run
//! // CRC-32/MPEG-2 //! // CRC-32/MPEG-2
//! const CRC_INITIAL: _ = 0xffffffff; // "init" or "xorin" of all ones #![doc = crate::before_snippet!()]
//! let mut crc = crc32_be(!CRC_INITIAL, &data0); // start //! # use esp_hal::rom::crc::crc32_be;
//! crc = crc32_be(crc, &data1); //! # let data0 = "123456789";
//! crc = !crc32_be(crc, &data2); // finish //! # let data1 = "123456789";
//! # let data2 = "123456789";
//! const CRC_INITIAL: u32 = 0xffffffff; // "init" or "xorin" of all ones
//! let mut crc = crc32_be(!CRC_INITIAL, &data0.as_ref()); // start
//! crc = crc32_be(crc, &data1.as_ref());
//! crc = !crc32_be(crc, &data2.as_ref()); // finish
//! # }
//! ``` //! ```
//! //!
//! ## Examples //! ## Examples
//! //!
//! A catalogue of these parameters can be found at //! A catalogue of these parameters can be found at
@ -39,36 +45,51 @@
//! //!
//! CRC-32/ISO-HDLC poly=0x04c11db7 init=0xffffffff refin=true refout=true //! CRC-32/ISO-HDLC poly=0x04c11db7 init=0xffffffff refin=true refout=true
//! xorout=0xffffffff //! xorout=0xffffffff
//! //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::rom::crc::crc32_le;
//! # let data = "123456789";
//! let crc = crc32_le(!0xffffffff, &data.as_ref());
//! # }
//! ``` //! ```
//! let crc = crc32_le(!0xffffffff, &data); //!
//! ```
//!
//! CRC-32/BZIP2 poly=0x04c11db7 init=0xffffffff refin=false refout=false //! CRC-32/BZIP2 poly=0x04c11db7 init=0xffffffff refin=false refout=false
//! xorout=0xffffffff //! xorout=0xffffffff
//! //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::rom::crc::crc32_be;
//! # let data = "123456789";
//! let crc = crc32_be(!0xffffffff, &data.as_ref());
//! # }
//! ``` //! ```
//! let crc = crc32_be(!0xffffffff, &data); //!
//! ```
//!
//! CRC-32/MPEG-2 poly=0x04c11db7 init=0xffffffff refin=false refout=false //! CRC-32/MPEG-2 poly=0x04c11db7 init=0xffffffff refin=false refout=false
//! xorout=0x00000000 //! xorout=0x00000000
//! //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::rom::crc::crc32_be;
//! # let data = "123456789";
//! let crc = !crc32_be(!0xffffffff, &data.as_ref());
//! # }
//! ``` //! ```
//! let crc = !crc32_be(!0xffffffff, &data); //!
//! ```
//!
//! CRC-32/CKSUM poly=0x04c11db7 init=0x00000000 refin=false refout=false //! CRC-32/CKSUM poly=0x04c11db7 init=0x00000000 refin=false refout=false
//! xorout=0xffffffff //! xorout=0xffffffff
//! //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::rom::crc::crc32_be;
//! # let data = "123456789";
//! let crc = crc32_be(!0, &data.as_ref());
//! # }
//! ``` //! ```
//! let crc = crc32_be(!0, &data); //!
//! ```
//!
//! CRC-16/KERMIT poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 //! CRC-16/KERMIT poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000
//! //! ```rust, no_run
//! ``` #![doc = crate::before_snippet!()]
//! let crc = !crc16_le(!0, &data); //! # use esp_hal::rom::crc::crc16_le;
//! # let data = "123456789";
//! let crc = !crc16_le(!0, &data.as_ref());
//! # }
//! ``` //! ```
// SAFETY: These functions are all implemented as table lookups. No locking is // SAFETY: These functions are all implemented as table lookups. No locking is

View File

@ -28,21 +28,37 @@
//! //!
//! To compute a full digest from a single buffer, use the following: //! To compute a full digest from a single buffer, use the following:
//! //!
//! ``` //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::rom::md5;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut uart0 = Uart::new(peripherals.UART0, &clocks);
//! # let data = "Dummy";
//! let d: md5::Digest = md5::compute(&data); //! let d: md5::Digest = md5::compute(&data);
//! writeln!(uart0, "{}", d); //! writeln!(uart0, "{}", d);
//! # }
//! ``` //! ```
//! //!
//! To compute a digest over multiple buffers: //! To compute a digest over multiple buffers:
//! //! ```rust, no_run
//! ``` #![doc = crate::before_snippet!()]
//! # use esp_hal::rom::md5;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut uart0 = Uart::new(peripherals.UART0, &clocks);
//! # let data0 = "Dummy";
//! # let data1 = "Dummy";
//! let mut ctx = md5::Context::new(); //! let mut ctx = md5::Context::new();
//! ctx.consume(&data0); //! ctx.consume(&data0);
//! ctx.consume(&data1); //! ctx.consume(&data1);
//! let d: md5::Digest = ctx.compute(); //! let d: md5::Digest = ctx.compute();
//! writeln!(uart0, "{}", d); //! writeln!(uart0, "{}", d);
//! # }
//! ``` //! ```
//! //!
//! [1]: <https://crates.io/crates/md5> //! [1]: <https://crates.io/crates/md5>
#[allow(unused)] #[allow(unused)]

View File

@ -19,38 +19,6 @@
//! cryptographic operations on `ESP` chips, allowing developers to //! cryptographic operations on `ESP` chips, allowing developers to
//! leverage the `RSA accelerator` for improved performance. //! leverage the `RSA accelerator` for improved performance.
//! //!
//! ## Examples
//! ### Initialization
//! ```no_run
//! let peripherals = Peripherals::take();
//!
//! let mut rsa = Rsa::new(peripherals.RSA, None);
//! ```
//!
//! ### Async (modular exponentiation)
//! ```no_run
//! #[embassy_executor::task]
//! async fn mod_exp_example(mut rsa: Rsa<'static>) {
//! let mut outbuf = [0_u32; U512::LIMBS];
//! let mut mod_exp = RsaModularExponentiation::<operand_sizes::Op512>::new(
//! &mut rsa,
//! BIGNUM_2.as_words(),
//! BIGNUM_3.as_words(),
//! compute_mprime(&BIGNUM_3),
//! );
//! let r = compute_r(&BIGNUM_3);
//! let base = &BIGNUM_1.as_words();
//! mod_exp
//! .exponentiation(base, r.as_words(), &mut outbuf)
//! .await;
//! let residue_params = DynResidueParams::new(&BIGNUM_3);
//! let residue = DynResidue::new(&BIGNUM_1, residue_params);
//! let sw_out = residue.pow(&BIGNUM_2);
//! assert_eq!(U512::from_words(outbuf), sw_out.retrieve());
//! println!("modular exponentiation done");
//! }
//! ```
//! This peripheral supports `async` on every available chip except of `esp32` //! This peripheral supports `async` on every available chip except of `esp32`
//! (to be solved). //! (to be solved).
//! //!
@ -59,7 +27,7 @@
//! with corresponding example]. //! with corresponding example].
//! //!
//! [nb]: https://docs.rs/nb/1.1.0/nb/ //! [nb]: https://docs.rs/nb/1.1.0/nb/
//! [the repository with corresponding example]: https://github.com/esp-rs/esp-hal/blob/main/esp32-hal/examples/rsa.rs //! [the repository with corresponding example]: https://github.com/esp-rs/esp-hal/blob/main/hil-test/tests/rsa.rs
use core::{marker::PhantomData, ptr::copy_nonoverlapping}; use core::{marker::PhantomData, ptr::copy_nonoverlapping};

View File

@ -19,51 +19,52 @@
//! //!
//! ## Examples //! ## Examples
//! ### Print time in milliseconds from the RTC Timer //! ### Print time in milliseconds from the RTC Timer
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use core::cell::RefCell;
//!
//! # use critical_section::Mutex;
//! # use esp_hal::delay::Delay;
//! # use esp_hal::rtc_cntl::Rtc;
//! # use esp_hal::rtc_cntl::Rwdt;
//! # use crate::esp_hal::prelude::_fugit_ExtU64;
//! static RWDT: Mutex<RefCell<Option<Rwdt>>> = Mutex::new(RefCell::new(None));
//! let mut delay = Delay::new(&clocks); //! let mut delay = Delay::new(&clocks);
//! //!
//! loop { //! let mut rtc = Rtc::new(peripherals.LPWR, Some(interrupt_handler));
//! esp_println::println!("rtc time in milliseconds is {}", rtc.get_time_ms()); //! rtc.rwdt.set_timeout(2000.millis());
//! delay.delay_ms(1000u32);
//! }
//! ```
//!
//! ### RTC Watchdog Timer
//! ```no_run
//! rtc.rwdt.start(2000u64.millis());
//! rtc.rwdt.listen(); //! rtc.rwdt.listen();
//! //!
//! interrupt::enable(
//! peripherals::Interrupt::LP_WDT,
//! interrupt::Priority::Priority1,
//! )
//! .unwrap();
//!
//! critical_section::with(|cs| RWDT.borrow_ref_mut(cs).replace(rtc.rwdt)); //! critical_section::with(|cs| RWDT.borrow_ref_mut(cs).replace(rtc.rwdt));
//! //!
//! unsafe {
//! riscv::interrupt::enable();
//! }
//! //!
//! loop {} //! loop {}
//! ``` //! # }
//! //!
//! Where the `LP_WDT` interrupt handler is defined as: //! // Where the `LP_WDT` interrupt handler is defined as:
//! ```no_run
//! // Handle the corresponding interrupt //! // Handle the corresponding interrupt
//! # use core::cell::RefCell;
//!
//! # use critical_section::Mutex;
//! # use esp_hal::prelude::handler;
//! # use esp_hal::interrupt::InterruptHandler;
//! # use esp_hal::interrupt;
//! # use esp_hal::interrupt::Priority;
//! # use crate::esp_hal::prelude::_fugit_ExtU64;
//! # use esp_hal::rtc_cntl::Rwdt;
//! static RWDT: Mutex<RefCell<Option<Rwdt>>> = Mutex::new(RefCell::new(None));
//! #[handler] //! #[handler]
//! fn interrupt_handler() { //! fn interrupt_handler() {
//! critical_section::with(|cs| { //! critical_section::with(|cs| {
//! esp_println::println!("RWDT Interrupt"); //! // esp_println::println!("RWDT Interrupt");
//! //!
//! let mut rwdt = RWDT.borrow_ref_mut(cs); //! let mut rwdt = RWDT.borrow_ref_mut(cs);
//! let rwdt = rwdt.as_mut().unwrap(); //! let rwdt = rwdt.as_mut().unwrap();
//!
//! rwdt.clear_interrupt(); //! rwdt.clear_interrupt();
//! //!
//! esp_println::println!("Restarting in 5 seconds..."); //! // esp_println::println!("Restarting in 5 seconds...");
//! //!
//! rwdt.start(5000u64.millis()); //! rwdt.set_timeout(5000u64.millis());
//! rwdt.unlisten(); //! rwdt.unlisten();
//! }); //! });
//! } //! }

View File

@ -28,32 +28,37 @@
//! if needed. //! if needed.
//! //!
//! ## Example //! ## Example
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::sha::Sha;
//! # use esp_hal::sha::ShaMode;
//! # use core::option::Option::None;
//! # use nb::block;
//! let source_data = "HELLO, ESPRESSIF!".as_bytes(); //! let source_data = "HELLO, ESPRESSIF!".as_bytes();
//! let mut remaining = source_data; //! let mut remaining = source_data;
//! let mut hasher = Sha::new(peripherals.SHA, ShaMode::SHA256); #![cfg_attr(
//! not(esp32),
//! // Short hashes can be created by decreasing the output buffer to the desired doc = "let mut hasher = Sha::new(peripherals.SHA, ShaMode::SHA256, None);"
//! // length )]
#![cfg_attr(
esp32,
doc = "let mut hasher = Sha::new(peripherals.SHA, ShaMode::SHA256);"
)]
//! // Short hashes can be created by decreasing the output buffer to the
//! // desired length
//! let mut output = [0u8; 32]; //! let mut output = [0u8; 32];
//! //!
//! while remaining.len() > 0 { //! while remaining.len() > 0 {
//! // All the HW Sha functions are infallible so unwrap is fine to use if you use //! // All the HW Sha functions are infallible so unwrap is fine to use if
//! // block! //! // you use block!
//! remaining = block!(hasher.update(remaining)).unwrap(); //! remaining = block!(hasher.update(remaining)).unwrap();
//! } //! }
//! //!
//! // Finish can be called as many times as desired to get multiple copies of the //! // Finish can be called as many times as desired to get multiple copies of
//! // output. //! // the output.
//! block!(hasher.finish(output.as_mut_slice())).unwrap(); //! block!(hasher.finish(output.as_mut_slice())).unwrap();
//! //!
//! println!("SHA256 Hash output {:02x?}", output); //! # }
//!
//! let mut hasher = Sha256::new();
//! hasher.update(source_data);
//! let soft_result = hasher.finalize();
//!
//! println!("SHA256 Hash output {:02x?}", soft_result);
//! ``` //! ```
use core::{convert::Infallible, marker::PhantomData}; use core::{convert::Infallible, marker::PhantomData};

View File

@ -8,41 +8,47 @@
//! //!
//! ## Example //! ## Example
//! //!
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::delay::Delay;
//! # use esp_hal::cpu_control::{CpuControl, Stack};
//! # use core::{cell::RefCell, ptr::addr_of_mut};
//! # use critical_section::Mutex;
//! # use esp_hal::prelude::*;
//! static mut APP_CORE_STACK: Stack<8192> = Stack::new(); //! static mut APP_CORE_STACK: Stack<8192> = Stack::new();
//! //!
//! # let delay = Delay::new(&clocks);
//!
//! let counter = Mutex::new(RefCell::new(0)); //! let counter = Mutex::new(RefCell::new(0));
//! //!
//! let mut cpu_control = CpuControl::new(peripherals.CPU_CTRL); //! let mut cpu_control = CpuControl::new(peripherals.CPU_CTRL);
//! let cpu1_fnctn = || { //! let cpu1_fnctn = || {
//! cpu1_task(&mut timer1, &counter); //! cpu1_task(&delay, &counter);
//! }; //! };
//! let _guard = cpu_control //! let _guard = cpu_control
//! .start_app_core(unsafe { &mut APP_CORE_STACK }, cpu1_fnctn) //! .start_app_core(unsafe { &mut *addr_of_mut!(APP_CORE_STACK) },
//! .unwrap(); //! cpu1_fnctn) .unwrap();
//! //!
//! loop { //! loop {
//! block!(timer0.wait()).unwrap(); //! delay.delay(1.secs());
//!
//! let count = critical_section::with(|cs| *counter.borrow_ref(cs)); //! let count = critical_section::with(|cs| *counter.borrow_ref(cs));
//! println!("Hello World - Core 0! Counter is {}", count);
//! } //! }
//! ``` //! # }
//! //!
//! Where `cpu1_task()` may be defined as: //! // Where `cpu1_task()` may be defined as:
//! //! # use esp_hal::delay::Delay;
//! ```no_run //! # use core::cell::RefCell;
//! # use esp_hal::prelude::*;
//! fn cpu1_task( //! fn cpu1_task(
//! timer: &mut Timer<Timer0<TIMG1>>, //! delay: &Delay,
//! counter: &critical_section::Mutex<RefCell<i32>>, //! counter: &critical_section::Mutex<RefCell<i32>>,
//! ) -> ! { //! ) -> ! {
//! println!("Hello World - Core 1!");
//! loop { //! loop {
//! block!(timer.wait()).unwrap(); //! delay.delay(500.millis());
//! //!
//! critical_section::with(|cs| { //! critical_section::with(|cs| {
//! let new_val = counter.borrow_ref_mut(cs).wrapping_add(1); //! let mut val = counter.borrow_ref_mut(cs);
//! *counter.borrow_ref_mut(cs) = new_val; //! *val = val.wrapping_add(1);
//! }); //! });
//! } //! }
//! } //! }

View File

@ -19,7 +19,13 @@
//! ## Example //! ## Example
//! //!
//! ### Read chip's MAC address from the eFuse storage. //! ### Read chip's MAC address from the eFuse storage.
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::efuse::Efuse;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks);
//! let mac_address = Efuse::read_base_mac_address(); //! let mac_address = Efuse::read_base_mac_address();
//! writeln!( //! writeln!(
//! serial_tx, //! serial_tx,
@ -31,6 +37,7 @@
//! mac_address[4], //! mac_address[4],
//! mac_address[5] //! mac_address[5]
//! ); //! );
//! # }
//! ``` //! ```
use fugit::{HertzU32, RateExtU32}; use fugit::{HertzU32, RateExtU32};

View File

@ -19,7 +19,13 @@
//! ## Example //! ## Example
//! //!
//! ### Read chip's MAC address from the eFuse storage. //! ### Read chip's MAC address from the eFuse storage.
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::efuse::Efuse;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks);
//! let mac_address = Efuse::read_base_mac_address(); //! let mac_address = Efuse::read_base_mac_address();
//! writeln!( //! writeln!(
//! serial_tx, //! serial_tx,
@ -31,6 +37,7 @@
//! mac_address[4], //! mac_address[4],
//! mac_address[5] //! mac_address[5]
//! ); //! );
//! # }
//! ``` //! ```
pub use self::fields::*; pub use self::fields::*;

View File

@ -19,7 +19,13 @@
//! ## Example //! ## Example
//! //!
//! ### Read chip's MAC address from the eFuse storage. //! ### Read chip's MAC address from the eFuse storage.
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::efuse::Efuse;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks);
//! let mac_address = Efuse::read_base_mac_address(); //! let mac_address = Efuse::read_base_mac_address();
//! writeln!( //! writeln!(
//! serial_tx, //! serial_tx,
@ -31,6 +37,7 @@
//! mac_address[4], //! mac_address[4],
//! mac_address[5] //! mac_address[5]
//! ); //! );
//! # }
//! ``` //! ```
pub use self::fields::*; pub use self::fields::*;

View File

@ -19,7 +19,13 @@
//! ## Example //! ## Example
//! //!
//! ### Read chip's MAC address from the eFuse storage. //! ### Read chip's MAC address from the eFuse storage.
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::efuse::Efuse;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks);
//! let mac_address = Efuse::read_base_mac_address(); //! let mac_address = Efuse::read_base_mac_address();
//! writeln!( //! writeln!(
//! serial_tx, //! serial_tx,
@ -31,6 +37,7 @@
//! mac_address[4], //! mac_address[4],
//! mac_address[5] //! mac_address[5]
//! ); //! );
//! # }
//! ``` //! ```
pub use self::fields::*; pub use self::fields::*;

View File

@ -13,30 +13,11 @@
//! //!
//! The `run` method starts the low power core and specifies the wakeup source. //! The `run` method starts the low power core and specifies the wakeup source.
//! //!
//! ## Example //! ⚠️: The examples for LP Core are quite extensive, so for a more
//! ```no_run //! detailed study of how to use this LP Core please visit [the repository
//! // configure GPIO 1 as LP output pin //! with corresponding example].
//! let lp_pin = LowPowerOutput::new(io.pins.gpio1);
//! //!
//! let mut lp_core = esp_hal::lp_core::LpCore::new(peripherals.LP_CORE); //! [the repository with corresponding example]: https://github.com/esp-rs/esp-hal/blob/main/examples/src/bin/lp_core_basic.rs
//! lp_core.stop();
//! println!("lp core stopped");
//!
//! // load code to LP core
//! let lp_core_code =
//! load_lp_code!("../esp-lp-hal/target/riscv32imac-unknown-none-elf/release/examples/blinky");
//!
//! // start LP core
//! lp_core.run(lp_core::LpCoreWakeupSource::HpCpu);
//! println!("lpcore run");
//!
//! let data = (0x5000_2000) as *mut u32;
//! loop {
//! print!("Current {:x} \u{000d}", unsafe {
//! data.read_volatile()
//! });
//! }
//! ```
use esp32c6 as pac; use esp32c6 as pac;

View File

@ -19,7 +19,13 @@
//! ## Example //! ## Example
//! //!
//! ### Read chip's MAC address from the eFuse storage. //! ### Read chip's MAC address from the eFuse storage.
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::efuse::Efuse;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks);
//! let mac_address = Efuse::read_base_mac_address(); //! let mac_address = Efuse::read_base_mac_address();
//! writeln!( //! writeln!(
//! serial_tx, //! serial_tx,
@ -31,6 +37,7 @@
//! mac_address[4], //! mac_address[4],
//! mac_address[5] //! mac_address[5]
//! ); //! );
//! # }
//! ``` //! ```
pub use self::fields::*; pub use self::fields::*;

View File

@ -19,7 +19,13 @@
//! ## Example //! ## Example
//! //!
//! ### Read chip's MAC address from the eFuse storage. //! ### Read chip's MAC address from the eFuse storage.
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::efuse::Efuse;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks);
//! let mac_address = Efuse::read_base_mac_address(); //! let mac_address = Efuse::read_base_mac_address();
//! writeln!( //! writeln!(
//! serial_tx, //! serial_tx,
@ -31,6 +37,7 @@
//! mac_address[4], //! mac_address[4],
//! mac_address[5] //! mac_address[5]
//! ); //! );
//! # }
//! ``` //! ```
pub use self::fields::*; pub use self::fields::*;
@ -42,22 +49,6 @@ pub struct Efuse;
impl Efuse { impl Efuse {
/// Reads chip's MAC address from the eFuse storage. /// Reads chip's MAC address from the eFuse storage.
///
/// # Example
///
/// ```
/// let mac_address = Efuse::get_mac_address();
/// writeln!(
/// serial_tx,
/// "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
/// mac_address[0],
/// mac_address[1],
/// mac_address[2],
/// mac_address[3],
/// mac_address[4],
/// mac_address[5]
/// );
/// ```
pub fn read_base_mac_address() -> [u8; 6] { pub fn read_base_mac_address() -> [u8; 6] {
Self::read_field_be(MAC) Self::read_field_be(MAC)
} }

View File

@ -13,28 +13,30 @@
//! CORE` instance. //! CORE` instance.
//! //!
//! ## Example //! ## Example
//! ```no_run //! ```rust, no_run
//! let mut ulp_core = esp_hal::ulp_core::UlpCore::new(peripherals.ULP_RISCV_CORE); #![doc = crate::before_snippet!()]
//! ulp_core.stop(); //! const CODE: &[u8] = &[
//! println!("ulp core stopped"); //! 0x17, 0x05, 0x00, 0x00, 0x13, 0x05, 0x05, 0x01, 0x81, 0x45, 0x85, 0x05,
//! 0x0c, 0xc1, 0xf5, 0xbf, 0x00, 0x00, 0x00, 0x00,
//! ];
//! let mut ulp_core =
//! esp_hal::ulp_core::UlpCore::new(peripherals.ULP_RISCV_CORE);
//! // ulp_core.stop(); currently not implemented
//! //!
//! // copy code to RTC ram //! // copy code to RTC ram
//! let lp_ram = 0x5000_0000 as *mut u8; //! let lp_ram = 0x5000_0000 as *mut u8;
//! unsafe { //! unsafe {
//! core::ptr::copy_nonoverlapping(CODE as *const _ as *const u8, lp_ram, CODE.len()); //! core::ptr::copy_nonoverlapping(CODE as *const _ as *const u8, lp_ram,
//! } //! CODE.len()); }
//! println!("copied code (len {})", CODE.len());
//! //!
//! // start ULP core //! // start ULP core
//! ulp_core.run(esp_hal::ulp_core::UlpCoreWakeupSource::HpCpu); //! ulp_core.run(esp_hal::ulp_core::UlpCoreWakeupSource::HpCpu);
//! println!("ulpcore run");
//! //!
//! unsafe { //! unsafe {
//! let data = 0x5000_0010 as *mut u32; //! let data = 0x5000_0010 as *mut u32;
//! loop { //! loop {}
//! println!("Current {}", unsafe { data.read_volatile() });
//! }
//! } //! }
//! # }
//! ``` //! ```
use esp32s2 as pac; use esp32s2 as pac;

View File

@ -8,41 +8,47 @@
//! //!
//! ## Example //! ## Example
//! //!
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::delay::Delay;
//! # use esp_hal::cpu_control::{CpuControl, Stack};
//! # use core::{cell::RefCell, ptr::addr_of_mut};
//! # use critical_section::Mutex;
//! # use esp_hal::prelude::*;
//! static mut APP_CORE_STACK: Stack<8192> = Stack::new(); //! static mut APP_CORE_STACK: Stack<8192> = Stack::new();
//! //!
//! # let delay = Delay::new(&clocks);
//!
//! let counter = Mutex::new(RefCell::new(0)); //! let counter = Mutex::new(RefCell::new(0));
//! //!
//! let mut cpu_control = CpuControl::new(peripherals.CPU_CTRL); //! let mut cpu_control = CpuControl::new(peripherals.CPU_CTRL);
//! let cpu1_fnctn = || { //! let cpu1_fnctn = || {
//! cpu1_task(&mut timer1, &counter); //! cpu1_task(&delay, &counter);
//! }; //! };
//! let _guard = cpu_control //! let _guard = cpu_control
//! .start_app_core(unsafe { &mut APP_CORE_STACK }, cpu1_fnctn) //! .start_app_core(unsafe { &mut *addr_of_mut!(APP_CORE_STACK) },
//! .unwrap(); //! cpu1_fnctn) .unwrap();
//! //!
//! loop { //! loop {
//! block!(timer0.wait()).unwrap(); //! delay.delay(1.secs());
//!
//! let count = critical_section::with(|cs| *counter.borrow_ref(cs)); //! let count = critical_section::with(|cs| *counter.borrow_ref(cs));
//! println!("Hello World - Core 0! Counter is {}", count);
//! } //! }
//! ``` //! # }
//! //!
//! Where `cpu1_task()` may be defined as: //! // Where `cpu1_task()` may be defined as:
//! //! # use esp_hal::delay::Delay;
//! ```no_run //! # use core::cell::RefCell;
//! # use esp_hal::prelude::*;
//! fn cpu1_task( //! fn cpu1_task(
//! timer: &mut Timer<Timer0<TIMG1>>, //! delay: &Delay,
//! counter: &critical_section::Mutex<RefCell<i32>>, //! counter: &critical_section::Mutex<RefCell<i32>>,
//! ) -> ! { //! ) -> ! {
//! println!("Hello World - Core 1!");
//! loop { //! loop {
//! block!(timer.wait()).unwrap(); //! delay.delay(500.millis());
//! //!
//! critical_section::with(|cs| { //! critical_section::with(|cs| {
//! let new_val = counter.borrow_ref_mut(cs).wrapping_add(1); //! let mut val = counter.borrow_ref_mut(cs);
//! *counter.borrow_ref_mut(cs) = new_val; //! *val = val.wrapping_add(1);
//! }); //! });
//! } //! }
//! } //! }

View File

@ -19,7 +19,13 @@
//! ## Example //! ## Example
//! //!
//! ### Read chip's MAC address from the eFuse storage. //! ### Read chip's MAC address from the eFuse storage.
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::efuse::Efuse;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks);
//! let mac_address = Efuse::read_base_mac_address(); //! let mac_address = Efuse::read_base_mac_address();
//! writeln!( //! writeln!(
//! serial_tx, //! serial_tx,
@ -31,6 +37,7 @@
//! mac_address[4], //! mac_address[4],
//! mac_address[5] //! mac_address[5]
//! ); //! );
//! # }
//! ``` //! ```
pub use self::fields::*; pub use self::fields::*;

View File

@ -13,28 +13,30 @@
//! to the `ULP CORE` instance. //! to the `ULP CORE` instance.
//! //!
//! ## Example //! ## Example
//! ```no_run //! ```rust, no_run
//! let mut ulp_core = esp_hal::ulp_core::UlpCore::new(peripherals.ULP_RISCV_CORE); #![doc = crate::before_snippet!()]
//! const CODE: &[u8] = &[
//! 0x17, 0x05, 0x00, 0x00, 0x13, 0x05, 0x05, 0x01, 0x81, 0x45, 0x85, 0x05,
//! 0x0c, 0xc1, 0xf5, 0xbf, 0x00, 0x00, 0x00, 0x00,
//! ];
//! let mut ulp_core =
//! esp_hal::ulp_core::UlpCore::new(peripherals.ULP_RISCV_CORE);
//! ulp_core.stop(); //! ulp_core.stop();
//! println!("ulp core stopped");
//! //!
//! // copy code to RTC ram //! // copy code to RTC ram
//! let lp_ram = 0x5000_0000 as *mut u8; //! let lp_ram = 0x5000_0000 as *mut u8;
//! unsafe { //! unsafe {
//! core::ptr::copy_nonoverlapping(CODE as *const _ as *const u8, lp_ram, CODE.len()); //! core::ptr::copy_nonoverlapping(CODE as *const _ as *const u8, lp_ram,
//! } //! CODE.len()); }
//! println!("copied code (len {})", CODE.len());
//! //!
//! // start ULP core //! // start ULP core
//! ulp_core.run(esp_hal::ulp_core::UlpCoreWakeupSource::HpCpu); //! ulp_core.run(esp_hal::ulp_core::UlpCoreWakeupSource::HpCpu);
//! println!("ulpcore run");
//! //!
//! unsafe { //! unsafe {
//! let data = 0x5000_0010 as *mut u32; //! let data = 0x5000_0010 as *mut u32;
//! loop { //! loop {}
//! println!("Current {}", unsafe { data.read_volatile() });
//! }
//! } //! }
//! # }
//! ``` //! ```
use esp32s3 as pac; use esp32s3 as pac;

View File

@ -7,23 +7,28 @@
//! [`Spi::new`]. //! [`Spi::new`].
//! //!
//! ## Example //! ## Example
//! ```rust //! ```rust, no_run
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); #![doc = crate::before_snippet!()]
//! let sclk = io.pins.gpio12; //! # use crate::esp_hal::prelude::_fugit_RateExtU32;
//! let miso = io.pins.gpio11; //! # use esp_hal::spi::SpiMode;
//! let mosi = io.pins.gpio13; //! # use esp_hal::spi::master::Spi;
//! let cs = io.pins.gpio10; //! # use esp_hal::gpio::Io;
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! let sclk = io.pins.gpio0;
//! let miso = io.pins.gpio2;
//! let mosi = io.pins.gpio1;
//! let cs = io.pins.gpio5;
//! //!
//! let mut spi = hal::spi::Spi::new( //! let mut spi = Spi::new(
//! peripherals.SPI2, //! peripherals.SPI2,
//! 100.kHz(), //! 100.kHz(),
//! SpiMode::Mode0, //! SpiMode::Mode0,
//! &mut peripheral_clock_control,
//! &mut clocks, //! &mut clocks,
//! ) //! )
//! .with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs)); //! .with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs));
//! # }
//! ``` //! ```
//! //!
//! ## Exclusive access to the SPI bus //! ## Exclusive access to the SPI bus
//! //!
//! If all you want to do is to communicate to a single device, and you initiate //! If all you want to do is to communicate to a single device, and you initiate

View File

@ -8,16 +8,6 @@
//! //!
//! ## Example //! ## Example
//! //!
//! ```rust
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! let sclk = io.pins.gpio12;
//! let miso = io.pins.gpio11;
//! let mosi = io.pins.gpio13;
//! let cs = io.pins.gpio10;
//!
//! let mut spi = hal::spi::slave::Spi::new(peripherals.SPI2, sclk, mosi, miso, cs, SpiMode::Mode0);
//! ```
//!
//! There are several options for working with the SPI peripheral in slave mode, //! There are several options for working with the SPI peripheral in slave mode,
//! but the code currently only supports single transfers (not segmented //! but the code currently only supports single transfers (not segmented
//! transfers), full duplex, single bit (not dual or quad SPI), and DMA mode //! transfers), full duplex, single bit (not dual or quad SPI), and DMA mode
@ -26,24 +16,48 @@
//! then the DmaTransfer trait instance can be wait()ed on or polled for //! then the DmaTransfer trait instance can be wait()ed on or polled for
//! is_done(). //! is_done().
//! //!
//! ```rust //! ```rust, no_run
//! let dma = Gdma::new(peripherals.DMA); #![doc = crate::before_snippet!()]
//! const N: usize = (buffer_size + 4091) / 4092; //! # use esp_hal::dma::DmaPriority;
//! let mut tx_descriptors = [0u32; N * 3]; //! # use esp_hal::dma_buffers;
//! let mut rx_descriptors = [0u32; N * 3]; //! # use esp_hal::spi::SpiMode;
//! let mut spi = spi.with_dma(dma.channel0.configure( //! # use esp_hal::spi::slave::{prelude::*, Spi};
//! /* circular = */ false, //! # use esp_hal::dma::Dma;
//! tx_descriptors, //! # use esp_hal::gpio::Io;
//! rx_descriptors, //! let dma = Dma::new(peripherals.DMA);
#![cfg_attr(esp32s2, doc = "let dma_channel = dma.spi2channel;")]
#![cfg_attr(not(esp32s2), doc = "let dma_channel = dma.channel0;")]
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! let sclk = io.pins.gpio0;
//! let miso = io.pins.gpio1;
//! let mosi = io.pins.gpio2;
//! let cs = io.pins.gpio3;
//!
//! let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) =
//! dma_buffers!(32000); let mut spi = Spi::new(
//! peripherals.SPI2,
//! sclk,
//! mosi,
//! miso,
//! cs,
//! SpiMode::Mode0,
//! )
//! .with_dma(dma_channel.configure(
//! false,
//! &mut tx_descriptors,
//! &mut rx_descriptors,
//! DmaPriority::Priority0, //! DmaPriority::Priority0,
//! )); //! ));
//! // This is not legal rust, but any method of getting a &mut 'static is good. //!
//! let tx_buf = &'static [0u8; N * 4092]; //! let mut send = tx_buffer;
//! let rx_buf = &mut 'static [0u8; N * 4092]; //! let mut receive = rx_buffer;
//! let transfer = spi.dma_transfer(tx_buf, rx_buf).unwrap(); //!
//! // Do other operations, checking transfer.is_done() //! let transfer = spi
//! // When the master sends enough clock pulses, is_done() will be true. //! .dma_transfer(&mut send, &mut receive)
//! (tx_buf, rx_buf, spi) = transfer.wait(); //! .unwrap();
//!
//! transfer.wait().unwrap();
//! # }
//! ``` //! ```
use core::marker::PhantomData; use core::marker::PhantomData;

View File

@ -21,10 +21,12 @@
//! The available peripherals are represented by the `Peripheral` enum //! The available peripherals are represented by the `Peripheral` enum
//! //!
//! ## Example //! ## Example
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! let peripherals = Peripherals::take(); //! let peripherals = Peripherals::take();
//! let system = SystemControl::new(peripherals.SYSTEM); //! let system = SystemControl::new(peripherals.SYSTEM);
//! let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); //! let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
//! # }
//! ``` //! ```
use crate::{interrupt::InterruptHandler, peripheral::PeripheralRef, peripherals::SYSTEM}; use crate::{interrupt::InterruptHandler, peripheral::PeripheralRef, peripherals::SYSTEM};

View File

@ -1,8 +1,11 @@
//! The `time` module offers a way to get the system uptime. //! The `time` module offers a way to get the system uptime.
//! //!
//! ### Example //! ### Example
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::time;
//! let time = time::current_time(); //! let time = time::current_time();
//! # }
//! ``` //! ```
#![warn(missing_docs)] #![warn(missing_docs)]

View File

@ -9,23 +9,32 @@
//! //!
//! #### One-shot Timer //! #### One-shot Timer
//! //!
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::timer::{OneShotTimer, PeriodicTimer, timg::TimerGroup};
//! # use esp_hal::prelude::*;
//! # use core::option::Option::None;
//! let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks, None); //! let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks, None);
//! let one_shot = OneShotTimer::new(timg0.timer0); //! let one_shot = OneShotTimer::new(timg0.timer0);
//! //!
//! one_shot.delay_millis(500); //! one_shot.delay_millis(500);
//! # }
//! ``` //! ```
//! //!
//! #### Periodic Timer //! #### Periodic Timer
//! //! ```rust, no_run
//! ```no_run #![doc = crate::before_snippet!()]
//! # use esp_hal::timer::{PeriodicTimer, timg::TimerGroup};
//! # use esp_hal::prelude::*;
//! # use core::option::Option::None;
//! let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks, None); //! let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks, None);
//! let periodic = PeriodicTimer::new(timg0.timer0); //! let mut periodic = PeriodicTimer::new(timg0.timer0);
//! //!
//! periodic.start(1.secs()); //! periodic.start(1.secs());
//! loop { //! loop {
//! nb::block!(periodic.wait()); //! nb::block!(periodic.wait());
//! } //! }
//! # }
//! ``` //! ```
#![deny(missing_docs)] #![deny(missing_docs)]

View File

@ -17,19 +17,60 @@
//! //!
//! #### General-purpose Timer //! #### General-purpose Timer
//! //!
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::timer::systimer::SystemTimer;
//! # use esp_hal::timer::timg::{TimerGroup, TimerInterrupts};
//! # use crate::esp_hal::prelude::_esp_hal_timer_Timer;
//! # use esp_hal::prelude::*;
//! let systimer = SystemTimer::new(peripherals.SYSTIMER); //! let systimer = SystemTimer::new(peripherals.SYSTIMER);
//! //!
//! // Get the current timestamp, in microseconds: //! // Get the current timestamp, in microseconds:
//! let now = systimer.now(); //! let now = SystemTimer::now();
//!
//! let timg0 = TimerGroup::new(
//! peripherals.TIMG0,
//! &clocks,
//! Some(TimerInterrupts {
//! timer0_t0: Some(tg0_t0_level),
//! ..Default::default()
//! }),
//! );
//!
//! # let timer0 = timg0.timer0;
//! //!
//! // Wait for timeout: //! // Wait for timeout:
//! systimer.load_value(1.secs()); //! timer0.load_value(1.secs());
//! systimer.start(); //! timer0.start();
//! //!
//! while !systimer.is_interrupt_set() { //! while !timer0.is_interrupt_set() {
//! // Wait //! // Wait
//! } //! }
//! # }
//!
//!
//! # use core::cell::RefCell;
//! # use critical_section::Mutex;
//! # use procmacros::handler;
//! # use esp_hal::interrupt::InterruptHandler;
//! # use esp_hal::interrupt;
//! # use esp_hal::peripherals::TIMG0;
//! # use esp_hal::timer::timg::{Timer, Timer0};
//! # use crate::esp_hal::prelude::_esp_hal_timer_Timer;
//! # static TIMER0: Mutex<RefCell<Option<Timer<Timer0<TIMG0>, esp_hal::Blocking>>>> = Mutex::new(RefCell::new(None));
//! #[handler]
//! fn tg0_t0_level() {
//! critical_section::with(|cs| {
//! let mut timer0 = TIMER0.borrow_ref_mut(cs);
//! let timer0 = timer0.as_mut().unwrap();
//!
//! timer0.clear_interrupt();
//!
//! // Counter value should be a very small number as the alarm triggered a
//! // counter reload to 0 and ETM stopped the counter quickly after
//! // esp_println::println!("counter in interrupt: {}", timer0.now());
//! });
//! }
//! ``` //! ```
use core::marker::PhantomData; use core::marker::PhantomData;
@ -662,12 +703,16 @@ pub mod etm {
//! COMPx //! COMPx
//! //!
//! ## Example //! ## Example
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::timer::systimer::{etm::SysTimerEtmEvent, SystemTimer};
//! # use fugit::ExtU32;
//! let syst = SystemTimer::new(peripherals.SYSTIMER); //! let syst = SystemTimer::new(peripherals.SYSTIMER);
//! let mut alarm0 = syst.alarm0.into_periodic(); //! let mut alarm0 = syst.alarm0.into_periodic();
//! alarm0.set_period(1.secs()); //! alarm0.set_period(1.secs());
//! //!
//! let timer_event = SysTimerEtmEvent::new(&mut alarm0); //! let timer_event = SysTimerEtmEvent::new(&mut alarm0);
//! # }
//! ``` //! ```
use super::*; use super::*;

View File

@ -20,8 +20,12 @@
//! //!
//! #### General-purpose Timer //! #### General-purpose Timer
//! //!
//! ```no_run //! ```rust, no_run
//! let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks); #![doc = crate::before_snippet!()]
//! # use esp_hal::timer::timg::TimerGroup;
//! # use crate::esp_hal::prelude::_esp_hal_timer_Timer;
//! # use esp_hal::prelude::*;
//! let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks, None);
//! let timer0 = timg0.timer0; //! let timer0 = timg0.timer0;
//! //!
//! // Get the current timestamp, in microseconds: //! // Get the current timestamp, in microseconds:
@ -34,12 +38,15 @@
//! while !timer0.is_interrupt_set() { //! while !timer0.is_interrupt_set() {
//! // Wait //! // Wait
//! } //! }
//! # }
//! ``` //! ```
//! //!
//! #### Watchdog Timer //! #### Watchdog Timer
//! //! ```rust, no_run
//! ```no_run #![doc = crate::before_snippet!()]
//! let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks); //! # use esp_hal::timer::timg::TimerGroup;
//! # use esp_hal::prelude::*;
//! let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks, None);
//! let mut wdt = timg0.wdt; //! let mut wdt = timg0.wdt;
//! //!
//! wdt.set_timeout(5_000.millis()); //! wdt.set_timeout(5_000.millis());
@ -48,6 +55,7 @@
//! loop { //! loop {
//! wdt.feed(); //! wdt.feed();
//! } //! }
//! # }
//! ``` //! ```
use core::{ use core::{

View File

@ -20,15 +20,18 @@
//! program execution. //! program execution.
//! //!
//! ## Example //! ## Example
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::trace::Trace;
//! let mut trace = Trace::new(peripherals.TRACE0); //! let mut trace = Trace::new(peripherals.TRACE0);
//! let buffer = unsafe { &mut BUFFER[..] }; //! let mut buffer = [0_u8; 1024];
//! trace.start_trace(buffer); //! trace.start_trace(&mut buffer);
//! // traced code //! // traced code
//! println!("Hello"); //!
//! // end traced code //! // end traced code
//! let res = trace.stop_trace().unwrap(); //! let res = trace.stop_trace().unwrap();
//! // transfer the trace result to the host and decode it there //! // transfer the trace result to the host and decode it there
//! # }
//! ``` //! ```
use crate::{ use crate::{

View File

@ -89,7 +89,7 @@ impl SingleStandardFilter {
/// ///
/// Example matching only even IDs, allowing any rtr value and any payload /// Example matching only even IDs, allowing any rtr value and any payload
/// data: /// data:
/// ``` /// ```rust, ignore
/// const FILTER: SingleStandardFilter = /// const FILTER: SingleStandardFilter =
/// SingleStandardFilter::new(b"xxxxxxxxxx0", b"x", [b"xxxxxxxx", b"xxxxxxxx"]); /// SingleStandardFilter::new(b"xxxxxxxxxx0", b"x", [b"xxxxxxxx", b"xxxxxxxx"]);
/// ``` /// ```
@ -149,7 +149,7 @@ impl SingleStandardFilter {
/// ///
/// A filter that matches every standard id that is even, is not an rtr /// A filter that matches every standard id that is even, is not an rtr
/// frame, with any bytes for the first two payload bytes. /// frame, with any bytes for the first two payload bytes.
/// ``` /// ```rust, ignore
/// let filter = twai::filter::SingleStandardFilter::new_from_code_mask( /// let filter = twai::filter::SingleStandardFilter::new_from_code_mask(
/// StandardId::new(0x000).unwrap(), /// StandardId::new(0x000).unwrap(),
/// StandardId::new(0x001).unwrap(), /// StandardId::new(0x001).unwrap(),
@ -213,7 +213,7 @@ impl SingleExtendedFilter {
/// ///
/// # Examples /// # Examples
/// A filter matching any odd extended IDs, with any rtr value. /// A filter matching any odd extended IDs, with any rtr value.
/// ``` /// ```rust, ignore
/// const FILTER: twai::filter::SingleExtendedFilter = /// const FILTER: twai::filter::SingleExtendedFilter =
/// twai::filter::SingleExtendedFilter::new(b"xxxxxxxxxxxxxxxxxxxxxxxxxxxx1", b"x"); /// twai::filter::SingleExtendedFilter::new(b"xxxxxxxxxxxxxxxxxxxxxxxxxxxx1", b"x");
/// ``` /// ```
@ -304,7 +304,7 @@ impl DualStandardFilter {
/// # Examples /// # Examples
/// A filter that matches any standard id that ends with a 00 or a 11, with /// A filter that matches any standard id that ends with a 00 or a 11, with
/// any RTR, and with any payload on the first filter. /// any RTR, and with any payload on the first filter.
/// ``` /// ```rust, ignore
/// const FILTER: twai::filter::DualStandardFilter = twai::filter::DualStandardFilter::new( /// const FILTER: twai::filter::DualStandardFilter = twai::filter::DualStandardFilter::new(
/// b"xxxxxxxxx00", /// b"xxxxxxxxx00",
/// b"x", /// b"x",
@ -452,7 +452,7 @@ impl DualExtendedFilter {
/// part of the id. For example this id matches: 0x000f000f, 0x000f000a, /// part of the id. For example this id matches: 0x000f000f, 0x000f000a,
/// 0x0000000a, 0x0000000b. /// 0x0000000a, 0x0000000b.
/// But it does not match: 0x000a000a /// But it does not match: 0x000a000a
/// ``` /// ```rust, ignore
/// const FILTER: twai::filter::DualExtendedFilter = /// const FILTER: twai::filter::DualExtendedFilter =
/// twai::filter::DualExtendedFilter::new([b"xxxxxxxxx0000xxx", b"xxxxxxxxx1111xxx"]); /// twai::filter::DualExtendedFilter::new([b"xxxxxxxxx0000xxx", b"xxxxxxxxx1111xxx"]);
/// ``` /// ```

View File

@ -17,14 +17,26 @@
//! Format (29-bit) frame identifiers. //! Format (29-bit) frame identifiers.
//! //!
//! ## Example //! ## Example
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::twai;
//! # use embedded_can::Id;
//! # use esp_hal::twai::filter::SingleStandardFilter;
//! # use esp_hal::twai::filter;
//! # use esp_hal::twai::TwaiConfiguration;
//! # use esp_hal::twai::BaudRate;
//! # use esp_hal::gpio::Io;
//! # use embedded_can::Frame;
//! # 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 CAN
//! // transceiver. //! // transceiver.
//! let can_tx_pin = io.pins.gpio2; //! let can_tx_pin = io.pins.gpio2;
//! let can_rx_pin = io.pins.gpio3; //! let can_rx_pin = io.pins.gpio3;
//! //!
//! // The speed of the CAN bus. //! // The speed of the CAN bus.
//! const CAN_BAUDRATE: twai::BaudRate = twai::BaudRate::B1000K; //! const CAN_BAUDRATE: twai::BaudRate = BaudRate::B1000K;
//! //!
//! // Begin configuring the TWAI peripheral. The peripheral is in a reset like //! // Begin configuring the TWAI peripheral. The peripheral is in a reset like
//! // state that prevents transmission but allows configuration. //! // state that prevents transmission but allows configuration.
@ -37,43 +49,25 @@
//! None, //! None,
//! ); //! );
//! //!
//! // Partially filter the incoming messages to reduce overhead of receiving undesired messages //! // Partially filter the incoming messages to reduce overhead of receiving
//! // undesired messages
//! const FILTER: twai::filter::SingleStandardFilter = //! const FILTER: twai::filter::SingleStandardFilter =
//! twai::filter::SingleStandardFilter::new(b"xxxxxxxxxx0", b"x", [b"xxxxxxxx", b"xxxxxxxx"]); //! SingleStandardFilter::new(b"xxxxxxxxxx0", b"x", [b"xxxxxxxx",
//! can_config.set_filter(FILTER); //! b"xxxxxxxx"]); can_config.set_filter(FILTER);
//! //!
//! // Start the peripheral. This locks the configuration settings of the peripheral //! // Start the peripheral. This locks the configuration settings of the
//! // and puts it into operation mode, allowing packets to be sent and //! // peripheral and puts it into operation mode, allowing packets to be sent
//! // received. //! // and received.
//! let mut can = can_config.start(); //! let mut can = can_config.start();
//! //!
//! loop { //! loop {
//! // Wait for a frame to be received. //! // Wait for a frame to be received.
//! let frame = block!(can.receive()).unwrap(); //! let frame = block!(can.receive()).unwrap();
//! //!
//! println!("Received a frame:");
//!
//! // Print different messages based on the frame id type.
//! match frame.id() {
//! Id::Standard(id) => {
//! println!("\tStandard Id: {:?}", id);
//! }
//! Id::Extended(id) => {
//! println!("\tExtended Id: {:?}", id);
//! }
//! }
//!
//! // Print out the frame data or the requested data length code for a remote
//! // transmission request frame.
//! if frame.is_data_frame() {
//! println!("\tData: {:?}", frame.data());
//! } else {
//! println!("\tRemote Frame. Data Length Code: {}", frame.dlc());
//! }
//!
//! // Transmit the frame back. //! // Transmit the frame back.
//! let _result = block!(can.transmit(&frame)).unwrap(); //! let _result = block!(can.transmit(&frame)).unwrap();
//! } //! }
//! # }
//! ``` //! ```
use core::marker::PhantomData; use core::marker::PhantomData;

View File

@ -18,14 +18,20 @@
//! configured. Additionally, the transmit (TX) and receive (RX) pins can be //! configured. Additionally, the transmit (TX) and receive (RX) pins can be
//! specified. //! specified.
//! //!
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use core::option::Option::Some;
//! # use esp_hal::uart::{config::Config, TxRxPins, Uart};
//! use esp_hal::gpio::Io;
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); //! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! let pins = TxRxPins::new_tx_rx(io.pins.gpio1, io.pins.gpio2); //! let pins = TxRxPins::new_tx_rx(io.pins.gpio1, io.pins.gpio2);
//! //!
//! let mut uart1 = //! let mut uart1 =
//! Uart::new_with_config(peripherals.UART1, Config::default(), Some(pins), &clocks); //! Uart::new_with_config(peripherals.UART1, Config::default(), Some(pins),
//! &clocks, None);
//! # }
//! ``` //! ```
//! //!
//! ## Usage //! ## Usage
//! //!
//! The UART driver implements a number of third-party traits, with the //! The UART driver implements a number of third-party traits, with the
@ -41,23 +47,47 @@
//! ### Examples //! ### Examples
//! //!
//! #### Sending and Receiving Data //! #### Sending and Receiving Data
//! //! ```rust, no_run
//! ```no_run #![doc = crate::before_snippet!()]
//! # use esp_hal::uart::{config::Config, TxRxPins, Uart};
//! use esp_hal::gpio::Io;
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! # let pins = TxRxPins::new_tx_rx(io.pins.gpio1, io.pins.gpio2);
//! # let mut uart1 = Uart::new_with_config(
//! # peripherals.UART1,
//! # Config::default(),
//! # Some(pins),
//! # &clocks,
//! # None,
//! # );
//! // Write bytes out over the UART: //! // Write bytes out over the UART:
//! uart1.write_bytes("Hello, world!".as_bytes())?; //! uart1.write_bytes("Hello, world!".as_bytes()).expect("write error!");
//! # }
//! ``` //! ```
//! //!
//! #### Splitting the UART into TX and RX Components //! #### Splitting the UART into TX and RX Components
//! //! ```rust, no_run
//! ```no_run #![doc = crate::before_snippet!()]
//! # use esp_hal::uart::{config::Config, TxRxPins, Uart};
//! use esp_hal::gpio::Io;
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! # let pins = TxRxPins::new_tx_rx(io.pins.gpio1, io.pins.gpio2);
//! # let mut uart1 = Uart::new_with_config(
//! # peripherals.UART1,
//! # Config::default(),
//! # Some(pins),
//! # &clocks,
//! # None,
//! # );
//! // The UART can be split into separate Transmit and Receive components: //! // The UART can be split into separate Transmit and Receive components:
//! let (mut tx, rx) = uart1.split(); //! let (mut tx, mut rx) = uart1.split();
//! //!
//! // Each component can be used individually to interact with the UART: //! // Each component can be used individually to interact with the UART:
//! tx.write_bytes(&[42u8])?; //! tx.write_bytes(&[42u8]).expect("write error!");
//! let byte = rx.read_byte()?; //! let byte = rx.read_byte().expect("read error!");
//! # }
//! ``` //! ```
//! //!
//! [embedded-hal]: https://docs.rs/embedded-hal/latest/embedded_hal/ //! [embedded-hal]: https://docs.rs/embedded-hal/latest/embedded_hal/
//! [embedded-io]: https://docs.rs/embedded-io/latest/embedded_io/ //! [embedded-io]: https://docs.rs/embedded-io/latest/embedded_io/
//! [embedded-hal-async]: https://docs.rs/embedded-hal-async/latest/embedded_hal_async/ //! [embedded-hal-async]: https://docs.rs/embedded-hal-async/latest/embedded_hal_async/
@ -466,13 +496,6 @@ where
} }
/// Read a byte from the UART /// Read a byte from the UART
///
/// Example
///
/// ```rust
/// let (_, mut rx) = serial.spilt();
/// let byte = rx.read_byte().unwrap();
/// ```
pub fn read_byte(&mut self) -> nb::Result<u8, Error> { pub fn read_byte(&mut self) -> nb::Result<u8, Error> {
// On the ESP32-S2 we need to use PeriBus2 to read the FIFO: // On the ESP32-S2 we need to use PeriBus2 to read the FIFO:
let offset = if cfg!(esp32s2) { 0x20C00000 } else { 0 }; let offset = if cfg!(esp32s2) { 0x20C00000 } else { 0 };

View File

@ -41,24 +41,33 @@
//! //!
//! ### Sending and Receiving Data //! ### Sending and Receiving Data
//! //!
//! ```no_run //! ```rust, no_run
#![doc = crate::before_snippet!()]
//! use esp_hal::usb_serial_jtag::UsbSerialJtag;
//! use core::option::Option::None;
//! let mut usb_serial = UsbSerialJtag::new(peripherals.USB_DEVICE, None); //! let mut usb_serial = UsbSerialJtag::new(peripherals.USB_DEVICE, None);
//! //!
//! // Write bytes out over the USB Serial/JTAG: //! // Write bytes out over the USB Serial/JTAG:
//! usb_serial.write_bytes("Hello, world!".as_bytes())?; //! usb_serial.write_bytes("Hello, world!".as_bytes()).expect("write error!");
//! }
//! ``` //! ```
//! //!
//! ### Splitting the USB Serial/JTAG into TX and RX Components //! ### Splitting the USB Serial/JTAG into TX and RX Components
//! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::usb_serial_jtag::UsbSerialJtag;
//! let mut usb_serial = UsbSerialJtag::new(peripherals.USB_DEVICE, None);
//! // The USB Serial/JTAG can be split into separate Transmit and Receive
//! // components:
//! let (mut tx, mut rx) = usb_serial.split();
//! //!
//! ```no_run //! // Each component can be used individually to interact with the USB
//! // The USB Serial/JTAG can be split into separate Transmit and Receive components: //! // Serial/JTAG:
//! let (mut tx, rx) = usb_serial.split(); //! tx.write_bytes(&[42u8]).expect("write error!");
//! //! let byte = rx.read_byte().expect("read error!");
//! // Each component can be used individually to interact with the USB Serial/JTAG: //! # }
//! tx.write_bytes(&[42u8])?;
//! let byte = rx.read_byte()?;
//! ``` //! ```
//! //!
//! [embedded-hal]: https://docs.rs/embedded-hal/latest/embedded_hal/ //! [embedded-hal]: https://docs.rs/embedded-hal/latest/embedded_hal/
//! [embedded-io]: https://docs.rs/embedded-io/latest/embedded_io/ //! [embedded-io]: https://docs.rs/embedded-io/latest/embedded_io/
//! [embedded-hal-async]: https://docs.rs/embedded-hal-async/latest/embedded_hal_async/ //! [embedded-hal-async]: https://docs.rs/embedded-hal-async/latest/embedded_hal_async/

View File

@ -66,10 +66,8 @@ async fn main(_spawner: Spawner) {
&clocks, &clocks,
); );
#[cfg(esp32)] #[cfg(not(features = "esp32"))]
{ let i2s = i2s.with_mclk(io.pins.gpio0);
i2s.with_mclk(io.pins.gpio0);
}
let i2s_rx = i2s let i2s_rx = i2s
.i2s_rx .i2s_rx

View File

@ -89,7 +89,6 @@ fn main() -> ! {
let mut src = [0_u8; 1024]; let mut src = [0_u8; 1024];
rng.read(src.as_mut_slice()); rng.read(src.as_mut_slice());
// println!("HMAC input {:02X?}", src);
let mut output = [0u8; 32]; let mut output = [0u8; 32];

View File

@ -63,10 +63,8 @@ fn main() -> ! {
&clocks, &clocks,
); );
#[cfg(esp32)] #[cfg(not(feature = "esp32"))]
{ let i2s = i2s.with_mclk(io.pins.gpio0);
i2s.with_mclk(io.pins.gpio0);
}
let mut i2s_rx = i2s let mut i2s_rx = i2s
.i2s_rx .i2s_rx

View File

@ -38,6 +38,8 @@ enum Cli {
GenerateEfuseFields(GenerateEfuseFieldsArgs), GenerateEfuseFields(GenerateEfuseFieldsArgs),
/// Lint all packages in the workspace with clippy /// Lint all packages in the workspace with clippy
LintPackages(LintPackagesArgs), LintPackages(LintPackagesArgs),
/// Run doctests for specified chip and package.
RunDocTest(ExampleArgs),
/// Run the given example for the specified chip. /// Run the given example for the specified chip.
RunExample(ExampleArgs), RunExample(ExampleArgs),
/// Run all applicable tests or the specified test for a specified chip. /// Run all applicable tests or the specified test for a specified chip.
@ -155,6 +157,7 @@ fn main() -> Result<()> {
Cli::FmtPackages(args) => fmt_packages(&workspace, args), Cli::FmtPackages(args) => fmt_packages(&workspace, args),
Cli::GenerateEfuseFields(args) => generate_efuse_src(&workspace, args), Cli::GenerateEfuseFields(args) => generate_efuse_src(&workspace, args),
Cli::LintPackages(args) => lint_packages(&workspace, args), Cli::LintPackages(args) => lint_packages(&workspace, args),
Cli::RunDocTest(args) => run_doctests(&workspace, args),
Cli::RunElfs(args) => run_elfs(args), Cli::RunElfs(args) => run_elfs(args),
Cli::RunExample(args) => examples(&workspace, args, CargoAction::Run), Cli::RunExample(args) => examples(&workspace, args, CargoAction::Run),
Cli::RunTests(args) => tests(&workspace, args, CargoAction::Run), Cli::RunTests(args) => tests(&workspace, args, CargoAction::Run),
@ -607,6 +610,33 @@ fn run_elfs(args: RunElfArgs) -> Result<()> {
Ok(()) Ok(())
} }
fn run_doctests(workspace: &Path, args: ExampleArgs) -> Result<()> {
let package_name = args.package.to_string();
let package_path = xtask::windows_safe_path(&workspace.join(&package_name));
// Determine the appropriate build target for the given package and chip:
let target = target_triple(&args.package, &args.chip)?;
let features = vec![args.chip.to_string()];
// Build up an array of command-line arguments to pass to `cargo`:
let builder = CargoArgsBuilder::default()
.subcommand("test")
.arg("--doc")
.arg("-Zdoctest-xcompile")
.arg("-Zbuild-std=core,panic_abort")
.target(target)
.features(&features)
.arg("--release");
let args = builder.build();
log::debug!("{args:#?}");
// Execute `cargo doc` from the package root:
xtask::cargo::run(&args, &package_path)?;
Ok(())
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Helper Functions // Helper Functions