From 424ddaf3d95417bcfe8b46475c8135aead3792d2 Mon Sep 17 00:00:00 2001 From: eZio Pan Date: Sat, 6 Jan 2024 22:22:38 +0800 Subject: impl waveform with TIM Channel --- examples/stm32f4/src/bin/ws2812_pwm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/stm32f4/src/bin/ws2812_pwm.rs b/examples/stm32f4/src/bin/ws2812_pwm.rs index 239709253..6122cea2d 100644 --- a/examples/stm32f4/src/bin/ws2812_pwm.rs +++ b/examples/stm32f4/src/bin/ws2812_pwm.rs @@ -91,7 +91,7 @@ async fn main(_spawner: Spawner) { loop { for &color in color_list { // with &mut, we can easily reuse same DMA channel multiple times - ws2812_pwm.gen_waveform(&mut dp.DMA1_CH2, pwm_channel, color).await; + ws2812_pwm.waveform_up(&mut dp.DMA1_CH2, pwm_channel, color).await; // ws2812 need at least 50 us low level input to confirm the input data and change it's state Timer::after_micros(50).await; // wait until ticker tick -- cgit From 4410aacafb2141c1c0838598d11581e24aab3b0f Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Fri, 19 Jan 2024 23:13:46 +0100 Subject: feat: add basic support for nRF51 chips to embassy-nrf --- examples/nrf51/.cargo/config.toml | 9 +++++++++ examples/nrf51/Cargo.toml | 20 ++++++++++++++++++++ examples/nrf51/build.rs | 35 +++++++++++++++++++++++++++++++++++ examples/nrf51/memory.x | 5 +++++ examples/nrf51/src/bin/blinky.rs | 21 +++++++++++++++++++++ 5 files changed, 90 insertions(+) create mode 100644 examples/nrf51/.cargo/config.toml create mode 100644 examples/nrf51/Cargo.toml create mode 100644 examples/nrf51/build.rs create mode 100644 examples/nrf51/memory.x create mode 100644 examples/nrf51/src/bin/blinky.rs (limited to 'examples') diff --git a/examples/nrf51/.cargo/config.toml b/examples/nrf51/.cargo/config.toml new file mode 100644 index 000000000..84f0e1572 --- /dev/null +++ b/examples/nrf51/.cargo/config.toml @@ -0,0 +1,9 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace nRF82840_xxAA with your chip as listed in `probe-rs chip list` +runner = "probe-rs run --chip nRF51822_xxAA" + +[build] +target = "thumbv6m-none-eabi" + +[env] +DEFMT_LOG = "trace" diff --git a/examples/nrf51/Cargo.toml b/examples/nrf51/Cargo.toml new file mode 100644 index 000000000..8507c415c --- /dev/null +++ b/examples/nrf51/Cargo.toml @@ -0,0 +1,20 @@ +[package] +edition = "2021" +name = "embassy-nrf51-examples" +version = "0.1.0" +license = "MIT OR Apache-2.0" + +[dependencies] +embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } +embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } +embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf51", "time-driver-rtc1", "unstable-pac", "time", "rt"] } + +defmt = "0.3" +defmt-rtt = "0.4" + +cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } +cortex-m-rt = "0.7" +panic-probe = { version = "0.3", features = ["print-defmt"] } + +[profile.release] +debug = 2 diff --git a/examples/nrf51/build.rs b/examples/nrf51/build.rs new file mode 100644 index 000000000..30691aa97 --- /dev/null +++ b/examples/nrf51/build.rs @@ -0,0 +1,35 @@ +//! This build script copies the `memory.x` file from the crate root into +//! a directory where the linker can always find it at build time. +//! For many projects this is optional, as the linker always searches the +//! project root directory -- wherever `Cargo.toml` is. However, if you +//! are using a workspace or have a more complicated build setup, this +//! build script becomes required. Additionally, by requesting that +//! Cargo re-run the build script whenever `memory.x` is changed, +//! updating `memory.x` ensures a rebuild of the application with the +//! new memory settings. + +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo:rerun-if-changed=memory.x"); + + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/examples/nrf51/memory.x b/examples/nrf51/memory.x new file mode 100644 index 000000000..ad5f80292 --- /dev/null +++ b/examples/nrf51/memory.x @@ -0,0 +1,5 @@ +MEMORY +{ + FLASH : ORIGIN = 0x00000000, LENGTH = 256K + RAM : ORIGIN = 0x20000000, LENGTH = 32K +} diff --git a/examples/nrf51/src/bin/blinky.rs b/examples/nrf51/src/bin/blinky.rs new file mode 100644 index 000000000..ff686c6ae --- /dev/null +++ b/examples/nrf51/src/bin/blinky.rs @@ -0,0 +1,21 @@ +#![no_std] +#![no_main] + +use embassy_executor::Spawner; +use embassy_nrf::gpio::{Level, Output, OutputDrive}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + + let p = embassy_nrf::init(Default::default()); + let mut led = Output::new(p.P0_21, Level::Low, OutputDrive::Standard); + + loop { + led.set_high(); + Timer::after_millis(300).await; + led.set_low(); + Timer::after_millis(300).await; + } +} -- cgit From 2a810a1a6ad5351ef2248133855dc01ba4b7a76b Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Sat, 20 Jan 2024 16:23:12 +0100 Subject: rustfmt --- examples/nrf51/src/bin/blinky.rs | 1 - 1 file changed, 1 deletion(-) (limited to 'examples') diff --git a/examples/nrf51/src/bin/blinky.rs b/examples/nrf51/src/bin/blinky.rs index ff686c6ae..7c12ffcbc 100644 --- a/examples/nrf51/src/bin/blinky.rs +++ b/examples/nrf51/src/bin/blinky.rs @@ -8,7 +8,6 @@ use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { - let p = embassy_nrf::init(Default::default()); let mut led = Output::new(p.P0_21, Level::Low, OutputDrive::Standard); -- cgit From 25f82538aed809c17264bab8cddad30004fb60cf Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Sat, 20 Jan 2024 20:56:24 +0100 Subject: fix doc comment --- examples/nrf51/.cargo/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/nrf51/.cargo/config.toml b/examples/nrf51/.cargo/config.toml index 84f0e1572..29d35a9b4 100644 --- a/examples/nrf51/.cargo/config.toml +++ b/examples/nrf51/.cargo/config.toml @@ -1,5 +1,5 @@ [target.'cfg(all(target_arch = "arm", target_os = "none"))'] -# replace nRF82840_xxAA with your chip as listed in `probe-rs chip list` +# replace nRF51822_xxAA with your chip as listed in `probe-rs chip list` runner = "probe-rs run --chip nRF51822_xxAA" [build] -- cgit From f117213b6ee80c224e781d7bf4e750df49c345a6 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Thu, 25 Jan 2024 21:47:49 +0100 Subject: fix: use nrf51-dk chip variant --- examples/nrf51/.cargo/config.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'examples') diff --git a/examples/nrf51/.cargo/config.toml b/examples/nrf51/.cargo/config.toml index 29d35a9b4..1671f5db1 100644 --- a/examples/nrf51/.cargo/config.toml +++ b/examples/nrf51/.cargo/config.toml @@ -1,6 +1,6 @@ [target.'cfg(all(target_arch = "arm", target_os = "none"))'] -# replace nRF51822_xxAA with your chip as listed in `probe-rs chip list` -runner = "probe-rs run --chip nRF51822_xxAA" +# replace nRF51422_xxAA with your chip as listed in `probe-rs chip list` +runner = "probe-rs run --chip nRF51422_xxAA" [build] target = "thumbv6m-none-eabi" -- cgit From b16eca3f21f947dcd4b3fe279bd4f577679428bc Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Thu, 25 Jan 2024 21:50:03 +0100 Subject: adjust memory settings for lower end variant --- examples/nrf51/memory.x | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'examples') diff --git a/examples/nrf51/memory.x b/examples/nrf51/memory.x index ad5f80292..98b3c792f 100644 --- a/examples/nrf51/memory.x +++ b/examples/nrf51/memory.x @@ -1,5 +1,5 @@ MEMORY { - FLASH : ORIGIN = 0x00000000, LENGTH = 256K - RAM : ORIGIN = 0x20000000, LENGTH = 32K + FLASH : ORIGIN = 0x00000000, LENGTH = 128K + RAM : ORIGIN = 0x20000000, LENGTH = 16K } -- cgit From 43553381cda95b75d9de1460d5ea6add6e739134 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Thu, 25 Jan 2024 21:51:23 +0100 Subject: lower arena for nrf51 --- examples/nrf51/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/nrf51/Cargo.toml b/examples/nrf51/Cargo.toml index 8507c415c..d1e919a33 100644 --- a/examples/nrf51/Cargo.toml +++ b/examples/nrf51/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" license = "MIT OR Apache-2.0" [dependencies] -embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } +embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-4096", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf51", "time-driver-rtc1", "unstable-pac", "time", "rt"] } -- cgit From a91a7a8557ae8998de7b08d753e7a55172fb43c8 Mon Sep 17 00:00:00 2001 From: Tomasz bla Fortuna Date: Sun, 14 Jan 2024 09:44:37 +0100 Subject: Add FDCAN dependency in correct flavor based on selected chip. Author: Torin Cooper-Bennun Change from review. --- examples/stm32g4/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index 895ad3e7c..b87f461b4 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32g491re to your chip name, if necessary. -embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] } +embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g473re", "memory-x", "unstable-pac", "exti", "fdcan"] } embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } -- cgit From 1698f4dbc3b5f4e561c3edd20246af63c22da507 Mon Sep 17 00:00:00 2001 From: Corey Schuhen Date: Thu, 25 Jan 2024 17:10:25 +1000 Subject: Add FDCAN examples for STM32G4, STM32H5 and STM32H7 Fix examples Fix examples Fix examples. --- examples/stm32g4/Cargo.toml | 2 +- examples/stm32g4/src/bin/can.rs | 56 +++++++++++++++++++++++++++++++ examples/stm32h5/src/bin/can.rs | 74 +++++++++++++++++++++++++++++++++++++++++ examples/stm32h7/src/bin/can.rs | 74 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 examples/stm32g4/src/bin/can.rs create mode 100644 examples/stm32h5/src/bin/can.rs create mode 100644 examples/stm32h7/src/bin/can.rs (limited to 'examples') diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index b87f461b4..895ad3e7c 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" [dependencies] # Change stm32g491re to your chip name, if necessary. -embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g473re", "memory-x", "unstable-pac", "exti", "fdcan"] } +embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] } embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } diff --git a/examples/stm32g4/src/bin/can.rs b/examples/stm32g4/src/bin/can.rs new file mode 100644 index 000000000..727921fba --- /dev/null +++ b/examples/stm32g4/src/bin/can.rs @@ -0,0 +1,56 @@ +#![no_std] +#![no_main] +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::peripherals::*; +use embassy_stm32::{bind_interrupts, can, Config}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + FDCAN1_IT0 => can::IT0InterruptHandler; + FDCAN1_IT1 => can::IT1InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let config = Config::default(); + + let peripherals = embassy_stm32::init(config); + + let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); + + // 250k bps + can.set_bitrate(250_000); + + info!("Configured"); + + //let mut can = can.into_external_loopback_mode(); + let mut can = can.into_normal_mode(); + + let mut i = 0; + loop { + let frame = can::TxFrame::new( + can::TxFrameHeader { + len: 1, + frame_format: can::FrameFormat::Standard, + id: can::StandardId::new(0x123).unwrap().into(), + bit_rate_switching: false, + marker: None, + }, + &[i], + ) + .unwrap(); + info!("Writing frame"); + _ = can.write(&frame).await; + + match can.read().await { + Ok(rx_frame) => info!("Rx: {}", rx_frame.data()[0]), + Err(_err) => error!("Error in frame"), + } + + Timer::after_millis(250).await; + + i += 1; + } +} diff --git a/examples/stm32h5/src/bin/can.rs b/examples/stm32h5/src/bin/can.rs new file mode 100644 index 000000000..2906d1576 --- /dev/null +++ b/examples/stm32h5/src/bin/can.rs @@ -0,0 +1,74 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::peripherals::*; +use embassy_stm32::{bind_interrupts, can, rcc, Config}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + FDCAN1_IT0 => can::IT0InterruptHandler; + FDCAN1_IT1 => can::IT1InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let mut config = Config::default(); + + // configure FDCAN to use PLL1_Q at 64 MHz + config.rcc.pll1 = Some(rcc::Pll { + source: rcc::PllSource::HSI, + prediv: rcc::PllPreDiv::DIV4, + mul: rcc::PllMul::MUL8, + divp: None, + divq: Some(rcc::PllDiv::DIV2), + divr: None, + }); + config.rcc.fdcan_clock_source = rcc::FdCanClockSource::PLL1_Q; + + let peripherals = embassy_stm32::init(config); + + let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); + + can.can.apply_config( + can::config::FdCanConfig::default().set_nominal_bit_timing(can::config::NominalBitTiming { + sync_jump_width: 1.try_into().unwrap(), + prescaler: 8.try_into().unwrap(), + seg1: 13.try_into().unwrap(), + seg2: 2.try_into().unwrap(), + }), + ); + + info!("Configured"); + + let mut can = can.into_external_loopback_mode(); + //let mut can = can.into_normal_mode(); + + let mut i = 0; + loop { + let frame = can::TxFrame::new( + can::TxFrameHeader { + len: 1, + frame_format: can::FrameFormat::Standard, + id: can::StandardId::new(0x123).unwrap().into(), + bit_rate_switching: false, + marker: None, + }, + &[i], + ) + .unwrap(); + info!("Writing frame"); + _ = can.write(&frame).await; + + match can.read().await { + Ok(rx_frame) => info!("Rx: {}", rx_frame.data()[0]), + Err(_err) => error!("Error in frame"), + } + + Timer::after_millis(250).await; + + i += 1; + } +} diff --git a/examples/stm32h7/src/bin/can.rs b/examples/stm32h7/src/bin/can.rs new file mode 100644 index 000000000..2906d1576 --- /dev/null +++ b/examples/stm32h7/src/bin/can.rs @@ -0,0 +1,74 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::peripherals::*; +use embassy_stm32::{bind_interrupts, can, rcc, Config}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + FDCAN1_IT0 => can::IT0InterruptHandler; + FDCAN1_IT1 => can::IT1InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let mut config = Config::default(); + + // configure FDCAN to use PLL1_Q at 64 MHz + config.rcc.pll1 = Some(rcc::Pll { + source: rcc::PllSource::HSI, + prediv: rcc::PllPreDiv::DIV4, + mul: rcc::PllMul::MUL8, + divp: None, + divq: Some(rcc::PllDiv::DIV2), + divr: None, + }); + config.rcc.fdcan_clock_source = rcc::FdCanClockSource::PLL1_Q; + + let peripherals = embassy_stm32::init(config); + + let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); + + can.can.apply_config( + can::config::FdCanConfig::default().set_nominal_bit_timing(can::config::NominalBitTiming { + sync_jump_width: 1.try_into().unwrap(), + prescaler: 8.try_into().unwrap(), + seg1: 13.try_into().unwrap(), + seg2: 2.try_into().unwrap(), + }), + ); + + info!("Configured"); + + let mut can = can.into_external_loopback_mode(); + //let mut can = can.into_normal_mode(); + + let mut i = 0; + loop { + let frame = can::TxFrame::new( + can::TxFrameHeader { + len: 1, + frame_format: can::FrameFormat::Standard, + id: can::StandardId::new(0x123).unwrap().into(), + bit_rate_switching: false, + marker: None, + }, + &[i], + ) + .unwrap(); + info!("Writing frame"); + _ = can.write(&frame).await; + + match can.read().await { + Ok(rx_frame) => info!("Rx: {}", rx_frame.data()[0]), + Err(_err) => error!("Error in frame"), + } + + Timer::after_millis(250).await; + + i += 1; + } +} -- cgit From 1e698af05bc6e7e520d3f35ef661f34ea6ea359e Mon Sep 17 00:00:00 2001 From: Caleb Jamison Date: Wed, 31 Jan 2024 14:04:48 -0500 Subject: Add timeout_at convenience function and example. --- examples/rp/src/bin/debounce.rs | 80 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 examples/rp/src/bin/debounce.rs (limited to 'examples') diff --git a/examples/rp/src/bin/debounce.rs b/examples/rp/src/bin/debounce.rs new file mode 100644 index 000000000..bf1579091 --- /dev/null +++ b/examples/rp/src/bin/debounce.rs @@ -0,0 +1,80 @@ +//! This example shows the ease of debouncing a button with async rust. +//! Hook up a button or switch between pin 9 and ground. + +#![no_std] +#![no_main] + +use defmt::info; +use embassy_executor::Spawner; +use embassy_rp::gpio::{Input, Level, Pull}; +use embassy_time::{timeout_at, Duration, Instant, Timer}; +use {defmt_rtt as _, panic_probe as _}; + +pub struct Debouncer<'a> { + input: Input<'a>, + debounce: Duration, +} + +impl<'a> Debouncer<'a> { + pub fn new(input: Input<'a>, debounce: Duration) -> Self { + Self { input, debounce } + } + + pub async fn debounce(&mut self) -> Level { + loop { + let l1 = self.input.get_level(); + + self.input.wait_for_any_edge().await; + + Timer::after(self.debounce).await; + + let l2 = self.input.get_level(); + if l1 != l2 { + break l2; + } + } + } +} + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_rp::init(Default::default()); + let mut btn = Debouncer::new(Input::new(p.PIN_9, Pull::Up), Duration::from_millis(20)); + + info!("Debounce Demo"); + + loop { + // button pressed + btn.debounce().await; + let start = Instant::now(); + info!("Button Press"); + + match timeout_at(start + Duration::from_secs(1), btn.debounce()).await { + // Button Released < 1s + Ok(_) => { + info!("Button pressed for: {}ms", start.elapsed().as_millis()); + continue; + } + // button held for > 1s + Err(_) => { + info!("Button Held"); + } + } + + match timeout_at(start + Duration::from_secs(5), btn.debounce()).await { + // Button released <5s + Ok(_) => { + info!("Button pressed for: {}ms", start.elapsed().as_millis()); + continue; + } + // button held for > >5s + Err(_) => { + info!("Button Long Held"); + } + } + + // wait for button release before handling another press + btn.debounce().await; + info!("Button pressed for: {}ms", start.elapsed().as_millis()); + } +} -- cgit From 8b7d85619537fc20ad7ad533433d84ba4975ddc4 Mon Sep 17 00:00:00 2001 From: Caleb Jamison Date: Wed, 31 Jan 2024 16:26:11 -0500 Subject: Rename timeout_at to with_deadline --- examples/rp/src/bin/debounce.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'examples') diff --git a/examples/rp/src/bin/debounce.rs b/examples/rp/src/bin/debounce.rs index bf1579091..0077f19fc 100644 --- a/examples/rp/src/bin/debounce.rs +++ b/examples/rp/src/bin/debounce.rs @@ -7,7 +7,7 @@ use defmt::info; use embassy_executor::Spawner; use embassy_rp::gpio::{Input, Level, Pull}; -use embassy_time::{timeout_at, Duration, Instant, Timer}; +use embassy_time::{with_deadline, Duration, Instant, Timer}; use {defmt_rtt as _, panic_probe as _}; pub struct Debouncer<'a> { @@ -49,7 +49,7 @@ async fn main(_spawner: Spawner) { let start = Instant::now(); info!("Button Press"); - match timeout_at(start + Duration::from_secs(1), btn.debounce()).await { + match with_deadline(start + Duration::from_secs(1), btn.debounce()).await { // Button Released < 1s Ok(_) => { info!("Button pressed for: {}ms", start.elapsed().as_millis()); @@ -61,7 +61,7 @@ async fn main(_spawner: Spawner) { } } - match timeout_at(start + Duration::from_secs(5), btn.debounce()).await { + match with_deadline(start + Duration::from_secs(5), btn.debounce()).await { // Button released <5s Ok(_) => { info!("Button pressed for: {}ms", start.elapsed().as_millis()); -- cgit From 42d8f3930a861dcc4540198bf2038151eb4e3e27 Mon Sep 17 00:00:00 2001 From: "Simon B. Gasse" Date: Fri, 19 Jan 2024 21:10:03 +0100 Subject: Implement MII interface - Extend the eth/v2 module to support MII besides RMII. - Replace `Ethernet::new` with `Ethernet::new_mii` and `Ethernet::new_rmii`. - Update ethernet examples. - Add example for MII ethernet. --- examples/stm32f4/src/bin/eth.rs | 2 +- examples/stm32f7/src/bin/eth.rs | 2 +- examples/stm32h5/src/bin/eth.rs | 2 +- examples/stm32h7/src/bin/eth.rs | 2 +- examples/stm32h7/src/bin/eth_client.rs | 2 +- examples/stm32h7/src/bin/eth_client_mii.rs | 142 +++++++++++++++++++++++++++++ 6 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 examples/stm32h7/src/bin/eth_client_mii.rs (limited to 'examples') diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs index 7f5c8fdb1..2933cfe3c 100644 --- a/examples/stm32f4/src/bin/eth.rs +++ b/examples/stm32f4/src/bin/eth.rs @@ -63,7 +63,7 @@ async fn main(spawner: Spawner) -> ! { let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; static PACKETS: StaticCell> = StaticCell::new(); - let device = Ethernet::new( + let device = Ethernet::new_rmii( PACKETS.init(PacketQueue::<16, 16>::new()), p.ETH, Irqs, diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index 5bff48197..85b5bd3e0 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -64,7 +64,7 @@ async fn main(spawner: Spawner) -> ! { let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; static PACKETS: StaticCell> = StaticCell::new(); - let device = Ethernet::new( + let device = Ethernet::new_rmii( PACKETS.init(PacketQueue::<16, 16>::new()), p.ETH, Irqs, diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index 2370656e6..79288877f 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs @@ -67,7 +67,7 @@ async fn main(spawner: Spawner) -> ! { let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; static PACKETS: StaticCell> = StaticCell::new(); - let device = Ethernet::new( + let device = Ethernet::new_rmii( PACKETS.init(PacketQueue::<4, 4>::new()), p.ETH, Irqs, diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index cd9a27fcd..9abdcf3c0 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -64,7 +64,7 @@ async fn main(spawner: Spawner) -> ! { let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; static PACKETS: StaticCell> = StaticCell::new(); - let device = Ethernet::new( + let device = Ethernet::new_rmii( PACKETS.init(PacketQueue::<4, 4>::new()), p.ETH, Irqs, diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index dcc6e36e2..c4da5776f 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -65,7 +65,7 @@ async fn main(spawner: Spawner) -> ! { let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; static PACKETS: StaticCell> = StaticCell::new(); - let device = Ethernet::new( + let device = Ethernet::new_rmii( PACKETS.init(PacketQueue::<16, 16>::new()), p.ETH, Irqs, diff --git a/examples/stm32h7/src/bin/eth_client_mii.rs b/examples/stm32h7/src/bin/eth_client_mii.rs new file mode 100644 index 000000000..de6ea522a --- /dev/null +++ b/examples/stm32h7/src/bin/eth_client_mii.rs @@ -0,0 +1,142 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_net::tcp::client::{TcpClient, TcpClientState}; +use embassy_net::{Stack, StackResources}; +use embassy_stm32::eth::generic_smi::GenericSMI; +use embassy_stm32::eth::{Ethernet, PacketQueue}; +use embassy_stm32::peripherals::ETH; +use embassy_stm32::rng::Rng; +use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; +use embassy_time::Timer; +use embedded_io_async::Write; +use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; +use rand_core::RngCore; +use static_cell::StaticCell; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + ETH => eth::InterruptHandler; + RNG => rng::InterruptHandler; +}); + +type Device = Ethernet<'static, ETH, GenericSMI>; + +#[embassy_executor::task] +async fn net_task(stack: &'static Stack) -> ! { + stack.run().await +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) -> ! { + let mut config = Config::default(); + { + use embassy_stm32::rcc::*; + config.rcc.hsi = Some(HSIPrescaler::DIV1); + config.rcc.csi = true; + config.rcc.hsi48 = Some(Default::default()); // needed for RNG + config.rcc.pll1 = Some(Pll { + source: PllSource::HSI, + prediv: PllPreDiv::DIV4, + mul: PllMul::MUL50, + divp: Some(PllDiv::DIV2), + divq: None, + divr: None, + }); + config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz + config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz + config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz + config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz + config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz + config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz + config.rcc.voltage_scale = VoltageScale::Scale1; + } + let p = embassy_stm32::init(config); + info!("Hello World!"); + + // Generate random seed. + let mut rng = Rng::new(p.RNG, Irqs); + let mut seed = [0; 8]; + rng.fill_bytes(&mut seed); + let seed = u64::from_le_bytes(seed); + + let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; + + static PACKETS: StaticCell> = StaticCell::new(); + + let device = Ethernet::new_mii( + PACKETS.init(PacketQueue::<16, 16>::new()), + p.ETH, + Irqs, + p.PA1, + p.PC3, + p.PA2, + p.PC1, + p.PA7, + p.PC4, + p.PC5, + p.PB0, + p.PB1, + p.PG13, + p.PG12, + p.PC2, + p.PE2, + p.PG11, + GenericSMI::new(1), + mac_addr, + ); + info!("Device created"); + + let config = embassy_net::Config::dhcpv4(Default::default()); + //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { + // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), + // dns_servers: Vec::new(), + // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), + //}); + + // Init network stack + static STACK: StaticCell> = StaticCell::new(); + static RESOURCES: StaticCell> = StaticCell::new(); + let stack = &*STACK.init(Stack::new( + device, + config, + RESOURCES.init(StackResources::<3>::new()), + seed, + )); + + // Launch network task + unwrap!(spawner.spawn(net_task(stack))); + + // Ensure DHCP configuration is up before trying connect + stack.wait_config_up().await; + + info!("Network task initialized"); + + let state: TcpClientState<1, 1024, 1024> = TcpClientState::new(); + let client = TcpClient::new(&stack, &state); + + loop { + // You need to start a server on the host machine, for example: `nc -l 8000` + let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 100, 1), 8000)); + + info!("connecting..."); + let r = client.connect(addr).await; + if let Err(e) = r { + info!("connect error: {:?}", e); + Timer::after_secs(1).await; + continue; + } + let mut connection = r.unwrap(); + info!("connected!"); + loop { + let r = connection.write_all(b"Hello\n").await; + if let Err(e) = r { + info!("write error: {:?}", e); + break; + } + Timer::after_secs(1).await; + } + } +} -- cgit From e613324e1603741df150730fd26652458d0d0c50 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 1 Feb 2024 01:39:52 +0100 Subject: stm32/eth: rename new_rmii to new, update metapac to fix issues with PC2_C. --- examples/stm32f4/src/bin/eth.rs | 2 +- examples/stm32f7/src/bin/eth.rs | 2 +- examples/stm32h5/src/bin/eth.rs | 2 +- examples/stm32h7/src/bin/eth.rs | 2 +- examples/stm32h7/src/bin/eth_client.rs | 3 ++- 5 files changed, 6 insertions(+), 5 deletions(-) (limited to 'examples') diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs index 2933cfe3c..7f5c8fdb1 100644 --- a/examples/stm32f4/src/bin/eth.rs +++ b/examples/stm32f4/src/bin/eth.rs @@ -63,7 +63,7 @@ async fn main(spawner: Spawner) -> ! { let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; static PACKETS: StaticCell> = StaticCell::new(); - let device = Ethernet::new_rmii( + let device = Ethernet::new( PACKETS.init(PacketQueue::<16, 16>::new()), p.ETH, Irqs, diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index 85b5bd3e0..5bff48197 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -64,7 +64,7 @@ async fn main(spawner: Spawner) -> ! { let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; static PACKETS: StaticCell> = StaticCell::new(); - let device = Ethernet::new_rmii( + let device = Ethernet::new( PACKETS.init(PacketQueue::<16, 16>::new()), p.ETH, Irqs, diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index 79288877f..2370656e6 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs @@ -67,7 +67,7 @@ async fn main(spawner: Spawner) -> ! { let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; static PACKETS: StaticCell> = StaticCell::new(); - let device = Ethernet::new_rmii( + let device = Ethernet::new( PACKETS.init(PacketQueue::<4, 4>::new()), p.ETH, Irqs, diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index 9abdcf3c0..cd9a27fcd 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -64,7 +64,7 @@ async fn main(spawner: Spawner) -> ! { let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; static PACKETS: StaticCell> = StaticCell::new(); - let device = Ethernet::new_rmii( + let device = Ethernet::new( PACKETS.init(PacketQueue::<4, 4>::new()), p.ETH, Irqs, diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index c4da5776f..aeb169e19 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -65,7 +65,8 @@ async fn main(spawner: Spawner) -> ! { let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; static PACKETS: StaticCell> = StaticCell::new(); - let device = Ethernet::new_rmii( + + let device = Ethernet::new( PACKETS.init(PacketQueue::<16, 16>::new()), p.ETH, Irqs, -- cgit From b9d0069671b33107e35af6bdaa662e9c7be8e3f9 Mon Sep 17 00:00:00 2001 From: Stefan Gehr Date: Sat, 3 Feb 2024 14:56:31 +0100 Subject: correct spelling of the word "receive" --- examples/rp/src/bin/i2c_slave.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'examples') diff --git a/examples/rp/src/bin/i2c_slave.rs b/examples/rp/src/bin/i2c_slave.rs index 479f9a16a..ac470d2be 100644 --- a/examples/rp/src/bin/i2c_slave.rs +++ b/examples/rp/src/bin/i2c_slave.rs @@ -26,7 +26,7 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! { loop { let mut buf = [0u8; 128]; match dev.listen(&mut buf).await { - Ok(i2c_slave::Command::GeneralCall(len)) => info!("Device recieved general call write: {}", buf[..len]), + Ok(i2c_slave::Command::GeneralCall(len)) => info!("Device received general call write: {}", buf[..len]), Ok(i2c_slave::Command::Read) => loop { match dev.respond_to_read(&[state]).await { Ok(x) => match x { @@ -40,9 +40,9 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! { Err(e) => error!("error while responding {}", e), } }, - Ok(i2c_slave::Command::Write(len)) => info!("Device recieved write: {}", buf[..len]), + Ok(i2c_slave::Command::Write(len)) => info!("Device received write: {}", buf[..len]), Ok(i2c_slave::Command::WriteRead(len)) => { - info!("device recieved write read: {:x}", buf[..len]); + info!("device received write read: {:x}", buf[..len]); match buf[0] { // Set the state 0xC2 => { -- cgit