mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-28 21:00:59 +00:00
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:
parent
b8af24071e
commit
4c5e493b1b
11
.github/workflows/ci.yml
vendored
11
.github/workflows/ci.yml
vendored
@ -104,6 +104,15 @@ jobs:
|
||||
# Build all supported examples for the specified device:
|
||||
- name: Build (examples)
|
||||
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:
|
||||
runs-on: ubuntu-latest
|
||||
@ -345,4 +354,4 @@ jobs:
|
||||
ldproxy: false
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- run: cargo xtask build-tests ${{ matrix.target.soc }}
|
||||
- run: cargo xtask build-tests ${{ matrix.target.soc }}
|
@ -23,7 +23,7 @@ macro_rules! heap_allocator {
|
||||
/// and the psram module path.
|
||||
///
|
||||
/// # Usage
|
||||
/// ```no_run
|
||||
/// ```rust, no_run
|
||||
/// esp_alloc::psram_allocator!(peripherals.PSRAM, hal::psram);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
|
@ -39,7 +39,7 @@
|
||||
//!
|
||||
//! Requires the `embassy` feature to be enabled.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! ```rust, no_run
|
||||
//! #[main]
|
||||
//! async fn main(spawner: Spawner) {
|
||||
//! // Your application's entry point
|
||||
@ -50,7 +50,7 @@
|
||||
//!
|
||||
//! Requires the `ram` feature to be enabled.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! ```rust, no_run
|
||||
//! #[ram(rtc_fast)]
|
||||
//! 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.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// ```rust, no_run
|
||||
/// let lp_core_code = load_lp_code!("path.elf");
|
||||
/// lp_core_code.run(&mut lp_core, lp_core::LpCoreWakeupSource::HpCpu, lp_pin);
|
||||
/// ````
|
||||
|
@ -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
|
||||
// remaining linker scripts which are common to all devices:
|
||||
copy_dir_all(&config_symbols, "ld/sections", &out)?;
|
||||
|
12
esp-hal/doc-helper/before
Normal file
12
esp-hal/doc-helper/before
Normal 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();
|
@ -12,53 +12,26 @@
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### Initialization
|
||||
//!
|
||||
//! ```no_run
|
||||
//! let mut aes = Aes::new(peripherals.AES);
|
||||
//! ```
|
||||
//!
|
||||
//! ### Creating key and block Buffer
|
||||
//!
|
||||
//! ```no_run
|
||||
//! let keytext = "SUp4SeCp@sSw0rd".as_bytes();
|
||||
//! let plaintext = "message".as_bytes();
|
||||
//!
|
||||
//! // create an array with aes128 key size
|
||||
//! let mut keybuf = [0_u8; 16];
|
||||
//! keybuf[..keytext.len()].copy_from_slice(keytext);
|
||||
//!
|
||||
//! // create an array with aes block size
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! # use esp_hal::aes::{Aes, Mode};
|
||||
//! # let keytext = "SUp4SeCp@sSw0rd".as_bytes();
|
||||
//! # let plaintext = "message".as_bytes();
|
||||
//! # let mut keybuf = [0_u8; 16];
|
||||
//! # keybuf[..keytext.len()].copy_from_slice(keytext);
|
||||
//! let mut block_buf = [0_u8; 16];
|
||||
//! block_buf[..plaintext.len()].copy_from_slice(plaintext);
|
||||
//! ```
|
||||
//!
|
||||
//! ### Encrypting and Decrypting (using hardware)
|
||||
//!
|
||||
//! ```no_run
|
||||
//! let mut block = block_buf.clone();
|
||||
//!
|
||||
//! let mut aes = Aes::new(peripherals.AES);
|
||||
//! aes.process(&mut block, Mode::Encryption128, keybuf);
|
||||
//! let hw_encrypted = block.clone();
|
||||
//!
|
||||
//! aes.process(&mut block, Mode::Decryption128, keybuf);
|
||||
//! let hw_decrypted = block;
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! ### Encrypting and Decrypting (using software)
|
||||
//!
|
||||
//! ```no_run
|
||||
//! let key = GenericArray::from(keybuf);
|
||||
//!
|
||||
//! let mut block = GenericArray::from(block_buf);
|
||||
//! let cipher = Aes128SW::new(&key);
|
||||
//! cipher.encrypt_block(&mut block);
|
||||
//!
|
||||
//! let sw_encrypted = block.clone();
|
||||
//! cipher.decrypt_block(&mut block);
|
||||
//!
|
||||
//! let sw_decrypted = block;
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! ### Implementation State
|
||||
//!
|
||||
//! * DMA mode is currently not supported on ESP32 and ESP32S2 ⚠️
|
||||
@ -69,39 +42,11 @@
|
||||
//!
|
||||
//! * 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
|
||||
//!
|
||||
//! ```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();
|
||||
//! ```
|
||||
//! [the repository with corresponding example]: https://github.com/esp-rs/esp-hal/blob/main/hil-test/tests/aes_dma.rs
|
||||
|
||||
use crate::{
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
|
@ -6,19 +6,36 @@
|
||||
//!
|
||||
//! ## 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 = ADC::<ADC1>::new(peripherals.ADC1, adc1_config);
|
||||
//! let mut pin = adc1_config.enable_pin(io.pins.gpio2, Attenuation::Attenuation11dB);
|
||||
//! let mut pin = adc1_config.enable_pin(analog_pin,
|
||||
//! Attenuation::Attenuation11dB); let mut adc1 = Adc::new(peripherals.ADC1,
|
||||
//! adc1_config);
|
||||
//!
|
||||
//! let mut delay = Delay::new(&clocks);
|
||||
//!
|
||||
//! loop {
|
||||
//! let pin_value: u16 = nb::block!(adc1.read(&mut pin)).unwrap();
|
||||
//! println!("PIN2 ADC reading = {}", pin_value);
|
||||
//! let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut pin)).unwrap();
|
||||
//!
|
||||
//! delay.delay_ms(1500u32);
|
||||
//! delay.delay_millis(1500);
|
||||
//! }
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
@ -11,29 +11,30 @@
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ```no_run
|
||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//! let gpio25 = io.pins.gpio25;
|
||||
//! let gpio26 = io.pins.gpio26;
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! # use esp_hal::gpio::Io;
|
||||
//! # 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 mut dac2 = Dac::new(peripherals.DAC2, gpio26);
|
||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
#![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 voltage_dac1 = 200u8;
|
||||
//! let mut voltage_dac2 = 255u8;
|
||||
//!
|
||||
//! // Change voltage on the pins using write function:
|
||||
//! loop {
|
||||
//! voltage_dac1 = voltage_dac1.wrapping_add(1);
|
||||
//! dac1.write(voltage_dac1);
|
||||
//!
|
||||
//! voltage_dac2 = voltage_dac2.wrapping_sub(1);
|
||||
//! dac2.write(voltage_dac2);
|
||||
//!
|
||||
//! delay.delay_ms(50u32);
|
||||
//! }
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
#![deny(missing_docs)]
|
||||
|
@ -40,19 +40,29 @@
|
||||
//! ## Examples
|
||||
//!
|
||||
//! #### Initialize with default clock frequency for this chip
|
||||
//! ```no_run
|
||||
//! let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
//! ```
|
||||
//!
|
||||
//! #### Initialize with the highest possible frequency for this chip
|
||||
//! ```no_run
|
||||
//! ```rust, no_run
|
||||
//! # #![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);
|
||||
//! // Initialize with the highest possible frequency for this chip
|
||||
//! let clocks = ClockControl::max(system.clock_control).freeze();
|
||||
//! ```
|
||||
//!
|
||||
//! #### Initialize with custom clock frequency
|
||||
//! ```no_run
|
||||
//! let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock160MHz).freeze();
|
||||
//! // Initialize with custom clock frequency
|
||||
//! // 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;
|
||||
|
||||
#[cfg(any(esp32, esp32c2))]
|
||||
|
@ -11,13 +11,16 @@
|
||||
//! affected by many factors, including interrupt usage.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let mut clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! # use esp_hal::delay::Delay;
|
||||
//! # use embedded_hal::delay::DelayNs;
|
||||
//! let mut delay = Delay::new(&clocks);
|
||||
//!
|
||||
//! delay.delay_ms(1000 as u32);
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! [DelayMs]: embedded_hal_02::blocking::delay::DelayMs
|
||||
//! [DelayUs]: embedded_hal_02::blocking::delay::DelayUs
|
||||
//! [embedded-hal]: https://docs.rs/embedded-hal/0.2.7/embedded_hal/index.html
|
||||
|
@ -18,10 +18,6 @@
|
||||
//! GDMA peripheral can be initializes using the `new` function, which requires
|
||||
//! a DMA peripheral instance and a clock control reference.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! let dma = Gdma::new(peripherals.DMA);
|
||||
//! ```
|
||||
//!
|
||||
//! <em>PS: Note that the number of DMA channels is chip-specific.</em>
|
||||
|
||||
use crate::{
|
||||
|
@ -15,31 +15,36 @@
|
||||
//!
|
||||
//! ### 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_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 mut rx_descriptors = [DmaDescriptor::EMPTY; 8];
|
||||
//! 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,
|
||||
//! 100.kHz(),
|
||||
//! SpiMode::Mode0,
|
||||
//! &clocks,
|
||||
//! )
|
||||
//! let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
|
||||
//! .with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
|
||||
//! .with_dma(dma_channel.configure(
|
||||
//! false,
|
||||
//! &mut descriptors,
|
||||
//! &mut tx_descriptors,
|
||||
//! &mut rx_descriptors,
|
||||
//! DmaPriority::Priority0,
|
||||
//! ));
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! ⚠️ Note: Descriptors should be sized as `(CHUNK_SIZE + 4091) / 4092`.
|
||||
//! 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
|
||||
///
|
||||
/// ## Usage
|
||||
/// ```rust,no_run
|
||||
/// ```rust,ignore
|
||||
/// // 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);
|
||||
/// ```
|
||||
@ -179,7 +184,7 @@ macro_rules! dma_buffers {
|
||||
/// Convenience macro to create circular DMA buffers and descriptors
|
||||
///
|
||||
/// ## Usage
|
||||
/// ```rust,no_run
|
||||
/// ```rust,ignore
|
||||
/// // 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_circular_buffers!(32000, 32000);
|
||||
@ -240,7 +245,7 @@ macro_rules! dma_circular_buffers {
|
||||
/// Convenience macro to create DMA descriptors
|
||||
///
|
||||
/// ## 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
|
||||
/// 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
|
||||
///
|
||||
/// ## 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
|
||||
/// let (mut tx_descriptors, mut rx_descriptors) = dma_circular_descriptors!(32000, 32000);
|
||||
/// ```
|
||||
|
@ -21,15 +21,33 @@
|
||||
//! For more information, please refer to the
|
||||
#, "/api-reference/peripherals/etm.html)")]
|
||||
//! ## 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;
|
||||
//!
|
||||
//! // setup ETM
|
||||
//! let gpio_ext = GpioEtmChannels::new(peripherals.GPIO_SD);
|
||||
//! let led_task = gpio_ext.channel0_task.toggle(&mut led);
|
||||
//! let button_event = gpio_ext.channel0_event.falling_edge(button);
|
||||
//! let led_task = gpio_ext.channel0_task.toggle(
|
||||
//! &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 channel0 = etm.channel0;
|
||||
@ -40,6 +58,7 @@
|
||||
//!
|
||||
//! // the LED is controlled by the button without involving the CPU
|
||||
//! loop {}
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use crate::{
|
||||
|
@ -22,7 +22,21 @@
|
||||
//! reversed
|
||||
//!
|
||||
//! ## 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(
|
||||
//! &mut led,
|
||||
//! GpioEtmOutputConfig {
|
||||
@ -34,6 +48,7 @@
|
||||
//! let button_event = gpio_ext
|
||||
//! .channel0_event
|
||||
//! .falling_edge(button, GpioEtmInputConfig { pull: Pull::Down });
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use crate::{
|
||||
|
@ -14,10 +14,14 @@
|
||||
//! chip from Deep-sleep.
|
||||
//!
|
||||
//! # 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);
|
||||
//! // 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;
|
||||
|
@ -15,11 +15,14 @@
|
||||
//! designed struct from the pac struct `GPIO` and `IO_MUX` using `Io::new`.
|
||||
//!
|
||||
//! ## 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 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/
|
||||
#![warn(missing_docs)]
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
//! chip from Deep-sleep.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! ```rust, ignore
|
||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//! // configure GPIO 1 as ULP output pin
|
||||
//! let lp_pin = LowPowerOutput::new(io.pins.gpio1);
|
||||
|
@ -14,7 +14,13 @@
|
||||
//! ## Example
|
||||
//! 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
|
||||
//! // and standard I2C clock speed
|
||||
//! let mut i2c = I2C::new(
|
||||
@ -28,9 +34,8 @@
|
||||
//! loop {
|
||||
//! let mut data = [0u8; 22];
|
||||
//! i2c.write_read(0x77, &[0xaa], &mut data).ok();
|
||||
//!
|
||||
//! println!("{:02x?}", data);
|
||||
//! }
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
@ -22,7 +22,25 @@
|
||||
//! ## Examples
|
||||
//!
|
||||
//! ### 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(
|
||||
//! peripherals.I2S0,
|
||||
//! Standard::Philips,
|
||||
@ -35,24 +53,15 @@
|
||||
//! DmaPriority::Priority0,
|
||||
//! ),
|
||||
//! &clocks,
|
||||
//! )
|
||||
//! .with_mclk(io.pins.gpio4);
|
||||
//! ```
|
||||
//!
|
||||
//! ### Reading
|
||||
//! ```no_run
|
||||
//! let i2s_rx = i2s.i2s_rx.
|
||||
//! );
|
||||
#![cfg_attr(not(esp32), doc = "let i2s = i2s.with_mclk(io.pins.gpio0);")]
|
||||
//! let mut i2s_rx = i2s.i2s_rx
|
||||
//! .with_bclk(io.pins.gpio1)
|
||||
//! .with_ws(io.pins.gpio2)
|
||||
//! .with_dout(io.pins.gpio5)
|
||||
//! .with_din(io.pins.gpio5)
|
||||
//! .build();
|
||||
//!
|
||||
//! // Creating DMA buffer
|
||||
//! static mut BUFFER: [u8; 4092 * 4] = [0u8; 4092 * 4];
|
||||
//! let buffer: &'static mut [u8; 4092 * 4] = unsafe { &mut BUFFER };
|
||||
//!
|
||||
//! let mut transfer = i2s_rx.read_dma_circular(buffer).unwrap();
|
||||
//! println!("Started transfer");
|
||||
//! let mut transfer = i2s_rx.read_dma_circular(&mut rx_buffer).unwrap();
|
||||
//!
|
||||
//! loop {
|
||||
//! let avail = transfer.available();
|
||||
@ -60,9 +69,9 @@
|
||||
//! if avail > 0 {
|
||||
//! let mut rcv = [0u8; 5000];
|
||||
//! transfer.pop(&mut rcv[..avail]).unwrap();
|
||||
//! println!("Received {:x?}...", &rcv[..30]);
|
||||
//! }
|
||||
//! }
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
@ -8,38 +8,53 @@
|
||||
//! This is the preferred way to register handlers.
|
||||
//!
|
||||
//! ## Example using the peripheral driver to register an interrupt handler
|
||||
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! # use core::cell::RefCell;
|
||||
//!
|
||||
//! ```no_run
|
||||
//! #[entry]
|
||||
//! fn main() -> ! {
|
||||
//! ...
|
||||
//! let mut sw_int = system.software_interrupt_control;
|
||||
//! # use critical_section::Mutex;
|
||||
//! # use esp_hal::{
|
||||
//! # prelude::*,
|
||||
//! # system::{SoftwareInterrupt, SystemControl},
|
||||
//! # };
|
||||
//! # 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| {
|
||||
//! sw_int
|
||||
//! .software_interrupt0
|
||||
//! .set_interrupt_handler(swint0_handler);
|
||||
//! .software_interrupt0
|
||||
//! .set_interrupt_handler(swint0_handler);
|
||||
//! SWINT0
|
||||
//! .borrow_ref_mut(cs)
|
||||
//! .replace(sw_int.software_interrupt0);
|
||||
//! .borrow_ref_mut(cs)
|
||||
//! .replace(sw_int.software_interrupt0);
|
||||
//! });
|
||||
//!
|
||||
//! // trigger the interrupt
|
||||
//! 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
|
||||
//! #[handler(priority = esp_hal::interrupt::Priority::Priority2)]
|
||||
//! # use procmacros::handler;
|
||||
//! # 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() {
|
||||
//! esp_println::println!("SW interrupt0");
|
||||
//! // esp_println::println!("SW interrupt0");
|
||||
//! 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
|
||||
//! 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
|
||||
|
@ -5,7 +5,7 @@
|
||||
//!
|
||||
//! On chips with a PLIC CPU interrupts 1,2,5,6,9 .. 19 are used.
|
||||
//!
|
||||
//! ```rust
|
||||
//! ```rust, ignore
|
||||
//! interrupt1() => Priority::Priority1
|
||||
//! interrupt2() => Priority::Priority2
|
||||
//! ...
|
||||
|
@ -12,7 +12,27 @@
|
||||
//! Following code shows how to receive some bytes from an 8 bit DVP stream in
|
||||
//! 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 vsync_pin = io.pins.gpio6;
|
||||
//! let href_pin = io.pins.gpio7;
|
||||
@ -29,9 +49,11 @@
|
||||
//! );
|
||||
//!
|
||||
//! let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
|
||||
//! let mut camera = Camera::new(lcd_cam.cam, channel.rx, data_pins, 20u32.MHz(), &clocks)
|
||||
//! .with_master_clock(mclk_pin) // Remove this for slave mode.
|
||||
//! .with_ctrl_pins(vsync_pin, href_pin, pclk_pin);
|
||||
//! let mut camera =
|
||||
//! Camera::new(lcd_cam.cam, channel.rx, data_pins, 20u32.MHz(), &clocks)
|
||||
//! .with_master_clock(mclk_pin) // Remove this for slave mode.
|
||||
//! .with_ctrl_pins(vsync_pin, href_pin, pclk_pin);
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use core::mem::size_of;
|
||||
|
@ -9,7 +9,28 @@
|
||||
//! Following code show how to send a command to a MIPI-DSI display over I8080
|
||||
//! 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(
|
||||
//! io.pins.gpio9,
|
||||
//! io.pins.gpio46,
|
||||
@ -33,6 +54,7 @@
|
||||
//! .with_ctrl_pins(io.pins.gpio0, io.pins.gpio47);
|
||||
//!
|
||||
//! i8080.send(0x3A, 0, &[0x55]).unwrap(); // RGB565
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use core::{fmt::Formatter, mem::size_of};
|
||||
|
@ -9,8 +9,22 @@
|
||||
//! The following will configure the Low Speed Channel0 to 24kHz output with
|
||||
//! 10% duty using the ABPClock
|
||||
//!
|
||||
//! ```no_run
|
||||
//! let mut ledc = Ledc::new(peripherals.LEDC, &clock_control);
|
||||
//! ```rust, no_run
|
||||
#![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);
|
||||
//!
|
||||
//! let mut lstimer0 = ledc.get_timer::<LowSpeed>(timer::Number::Timer0);
|
||||
@ -26,37 +40,13 @@
|
||||
//! channel0
|
||||
//! .configure(channel::config::Config {
|
||||
//! timer: &lstimer0,
|
||||
//! duty: 10,
|
||||
//! duty_pct: 10,
|
||||
//! pin_config: channel::config::PinConfig::PushPull,
|
||||
//! })
|
||||
//! .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
|
||||
//! - Source clock selection
|
||||
//! - Interrupts
|
||||
|
@ -32,7 +32,7 @@
|
||||
//! Invoke the following command in the root of the esp-hal repository to get
|
||||
//! started.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! ```bash
|
||||
//! cargo xtask help
|
||||
//! ```
|
||||
//!
|
||||
@ -45,7 +45,7 @@
|
||||
//! 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
|
||||
//!
|
||||
//! ```no_run
|
||||
//! ```bash
|
||||
//! cargo generate -a esp-rs/esp-template
|
||||
//! ```
|
||||
//!
|
||||
@ -461,8 +461,8 @@ mod critical_section_impl {
|
||||
/// often a `const` variable.
|
||||
///
|
||||
/// Example usage using [`spi::master::dma::SpiDma`]
|
||||
/// ```no_run
|
||||
/// const ARRAY_IN_FLASH = [0xAA; 128]
|
||||
/// ```rust, ignore
|
||||
/// const ARRAY_IN_FLASH = [0xAA; 128];
|
||||
///
|
||||
/// let spi = SpiDma::new(/* */);
|
||||
///
|
||||
@ -525,3 +525,23 @@ fn hal_main(a0: usize, a1: usize, a2: usize) -> ! {
|
||||
unsafe extern "C" fn stack_chk_fail() {
|
||||
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"))
|
||||
};
|
||||
}
|
||||
|
@ -31,14 +31,26 @@
|
||||
//! ## Example
|
||||
//! Uses timer0 and operator0 of the MCPWM0 peripheral to output a 50% duty
|
||||
//! signal at 20 kHz. The signal will be output to the pin assigned to `pin`.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! # 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
|
||||
//! let clock_cfg = PeripheralClockConfig::with_frequency(&clocks, 40.MHz()).unwrap();
|
||||
//! let mut mcpwm = McPwm::new(peripherals.PWM0, clock_cfg);
|
||||
#![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);
|
||||
//!
|
||||
//! // connect operator0 to timer0
|
||||
//! mcpwm.operator0.set_timer(&mcpwm.timer0);
|
||||
@ -47,7 +59,8 @@
|
||||
//! .operator0
|
||||
//! .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
|
||||
//! .timer_clock_with_frequency(99, PwmWorkingMode::Increase, 20.kHz())
|
||||
//! .unwrap();
|
||||
@ -55,6 +68,7 @@
|
||||
//!
|
||||
//! // pin will be high 50% of the time
|
||||
//! pwm_pin.set_timestamp(50);
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
#![deny(missing_docs)]
|
||||
|
@ -480,17 +480,34 @@ impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool>
|
||||
/// configured deadtime.
|
||||
///
|
||||
/// # 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
|
||||
/// let bridge_active = DeadTimeCfg::new_ahc();
|
||||
/// // 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(
|
||||
/// pin_a,
|
||||
/// io.pins.gpio0,
|
||||
/// PwmPinConfig::UP_DOWN_ACTIVE_HIGH, // use PWMA as our main input
|
||||
/// pin_b,
|
||||
/// io.pins.gpio1,
|
||||
/// PwmPinConfig::EMPTY, // keep PWMB "low"
|
||||
/// bride_off,
|
||||
/// bridge_off,
|
||||
/// );
|
||||
///
|
||||
/// 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);
|
||||
/// // pin_a: _______-------_____________-------______
|
||||
/// // pin_b: ------_________-----------_________-----
|
||||
/// # }
|
||||
/// ```
|
||||
pub struct LinkedPins<'d, PinA, PinB, PWM, const OP: u8> {
|
||||
pin_a: PwmPin<'d, PinA, PWM, OP, true>,
|
||||
|
@ -12,9 +12,25 @@
|
||||
//! ## Examples
|
||||
//!
|
||||
//! ### 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
|
||||
//! 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
|
||||
//! let mut pin_conf = TxPinConfigWithValidPin::new(tx_pins, io.pins.gpio5);
|
||||
@ -45,18 +61,32 @@
|
||||
//! BitPackOrder::Msb,
|
||||
//! )
|
||||
//! .unwrap();
|
||||
//! ```
|
||||
//!
|
||||
//! ### Start TX transfer
|
||||
//! ```no_run
|
||||
//! let mut transfer = parl_io_tx.write_dma(buffer).unwrap();
|
||||
//! let mut transfer = parl_io_tx.write_dma(&buffer).unwrap();
|
||||
//!
|
||||
//! transfer.wait().unwrap();
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! ### Initialization for RX
|
||||
//! ```no_run
|
||||
//! let mut rx_pins = RxFourBits::new(io.pins.gpio1, io.pins.gpio2, io.pins.gpio3, io.pins.gpio4);
|
||||
//! ```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::{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(
|
||||
//! peripherals.PARL_IO,
|
||||
@ -75,13 +105,12 @@
|
||||
//! .rx
|
||||
//! .with_config(&mut rx_pins, no_clk_pin(), BitPackOrder::Msb, Some(0xfff))
|
||||
//! .unwrap();
|
||||
//! ```
|
||||
//!
|
||||
//! ### Start RX transfer
|
||||
//! ```no_run
|
||||
//! let mut transfer = parl_io_rx.read_dma(buffer).unwrap();
|
||||
//! let mut transfer = parl_io_rx.read_dma(&mut buffer).unwrap();
|
||||
//! transfer.wait().unwrap();
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
@ -28,107 +28,13 @@
|
||||
//! enables users to pause, resume, and clear the counter, as well as enable or
|
||||
//! disable interrupts for specific events associated with the unit.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let unit_number = unit::Number::Unit1;
|
||||
//!
|
||||
//! // setup a pulse couter
|
||||
//! println!("setup pulse counter unit 0");
|
||||
//! let pcnt = Pcnt::new(peripherals.PCNT, 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();
|
||||
//! }
|
||||
//! });
|
||||
//! }
|
||||
//! ```
|
||||
//! ⚠️: The examples for PCNT peripheral are quite extensive, so for a more
|
||||
//! detailed study of how to use this driver please visit [the repository
|
||||
//! with corresponding example].
|
||||
//!
|
||||
//! [channel]: channel/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 crate::{
|
||||
|
@ -20,20 +20,6 @@
|
||||
//! The module also includes a `peripheral_macros` module, which contains macros
|
||||
//! for generating peripheral structs and associated traits based on
|
||||
//! configuration options.
|
||||
//!
|
||||
//! ## Examples
|
||||
//!
|
||||
//! ### Initialization
|
||||
//! ```no_run
|
||||
//! let peripherals = Peripherals::take();
|
||||
//! ```
|
||||
//! ### Accessing peripherals
|
||||
//! ```no_run
|
||||
//! let mut rtc = Rtc::new(peripherals.LPWR, None);
|
||||
//! ```
|
||||
//! ```no_run
|
||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//! ```
|
||||
|
||||
use core::{
|
||||
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:
|
||||
///
|
||||
/// ```ignore
|
||||
/// ```rust, ignore
|
||||
/// impl<'d, T: Instance> Twim<'d, T> {
|
||||
/// pub fn new(
|
||||
/// 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
|
||||
/// live forever (`'static`):
|
||||
///
|
||||
/// ```ignore
|
||||
/// ```rust, ignore
|
||||
/// 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
|
||||
/// 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);
|
||||
/// ```
|
||||
///
|
||||
|
@ -40,8 +40,19 @@
|
||||
//!
|
||||
//! ### Initialization
|
||||
//!
|
||||
//! ```no_run
|
||||
//! let rmt = Rmt::new(peripherals.RMT, 80.MHz(), &mut clock_control, &clocks).unwrap();
|
||||
//! ```rust, no_run
|
||||
#![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
|
||||
//! .channel0
|
||||
//! .configure(
|
||||
@ -57,31 +68,11 @@
|
||||
//! },
|
||||
//! )
|
||||
//! .unwrap();
|
||||
//! # }
|
||||
//! ```
|
||||
//! (on ESP32 and ESP32-S2 you cannot specify a base frequency other than 80
|
||||
//! 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)]
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
@ -41,26 +41,6 @@
|
||||
//!
|
||||
//! For more information, please refer to the
|
||||
#, "/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;
|
||||
|
||||
|
@ -24,14 +24,20 @@
|
||||
//! ongoing calculation over multiple buffers. To do this, the initial value
|
||||
//! passed in and the final value returned are one's complemented.
|
||||
//!
|
||||
//! ```
|
||||
//! ```rust, no_run
|
||||
//! // CRC-32/MPEG-2
|
||||
//! const CRC_INITIAL: _ = 0xffffffff; // "init" or "xorin" of all ones
|
||||
//! let mut crc = crc32_be(!CRC_INITIAL, &data0); // start
|
||||
//! crc = crc32_be(crc, &data1);
|
||||
//! crc = !crc32_be(crc, &data2); // finish
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! # use esp_hal::rom::crc::crc32_be;
|
||||
//! # let data0 = "123456789";
|
||||
//! # 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
|
||||
//!
|
||||
//! 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
|
||||
//! 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
|
||||
//! 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
|
||||
//! 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
|
||||
//! 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
|
||||
//!
|
||||
//! ```
|
||||
//! let crc = !crc16_le(!0, &data);
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! # 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
|
||||
|
@ -28,21 +28,37 @@
|
||||
//!
|
||||
//! 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);
|
||||
//! writeln!(uart0, "{}", d);
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! 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();
|
||||
//! ctx.consume(&data0);
|
||||
//! ctx.consume(&data1);
|
||||
//! let d: md5::Digest = ctx.compute();
|
||||
//! writeln!(uart0, "{}", d);
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! [1]: <https://crates.io/crates/md5>
|
||||
|
||||
#[allow(unused)]
|
||||
|
@ -19,38 +19,6 @@
|
||||
//! cryptographic operations on `ESP` chips, allowing developers to
|
||||
//! leverage the `RSA accelerator` for improved performance.
|
||||
//!
|
||||
//! ## Examples
|
||||
//! ### Initialization
|
||||
//! ```no_run
|
||||
//! let peripherals = Peripherals::take();
|
||||
//!
|
||||
//! let mut 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`
|
||||
//! (to be solved).
|
||||
//!
|
||||
@ -59,7 +27,7 @@
|
||||
//! with corresponding example].
|
||||
//!
|
||||
//! [nb]: https://docs.rs/nb/1.1.0/nb/
|
||||
//! [the repository with corresponding example]: https://github.com/esp-rs/esp-hal/blob/main/esp32-hal/examples/rsa.rs
|
||||
//! [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};
|
||||
|
||||
|
@ -19,51 +19,52 @@
|
||||
//!
|
||||
//! ## Examples
|
||||
//! ### 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);
|
||||
//!
|
||||
//! loop {
|
||||
//! esp_println::println!("rtc time in milliseconds is {}", rtc.get_time_ms());
|
||||
//! delay.delay_ms(1000u32);
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ### RTC Watchdog Timer
|
||||
//! ```no_run
|
||||
//! rtc.rwdt.start(2000u64.millis());
|
||||
//! let mut rtc = Rtc::new(peripherals.LPWR, Some(interrupt_handler));
|
||||
//! rtc.rwdt.set_timeout(2000.millis());
|
||||
//! rtc.rwdt.listen();
|
||||
//!
|
||||
//! interrupt::enable(
|
||||
//! peripherals::Interrupt::LP_WDT,
|
||||
//! interrupt::Priority::Priority1,
|
||||
//! )
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! critical_section::with(|cs| RWDT.borrow_ref_mut(cs).replace(rtc.rwdt));
|
||||
//!
|
||||
//! unsafe {
|
||||
//! riscv::interrupt::enable();
|
||||
//! }
|
||||
//!
|
||||
//! loop {}
|
||||
//! ```
|
||||
//! # }
|
||||
//!
|
||||
//! Where the `LP_WDT` interrupt handler is defined as:
|
||||
//! ```no_run
|
||||
//! // Where the `LP_WDT` interrupt handler is defined as:
|
||||
//! // 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]
|
||||
//! fn interrupt_handler() {
|
||||
//! critical_section::with(|cs| {
|
||||
//! esp_println::println!("RWDT Interrupt");
|
||||
//! // esp_println::println!("RWDT Interrupt");
|
||||
//!
|
||||
//! let mut rwdt = RWDT.borrow_ref_mut(cs);
|
||||
//! let rwdt = rwdt.as_mut().unwrap();
|
||||
//!
|
||||
//! rwdt.clear_interrupt();
|
||||
//!
|
||||
//! esp_println::println!("Restarting in 5 seconds...");
|
||||
//! // esp_println::println!("Restarting in 5 seconds...");
|
||||
//!
|
||||
//! rwdt.start(5000u64.millis());
|
||||
//! rwdt.set_timeout(5000u64.millis());
|
||||
//! rwdt.unlisten();
|
||||
//! });
|
||||
//! }
|
||||
|
@ -28,32 +28,37 @@
|
||||
//! if needed.
|
||||
//!
|
||||
//! ## 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 mut remaining = source_data;
|
||||
//! let mut hasher = Sha::new(peripherals.SHA, ShaMode::SHA256);
|
||||
//!
|
||||
//! // Short hashes can be created by decreasing the output buffer to the desired
|
||||
//! // length
|
||||
#![cfg_attr(
|
||||
not(esp32),
|
||||
doc = "let mut hasher = Sha::new(peripherals.SHA, ShaMode::SHA256, None);"
|
||||
)]
|
||||
#![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];
|
||||
//!
|
||||
//! while remaining.len() > 0 {
|
||||
//! // All the HW Sha functions are infallible so unwrap is fine to use if you use
|
||||
//! // block!
|
||||
//! // All the HW Sha functions are infallible so unwrap is fine to use if
|
||||
//! // you use block!
|
||||
//! remaining = block!(hasher.update(remaining)).unwrap();
|
||||
//! }
|
||||
//!
|
||||
//! // Finish can be called as many times as desired to get multiple copies of the
|
||||
//! // output.
|
||||
//! // Finish can be called as many times as desired to get multiple copies of
|
||||
//! // the output.
|
||||
//! block!(hasher.finish(output.as_mut_slice())).unwrap();
|
||||
//!
|
||||
//! println!("SHA256 Hash output {:02x?}", output);
|
||||
//!
|
||||
//! let mut hasher = Sha256::new();
|
||||
//! hasher.update(source_data);
|
||||
//! let soft_result = hasher.finalize();
|
||||
//!
|
||||
//! println!("SHA256 Hash output {:02x?}", soft_result);
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use core::{convert::Infallible, marker::PhantomData};
|
||||
|
@ -8,41 +8,47 @@
|
||||
//!
|
||||
//! ## 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();
|
||||
//!
|
||||
//! # let delay = Delay::new(&clocks);
|
||||
//!
|
||||
//! let counter = Mutex::new(RefCell::new(0));
|
||||
//!
|
||||
//! let mut cpu_control = CpuControl::new(peripherals.CPU_CTRL);
|
||||
//! let cpu1_fnctn = || {
|
||||
//! cpu1_task(&mut timer1, &counter);
|
||||
//! cpu1_task(&delay, &counter);
|
||||
//! };
|
||||
//! let _guard = cpu_control
|
||||
//! .start_app_core(unsafe { &mut APP_CORE_STACK }, cpu1_fnctn)
|
||||
//! .unwrap();
|
||||
//! .start_app_core(unsafe { &mut *addr_of_mut!(APP_CORE_STACK) },
|
||||
//! cpu1_fnctn) .unwrap();
|
||||
//!
|
||||
//! loop {
|
||||
//! block!(timer0.wait()).unwrap();
|
||||
//!
|
||||
//! delay.delay(1.secs());
|
||||
//! let count = critical_section::with(|cs| *counter.borrow_ref(cs));
|
||||
//! println!("Hello World - Core 0! Counter is {}", count);
|
||||
//! }
|
||||
//! ```
|
||||
//! # }
|
||||
//!
|
||||
//! Where `cpu1_task()` may be defined as:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! // Where `cpu1_task()` may be defined as:
|
||||
//! # use esp_hal::delay::Delay;
|
||||
//! # use core::cell::RefCell;
|
||||
//! # use esp_hal::prelude::*;
|
||||
//! fn cpu1_task(
|
||||
//! timer: &mut Timer<Timer0<TIMG1>>,
|
||||
//! delay: &Delay,
|
||||
//! counter: &critical_section::Mutex<RefCell<i32>>,
|
||||
//! ) -> ! {
|
||||
//! println!("Hello World - Core 1!");
|
||||
//! loop {
|
||||
//! block!(timer.wait()).unwrap();
|
||||
//! delay.delay(500.millis());
|
||||
//!
|
||||
//! critical_section::with(|cs| {
|
||||
//! let new_val = counter.borrow_ref_mut(cs).wrapping_add(1);
|
||||
//! *counter.borrow_ref_mut(cs) = new_val;
|
||||
//! let mut val = counter.borrow_ref_mut(cs);
|
||||
//! *val = val.wrapping_add(1);
|
||||
//! });
|
||||
//! }
|
||||
//! }
|
||||
|
@ -19,7 +19,13 @@
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### 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();
|
||||
//! writeln!(
|
||||
//! serial_tx,
|
||||
@ -31,6 +37,7 @@
|
||||
//! mac_address[4],
|
||||
//! mac_address[5]
|
||||
//! );
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use fugit::{HertzU32, RateExtU32};
|
||||
|
@ -19,7 +19,13 @@
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### 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();
|
||||
//! writeln!(
|
||||
//! serial_tx,
|
||||
@ -31,6 +37,7 @@
|
||||
//! mac_address[4],
|
||||
//! mac_address[5]
|
||||
//! );
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
pub use self::fields::*;
|
||||
|
@ -19,7 +19,13 @@
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### 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();
|
||||
//! writeln!(
|
||||
//! serial_tx,
|
||||
@ -31,6 +37,7 @@
|
||||
//! mac_address[4],
|
||||
//! mac_address[5]
|
||||
//! );
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
pub use self::fields::*;
|
||||
|
@ -19,7 +19,13 @@
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### 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();
|
||||
//! writeln!(
|
||||
//! serial_tx,
|
||||
@ -31,6 +37,7 @@
|
||||
//! mac_address[4],
|
||||
//! mac_address[5]
|
||||
//! );
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
pub use self::fields::*;
|
||||
|
@ -13,30 +13,11 @@
|
||||
//!
|
||||
//! The `run` method starts the low power core and specifies the wakeup source.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! // configure GPIO 1 as LP output pin
|
||||
//! let lp_pin = LowPowerOutput::new(io.pins.gpio1);
|
||||
//! ⚠️: The examples for LP Core are quite extensive, so for a more
|
||||
//! detailed study of how to use this LP Core please visit [the repository
|
||||
//! with corresponding example].
|
||||
//!
|
||||
//! let mut lp_core = esp_hal::lp_core::LpCore::new(peripherals.LP_CORE);
|
||||
//! 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()
|
||||
//! });
|
||||
//! }
|
||||
//! ```
|
||||
//! [the repository with corresponding example]: https://github.com/esp-rs/esp-hal/blob/main/examples/src/bin/lp_core_basic.rs
|
||||
|
||||
use esp32c6 as pac;
|
||||
|
||||
|
@ -19,7 +19,13 @@
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### 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();
|
||||
//! writeln!(
|
||||
//! serial_tx,
|
||||
@ -31,6 +37,7 @@
|
||||
//! mac_address[4],
|
||||
//! mac_address[5]
|
||||
//! );
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
pub use self::fields::*;
|
||||
|
@ -19,7 +19,13 @@
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### 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();
|
||||
//! writeln!(
|
||||
//! serial_tx,
|
||||
@ -31,6 +37,7 @@
|
||||
//! mac_address[4],
|
||||
//! mac_address[5]
|
||||
//! );
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
pub use self::fields::*;
|
||||
@ -42,22 +49,6 @@ pub struct Efuse;
|
||||
|
||||
impl Efuse {
|
||||
/// Reads chip's MAC address from the eFuse storage.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let mac_address = Efuse::get_mac_address();
|
||||
/// writeln!(
|
||||
/// serial_tx,
|
||||
/// "MAC: {:#X}:{:#X}:{:#X}:{:#X}:{:#X}:{:#X}",
|
||||
/// mac_address[0],
|
||||
/// mac_address[1],
|
||||
/// mac_address[2],
|
||||
/// mac_address[3],
|
||||
/// mac_address[4],
|
||||
/// mac_address[5]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn read_base_mac_address() -> [u8; 6] {
|
||||
Self::read_field_be(MAC)
|
||||
}
|
||||
|
@ -13,28 +13,30 @@
|
||||
//! CORE` instance.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let mut ulp_core = esp_hal::ulp_core::UlpCore::new(peripherals.ULP_RISCV_CORE);
|
||||
//! ulp_core.stop();
|
||||
//! println!("ulp core stopped");
|
||||
//! ```rust, no_run
|
||||
#![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(); currently not implemented
|
||||
//!
|
||||
//! // copy code to RTC ram
|
||||
//! let lp_ram = 0x5000_0000 as *mut u8;
|
||||
//! unsafe {
|
||||
//! core::ptr::copy_nonoverlapping(CODE as *const _ as *const u8, lp_ram, CODE.len());
|
||||
//! }
|
||||
//! println!("copied code (len {})", CODE.len());
|
||||
//! core::ptr::copy_nonoverlapping(CODE as *const _ as *const u8, lp_ram,
|
||||
//! CODE.len()); }
|
||||
//!
|
||||
//! // start ULP core
|
||||
//! ulp_core.run(esp_hal::ulp_core::UlpCoreWakeupSource::HpCpu);
|
||||
//! println!("ulpcore run");
|
||||
//!
|
||||
//! unsafe {
|
||||
//! let data = 0x5000_0010 as *mut u32;
|
||||
//! loop {
|
||||
//! println!("Current {}", unsafe { data.read_volatile() });
|
||||
//! }
|
||||
//! loop {}
|
||||
//! }
|
||||
//! # }
|
||||
//! ```
|
||||
use esp32s2 as pac;
|
||||
|
||||
|
@ -8,41 +8,47 @@
|
||||
//!
|
||||
//! ## 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();
|
||||
//!
|
||||
//! # let delay = Delay::new(&clocks);
|
||||
//!
|
||||
//! let counter = Mutex::new(RefCell::new(0));
|
||||
//!
|
||||
//! let mut cpu_control = CpuControl::new(peripherals.CPU_CTRL);
|
||||
//! let cpu1_fnctn = || {
|
||||
//! cpu1_task(&mut timer1, &counter);
|
||||
//! cpu1_task(&delay, &counter);
|
||||
//! };
|
||||
//! let _guard = cpu_control
|
||||
//! .start_app_core(unsafe { &mut APP_CORE_STACK }, cpu1_fnctn)
|
||||
//! .unwrap();
|
||||
//! .start_app_core(unsafe { &mut *addr_of_mut!(APP_CORE_STACK) },
|
||||
//! cpu1_fnctn) .unwrap();
|
||||
//!
|
||||
//! loop {
|
||||
//! block!(timer0.wait()).unwrap();
|
||||
//!
|
||||
//! delay.delay(1.secs());
|
||||
//! let count = critical_section::with(|cs| *counter.borrow_ref(cs));
|
||||
//! println!("Hello World - Core 0! Counter is {}", count);
|
||||
//! }
|
||||
//! ```
|
||||
//! # }
|
||||
//!
|
||||
//! Where `cpu1_task()` may be defined as:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! // Where `cpu1_task()` may be defined as:
|
||||
//! # use esp_hal::delay::Delay;
|
||||
//! # use core::cell::RefCell;
|
||||
//! # use esp_hal::prelude::*;
|
||||
//! fn cpu1_task(
|
||||
//! timer: &mut Timer<Timer0<TIMG1>>,
|
||||
//! delay: &Delay,
|
||||
//! counter: &critical_section::Mutex<RefCell<i32>>,
|
||||
//! ) -> ! {
|
||||
//! println!("Hello World - Core 1!");
|
||||
//! loop {
|
||||
//! block!(timer.wait()).unwrap();
|
||||
//! delay.delay(500.millis());
|
||||
//!
|
||||
//! critical_section::with(|cs| {
|
||||
//! let new_val = counter.borrow_ref_mut(cs).wrapping_add(1);
|
||||
//! *counter.borrow_ref_mut(cs) = new_val;
|
||||
//! let mut val = counter.borrow_ref_mut(cs);
|
||||
//! *val = val.wrapping_add(1);
|
||||
//! });
|
||||
//! }
|
||||
//! }
|
||||
|
@ -19,7 +19,13 @@
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### 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();
|
||||
//! writeln!(
|
||||
//! serial_tx,
|
||||
@ -31,6 +37,7 @@
|
||||
//! mac_address[4],
|
||||
//! mac_address[5]
|
||||
//! );
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
pub use self::fields::*;
|
||||
|
@ -13,28 +13,30 @@
|
||||
//! to the `ULP CORE` instance.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! let mut ulp_core = esp_hal::ulp_core::UlpCore::new(peripherals.ULP_RISCV_CORE);
|
||||
//! ```rust, no_run
|
||||
#![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();
|
||||
//! println!("ulp core stopped");
|
||||
//!
|
||||
//! // copy code to RTC ram
|
||||
//! let lp_ram = 0x5000_0000 as *mut u8;
|
||||
//! unsafe {
|
||||
//! core::ptr::copy_nonoverlapping(CODE as *const _ as *const u8, lp_ram, CODE.len());
|
||||
//! }
|
||||
//! println!("copied code (len {})", CODE.len());
|
||||
//! core::ptr::copy_nonoverlapping(CODE as *const _ as *const u8, lp_ram,
|
||||
//! CODE.len()); }
|
||||
//!
|
||||
//! // start ULP core
|
||||
//! ulp_core.run(esp_hal::ulp_core::UlpCoreWakeupSource::HpCpu);
|
||||
//! println!("ulpcore run");
|
||||
//!
|
||||
//! unsafe {
|
||||
//! let data = 0x5000_0010 as *mut u32;
|
||||
//! loop {
|
||||
//! println!("Current {}", unsafe { data.read_volatile() });
|
||||
//! }
|
||||
//! loop {}
|
||||
//! }
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use esp32s3 as pac;
|
||||
|
@ -7,23 +7,28 @@
|
||||
//! [`Spi::new`].
|
||||
//!
|
||||
//! ## 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;
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! # use crate::esp_hal::prelude::_fugit_RateExtU32;
|
||||
//! # use esp_hal::spi::SpiMode;
|
||||
//! # use esp_hal::spi::master::Spi;
|
||||
//! # 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,
|
||||
//! 100.kHz(),
|
||||
//! SpiMode::Mode0,
|
||||
//! &mut peripheral_clock_control,
|
||||
//! &mut clocks,
|
||||
//! )
|
||||
//! .with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs));
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! ## Exclusive access to the SPI bus
|
||||
//!
|
||||
//! If all you want to do is to communicate to a single device, and you initiate
|
||||
|
@ -8,16 +8,6 @@
|
||||
//!
|
||||
//! ## 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,
|
||||
//! but the code currently only supports single transfers (not segmented
|
||||
//! 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
|
||||
//! is_done().
|
||||
//!
|
||||
//! ```rust
|
||||
//! let dma = Gdma::new(peripherals.DMA);
|
||||
//! const N: usize = (buffer_size + 4091) / 4092;
|
||||
//! let mut tx_descriptors = [0u32; N * 3];
|
||||
//! let mut rx_descriptors = [0u32; N * 3];
|
||||
//! let mut spi = spi.with_dma(dma.channel0.configure(
|
||||
//! /* circular = */ false,
|
||||
//! tx_descriptors,
|
||||
//! rx_descriptors,
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! # use esp_hal::dma::DmaPriority;
|
||||
//! # use esp_hal::dma_buffers;
|
||||
//! # use esp_hal::spi::SpiMode;
|
||||
//! # use esp_hal::spi::slave::{prelude::*, Spi};
|
||||
//! # use esp_hal::dma::Dma;
|
||||
//! # use esp_hal::gpio::Io;
|
||||
//! 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,
|
||||
//! ));
|
||||
//! // This is not legal rust, but any method of getting a &mut 'static is good.
|
||||
//! let tx_buf = &'static [0u8; N * 4092];
|
||||
//! let rx_buf = &mut 'static [0u8; N * 4092];
|
||||
//! let transfer = spi.dma_transfer(tx_buf, rx_buf).unwrap();
|
||||
//! // Do other operations, checking transfer.is_done()
|
||||
//! // When the master sends enough clock pulses, is_done() will be true.
|
||||
//! (tx_buf, rx_buf, spi) = transfer.wait();
|
||||
//!
|
||||
//! let mut send = tx_buffer;
|
||||
//! let mut receive = rx_buffer;
|
||||
//!
|
||||
//! let transfer = spi
|
||||
//! .dma_transfer(&mut send, &mut receive)
|
||||
//! .unwrap();
|
||||
//!
|
||||
//! transfer.wait().unwrap();
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
@ -21,10 +21,12 @@
|
||||
//! The available peripherals are represented by the `Peripheral` enum
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! let peripherals = Peripherals::take();
|
||||
//! let system = SystemControl::new(peripherals.SYSTEM);
|
||||
//! let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use crate::{interrupt::InterruptHandler, peripheral::PeripheralRef, peripherals::SYSTEM};
|
||||
|
@ -1,8 +1,11 @@
|
||||
//! The `time` module offers a way to get the system uptime.
|
||||
//!
|
||||
//! ### Example
|
||||
//! ```no_run
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! # use esp_hal::time;
|
||||
//! let time = time::current_time();
|
||||
//! # }
|
||||
//! ```
|
||||
#![warn(missing_docs)]
|
||||
|
||||
|
@ -9,23 +9,32 @@
|
||||
//!
|
||||
//! #### 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 one_shot = OneShotTimer::new(timg0.timer0);
|
||||
//!
|
||||
//! one_shot.delay_millis(500);
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! #### Periodic Timer
|
||||
//!
|
||||
//! ```no_run
|
||||
//! ```rust, 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 periodic = PeriodicTimer::new(timg0.timer0);
|
||||
//! let mut periodic = PeriodicTimer::new(timg0.timer0);
|
||||
//!
|
||||
//! periodic.start(1.secs());
|
||||
//! loop {
|
||||
//! nb::block!(periodic.wait());
|
||||
//! }
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
#![deny(missing_docs)]
|
||||
|
@ -17,19 +17,60 @@
|
||||
//!
|
||||
//! #### 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);
|
||||
//!
|
||||
//! // 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:
|
||||
//! systimer.load_value(1.secs());
|
||||
//! systimer.start();
|
||||
//! timer0.load_value(1.secs());
|
||||
//! timer0.start();
|
||||
//!
|
||||
//! while !systimer.is_interrupt_set() {
|
||||
//! while !timer0.is_interrupt_set() {
|
||||
//! // 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;
|
||||
@ -662,12 +703,16 @@ pub mod etm {
|
||||
//! COMPx
|
||||
//!
|
||||
//! ## 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 mut alarm0 = syst.alarm0.into_periodic();
|
||||
//! alarm0.set_period(1.secs());
|
||||
//!
|
||||
//! let timer_event = SysTimerEtmEvent::new(&mut alarm0);
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use super::*;
|
||||
|
@ -20,8 +20,12 @@
|
||||
//!
|
||||
//! #### General-purpose Timer
|
||||
//!
|
||||
//! ```no_run
|
||||
//! let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
|
||||
//! ```rust, no_run
|
||||
#![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;
|
||||
//!
|
||||
//! // Get the current timestamp, in microseconds:
|
||||
@ -34,12 +38,15 @@
|
||||
//! while !timer0.is_interrupt_set() {
|
||||
//! // Wait
|
||||
//! }
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! #### Watchdog Timer
|
||||
//!
|
||||
//! ```no_run
|
||||
//! let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! # use esp_hal::timer::timg::TimerGroup;
|
||||
//! # use esp_hal::prelude::*;
|
||||
//! let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks, None);
|
||||
//! let mut wdt = timg0.wdt;
|
||||
//!
|
||||
//! wdt.set_timeout(5_000.millis());
|
||||
@ -48,6 +55,7 @@
|
||||
//! loop {
|
||||
//! wdt.feed();
|
||||
//! }
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use core::{
|
||||
|
@ -20,15 +20,18 @@
|
||||
//! program execution.
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```no_run
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! # use esp_hal::trace::Trace;
|
||||
//! let mut trace = Trace::new(peripherals.TRACE0);
|
||||
//! let buffer = unsafe { &mut BUFFER[..] };
|
||||
//! trace.start_trace(buffer);
|
||||
//! let mut buffer = [0_u8; 1024];
|
||||
//! trace.start_trace(&mut buffer);
|
||||
//! // traced code
|
||||
//! println!("Hello");
|
||||
//!
|
||||
//! // end traced code
|
||||
//! let res = trace.stop_trace().unwrap();
|
||||
//! // transfer the trace result to the host and decode it there
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use crate::{
|
||||
|
@ -89,7 +89,7 @@ impl SingleStandardFilter {
|
||||
///
|
||||
/// Example matching only even IDs, allowing any rtr value and any payload
|
||||
/// data:
|
||||
/// ```
|
||||
/// ```rust, ignore
|
||||
/// const FILTER: SingleStandardFilter =
|
||||
/// 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
|
||||
/// frame, with any bytes for the first two payload bytes.
|
||||
/// ```
|
||||
/// ```rust, ignore
|
||||
/// let filter = twai::filter::SingleStandardFilter::new_from_code_mask(
|
||||
/// StandardId::new(0x000).unwrap(),
|
||||
/// StandardId::new(0x001).unwrap(),
|
||||
@ -213,7 +213,7 @@ impl SingleExtendedFilter {
|
||||
///
|
||||
/// # Examples
|
||||
/// A filter matching any odd extended IDs, with any rtr value.
|
||||
/// ```
|
||||
/// ```rust, ignore
|
||||
/// const FILTER: twai::filter::SingleExtendedFilter =
|
||||
/// twai::filter::SingleExtendedFilter::new(b"xxxxxxxxxxxxxxxxxxxxxxxxxxxx1", b"x");
|
||||
/// ```
|
||||
@ -304,7 +304,7 @@ impl DualStandardFilter {
|
||||
/// # Examples
|
||||
/// 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.
|
||||
/// ```
|
||||
/// ```rust, ignore
|
||||
/// const FILTER: twai::filter::DualStandardFilter = twai::filter::DualStandardFilter::new(
|
||||
/// b"xxxxxxxxx00",
|
||||
/// b"x",
|
||||
@ -452,7 +452,7 @@ impl DualExtendedFilter {
|
||||
/// part of the id. For example this id matches: 0x000f000f, 0x000f000a,
|
||||
/// 0x0000000a, 0x0000000b.
|
||||
/// But it does not match: 0x000a000a
|
||||
/// ```
|
||||
/// ```rust, ignore
|
||||
/// const FILTER: twai::filter::DualExtendedFilter =
|
||||
/// twai::filter::DualExtendedFilter::new([b"xxxxxxxxx0000xxx", b"xxxxxxxxx1111xxx"]);
|
||||
/// ```
|
||||
|
@ -17,14 +17,26 @@
|
||||
//! Format (29-bit) frame identifiers.
|
||||
//!
|
||||
//! ## 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
|
||||
//! // transceiver.
|
||||
//! let can_tx_pin = io.pins.gpio2;
|
||||
//! let can_rx_pin = io.pins.gpio3;
|
||||
//!
|
||||
//! // The speed of the CAN bus.
|
||||
//! const CAN_BAUDRATE: twai::BaudRate = twai::BaudRate::B1000K;
|
||||
//! const CAN_BAUDRATE: twai::BaudRate = BaudRate::B1000K;
|
||||
//!
|
||||
//! // Begin configuring the TWAI peripheral. The peripheral is in a reset like
|
||||
//! // state that prevents transmission but allows configuration.
|
||||
@ -37,43 +49,25 @@
|
||||
//! 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 =
|
||||
//! twai::filter::SingleStandardFilter::new(b"xxxxxxxxxx0", b"x", [b"xxxxxxxx", b"xxxxxxxx"]);
|
||||
//! can_config.set_filter(FILTER);
|
||||
//! SingleStandardFilter::new(b"xxxxxxxxxx0", b"x", [b"xxxxxxxx",
|
||||
//! b"xxxxxxxx"]); can_config.set_filter(FILTER);
|
||||
//!
|
||||
//! // Start the peripheral. This locks the configuration settings of the peripheral
|
||||
//! // and puts it into operation mode, allowing packets to be sent and
|
||||
//! // received.
|
||||
//! // Start the peripheral. This locks the configuration settings of the
|
||||
//! // peripheral and puts it into operation mode, allowing packets to be sent
|
||||
//! // and received.
|
||||
//! let mut can = can_config.start();
|
||||
//!
|
||||
//! loop {
|
||||
//! // Wait for a frame to be received.
|
||||
//! let frame = block!(can.receive()).unwrap();
|
||||
//!
|
||||
//! println!("Received a frame:");
|
||||
//!
|
||||
//! // Print different messages based on the frame id type.
|
||||
//! match frame.id() {
|
||||
//! Id::Standard(id) => {
|
||||
//! println!("\tStandard Id: {:?}", id);
|
||||
//! }
|
||||
//! Id::Extended(id) => {
|
||||
//! println!("\tExtended Id: {:?}", id);
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! // Print out the frame data or the requested data length code for a remote
|
||||
//! // transmission request frame.
|
||||
//! if frame.is_data_frame() {
|
||||
//! println!("\tData: {:?}", frame.data());
|
||||
//! } else {
|
||||
//! println!("\tRemote Frame. Data Length Code: {}", frame.dlc());
|
||||
//! }
|
||||
//!
|
||||
//! // Transmit the frame back.
|
||||
//! let _result = block!(can.transmit(&frame)).unwrap();
|
||||
//! }
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
@ -18,14 +18,20 @@
|
||||
//! configured. Additionally, the transmit (TX) and receive (RX) pins can be
|
||||
//! 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 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);
|
||||
//! Uart::new_with_config(peripherals.UART1, Config::default(), Some(pins),
|
||||
//! &clocks, None);
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! ## Usage
|
||||
//!
|
||||
//! The UART driver implements a number of third-party traits, with the
|
||||
@ -41,23 +47,47 @@
|
||||
//! ### Examples
|
||||
//!
|
||||
//! #### Sending and Receiving Data
|
||||
//!
|
||||
//! ```no_run
|
||||
//! ```rust, 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:
|
||||
//! 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
|
||||
//!
|
||||
//! ```no_run
|
||||
//! ```rust, 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:
|
||||
//! let (mut tx, rx) = uart1.split();
|
||||
//! let (mut tx, mut rx) = uart1.split();
|
||||
//!
|
||||
//! // Each component can be used individually to interact with the UART:
|
||||
//! tx.write_bytes(&[42u8])?;
|
||||
//! let byte = rx.read_byte()?;
|
||||
//! tx.write_bytes(&[42u8]).expect("write error!");
|
||||
//! let byte = rx.read_byte().expect("read error!");
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! [embedded-hal]: https://docs.rs/embedded-hal/latest/embedded_hal/
|
||||
//! [embedded-io]: https://docs.rs/embedded-io/latest/embedded_io/
|
||||
//! [embedded-hal-async]: https://docs.rs/embedded-hal-async/latest/embedded_hal_async/
|
||||
@ -466,13 +496,6 @@ where
|
||||
}
|
||||
|
||||
/// 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> {
|
||||
// On the ESP32-S2 we need to use PeriBus2 to read the FIFO:
|
||||
let offset = if cfg!(esp32s2) { 0x20C00000 } else { 0 };
|
||||
|
@ -41,24 +41,33 @@
|
||||
//!
|
||||
//! ### 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);
|
||||
//!
|
||||
//! // 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
|
||||
//! ```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
|
||||
//! // The USB Serial/JTAG can be split into separate Transmit and Receive components:
|
||||
//! let (mut tx, rx) = usb_serial.split();
|
||||
//!
|
||||
//! // Each component can be used individually to interact with the USB Serial/JTAG:
|
||||
//! tx.write_bytes(&[42u8])?;
|
||||
//! let byte = rx.read_byte()?;
|
||||
//! // Each component can be used individually to interact with the USB
|
||||
//! // Serial/JTAG:
|
||||
//! tx.write_bytes(&[42u8]).expect("write error!");
|
||||
//! let byte = rx.read_byte().expect("read error!");
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! [embedded-hal]: https://docs.rs/embedded-hal/latest/embedded_hal/
|
||||
//! [embedded-io]: https://docs.rs/embedded-io/latest/embedded_io/
|
||||
//! [embedded-hal-async]: https://docs.rs/embedded-hal-async/latest/embedded_hal_async/
|
||||
|
@ -66,10 +66,8 @@ async fn main(_spawner: Spawner) {
|
||||
&clocks,
|
||||
);
|
||||
|
||||
#[cfg(esp32)]
|
||||
{
|
||||
i2s.with_mclk(io.pins.gpio0);
|
||||
}
|
||||
#[cfg(not(features = "esp32"))]
|
||||
let i2s = i2s.with_mclk(io.pins.gpio0);
|
||||
|
||||
let i2s_rx = i2s
|
||||
.i2s_rx
|
||||
|
@ -89,7 +89,6 @@ fn main() -> ! {
|
||||
|
||||
let mut src = [0_u8; 1024];
|
||||
rng.read(src.as_mut_slice());
|
||||
// println!("HMAC input {:02X?}", src);
|
||||
|
||||
let mut output = [0u8; 32];
|
||||
|
||||
|
@ -63,10 +63,8 @@ fn main() -> ! {
|
||||
&clocks,
|
||||
);
|
||||
|
||||
#[cfg(esp32)]
|
||||
{
|
||||
i2s.with_mclk(io.pins.gpio0);
|
||||
}
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
let i2s = i2s.with_mclk(io.pins.gpio0);
|
||||
|
||||
let mut i2s_rx = i2s
|
||||
.i2s_rx
|
||||
|
@ -38,6 +38,8 @@ enum Cli {
|
||||
GenerateEfuseFields(GenerateEfuseFieldsArgs),
|
||||
/// Lint all packages in the workspace with clippy
|
||||
LintPackages(LintPackagesArgs),
|
||||
/// Run doctests for specified chip and package.
|
||||
RunDocTest(ExampleArgs),
|
||||
/// Run the given example for the specified chip.
|
||||
RunExample(ExampleArgs),
|
||||
/// 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::GenerateEfuseFields(args) => generate_efuse_src(&workspace, args),
|
||||
Cli::LintPackages(args) => lint_packages(&workspace, args),
|
||||
Cli::RunDocTest(args) => run_doctests(&workspace, args),
|
||||
Cli::RunElfs(args) => run_elfs(args),
|
||||
Cli::RunExample(args) => examples(&workspace, args, CargoAction::Run),
|
||||
Cli::RunTests(args) => tests(&workspace, args, CargoAction::Run),
|
||||
@ -607,6 +610,33 @@ fn run_elfs(args: RunElfArgs) -> Result<()> {
|
||||
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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user