diff options
| author | Karun Koppula <[email protected]> | 2024-03-07 15:20:29 -0500 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-03-07 15:20:29 -0500 |
| commit | 54751b7a5093b7960e42cee1bc9a850f9c4b7a8f (patch) | |
| tree | df08df503f2b441c5b62306d50532403fe4c19c9 /examples | |
| parent | 3b1d87050e2a30b598e92979b6f202b67664a29c (diff) | |
| parent | b2d236ee390081ec6aeef1a27da06098f9febbf9 (diff) | |
Merge branch 'main' into karun/main_octospi_implementation
Diffstat (limited to 'examples')
132 files changed, 2223 insertions, 416 deletions
diff --git a/examples/boot/.cargo/config.toml b/examples/boot/.cargo/config.toml index de3a814f7..be1b73e45 100644 --- a/examples/boot/.cargo/config.toml +++ b/examples/boot/.cargo/config.toml | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | [unstable] | 1 | [unstable] |
| 2 | build-std = ["core"] | 2 | #build-std = ["core"] |
| 3 | build-std-features = ["panic_immediate_abort"] | 3 | #build-std-features = ["panic_immediate_abort"] |
| 4 | 4 | ||
| 5 | [build] | 5 | [build] |
| 6 | target = "thumbv7em-none-eabi" | 6 | target = "thumbv7em-none-eabi" |
diff --git a/examples/boot/application/nrf/src/bin/a.rs b/examples/boot/application/nrf/src/bin/a.rs index f3abfddbc..851a3d721 100644 --- a/examples/boot/application/nrf/src/bin/a.rs +++ b/examples/boot/application/nrf/src/bin/a.rs | |||
| @@ -50,7 +50,7 @@ async fn main(_spawner: Spawner) { | |||
| 50 | let nvmc = Nvmc::new(p.NVMC); | 50 | let nvmc = Nvmc::new(p.NVMC); |
| 51 | let nvmc = Mutex::new(BlockingAsync::new(nvmc)); | 51 | let nvmc = Mutex::new(BlockingAsync::new(nvmc)); |
| 52 | 52 | ||
| 53 | let config = FirmwareUpdaterConfig::from_linkerfile(&nvmc); | 53 | let config = FirmwareUpdaterConfig::from_linkerfile(&nvmc, &nvmc); |
| 54 | let mut magic = [0; 4]; | 54 | let mut magic = [0; 4]; |
| 55 | let mut updater = FirmwareUpdater::new(config, &mut magic); | 55 | let mut updater = FirmwareUpdater::new(config, &mut magic); |
| 56 | loop { | 56 | loop { |
diff --git a/examples/boot/application/rp/.cargo/config.toml b/examples/boot/application/rp/.cargo/config.toml index cd8d1ef02..22ab3a5c1 100644 --- a/examples/boot/application/rp/.cargo/config.toml +++ b/examples/boot/application/rp/.cargo/config.toml | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | [unstable] | 1 | [unstable] |
| 2 | build-std = ["core"] | 2 | #build-std = ["core"] |
| 3 | build-std-features = ["panic_immediate_abort"] | 3 | #build-std-features = ["panic_immediate_abort"] |
| 4 | 4 | ||
| 5 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | 5 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] |
| 6 | runner = "probe-rs run --chip RP2040" | 6 | runner = "probe-rs run --chip RP2040" |
diff --git a/examples/boot/application/rp/src/bin/a.rs b/examples/boot/application/rp/src/bin/a.rs index 3f0bf90e2..ede0c07da 100644 --- a/examples/boot/application/rp/src/bin/a.rs +++ b/examples/boot/application/rp/src/bin/a.rs | |||
| @@ -36,7 +36,7 @@ async fn main(_s: Spawner) { | |||
| 36 | let flash = Flash::<_, _, FLASH_SIZE>::new_blocking(p.FLASH); | 36 | let flash = Flash::<_, _, FLASH_SIZE>::new_blocking(p.FLASH); |
| 37 | let flash = Mutex::new(RefCell::new(flash)); | 37 | let flash = Mutex::new(RefCell::new(flash)); |
| 38 | 38 | ||
| 39 | let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash); | 39 | let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash, &flash); |
| 40 | let mut aligned = AlignedBuffer([0; 1]); | 40 | let mut aligned = AlignedBuffer([0; 1]); |
| 41 | let mut updater = BlockingFirmwareUpdater::new(config, &mut aligned.0); | 41 | let mut updater = BlockingFirmwareUpdater::new(config, &mut aligned.0); |
| 42 | 42 | ||
diff --git a/examples/boot/application/stm32f3/memory.x b/examples/boot/application/stm32f3/memory.x index f51875766..02ebe3ecf 100644 --- a/examples/boot/application/stm32f3/memory.x +++ b/examples/boot/application/stm32f3/memory.x | |||
| @@ -3,8 +3,8 @@ MEMORY | |||
| 3 | /* NOTE 1 K = 1 KiBi = 1024 bytes */ | 3 | /* NOTE 1 K = 1 KiBi = 1024 bytes */ |
| 4 | BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K | 4 | BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K |
| 5 | BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K | 5 | BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K |
| 6 | FLASH : ORIGIN = 0x08008000, LENGTH = 32K | 6 | FLASH : ORIGIN = 0x08008000, LENGTH = 64K |
| 7 | DFU : ORIGIN = 0x08010000, LENGTH = 36K | 7 | DFU : ORIGIN = 0x08018000, LENGTH = 66K |
| 8 | RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K | 8 | RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K |
| 9 | } | 9 | } |
| 10 | 10 | ||
diff --git a/examples/boot/application/stm32f3/src/bin/a.rs b/examples/boot/application/stm32f3/src/bin/a.rs index 96ae5c47b..8858ae3da 100644 --- a/examples/boot/application/stm32f3/src/bin/a.rs +++ b/examples/boot/application/stm32f3/src/bin/a.rs | |||
| @@ -8,7 +8,7 @@ use embassy_embedded_hal::adapter::BlockingAsync; | |||
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::exti::ExtiInput; | 9 | use embassy_stm32::exti::ExtiInput; |
| 10 | use embassy_stm32::flash::{Flash, WRITE_SIZE}; | 10 | use embassy_stm32::flash::{Flash, WRITE_SIZE}; |
| 11 | use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; | 11 | use embassy_stm32::gpio::{Level, Output, Pull, Speed}; |
| 12 | use embassy_sync::mutex::Mutex; | 12 | use embassy_sync::mutex::Mutex; |
| 13 | use panic_reset as _; | 13 | use panic_reset as _; |
| 14 | 14 | ||
| @@ -23,13 +23,12 @@ async fn main(_spawner: Spawner) { | |||
| 23 | let flash = Flash::new_blocking(p.FLASH); | 23 | let flash = Flash::new_blocking(p.FLASH); |
| 24 | let flash = Mutex::new(BlockingAsync::new(flash)); | 24 | let flash = Mutex::new(BlockingAsync::new(flash)); |
| 25 | 25 | ||
| 26 | let button = Input::new(p.PC13, Pull::Up); | 26 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); |
| 27 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 28 | 27 | ||
| 29 | let mut led = Output::new(p.PA5, Level::Low, Speed::Low); | 28 | let mut led = Output::new(p.PA5, Level::Low, Speed::Low); |
| 30 | led.set_high(); | 29 | led.set_high(); |
| 31 | 30 | ||
| 32 | let config = FirmwareUpdaterConfig::from_linkerfile(&flash); | 31 | let config = FirmwareUpdaterConfig::from_linkerfile(&flash, &flash); |
| 33 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); | 32 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); |
| 34 | let mut updater = FirmwareUpdater::new(config, &mut magic.0); | 33 | let mut updater = FirmwareUpdater::new(config, &mut magic.0); |
| 35 | button.wait_for_falling_edge().await; | 34 | button.wait_for_falling_edge().await; |
diff --git a/examples/boot/application/stm32f7/src/bin/a.rs b/examples/boot/application/stm32f7/src/bin/a.rs index a6107386a..d3df11fe4 100644 --- a/examples/boot/application/stm32f7/src/bin/a.rs +++ b/examples/boot/application/stm32f7/src/bin/a.rs | |||
| @@ -9,7 +9,7 @@ use embassy_boot_stm32::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdater | |||
| 9 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 10 | use embassy_stm32::exti::ExtiInput; | 10 | use embassy_stm32::exti::ExtiInput; |
| 11 | use embassy_stm32::flash::{Flash, WRITE_SIZE}; | 11 | use embassy_stm32::flash::{Flash, WRITE_SIZE}; |
| 12 | use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; | 12 | use embassy_stm32::gpio::{Level, Output, Pull, Speed}; |
| 13 | use embassy_sync::blocking_mutex::Mutex; | 13 | use embassy_sync::blocking_mutex::Mutex; |
| 14 | use embedded_storage::nor_flash::NorFlash; | 14 | use embedded_storage::nor_flash::NorFlash; |
| 15 | use panic_reset as _; | 15 | use panic_reset as _; |
| @@ -25,13 +25,12 @@ async fn main(_spawner: Spawner) { | |||
| 25 | let flash = Flash::new_blocking(p.FLASH); | 25 | let flash = Flash::new_blocking(p.FLASH); |
| 26 | let flash = Mutex::new(RefCell::new(flash)); | 26 | let flash = Mutex::new(RefCell::new(flash)); |
| 27 | 27 | ||
| 28 | let button = Input::new(p.PC13, Pull::Down); | 28 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); |
| 29 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 30 | 29 | ||
| 31 | let mut led = Output::new(p.PB7, Level::Low, Speed::Low); | 30 | let mut led = Output::new(p.PB7, Level::Low, Speed::Low); |
| 32 | led.set_high(); | 31 | led.set_high(); |
| 33 | 32 | ||
| 34 | let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash); | 33 | let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash, &flash); |
| 35 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); | 34 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); |
| 36 | let mut updater = BlockingFirmwareUpdater::new(config, &mut magic.0); | 35 | let mut updater = BlockingFirmwareUpdater::new(config, &mut magic.0); |
| 37 | let writer = updater.prepare_update().unwrap(); | 36 | let writer = updater.prepare_update().unwrap(); |
diff --git a/examples/boot/application/stm32h7/src/bin/a.rs b/examples/boot/application/stm32h7/src/bin/a.rs index b73506cf3..f61ac1f71 100644 --- a/examples/boot/application/stm32h7/src/bin/a.rs +++ b/examples/boot/application/stm32h7/src/bin/a.rs | |||
| @@ -9,7 +9,7 @@ use embassy_boot_stm32::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdater | |||
| 9 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 10 | use embassy_stm32::exti::ExtiInput; | 10 | use embassy_stm32::exti::ExtiInput; |
| 11 | use embassy_stm32::flash::{Flash, WRITE_SIZE}; | 11 | use embassy_stm32::flash::{Flash, WRITE_SIZE}; |
| 12 | use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; | 12 | use embassy_stm32::gpio::{Level, Output, Pull, Speed}; |
| 13 | use embassy_sync::blocking_mutex::Mutex; | 13 | use embassy_sync::blocking_mutex::Mutex; |
| 14 | use embedded_storage::nor_flash::NorFlash; | 14 | use embedded_storage::nor_flash::NorFlash; |
| 15 | use panic_reset as _; | 15 | use panic_reset as _; |
| @@ -25,13 +25,12 @@ async fn main(_spawner: Spawner) { | |||
| 25 | let flash = Flash::new_blocking(p.FLASH); | 25 | let flash = Flash::new_blocking(p.FLASH); |
| 26 | let flash = Mutex::new(RefCell::new(flash)); | 26 | let flash = Mutex::new(RefCell::new(flash)); |
| 27 | 27 | ||
| 28 | let button = Input::new(p.PC13, Pull::Down); | 28 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); |
| 29 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 30 | 29 | ||
| 31 | let mut led = Output::new(p.PB14, Level::Low, Speed::Low); | 30 | let mut led = Output::new(p.PB14, Level::Low, Speed::Low); |
| 32 | led.set_high(); | 31 | led.set_high(); |
| 33 | 32 | ||
| 34 | let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash); | 33 | let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash, &flash); |
| 35 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); | 34 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); |
| 36 | let mut updater = BlockingFirmwareUpdater::new(config, &mut magic.0); | 35 | let mut updater = BlockingFirmwareUpdater::new(config, &mut magic.0); |
| 37 | let writer = updater.prepare_update().unwrap(); | 36 | let writer = updater.prepare_update().unwrap(); |
diff --git a/examples/boot/application/stm32l0/memory.x b/examples/boot/application/stm32l0/memory.x index a99330145..8866506a8 100644 --- a/examples/boot/application/stm32l0/memory.x +++ b/examples/boot/application/stm32l0/memory.x | |||
| @@ -3,8 +3,8 @@ MEMORY | |||
| 3 | /* NOTE 1 K = 1 KiBi = 1024 bytes */ | 3 | /* NOTE 1 K = 1 KiBi = 1024 bytes */ |
| 4 | BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K | 4 | BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K |
| 5 | BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K | 5 | BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K |
| 6 | FLASH : ORIGIN = 0x08008000, LENGTH = 32K | 6 | FLASH : ORIGIN = 0x08008000, LENGTH = 64K |
| 7 | DFU : ORIGIN = 0x08010000, LENGTH = 36K | 7 | DFU : ORIGIN = 0x08018000, LENGTH = 66K |
| 8 | RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K | 8 | RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K |
| 9 | } | 9 | } |
| 10 | 10 | ||
diff --git a/examples/boot/application/stm32l0/src/bin/a.rs b/examples/boot/application/stm32l0/src/bin/a.rs index 02f74bdef..f066c1139 100644 --- a/examples/boot/application/stm32l0/src/bin/a.rs +++ b/examples/boot/application/stm32l0/src/bin/a.rs | |||
| @@ -8,7 +8,7 @@ use embassy_embedded_hal::adapter::BlockingAsync; | |||
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::exti::ExtiInput; | 9 | use embassy_stm32::exti::ExtiInput; |
| 10 | use embassy_stm32::flash::{Flash, WRITE_SIZE}; | 10 | use embassy_stm32::flash::{Flash, WRITE_SIZE}; |
| 11 | use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; | 11 | use embassy_stm32::gpio::{Level, Output, Pull, Speed}; |
| 12 | use embassy_sync::mutex::Mutex; | 12 | use embassy_sync::mutex::Mutex; |
| 13 | use embassy_time::Timer; | 13 | use embassy_time::Timer; |
| 14 | use panic_reset as _; | 14 | use panic_reset as _; |
| @@ -24,14 +24,13 @@ async fn main(_spawner: Spawner) { | |||
| 24 | let flash = Flash::new_blocking(p.FLASH); | 24 | let flash = Flash::new_blocking(p.FLASH); |
| 25 | let flash = Mutex::new(BlockingAsync::new(flash)); | 25 | let flash = Mutex::new(BlockingAsync::new(flash)); |
| 26 | 26 | ||
| 27 | let button = Input::new(p.PB2, Pull::Up); | 27 | let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up); |
| 28 | let mut button = ExtiInput::new(button, p.EXTI2); | ||
| 29 | 28 | ||
| 30 | let mut led = Output::new(p.PB5, Level::Low, Speed::Low); | 29 | let mut led = Output::new(p.PB5, Level::Low, Speed::Low); |
| 31 | 30 | ||
| 32 | led.set_high(); | 31 | led.set_high(); |
| 33 | 32 | ||
| 34 | let config = FirmwareUpdaterConfig::from_linkerfile(&flash); | 33 | let config = FirmwareUpdaterConfig::from_linkerfile(&flash, &flash); |
| 35 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); | 34 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); |
| 36 | let mut updater = FirmwareUpdater::new(config, &mut magic.0); | 35 | let mut updater = FirmwareUpdater::new(config, &mut magic.0); |
| 37 | button.wait_for_falling_edge().await; | 36 | button.wait_for_falling_edge().await; |
diff --git a/examples/boot/application/stm32l1/memory.x b/examples/boot/application/stm32l1/memory.x index a99330145..caa525278 100644 --- a/examples/boot/application/stm32l1/memory.x +++ b/examples/boot/application/stm32l1/memory.x | |||
| @@ -3,8 +3,8 @@ MEMORY | |||
| 3 | /* NOTE 1 K = 1 KiBi = 1024 bytes */ | 3 | /* NOTE 1 K = 1 KiBi = 1024 bytes */ |
| 4 | BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K | 4 | BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K |
| 5 | BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K | 5 | BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K |
| 6 | FLASH : ORIGIN = 0x08008000, LENGTH = 32K | 6 | FLASH : ORIGIN = 0x08008000, LENGTH = 46K |
| 7 | DFU : ORIGIN = 0x08010000, LENGTH = 36K | 7 | DFU : ORIGIN = 0x08013800, LENGTH = 54K |
| 8 | RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K | 8 | RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K |
| 9 | } | 9 | } |
| 10 | 10 | ||
diff --git a/examples/boot/application/stm32l1/src/bin/a.rs b/examples/boot/application/stm32l1/src/bin/a.rs index 02f74bdef..f066c1139 100644 --- a/examples/boot/application/stm32l1/src/bin/a.rs +++ b/examples/boot/application/stm32l1/src/bin/a.rs | |||
| @@ -8,7 +8,7 @@ use embassy_embedded_hal::adapter::BlockingAsync; | |||
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::exti::ExtiInput; | 9 | use embassy_stm32::exti::ExtiInput; |
| 10 | use embassy_stm32::flash::{Flash, WRITE_SIZE}; | 10 | use embassy_stm32::flash::{Flash, WRITE_SIZE}; |
| 11 | use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; | 11 | use embassy_stm32::gpio::{Level, Output, Pull, Speed}; |
| 12 | use embassy_sync::mutex::Mutex; | 12 | use embassy_sync::mutex::Mutex; |
| 13 | use embassy_time::Timer; | 13 | use embassy_time::Timer; |
| 14 | use panic_reset as _; | 14 | use panic_reset as _; |
| @@ -24,14 +24,13 @@ async fn main(_spawner: Spawner) { | |||
| 24 | let flash = Flash::new_blocking(p.FLASH); | 24 | let flash = Flash::new_blocking(p.FLASH); |
| 25 | let flash = Mutex::new(BlockingAsync::new(flash)); | 25 | let flash = Mutex::new(BlockingAsync::new(flash)); |
| 26 | 26 | ||
| 27 | let button = Input::new(p.PB2, Pull::Up); | 27 | let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up); |
| 28 | let mut button = ExtiInput::new(button, p.EXTI2); | ||
| 29 | 28 | ||
| 30 | let mut led = Output::new(p.PB5, Level::Low, Speed::Low); | 29 | let mut led = Output::new(p.PB5, Level::Low, Speed::Low); |
| 31 | 30 | ||
| 32 | led.set_high(); | 31 | led.set_high(); |
| 33 | 32 | ||
| 34 | let config = FirmwareUpdaterConfig::from_linkerfile(&flash); | 33 | let config = FirmwareUpdaterConfig::from_linkerfile(&flash, &flash); |
| 35 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); | 34 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); |
| 36 | let mut updater = FirmwareUpdater::new(config, &mut magic.0); | 35 | let mut updater = FirmwareUpdater::new(config, &mut magic.0); |
| 37 | button.wait_for_falling_edge().await; | 36 | button.wait_for_falling_edge().await; |
diff --git a/examples/boot/application/stm32l4/memory.x b/examples/boot/application/stm32l4/memory.x index f51875766..e1d4e7fa8 100644 --- a/examples/boot/application/stm32l4/memory.x +++ b/examples/boot/application/stm32l4/memory.x | |||
| @@ -3,8 +3,8 @@ MEMORY | |||
| 3 | /* NOTE 1 K = 1 KiBi = 1024 bytes */ | 3 | /* NOTE 1 K = 1 KiBi = 1024 bytes */ |
| 4 | BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K | 4 | BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K |
| 5 | BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K | 5 | BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K |
| 6 | FLASH : ORIGIN = 0x08008000, LENGTH = 32K | 6 | FLASH : ORIGIN = 0x08008000, LENGTH = 64K |
| 7 | DFU : ORIGIN = 0x08010000, LENGTH = 36K | 7 | DFU : ORIGIN = 0x08018000, LENGTH = 68K |
| 8 | RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K | 8 | RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K |
| 9 | } | 9 | } |
| 10 | 10 | ||
diff --git a/examples/boot/application/stm32l4/src/bin/a.rs b/examples/boot/application/stm32l4/src/bin/a.rs index 892446968..a0079ee33 100644 --- a/examples/boot/application/stm32l4/src/bin/a.rs +++ b/examples/boot/application/stm32l4/src/bin/a.rs | |||
| @@ -8,7 +8,7 @@ use embassy_embedded_hal::adapter::BlockingAsync; | |||
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::exti::ExtiInput; | 9 | use embassy_stm32::exti::ExtiInput; |
| 10 | use embassy_stm32::flash::{Flash, WRITE_SIZE}; | 10 | use embassy_stm32::flash::{Flash, WRITE_SIZE}; |
| 11 | use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; | 11 | use embassy_stm32::gpio::{Level, Output, Pull, Speed}; |
| 12 | use embassy_sync::mutex::Mutex; | 12 | use embassy_sync::mutex::Mutex; |
| 13 | use panic_reset as _; | 13 | use panic_reset as _; |
| 14 | 14 | ||
| @@ -23,13 +23,12 @@ async fn main(_spawner: Spawner) { | |||
| 23 | let flash = Flash::new_blocking(p.FLASH); | 23 | let flash = Flash::new_blocking(p.FLASH); |
| 24 | let flash = Mutex::new(BlockingAsync::new(flash)); | 24 | let flash = Mutex::new(BlockingAsync::new(flash)); |
| 25 | 25 | ||
| 26 | let button = Input::new(p.PC13, Pull::Up); | 26 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); |
| 27 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 28 | 27 | ||
| 29 | let mut led = Output::new(p.PB14, Level::Low, Speed::Low); | 28 | let mut led = Output::new(p.PB14, Level::Low, Speed::Low); |
| 30 | led.set_high(); | 29 | led.set_high(); |
| 31 | 30 | ||
| 32 | let config = FirmwareUpdaterConfig::from_linkerfile(&flash); | 31 | let config = FirmwareUpdaterConfig::from_linkerfile(&flash, &flash); |
| 33 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); | 32 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); |
| 34 | let mut updater = FirmwareUpdater::new(config, &mut magic.0); | 33 | let mut updater = FirmwareUpdater::new(config, &mut magic.0); |
| 35 | button.wait_for_falling_edge().await; | 34 | button.wait_for_falling_edge().await; |
diff --git a/examples/boot/application/stm32wb-dfu/README.md b/examples/boot/application/stm32wb-dfu/README.md index c8dce0387..7f656cde6 100644 --- a/examples/boot/application/stm32wb-dfu/README.md +++ b/examples/boot/application/stm32wb-dfu/README.md | |||
| @@ -1,29 +1,9 @@ | |||
| 1 | # Examples using bootloader | 1 | # Examples using bootloader |
| 2 | 2 | ||
| 3 | Example for STM32WL demonstrating the bootloader. The example consists of application binaries, 'a' | 3 | Example for STM32WB demonstrating the USB DFU application. |
| 4 | which allows you to press a button to start the DFU process, and 'b' which is the updated | ||
| 5 | application. | ||
| 6 | |||
| 7 | |||
| 8 | ## Prerequisites | ||
| 9 | |||
| 10 | * `cargo-binutils` | ||
| 11 | * `cargo-flash` | ||
| 12 | * `embassy-boot-stm32` | ||
| 13 | 4 | ||
| 14 | ## Usage | 5 | ## Usage |
| 15 | 6 | ||
| 16 | ``` | 7 | ``` |
| 17 | # Flash bootloader | 8 | cargo flash --release --chip STM32WB55RGVx |
| 18 | cargo flash --manifest-path ../../bootloader/stm32/Cargo.toml --release --features embassy-stm32/stm32wl55jc-cm4 --chip STM32WLE5JCIx | ||
| 19 | # Build 'b' | ||
| 20 | cargo build --release --bin b | ||
| 21 | # Generate binary for 'b' | ||
| 22 | cargo objcopy --release --bin b -- -O binary b.bin | ||
| 23 | ``` | ||
| 24 | |||
| 25 | # Flash `a` (which includes b.bin) | ||
| 26 | |||
| 27 | ``` | ||
| 28 | cargo flash --release --bin a --chip STM32WLE5JCIx | ||
| 29 | ``` | 9 | ``` |
diff --git a/examples/boot/application/stm32wb-dfu/src/main.rs b/examples/boot/application/stm32wb-dfu/src/main.rs index b2ccb9e1a..37c3d7d90 100644 --- a/examples/boot/application/stm32wb-dfu/src/main.rs +++ b/examples/boot/application/stm32wb-dfu/src/main.rs | |||
| @@ -30,7 +30,7 @@ async fn main(_spawner: Spawner) { | |||
| 30 | let flash = Flash::new_blocking(p.FLASH); | 30 | let flash = Flash::new_blocking(p.FLASH); |
| 31 | let flash = Mutex::new(RefCell::new(flash)); | 31 | let flash = Mutex::new(RefCell::new(flash)); |
| 32 | 32 | ||
| 33 | let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash); | 33 | let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash, &flash); |
| 34 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); | 34 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); |
| 35 | let mut firmware_state = BlockingFirmwareState::from_config(config, &mut magic.0); | 35 | let mut firmware_state = BlockingFirmwareState::from_config(config, &mut magic.0); |
| 36 | firmware_state.mark_booted().expect("Failed to mark booted"); | 36 | firmware_state.mark_booted().expect("Failed to mark booted"); |
diff --git a/examples/boot/application/stm32wl/memory.x b/examples/boot/application/stm32wl/memory.x index f51875766..e1d4e7fa8 100644 --- a/examples/boot/application/stm32wl/memory.x +++ b/examples/boot/application/stm32wl/memory.x | |||
| @@ -3,8 +3,8 @@ MEMORY | |||
| 3 | /* NOTE 1 K = 1 KiBi = 1024 bytes */ | 3 | /* NOTE 1 K = 1 KiBi = 1024 bytes */ |
| 4 | BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K | 4 | BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K |
| 5 | BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K | 5 | BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K |
| 6 | FLASH : ORIGIN = 0x08008000, LENGTH = 32K | 6 | FLASH : ORIGIN = 0x08008000, LENGTH = 64K |
| 7 | DFU : ORIGIN = 0x08010000, LENGTH = 36K | 7 | DFU : ORIGIN = 0x08018000, LENGTH = 68K |
| 8 | RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K | 8 | RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K |
| 9 | } | 9 | } |
| 10 | 10 | ||
diff --git a/examples/boot/application/stm32wl/src/bin/a.rs b/examples/boot/application/stm32wl/src/bin/a.rs index d9665e6ee..2fb16bdc4 100644 --- a/examples/boot/application/stm32wl/src/bin/a.rs +++ b/examples/boot/application/stm32wl/src/bin/a.rs | |||
| @@ -8,7 +8,7 @@ use embassy_embedded_hal::adapter::BlockingAsync; | |||
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::exti::ExtiInput; | 9 | use embassy_stm32::exti::ExtiInput; |
| 10 | use embassy_stm32::flash::{Flash, WRITE_SIZE}; | 10 | use embassy_stm32::flash::{Flash, WRITE_SIZE}; |
| 11 | use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; | 11 | use embassy_stm32::gpio::{Level, Output, Pull, Speed}; |
| 12 | use embassy_sync::mutex::Mutex; | 12 | use embassy_sync::mutex::Mutex; |
| 13 | use panic_reset as _; | 13 | use panic_reset as _; |
| 14 | 14 | ||
| @@ -23,13 +23,12 @@ async fn main(_spawner: Spawner) { | |||
| 23 | let flash = Flash::new_blocking(p.FLASH); | 23 | let flash = Flash::new_blocking(p.FLASH); |
| 24 | let flash = Mutex::new(BlockingAsync::new(flash)); | 24 | let flash = Mutex::new(BlockingAsync::new(flash)); |
| 25 | 25 | ||
| 26 | let button = Input::new(p.PA0, Pull::Up); | 26 | let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Up); |
| 27 | let mut button = ExtiInput::new(button, p.EXTI0); | ||
| 28 | 27 | ||
| 29 | let mut led = Output::new(p.PB9, Level::Low, Speed::Low); | 28 | let mut led = Output::new(p.PB9, Level::Low, Speed::Low); |
| 30 | led.set_high(); | 29 | led.set_high(); |
| 31 | 30 | ||
| 32 | let config = FirmwareUpdaterConfig::from_linkerfile(&flash); | 31 | let config = FirmwareUpdaterConfig::from_linkerfile(&flash, &flash); |
| 33 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); | 32 | let mut magic = AlignedBuffer([0; WRITE_SIZE]); |
| 34 | let mut updater = FirmwareUpdater::new(config, &mut magic.0); | 33 | let mut updater = FirmwareUpdater::new(config, &mut magic.0); |
| 35 | button.wait_for_falling_edge().await; | 34 | button.wait_for_falling_edge().await; |
diff --git a/examples/boot/bootloader/nrf/.cargo/config.toml b/examples/boot/bootloader/nrf/.cargo/config.toml index c292846aa..58acd1a49 100644 --- a/examples/boot/bootloader/nrf/.cargo/config.toml +++ b/examples/boot/bootloader/nrf/.cargo/config.toml | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | [unstable] | 1 | [unstable] |
| 2 | build-std = ["core"] | 2 | #build-std = ["core"] |
| 3 | build-std-features = ["panic_immediate_abort"] | 3 | #build-std-features = ["panic_immediate_abort"] |
| 4 | 4 | ||
| 5 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | 5 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] |
| 6 | #runner = "./fruitrunner" | 6 | #runner = "./fruitrunner" |
| @@ -8,7 +8,7 @@ runner = "probe-rs run --chip nrf52840_xxAA" | |||
| 8 | 8 | ||
| 9 | rustflags = [ | 9 | rustflags = [ |
| 10 | # Code-size optimizations. | 10 | # Code-size optimizations. |
| 11 | "-Z", "trap-unreachable=no", | 11 | #"-Z", "trap-unreachable=no", |
| 12 | #"-C", "no-vectorize-loops", | 12 | #"-C", "no-vectorize-loops", |
| 13 | "-C", "force-frame-pointers=yes", | 13 | "-C", "force-frame-pointers=yes", |
| 14 | ] | 14 | ] |
diff --git a/examples/boot/bootloader/nrf/src/main.rs b/examples/boot/bootloader/nrf/src/main.rs index 74e2e293f..67c700437 100644 --- a/examples/boot/bootloader/nrf/src/main.rs +++ b/examples/boot/bootloader/nrf/src/main.rs | |||
| @@ -31,7 +31,7 @@ fn main() -> ! { | |||
| 31 | let flash = WatchdogFlash::start(Nvmc::new(p.NVMC), p.WDT, wdt_config); | 31 | let flash = WatchdogFlash::start(Nvmc::new(p.NVMC), p.WDT, wdt_config); |
| 32 | let flash = Mutex::new(RefCell::new(flash)); | 32 | let flash = Mutex::new(RefCell::new(flash)); |
| 33 | 33 | ||
| 34 | let config = BootLoaderConfig::from_linkerfile_blocking(&flash); | 34 | let config = BootLoaderConfig::from_linkerfile_blocking(&flash, &flash, &flash); |
| 35 | let active_offset = config.active.offset(); | 35 | let active_offset = config.active.offset(); |
| 36 | let bl: BootLoader = BootLoader::prepare(config); | 36 | let bl: BootLoader = BootLoader::prepare(config); |
| 37 | 37 | ||
diff --git a/examples/boot/bootloader/rp/src/main.rs b/examples/boot/bootloader/rp/src/main.rs index c0e75d1ea..25b1657b8 100644 --- a/examples/boot/bootloader/rp/src/main.rs +++ b/examples/boot/bootloader/rp/src/main.rs | |||
| @@ -27,7 +27,7 @@ fn main() -> ! { | |||
| 27 | let flash = WatchdogFlash::<FLASH_SIZE>::start(p.FLASH, p.WATCHDOG, Duration::from_secs(8)); | 27 | let flash = WatchdogFlash::<FLASH_SIZE>::start(p.FLASH, p.WATCHDOG, Duration::from_secs(8)); |
| 28 | let flash = Mutex::new(RefCell::new(flash)); | 28 | let flash = Mutex::new(RefCell::new(flash)); |
| 29 | 29 | ||
| 30 | let config = BootLoaderConfig::from_linkerfile_blocking(&flash); | 30 | let config = BootLoaderConfig::from_linkerfile_blocking(&flash, &flash, &flash); |
| 31 | let active_offset = config.active.offset(); | 31 | let active_offset = config.active.offset(); |
| 32 | let bl: BootLoader = BootLoader::prepare(config); | 32 | let bl: BootLoader = BootLoader::prepare(config); |
| 33 | 33 | ||
diff --git a/examples/boot/bootloader/stm32-dual-bank/Cargo.toml b/examples/boot/bootloader/stm32-dual-bank/Cargo.toml new file mode 100644 index 000000000..313187adc --- /dev/null +++ b/examples/boot/bootloader/stm32-dual-bank/Cargo.toml | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2021" | ||
| 3 | name = "stm32-bootloader-dual-bank-flash-example" | ||
| 4 | version = "0.1.0" | ||
| 5 | description = "Example bootloader for dual-bank flash STM32 chips" | ||
| 6 | license = "MIT OR Apache-2.0" | ||
| 7 | |||
| 8 | [dependencies] | ||
| 9 | defmt = { version = "0.3", optional = true } | ||
| 10 | defmt-rtt = { version = "0.4", optional = true } | ||
| 11 | |||
| 12 | embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } | ||
| 13 | embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } | ||
| 14 | cortex-m = { version = "0.7.6", features = [ | ||
| 15 | "inline-asm", | ||
| 16 | "critical-section-single-core", | ||
| 17 | ] } | ||
| 18 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | ||
| 19 | cortex-m-rt = { version = "0.7" } | ||
| 20 | embedded-storage = "0.3.1" | ||
| 21 | embedded-storage-async = "0.4.0" | ||
| 22 | cfg-if = "1.0.0" | ||
| 23 | |||
| 24 | [features] | ||
| 25 | defmt = ["dep:defmt", "embassy-boot-stm32/defmt", "embassy-stm32/defmt"] | ||
| 26 | debug = ["defmt-rtt", "defmt"] | ||
| 27 | |||
| 28 | [profile.dev] | ||
| 29 | debug = 2 | ||
| 30 | debug-assertions = true | ||
| 31 | incremental = false | ||
| 32 | opt-level = 'z' | ||
| 33 | overflow-checks = true | ||
| 34 | |||
| 35 | [profile.release] | ||
| 36 | codegen-units = 1 | ||
| 37 | debug = 2 | ||
| 38 | debug-assertions = false | ||
| 39 | incremental = false | ||
| 40 | lto = 'fat' | ||
| 41 | opt-level = 'z' | ||
| 42 | overflow-checks = false | ||
| 43 | |||
| 44 | # do not optimize proc-macro crates = faster builds from scratch | ||
| 45 | [profile.dev.build-override] | ||
| 46 | codegen-units = 8 | ||
| 47 | debug = false | ||
| 48 | debug-assertions = false | ||
| 49 | opt-level = 0 | ||
| 50 | overflow-checks = false | ||
| 51 | |||
| 52 | [profile.release.build-override] | ||
| 53 | codegen-units = 8 | ||
| 54 | debug = false | ||
| 55 | debug-assertions = false | ||
| 56 | opt-level = 0 | ||
| 57 | overflow-checks = false | ||
diff --git a/examples/boot/bootloader/stm32-dual-bank/README.md b/examples/boot/bootloader/stm32-dual-bank/README.md new file mode 100644 index 000000000..3de3171cd --- /dev/null +++ b/examples/boot/bootloader/stm32-dual-bank/README.md | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | # STM32 dual-bank flash Bootloader | ||
| 2 | |||
| 3 | ## Overview | ||
| 4 | |||
| 5 | This bootloader leverages `embassy-boot` to interact with the flash. | ||
| 6 | This example targets STM32 devices with dual-bank flash memory, with a primary focus on the STM32H747XI series. | ||
| 7 | Users must modify the `memory.x` configuration file to match with the memory layout of their specific STM32 device. | ||
| 8 | |||
| 9 | Additionally, this example can be extended to utilize external flash memory, such as QSPI, for storing partitions. | ||
| 10 | |||
| 11 | ## Memory Configuration | ||
| 12 | |||
| 13 | In this example's `memory.x` file, various symbols are defined to assist in effective memory management within the bootloader environment. | ||
| 14 | For dual-bank STM32 devices, it's crucial to assign these symbols correctly to their respective memory banks. | ||
| 15 | |||
| 16 | ### Symbol Definitions | ||
| 17 | |||
| 18 | The bootloader's state and active symbols are anchored to the flash origin of **bank 1**: | ||
| 19 | |||
| 20 | - `__bootloader_state_start` and `__bootloader_state_end` | ||
| 21 | - `__bootloader_active_start` and `__bootloader_active_end` | ||
| 22 | |||
| 23 | In contrast, the Device Firmware Upgrade (DFU) symbols are aligned with the DFU flash origin in **bank 2**: | ||
| 24 | |||
| 25 | - `__bootloader_dfu_start` and `__bootloader_dfu_end` | ||
| 26 | |||
| 27 | ```rust | ||
| 28 | __bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(**FLASH**); | ||
| 29 | __bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE) - ORIGIN(**FLASH**); | ||
| 30 | |||
| 31 | __bootloader_active_start = ORIGIN(ACTIVE) - ORIGIN(**FLASH**); | ||
| 32 | __bootloader_active_end = ORIGIN(ACTIVE) + LENGTH(ACTIVE) - ORIGIN(**FLASH**); | ||
| 33 | |||
| 34 | __bootloader_dfu_start = ORIGIN(DFU) - ORIGIN(**DFU**); | ||
| 35 | __bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU) - ORIGIN(**DFU**); | ||
| 36 | ``` | ||
| 37 | |||
| 38 | ## Flashing the Bootloader | ||
| 39 | |||
| 40 | To flash the bootloader onto your STM32H747XI device, use the following command: | ||
| 41 | |||
| 42 | ```bash | ||
| 43 | cargo flash --features embassy-stm32/stm32h747xi-cm7 --release --chip STM32H747XIHx | ||
| 44 | ``` | ||
diff --git a/examples/boot/bootloader/stm32-dual-bank/build.rs b/examples/boot/bootloader/stm32-dual-bank/build.rs new file mode 100644 index 000000000..fd605991f --- /dev/null +++ b/examples/boot/bootloader/stm32-dual-bank/build.rs | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | use std::env; | ||
| 2 | use std::fs::File; | ||
| 3 | use std::io::Write; | ||
| 4 | use std::path::PathBuf; | ||
| 5 | |||
| 6 | fn main() { | ||
| 7 | // Put `memory.x` in our output directory and ensure it's | ||
| 8 | // on the linker search path. | ||
| 9 | let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); | ||
| 10 | File::create(out.join("memory.x")) | ||
| 11 | .unwrap() | ||
| 12 | .write_all(include_bytes!("memory.x")) | ||
| 13 | .unwrap(); | ||
| 14 | println!("cargo:rustc-link-search={}", out.display()); | ||
| 15 | |||
| 16 | // By default, Cargo will re-run a build script whenever | ||
| 17 | // any file in the project changes. By specifying `memory.x` | ||
| 18 | // here, we ensure the build script is only re-run when | ||
| 19 | // `memory.x` is changed. | ||
| 20 | println!("cargo:rerun-if-changed=memory.x"); | ||
| 21 | |||
| 22 | println!("cargo:rustc-link-arg-bins=--nmagic"); | ||
| 23 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | ||
| 24 | if env::var("CARGO_FEATURE_DEFMT").is_ok() { | ||
| 25 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
| 26 | } | ||
| 27 | } | ||
diff --git a/examples/boot/bootloader/stm32-dual-bank/memory.x b/examples/boot/bootloader/stm32-dual-bank/memory.x new file mode 100644 index 000000000..665da7139 --- /dev/null +++ b/examples/boot/bootloader/stm32-dual-bank/memory.x | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | /* NOTE 1 K = 1 KiBi = 1024 bytes */ | ||
| 4 | FLASH : ORIGIN = 0x08000000, LENGTH = 128K | ||
| 5 | BOOTLOADER_STATE : ORIGIN = 0x08020000, LENGTH = 128K | ||
| 6 | ACTIVE : ORIGIN = 0x08040000, LENGTH = 512K | ||
| 7 | DFU : ORIGIN = 0x08100000, LENGTH = 640K | ||
| 8 | RAM (rwx) : ORIGIN = 0x24000000, LENGTH = 512K | ||
| 9 | } | ||
| 10 | |||
| 11 | __bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(FLASH); | ||
| 12 | __bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE) - ORIGIN(FLASH); | ||
| 13 | |||
| 14 | __bootloader_active_start = ORIGIN(ACTIVE) - ORIGIN(FLASH); | ||
| 15 | __bootloader_active_end = ORIGIN(ACTIVE) + LENGTH(ACTIVE) - ORIGIN(FLASH); | ||
| 16 | |||
| 17 | __bootloader_dfu_start = ORIGIN(DFU) - ORIGIN(DFU); | ||
| 18 | __bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU) - ORIGIN(DFU); | ||
diff --git a/examples/boot/bootloader/stm32-dual-bank/src/main.rs b/examples/boot/bootloader/stm32-dual-bank/src/main.rs new file mode 100644 index 000000000..4d2e82d26 --- /dev/null +++ b/examples/boot/bootloader/stm32-dual-bank/src/main.rs | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use core::cell::RefCell; | ||
| 5 | |||
| 6 | use cortex_m_rt::{entry, exception}; | ||
| 7 | #[cfg(feature = "defmt")] | ||
| 8 | use defmt_rtt as _; | ||
| 9 | use embassy_boot_stm32::*; | ||
| 10 | use embassy_stm32::flash::{Flash, BANK1_REGION}; | ||
| 11 | use embassy_sync::blocking_mutex::Mutex; | ||
| 12 | |||
| 13 | #[entry] | ||
| 14 | fn main() -> ! { | ||
| 15 | let p = embassy_stm32::init(Default::default()); | ||
| 16 | |||
| 17 | // Uncomment this if you are debugging the bootloader with debugger/RTT attached, | ||
| 18 | // as it prevents a hard fault when accessing flash 'too early' after boot. | ||
| 19 | /* | ||
| 20 | for i in 0..10000000 { | ||
| 21 | cortex_m::asm::nop(); | ||
| 22 | } | ||
| 23 | */ | ||
| 24 | |||
| 25 | let layout = Flash::new_blocking(p.FLASH).into_blocking_regions(); | ||
| 26 | let flash_bank1 = Mutex::new(RefCell::new(layout.bank1_region)); | ||
| 27 | let flash_bank2 = Mutex::new(RefCell::new(layout.bank2_region)); | ||
| 28 | |||
| 29 | let config = BootLoaderConfig::from_linkerfile_blocking(&flash_bank1, &flash_bank2, &flash_bank1); | ||
| 30 | let active_offset = config.active.offset(); | ||
| 31 | let bl = BootLoader::prepare::<_, _, _, 2048>(config); | ||
| 32 | |||
| 33 | unsafe { bl.load(BANK1_REGION.base + active_offset) } | ||
| 34 | } | ||
| 35 | |||
| 36 | #[no_mangle] | ||
| 37 | #[cfg_attr(target_os = "none", link_section = ".HardFault.user")] | ||
| 38 | unsafe extern "C" fn HardFault() { | ||
| 39 | cortex_m::peripheral::SCB::sys_reset(); | ||
| 40 | } | ||
| 41 | |||
| 42 | #[exception] | ||
| 43 | unsafe fn DefaultHandler(_: i16) -> ! { | ||
| 44 | const SCB_ICSR: *const u32 = 0xE000_ED04 as *const u32; | ||
| 45 | let irqn = core::ptr::read_volatile(SCB_ICSR) as u8 as i16 - 16; | ||
| 46 | |||
| 47 | panic!("DefaultHandler #{:?}", irqn); | ||
| 48 | } | ||
| 49 | |||
| 50 | #[panic_handler] | ||
| 51 | fn panic(_info: &core::panic::PanicInfo) -> ! { | ||
| 52 | cortex_m::asm::udf(); | ||
| 53 | } | ||
diff --git a/examples/boot/bootloader/stm32/src/main.rs b/examples/boot/bootloader/stm32/src/main.rs index 5fd9ea588..99a7a6a6b 100644 --- a/examples/boot/bootloader/stm32/src/main.rs +++ b/examples/boot/bootloader/stm32/src/main.rs | |||
| @@ -25,7 +25,7 @@ fn main() -> ! { | |||
| 25 | let layout = Flash::new_blocking(p.FLASH).into_blocking_regions(); | 25 | let layout = Flash::new_blocking(p.FLASH).into_blocking_regions(); |
| 26 | let flash = Mutex::new(RefCell::new(layout.bank1_region)); | 26 | let flash = Mutex::new(RefCell::new(layout.bank1_region)); |
| 27 | 27 | ||
| 28 | let config = BootLoaderConfig::from_linkerfile_blocking(&flash); | 28 | let config = BootLoaderConfig::from_linkerfile_blocking(&flash, &flash, &flash); |
| 29 | let active_offset = config.active.offset(); | 29 | let active_offset = config.active.offset(); |
| 30 | let bl = BootLoader::prepare::<_, _, _, 2048>(config); | 30 | let bl = BootLoader::prepare::<_, _, _, 2048>(config); |
| 31 | 31 | ||
diff --git a/examples/boot/bootloader/stm32wb-dfu/Cargo.toml b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml index 96635afa2..854f94d85 100644 --- a/examples/boot/bootloader/stm32wb-dfu/Cargo.toml +++ b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml | |||
| @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" | |||
| 9 | defmt = { version = "0.3", optional = true } | 9 | defmt = { version = "0.3", optional = true } |
| 10 | defmt-rtt = { version = "0.4", optional = true } | 10 | defmt-rtt = { version = "0.4", optional = true } |
| 11 | 11 | ||
| 12 | embassy-stm32 = { path = "../../../../embassy-stm32", features = ["stm32wb55rg"] } | 12 | embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } |
| 13 | embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } | 13 | embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } |
| 14 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | 14 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } |
| 15 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } | 15 | embassy-sync = { version = "0.5.0", path = "../../../../embassy-sync" } |
diff --git a/examples/boot/bootloader/stm32wb-dfu/README.md b/examples/boot/bootloader/stm32wb-dfu/README.md index a82b730b9..d5c6ea57c 100644 --- a/examples/boot/bootloader/stm32wb-dfu/README.md +++ b/examples/boot/bootloader/stm32wb-dfu/README.md | |||
| @@ -7,5 +7,5 @@ The bootloader uses `embassy-boot` to interact with the flash. | |||
| 7 | Flash the bootloader | 7 | Flash the bootloader |
| 8 | 8 | ||
| 9 | ``` | 9 | ``` |
| 10 | cargo flash --features embassy-stm32/stm32wl55jc-cm4 --release --chip STM32WLE5JCIx | 10 | cargo flash --features embassy-stm32/stm32wb55rg --release --chip STM32WB55RGVx |
| 11 | ``` | 11 | ``` |
diff --git a/examples/boot/bootloader/stm32wb-dfu/src/main.rs b/examples/boot/bootloader/stm32wb-dfu/src/main.rs index a7ab813b6..d989fbfdf 100644 --- a/examples/boot/bootloader/stm32wb-dfu/src/main.rs +++ b/examples/boot/bootloader/stm32wb-dfu/src/main.rs | |||
| @@ -35,7 +35,7 @@ fn main() -> ! { | |||
| 35 | let layout = Flash::new_blocking(p.FLASH).into_blocking_regions(); | 35 | let layout = Flash::new_blocking(p.FLASH).into_blocking_regions(); |
| 36 | let flash = Mutex::new(RefCell::new(layout.bank1_region)); | 36 | let flash = Mutex::new(RefCell::new(layout.bank1_region)); |
| 37 | 37 | ||
| 38 | let config = BootLoaderConfig::from_linkerfile_blocking(&flash); | 38 | let config = BootLoaderConfig::from_linkerfile_blocking(&flash, &flash, &flash); |
| 39 | let active_offset = config.active.offset(); | 39 | let active_offset = config.active.offset(); |
| 40 | let bl = BootLoader::prepare::<_, _, _, 2048>(config); | 40 | let bl = BootLoader::prepare::<_, _, _, 2048>(config); |
| 41 | if bl.state == State::DfuDetach { | 41 | if bl.state == State::DfuDetach { |
| @@ -45,7 +45,7 @@ fn main() -> ! { | |||
| 45 | config.product = Some("USB-DFU Bootloader example"); | 45 | config.product = Some("USB-DFU Bootloader example"); |
| 46 | config.serial_number = Some("1235678"); | 46 | config.serial_number = Some("1235678"); |
| 47 | 47 | ||
| 48 | let fw_config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash); | 48 | let fw_config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash, &flash); |
| 49 | let mut buffer = AlignedBuffer([0; WRITE_SIZE]); | 49 | let mut buffer = AlignedBuffer([0; WRITE_SIZE]); |
| 50 | let updater = BlockingFirmwareUpdater::new(fw_config, &mut buffer.0[..]); | 50 | let updater = BlockingFirmwareUpdater::new(fw_config, &mut buffer.0[..]); |
| 51 | 51 | ||
diff --git a/examples/nrf51/.cargo/config.toml b/examples/nrf51/.cargo/config.toml new file mode 100644 index 000000000..1671f5db1 --- /dev/null +++ b/examples/nrf51/.cargo/config.toml | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | ||
| 2 | # replace nRF51422_xxAA with your chip as listed in `probe-rs chip list` | ||
| 3 | runner = "probe-rs run --chip nRF51422_xxAA" | ||
| 4 | |||
| 5 | [build] | ||
| 6 | target = "thumbv6m-none-eabi" | ||
| 7 | |||
| 8 | [env] | ||
| 9 | DEFMT_LOG = "trace" | ||
diff --git a/examples/nrf51/Cargo.toml b/examples/nrf51/Cargo.toml new file mode 100644 index 000000000..06c3d20cb --- /dev/null +++ b/examples/nrf51/Cargo.toml | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2021" | ||
| 3 | name = "embassy-nrf51-examples" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | |||
| 7 | [dependencies] | ||
| 8 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-4096", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | ||
| 9 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | ||
| 10 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf51", "gpiote", "time-driver-rtc1", "unstable-pac", "time", "rt"] } | ||
| 11 | |||
| 12 | defmt = "0.3" | ||
| 13 | defmt-rtt = "0.4" | ||
| 14 | |||
| 15 | cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } | ||
| 16 | cortex-m-rt = "0.7" | ||
| 17 | panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
| 18 | |||
| 19 | [profile.release] | ||
| 20 | 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 @@ | |||
| 1 | //! This build script copies the `memory.x` file from the crate root into | ||
| 2 | //! a directory where the linker can always find it at build time. | ||
| 3 | //! For many projects this is optional, as the linker always searches the | ||
| 4 | //! project root directory -- wherever `Cargo.toml` is. However, if you | ||
| 5 | //! are using a workspace or have a more complicated build setup, this | ||
| 6 | //! build script becomes required. Additionally, by requesting that | ||
| 7 | //! Cargo re-run the build script whenever `memory.x` is changed, | ||
| 8 | //! updating `memory.x` ensures a rebuild of the application with the | ||
| 9 | //! new memory settings. | ||
| 10 | |||
| 11 | use std::env; | ||
| 12 | use std::fs::File; | ||
| 13 | use std::io::Write; | ||
| 14 | use std::path::PathBuf; | ||
| 15 | |||
| 16 | fn main() { | ||
| 17 | // Put `memory.x` in our output directory and ensure it's | ||
| 18 | // on the linker search path. | ||
| 19 | let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); | ||
| 20 | File::create(out.join("memory.x")) | ||
| 21 | .unwrap() | ||
| 22 | .write_all(include_bytes!("memory.x")) | ||
| 23 | .unwrap(); | ||
| 24 | println!("cargo:rustc-link-search={}", out.display()); | ||
| 25 | |||
| 26 | // By default, Cargo will re-run a build script whenever | ||
| 27 | // any file in the project changes. By specifying `memory.x` | ||
| 28 | // here, we ensure the build script is only re-run when | ||
| 29 | // `memory.x` is changed. | ||
| 30 | println!("cargo:rerun-if-changed=memory.x"); | ||
| 31 | |||
| 32 | println!("cargo:rustc-link-arg-bins=--nmagic"); | ||
| 33 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | ||
| 34 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
| 35 | } | ||
diff --git a/examples/nrf51/memory.x b/examples/nrf51/memory.x new file mode 100644 index 000000000..98b3c792f --- /dev/null +++ b/examples/nrf51/memory.x | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 128K | ||
| 4 | RAM : ORIGIN = 0x20000000, LENGTH = 16K | ||
| 5 | } | ||
diff --git a/examples/nrf51/src/bin/blinky.rs b/examples/nrf51/src/bin/blinky.rs new file mode 100644 index 000000000..7c12ffcbc --- /dev/null +++ b/examples/nrf51/src/bin/blinky.rs | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use embassy_executor::Spawner; | ||
| 5 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | ||
| 6 | use embassy_time::Timer; | ||
| 7 | use {defmt_rtt as _, panic_probe as _}; | ||
| 8 | |||
| 9 | #[embassy_executor::main] | ||
| 10 | async fn main(_spawner: Spawner) { | ||
| 11 | let p = embassy_nrf::init(Default::default()); | ||
| 12 | let mut led = Output::new(p.P0_21, Level::Low, OutputDrive::Standard); | ||
| 13 | |||
| 14 | loop { | ||
| 15 | led.set_high(); | ||
| 16 | Timer::after_millis(300).await; | ||
| 17 | led.set_low(); | ||
| 18 | Timer::after_millis(300).await; | ||
| 19 | } | ||
| 20 | } | ||
diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index abb995be6..4ab5c7b7c 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml | |||
| @@ -28,7 +28,7 @@ panic-probe = { version = "0.3", features = ["print-defmt"] } | |||
| 28 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 28 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 29 | rand = { version = "0.8.4", default-features = false } | 29 | rand = { version = "0.8.4", default-features = false } |
| 30 | embedded-storage = "0.3.1" | 30 | embedded-storage = "0.3.1" |
| 31 | usbd-hid = "0.6.0" | 31 | usbd-hid = "0.7.0" |
| 32 | serde = { version = "1.0.136", default-features = false } | 32 | serde = { version = "1.0.136", default-features = false } |
| 33 | embedded-hal = { version = "1.0" } | 33 | embedded-hal = { version = "1.0" } |
| 34 | embedded-hal-async = { version = "1.0" } | 34 | embedded-hal-async = { version = "1.0" } |
diff --git a/examples/nrf52840/src/bin/ethernet_enc28j60.rs b/examples/nrf52840/src/bin/ethernet_enc28j60.rs index a8e64b38a..279f32edc 100644 --- a/examples/nrf52840/src/bin/ethernet_enc28j60.rs +++ b/examples/nrf52840/src/bin/ethernet_enc28j60.rs | |||
| @@ -24,10 +24,7 @@ bind_interrupts!(struct Irqs { | |||
| 24 | #[embassy_executor::task] | 24 | #[embassy_executor::task] |
| 25 | async fn net_task( | 25 | async fn net_task( |
| 26 | stack: &'static Stack< | 26 | stack: &'static Stack< |
| 27 | Enc28j60< | 27 | Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>, |
| 28 | ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static, peripherals::P0_15>, Delay>, | ||
| 29 | Output<'static, peripherals::P0_13>, | ||
| 30 | >, | ||
| 31 | >, | 28 | >, |
| 32 | ) -> ! { | 29 | ) -> ! { |
| 33 | stack.run().await | 30 | stack.run().await |
| @@ -71,12 +68,7 @@ async fn main(spawner: Spawner) { | |||
| 71 | // Init network stack | 68 | // Init network stack |
| 72 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | 69 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); |
| 73 | static STACK: StaticCell< | 70 | static STACK: StaticCell< |
| 74 | Stack< | 71 | Stack<Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>>, |
| 75 | Enc28j60< | ||
| 76 | ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static, peripherals::P0_15>, Delay>, | ||
| 77 | Output<'static, peripherals::P0_13>, | ||
| 78 | >, | ||
| 79 | >, | ||
| 80 | > = StaticCell::new(); | 72 | > = StaticCell::new(); |
| 81 | let stack = STACK.init(Stack::new( | 73 | let stack = STACK.init(Stack::new( |
| 82 | device, | 74 | device, |
diff --git a/examples/nrf52840/src/bin/gpiote_port.rs b/examples/nrf52840/src/bin/gpiote_port.rs index c1afe2f20..0dddb1a97 100644 --- a/examples/nrf52840/src/bin/gpiote_port.rs +++ b/examples/nrf52840/src/bin/gpiote_port.rs | |||
| @@ -3,11 +3,11 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::{info, unwrap}; | 4 | use defmt::{info, unwrap}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_nrf::gpio::{AnyPin, Input, Pin as _, Pull}; | 6 | use embassy_nrf::gpio::{Input, Pull}; |
| 7 | use {defmt_rtt as _, panic_probe as _}; | 7 | use {defmt_rtt as _, panic_probe as _}; |
| 8 | 8 | ||
| 9 | #[embassy_executor::task(pool_size = 4)] | 9 | #[embassy_executor::task(pool_size = 4)] |
| 10 | async fn button_task(n: usize, mut pin: Input<'static, AnyPin>) { | 10 | async fn button_task(n: usize, mut pin: Input<'static>) { |
| 11 | loop { | 11 | loop { |
| 12 | pin.wait_for_low().await; | 12 | pin.wait_for_low().await; |
| 13 | info!("Button {:?} pressed!", n); | 13 | info!("Button {:?} pressed!", n); |
| @@ -21,10 +21,10 @@ async fn main(spawner: Spawner) { | |||
| 21 | let p = embassy_nrf::init(Default::default()); | 21 | let p = embassy_nrf::init(Default::default()); |
| 22 | info!("Starting!"); | 22 | info!("Starting!"); |
| 23 | 23 | ||
| 24 | let btn1 = Input::new(p.P0_11.degrade(), Pull::Up); | 24 | let btn1 = Input::new(p.P0_11, Pull::Up); |
| 25 | let btn2 = Input::new(p.P0_12.degrade(), Pull::Up); | 25 | let btn2 = Input::new(p.P0_12, Pull::Up); |
| 26 | let btn3 = Input::new(p.P0_24.degrade(), Pull::Up); | 26 | let btn3 = Input::new(p.P0_24, Pull::Up); |
| 27 | let btn4 = Input::new(p.P0_25.degrade(), Pull::Up); | 27 | let btn4 = Input::new(p.P0_25, Pull::Up); |
| 28 | 28 | ||
| 29 | unwrap!(spawner.spawn(button_task(1, btn1))); | 29 | unwrap!(spawner.spawn(button_task(1, btn1))); |
| 30 | unwrap!(spawner.spawn(button_task(2, btn2))); | 30 | unwrap!(spawner.spawn(button_task(2, btn2))); |
diff --git a/examples/nrf52840/src/bin/usb_hid_keyboard.rs b/examples/nrf52840/src/bin/usb_hid_keyboard.rs index 45850b4a4..3e86590c4 100644 --- a/examples/nrf52840/src/bin/usb_hid_keyboard.rs +++ b/examples/nrf52840/src/bin/usb_hid_keyboard.rs | |||
| @@ -8,7 +8,7 @@ use defmt::*; | |||
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_futures::join::join; | 9 | use embassy_futures::join::join; |
| 10 | use embassy_futures::select::{select, Either}; | 10 | use embassy_futures::select::{select, Either}; |
| 11 | use embassy_nrf::gpio::{Input, Pin, Pull}; | 11 | use embassy_nrf::gpio::{Input, Pull}; |
| 12 | use embassy_nrf::usb::vbus_detect::HardwareVbusDetect; | 12 | use embassy_nrf::usb::vbus_detect::HardwareVbusDetect; |
| 13 | use embassy_nrf::usb::Driver; | 13 | use embassy_nrf::usb::Driver; |
| 14 | use embassy_nrf::{bind_interrupts, pac, peripherals, usb}; | 14 | use embassy_nrf::{bind_interrupts, pac, peripherals, usb}; |
| @@ -97,7 +97,7 @@ async fn main(_spawner: Spawner) { | |||
| 97 | } | 97 | } |
| 98 | }; | 98 | }; |
| 99 | 99 | ||
| 100 | let mut button = Input::new(p.P0_11.degrade(), Pull::Up); | 100 | let mut button = Input::new(p.P0_11, Pull::Up); |
| 101 | 101 | ||
| 102 | let (reader, mut writer) = hid.split(); | 102 | let (reader, mut writer) = hid.split(); |
| 103 | 103 | ||
diff --git a/examples/nrf52840/src/bin/wifi_esp_hosted.rs b/examples/nrf52840/src/bin/wifi_esp_hosted.rs index fc2086f75..00bd50081 100644 --- a/examples/nrf52840/src/bin/wifi_esp_hosted.rs +++ b/examples/nrf52840/src/bin/wifi_esp_hosted.rs | |||
| @@ -5,7 +5,7 @@ use defmt::{info, unwrap, warn}; | |||
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_net::tcp::TcpSocket; | 6 | use embassy_net::tcp::TcpSocket; |
| 7 | use embassy_net::{Stack, StackResources}; | 7 | use embassy_net::{Stack, StackResources}; |
| 8 | use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin, Pull}; | 8 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; |
| 9 | use embassy_nrf::rng::Rng; | 9 | use embassy_nrf::rng::Rng; |
| 10 | use embassy_nrf::spim::{self, Spim}; | 10 | use embassy_nrf::spim::{self, Spim}; |
| 11 | use embassy_nrf::{bind_interrupts, peripherals}; | 11 | use embassy_nrf::{bind_interrupts, peripherals}; |
| @@ -27,9 +27,9 @@ bind_interrupts!(struct Irqs { | |||
| 27 | async fn wifi_task( | 27 | async fn wifi_task( |
| 28 | runner: hosted::Runner< | 28 | runner: hosted::Runner< |
| 29 | 'static, | 29 | 'static, |
| 30 | ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static, peripherals::P0_31>, Delay>, | 30 | ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, |
| 31 | Input<'static, AnyPin>, | 31 | Input<'static>, |
| 32 | Output<'static, peripherals::P1_05>, | 32 | Output<'static>, |
| 33 | >, | 33 | >, |
| 34 | ) -> ! { | 34 | ) -> ! { |
| 35 | runner.run().await | 35 | runner.run().await |
| @@ -50,8 +50,8 @@ async fn main(spawner: Spawner) { | |||
| 50 | let sck = p.P0_29; | 50 | let sck = p.P0_29; |
| 51 | let mosi = p.P0_30; | 51 | let mosi = p.P0_30; |
| 52 | let cs = Output::new(p.P0_31, Level::High, OutputDrive::HighDrive); | 52 | let cs = Output::new(p.P0_31, Level::High, OutputDrive::HighDrive); |
| 53 | let handshake = Input::new(p.P1_01.degrade(), Pull::Up); | 53 | let handshake = Input::new(p.P1_01, Pull::Up); |
| 54 | let ready = Input::new(p.P1_04.degrade(), Pull::None); | 54 | let ready = Input::new(p.P1_04, Pull::None); |
| 55 | let reset = Output::new(p.P1_05, Level::Low, OutputDrive::Standard); | 55 | let reset = Output::new(p.P1_05, Level::Low, OutputDrive::Standard); |
| 56 | 56 | ||
| 57 | let mut config = spim::Config::default(); | 57 | let mut config = spim::Config::default(); |
diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index 56b9c8018..24aa560d5 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml | |||
| @@ -24,7 +24,7 @@ panic-probe = { version = "0.3", features = ["print-defmt"] } | |||
| 24 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 24 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 25 | rand = { version = "0.8.4", default-features = false } | 25 | rand = { version = "0.8.4", default-features = false } |
| 26 | embedded-storage = "0.3.1" | 26 | embedded-storage = "0.3.1" |
| 27 | usbd-hid = "0.6.0" | 27 | usbd-hid = "0.7.0" |
| 28 | serde = { version = "1.0.136", default-features = false } | 28 | serde = { version = "1.0.136", default-features = false } |
| 29 | 29 | ||
| 30 | [profile.release] | 30 | [profile.release] |
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index e1092dba4..585349506 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml | |||
| @@ -36,7 +36,7 @@ display-interface = "0.4.1" | |||
| 36 | byte-slice-cast = { version = "1.2.0", default-features = false } | 36 | byte-slice-cast = { version = "1.2.0", default-features = false } |
| 37 | smart-leds = "0.3.0" | 37 | smart-leds = "0.3.0" |
| 38 | heapless = "0.8" | 38 | heapless = "0.8" |
| 39 | usbd-hid = "0.6.1" | 39 | usbd-hid = "0.7.0" |
| 40 | 40 | ||
| 41 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 41 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 42 | embedded-hal-async = "1.0" | 42 | embedded-hal-async = "1.0" |
diff --git a/examples/rp/src/bin/blinky_two_tasks.rs b/examples/rp/src/bin/blinky_two_tasks.rs index a03f3a592..a57b513d6 100644 --- a/examples/rp/src/bin/blinky_two_tasks.rs +++ b/examples/rp/src/bin/blinky_two_tasks.rs | |||
| @@ -14,7 +14,7 @@ use embassy_time::{Duration, Ticker}; | |||
| 14 | use gpio::{AnyPin, Level, Output}; | 14 | use gpio::{AnyPin, Level, Output}; |
| 15 | use {defmt_rtt as _, panic_probe as _}; | 15 | use {defmt_rtt as _, panic_probe as _}; |
| 16 | 16 | ||
| 17 | type LedType = Mutex<ThreadModeRawMutex, Option<Output<'static, AnyPin>>>; | 17 | type LedType = Mutex<ThreadModeRawMutex, Option<Output<'static>>>; |
| 18 | static LED: LedType = Mutex::new(None); | 18 | static LED: LedType = Mutex::new(None); |
| 19 | 19 | ||
| 20 | #[embassy_executor::main] | 20 | #[embassy_executor::main] |
diff --git a/examples/rp/src/bin/debounce.rs b/examples/rp/src/bin/debounce.rs new file mode 100644 index 000000000..0077f19fc --- /dev/null +++ b/examples/rp/src/bin/debounce.rs | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | //! This example shows the ease of debouncing a button with async rust. | ||
| 2 | //! Hook up a button or switch between pin 9 and ground. | ||
| 3 | |||
| 4 | #![no_std] | ||
| 5 | #![no_main] | ||
| 6 | |||
| 7 | use defmt::info; | ||
| 8 | use embassy_executor::Spawner; | ||
| 9 | use embassy_rp::gpio::{Input, Level, Pull}; | ||
| 10 | use embassy_time::{with_deadline, Duration, Instant, Timer}; | ||
| 11 | use {defmt_rtt as _, panic_probe as _}; | ||
| 12 | |||
| 13 | pub struct Debouncer<'a> { | ||
| 14 | input: Input<'a>, | ||
| 15 | debounce: Duration, | ||
| 16 | } | ||
| 17 | |||
| 18 | impl<'a> Debouncer<'a> { | ||
| 19 | pub fn new(input: Input<'a>, debounce: Duration) -> Self { | ||
| 20 | Self { input, debounce } | ||
| 21 | } | ||
| 22 | |||
| 23 | pub async fn debounce(&mut self) -> Level { | ||
| 24 | loop { | ||
| 25 | let l1 = self.input.get_level(); | ||
| 26 | |||
| 27 | self.input.wait_for_any_edge().await; | ||
| 28 | |||
| 29 | Timer::after(self.debounce).await; | ||
| 30 | |||
| 31 | let l2 = self.input.get_level(); | ||
| 32 | if l1 != l2 { | ||
| 33 | break l2; | ||
| 34 | } | ||
| 35 | } | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | #[embassy_executor::main] | ||
| 40 | async fn main(_spawner: Spawner) { | ||
| 41 | let p = embassy_rp::init(Default::default()); | ||
| 42 | let mut btn = Debouncer::new(Input::new(p.PIN_9, Pull::Up), Duration::from_millis(20)); | ||
| 43 | |||
| 44 | info!("Debounce Demo"); | ||
| 45 | |||
| 46 | loop { | ||
| 47 | // button pressed | ||
| 48 | btn.debounce().await; | ||
| 49 | let start = Instant::now(); | ||
| 50 | info!("Button Press"); | ||
| 51 | |||
| 52 | match with_deadline(start + Duration::from_secs(1), btn.debounce()).await { | ||
| 53 | // Button Released < 1s | ||
| 54 | Ok(_) => { | ||
| 55 | info!("Button pressed for: {}ms", start.elapsed().as_millis()); | ||
| 56 | continue; | ||
| 57 | } | ||
| 58 | // button held for > 1s | ||
| 59 | Err(_) => { | ||
| 60 | info!("Button Held"); | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | match with_deadline(start + Duration::from_secs(5), btn.debounce()).await { | ||
| 65 | // Button released <5s | ||
| 66 | Ok(_) => { | ||
| 67 | info!("Button pressed for: {}ms", start.elapsed().as_millis()); | ||
| 68 | continue; | ||
| 69 | } | ||
| 70 | // button held for > >5s | ||
| 71 | Err(_) => { | ||
| 72 | info!("Button Long Held"); | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | // wait for button release before handling another press | ||
| 77 | btn.debounce().await; | ||
| 78 | info!("Button pressed for: {}ms", start.elapsed().as_millis()); | ||
| 79 | } | ||
| 80 | } | ||
diff --git a/examples/rp/src/bin/ethernet_w5500_multisocket.rs b/examples/rp/src/bin/ethernet_w5500_multisocket.rs index a16ea0007..bd52cadca 100644 --- a/examples/rp/src/bin/ethernet_w5500_multisocket.rs +++ b/examples/rp/src/bin/ethernet_w5500_multisocket.rs | |||
| @@ -13,7 +13,7 @@ use embassy_net_wiznet::chip::W5500; | |||
| 13 | use embassy_net_wiznet::*; | 13 | use embassy_net_wiznet::*; |
| 14 | use embassy_rp::clocks::RoscRng; | 14 | use embassy_rp::clocks::RoscRng; |
| 15 | use embassy_rp::gpio::{Input, Level, Output, Pull}; | 15 | use embassy_rp::gpio::{Input, Level, Output, Pull}; |
| 16 | use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0}; | 16 | use embassy_rp::peripherals::SPI0; |
| 17 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; | 17 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; |
| 18 | use embassy_time::{Delay, Duration}; | 18 | use embassy_time::{Delay, Duration}; |
| 19 | use embedded_hal_bus::spi::ExclusiveDevice; | 19 | use embedded_hal_bus::spi::ExclusiveDevice; |
| @@ -27,9 +27,9 @@ async fn ethernet_task( | |||
| 27 | runner: Runner< | 27 | runner: Runner< |
| 28 | 'static, | 28 | 'static, |
| 29 | W5500, | 29 | W5500, |
| 30 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, | 30 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>, |
| 31 | Input<'static, PIN_21>, | 31 | Input<'static>, |
| 32 | Output<'static, PIN_20>, | 32 | Output<'static>, |
| 33 | >, | 33 | >, |
| 34 | ) -> ! { | 34 | ) -> ! { |
| 35 | runner.run().await | 35 | runner.run().await |
diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs index 975b3d385..3e4fbd2e6 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs | |||
| @@ -15,7 +15,7 @@ use embassy_net_wiznet::chip::W5500; | |||
| 15 | use embassy_net_wiznet::*; | 15 | use embassy_net_wiznet::*; |
| 16 | use embassy_rp::clocks::RoscRng; | 16 | use embassy_rp::clocks::RoscRng; |
| 17 | use embassy_rp::gpio::{Input, Level, Output, Pull}; | 17 | use embassy_rp::gpio::{Input, Level, Output, Pull}; |
| 18 | use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0}; | 18 | use embassy_rp::peripherals::SPI0; |
| 19 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; | 19 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; |
| 20 | use embassy_time::{Delay, Duration, Timer}; | 20 | use embassy_time::{Delay, Duration, Timer}; |
| 21 | use embedded_hal_bus::spi::ExclusiveDevice; | 21 | use embedded_hal_bus::spi::ExclusiveDevice; |
| @@ -29,9 +29,9 @@ async fn ethernet_task( | |||
| 29 | runner: Runner< | 29 | runner: Runner< |
| 30 | 'static, | 30 | 'static, |
| 31 | W5500, | 31 | W5500, |
| 32 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, | 32 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>, |
| 33 | Input<'static, PIN_21>, | 33 | Input<'static>, |
| 34 | Output<'static, PIN_20>, | 34 | Output<'static>, |
| 35 | >, | 35 | >, |
| 36 | ) -> ! { | 36 | ) -> ! { |
| 37 | runner.run().await | 37 | runner.run().await |
diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs index 489af2c76..5532851f3 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs | |||
| @@ -14,7 +14,7 @@ use embassy_net_wiznet::chip::W5500; | |||
| 14 | use embassy_net_wiznet::*; | 14 | use embassy_net_wiznet::*; |
| 15 | use embassy_rp::clocks::RoscRng; | 15 | use embassy_rp::clocks::RoscRng; |
| 16 | use embassy_rp::gpio::{Input, Level, Output, Pull}; | 16 | use embassy_rp::gpio::{Input, Level, Output, Pull}; |
| 17 | use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0}; | 17 | use embassy_rp::peripherals::SPI0; |
| 18 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; | 18 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; |
| 19 | use embassy_time::{Delay, Duration}; | 19 | use embassy_time::{Delay, Duration}; |
| 20 | use embedded_hal_bus::spi::ExclusiveDevice; | 20 | use embedded_hal_bus::spi::ExclusiveDevice; |
| @@ -28,9 +28,9 @@ async fn ethernet_task( | |||
| 28 | runner: Runner< | 28 | runner: Runner< |
| 29 | 'static, | 29 | 'static, |
| 30 | W5500, | 30 | W5500, |
| 31 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, | 31 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>, |
| 32 | Input<'static, PIN_21>, | 32 | Input<'static>, |
| 33 | Output<'static, PIN_20>, | 33 | Output<'static>, |
| 34 | >, | 34 | >, |
| 35 | ) -> ! { | 35 | ) -> ! { |
| 36 | runner.run().await | 36 | runner.run().await |
diff --git a/examples/rp/src/bin/ethernet_w5500_udp.rs b/examples/rp/src/bin/ethernet_w5500_udp.rs index 41bd7d077..adb1d8941 100644 --- a/examples/rp/src/bin/ethernet_w5500_udp.rs +++ b/examples/rp/src/bin/ethernet_w5500_udp.rs | |||
| @@ -14,7 +14,7 @@ use embassy_net_wiznet::chip::W5500; | |||
| 14 | use embassy_net_wiznet::*; | 14 | use embassy_net_wiznet::*; |
| 15 | use embassy_rp::clocks::RoscRng; | 15 | use embassy_rp::clocks::RoscRng; |
| 16 | use embassy_rp::gpio::{Input, Level, Output, Pull}; | 16 | use embassy_rp::gpio::{Input, Level, Output, Pull}; |
| 17 | use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0}; | 17 | use embassy_rp::peripherals::SPI0; |
| 18 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; | 18 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; |
| 19 | use embassy_time::Delay; | 19 | use embassy_time::Delay; |
| 20 | use embedded_hal_bus::spi::ExclusiveDevice; | 20 | use embedded_hal_bus::spi::ExclusiveDevice; |
| @@ -27,9 +27,9 @@ async fn ethernet_task( | |||
| 27 | runner: Runner< | 27 | runner: Runner< |
| 28 | 'static, | 28 | 'static, |
| 29 | W5500, | 29 | W5500, |
| 30 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, | 30 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>, |
| 31 | Input<'static, PIN_21>, | 31 | Input<'static>, |
| 32 | Output<'static, PIN_20>, | 32 | Output<'static>, |
| 33 | >, | 33 | >, |
| 34 | ) -> ! { | 34 | ) -> ! { |
| 35 | runner.run().await | 35 | runner.run().await |
diff --git a/examples/rp/src/bin/i2c_slave.rs b/examples/rp/src/bin/i2c_slave.rs index 479f9a16a..9fffb4646 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>) -> ! { | |||
| 26 | loop { | 26 | loop { |
| 27 | let mut buf = [0u8; 128]; | 27 | let mut buf = [0u8; 128]; |
| 28 | match dev.listen(&mut buf).await { | 28 | match dev.listen(&mut buf).await { |
| 29 | Ok(i2c_slave::Command::GeneralCall(len)) => info!("Device recieved general call write: {}", buf[..len]), | 29 | Ok(i2c_slave::Command::GeneralCall(len)) => info!("Device received general call write: {}", buf[..len]), |
| 30 | Ok(i2c_slave::Command::Read) => loop { | 30 | Ok(i2c_slave::Command::Read) => loop { |
| 31 | match dev.respond_to_read(&[state]).await { | 31 | match dev.respond_to_read(&[state]).await { |
| 32 | Ok(x) => match x { | 32 | Ok(x) => match x { |
| @@ -40,9 +40,9 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! { | |||
| 40 | Err(e) => error!("error while responding {}", e), | 40 | Err(e) => error!("error while responding {}", e), |
| 41 | } | 41 | } |
| 42 | }, | 42 | }, |
| 43 | Ok(i2c_slave::Command::Write(len)) => info!("Device recieved write: {}", buf[..len]), | 43 | Ok(i2c_slave::Command::Write(len)) => info!("Device received write: {}", buf[..len]), |
| 44 | Ok(i2c_slave::Command::WriteRead(len)) => { | 44 | Ok(i2c_slave::Command::WriteRead(len)) => { |
| 45 | info!("device recieved write read: {:x}", buf[..len]); | 45 | info!("device received write read: {:x}", buf[..len]); |
| 46 | match buf[0] { | 46 | match buf[0] { |
| 47 | // Set the state | 47 | // Set the state |
| 48 | 0xC2 => { | 48 | 0xC2 => { |
| @@ -110,7 +110,7 @@ async fn main(spawner: Spawner) { | |||
| 110 | let c_sda = p.PIN_1; | 110 | let c_sda = p.PIN_1; |
| 111 | let c_scl = p.PIN_0; | 111 | let c_scl = p.PIN_0; |
| 112 | let mut config = i2c::Config::default(); | 112 | let mut config = i2c::Config::default(); |
| 113 | config.frequency = 5_000; | 113 | config.frequency = 1_000_000; |
| 114 | let controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, config); | 114 | let controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, config); |
| 115 | 115 | ||
| 116 | unwrap!(spawner.spawn(controller_task(controller))); | 116 | unwrap!(spawner.spawn(controller_task(controller))); |
diff --git a/examples/rp/src/bin/multicore.rs b/examples/rp/src/bin/multicore.rs index a1678d99a..c7b087476 100644 --- a/examples/rp/src/bin/multicore.rs +++ b/examples/rp/src/bin/multicore.rs | |||
| @@ -9,7 +9,6 @@ use defmt::*; | |||
| 9 | use embassy_executor::Executor; | 9 | use embassy_executor::Executor; |
| 10 | use embassy_rp::gpio::{Level, Output}; | 10 | use embassy_rp::gpio::{Level, Output}; |
| 11 | use embassy_rp::multicore::{spawn_core1, Stack}; | 11 | use embassy_rp::multicore::{spawn_core1, Stack}; |
| 12 | use embassy_rp::peripherals::PIN_25; | ||
| 13 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 12 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 14 | use embassy_sync::channel::Channel; | 13 | use embassy_sync::channel::Channel; |
| 15 | use embassy_time::Timer; | 14 | use embassy_time::Timer; |
| @@ -52,7 +51,7 @@ async fn core0_task() { | |||
| 52 | } | 51 | } |
| 53 | 52 | ||
| 54 | #[embassy_executor::task] | 53 | #[embassy_executor::task] |
| 55 | async fn core1_task(mut led: Output<'static, PIN_25>) { | 54 | async fn core1_task(mut led: Output<'static>) { |
| 56 | info!("Hello from core 1"); | 55 | info!("Hello from core 1"); |
| 57 | loop { | 56 | loop { |
| 58 | match CHANNEL.receive().await { | 57 | match CHANNEL.receive().await { |
diff --git a/examples/rp/src/bin/pio_i2s.rs b/examples/rp/src/bin/pio_i2s.rs new file mode 100644 index 000000000..cf60e5b30 --- /dev/null +++ b/examples/rp/src/bin/pio_i2s.rs | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | //! This example shows generating audio and sending it to a connected i2s DAC using the PIO | ||
| 2 | //! module of the RP2040. | ||
| 3 | //! | ||
| 4 | //! Connect the i2s DAC as follows: | ||
| 5 | //! bclk : GPIO 18 | ||
| 6 | //! lrc : GPIO 19 | ||
| 7 | //! din : GPIO 20 | ||
| 8 | //! Then hold down the boot select button to trigger a rising triangle waveform. | ||
| 9 | |||
| 10 | #![no_std] | ||
| 11 | #![no_main] | ||
| 12 | |||
| 13 | use core::mem; | ||
| 14 | |||
| 15 | use embassy_executor::Spawner; | ||
| 16 | use embassy_rp::peripherals::PIO0; | ||
| 17 | use embassy_rp::pio::{Config, FifoJoin, InterruptHandler, Pio, ShiftConfig, ShiftDirection}; | ||
| 18 | use embassy_rp::{bind_interrupts, Peripheral}; | ||
| 19 | use fixed::traits::ToFixed; | ||
| 20 | use static_cell::StaticCell; | ||
| 21 | use {defmt_rtt as _, panic_probe as _}; | ||
| 22 | |||
| 23 | bind_interrupts!(struct Irqs { | ||
| 24 | PIO0_IRQ_0 => InterruptHandler<PIO0>; | ||
| 25 | }); | ||
| 26 | |||
| 27 | const SAMPLE_RATE: u32 = 48_000; | ||
| 28 | |||
| 29 | #[embassy_executor::main] | ||
| 30 | async fn main(_spawner: Spawner) { | ||
| 31 | let mut p = embassy_rp::init(Default::default()); | ||
| 32 | |||
| 33 | // Setup pio state machine for i2s output | ||
| 34 | let mut pio = Pio::new(p.PIO0, Irqs); | ||
| 35 | |||
| 36 | #[rustfmt::skip] | ||
| 37 | let pio_program = pio_proc::pio_asm!( | ||
| 38 | ".side_set 2", | ||
| 39 | " set x, 14 side 0b01", // side 0bWB - W = Word Clock, B = Bit Clock | ||
| 40 | "left_data:", | ||
| 41 | " out pins, 1 side 0b00", | ||
| 42 | " jmp x-- left_data side 0b01", | ||
| 43 | " out pins 1 side 0b10", | ||
| 44 | " set x, 14 side 0b11", | ||
| 45 | "right_data:", | ||
| 46 | " out pins 1 side 0b10", | ||
| 47 | " jmp x-- right_data side 0b11", | ||
| 48 | " out pins 1 side 0b00", | ||
| 49 | ); | ||
| 50 | |||
| 51 | let bit_clock_pin = p.PIN_18; | ||
| 52 | let left_right_clock_pin = p.PIN_19; | ||
| 53 | let data_pin = p.PIN_20; | ||
| 54 | |||
| 55 | let data_pin = pio.common.make_pio_pin(data_pin); | ||
| 56 | let bit_clock_pin = pio.common.make_pio_pin(bit_clock_pin); | ||
| 57 | let left_right_clock_pin = pio.common.make_pio_pin(left_right_clock_pin); | ||
| 58 | |||
| 59 | let cfg = { | ||
| 60 | let mut cfg = Config::default(); | ||
| 61 | cfg.use_program( | ||
| 62 | &pio.common.load_program(&pio_program.program), | ||
| 63 | &[&bit_clock_pin, &left_right_clock_pin], | ||
| 64 | ); | ||
| 65 | cfg.set_out_pins(&[&data_pin]); | ||
| 66 | const BIT_DEPTH: u32 = 16; | ||
| 67 | const CHANNELS: u32 = 2; | ||
| 68 | let clock_frequency = SAMPLE_RATE * BIT_DEPTH * CHANNELS; | ||
| 69 | cfg.clock_divider = (125_000_000. / clock_frequency as f64 / 2.).to_fixed(); | ||
| 70 | cfg.shift_out = ShiftConfig { | ||
| 71 | threshold: 32, | ||
| 72 | direction: ShiftDirection::Left, | ||
| 73 | auto_fill: true, | ||
| 74 | }; | ||
| 75 | // join fifos to have twice the time to start the next dma transfer | ||
| 76 | cfg.fifo_join = FifoJoin::TxOnly; | ||
| 77 | cfg | ||
| 78 | }; | ||
| 79 | pio.sm0.set_config(&cfg); | ||
| 80 | pio.sm0.set_pin_dirs( | ||
| 81 | embassy_rp::pio::Direction::Out, | ||
| 82 | &[&data_pin, &left_right_clock_pin, &bit_clock_pin], | ||
| 83 | ); | ||
| 84 | |||
| 85 | // create two audio buffers (back and front) which will take turns being | ||
| 86 | // filled with new audio data and being sent to the pio fifo using dma | ||
| 87 | const BUFFER_SIZE: usize = 960; | ||
| 88 | static DMA_BUFFER: StaticCell<[u32; BUFFER_SIZE * 2]> = StaticCell::new(); | ||
| 89 | let dma_buffer = DMA_BUFFER.init_with(|| [0u32; BUFFER_SIZE * 2]); | ||
| 90 | let (mut back_buffer, mut front_buffer) = dma_buffer.split_at_mut(BUFFER_SIZE); | ||
| 91 | |||
| 92 | // start pio state machine | ||
| 93 | pio.sm0.set_enable(true); | ||
| 94 | let tx = pio.sm0.tx(); | ||
| 95 | let mut dma_ref = p.DMA_CH0.into_ref(); | ||
| 96 | |||
| 97 | let mut fade_value: i32 = 0; | ||
| 98 | let mut phase: i32 = 0; | ||
| 99 | |||
| 100 | loop { | ||
| 101 | // trigger transfer of front buffer data to the pio fifo | ||
| 102 | // but don't await the returned future, yet | ||
| 103 | let dma_future = tx.dma_push(dma_ref.reborrow(), front_buffer); | ||
| 104 | |||
| 105 | // fade in audio when bootsel is pressed | ||
| 106 | let fade_target = if p.BOOTSEL.is_pressed() { i32::MAX } else { 0 }; | ||
| 107 | |||
| 108 | // fill back buffer with fresh audio samples before awaiting the dma future | ||
| 109 | for s in back_buffer.iter_mut() { | ||
| 110 | // exponential approach of fade_value => fade_target | ||
| 111 | fade_value += (fade_target - fade_value) >> 14; | ||
| 112 | // generate triangle wave with amplitude and frequency based on fade value | ||
| 113 | phase = (phase + (fade_value >> 22)) & 0xffff; | ||
| 114 | let triangle_sample = (phase as i16 as i32).abs() - 16384; | ||
| 115 | let sample = (triangle_sample * (fade_value >> 15)) >> 16; | ||
| 116 | // duplicate mono sample into lower and upper half of dma word | ||
| 117 | *s = (sample as u16 as u32) * 0x10001; | ||
| 118 | } | ||
| 119 | |||
| 120 | // now await the dma future. once the dma finishes, the next buffer needs to be queued | ||
| 121 | // within DMA_DEPTH / SAMPLE_RATE = 8 / 48000 seconds = 166us | ||
| 122 | dma_future.await; | ||
| 123 | mem::swap(&mut back_buffer, &mut front_buffer); | ||
| 124 | } | ||
| 125 | } | ||
diff --git a/examples/rp/src/bin/pio_ws2812.rs b/examples/rp/src/bin/pio_ws2812.rs index 9a97cb8a7..ac145933c 100644 --- a/examples/rp/src/bin/pio_ws2812.rs +++ b/examples/rp/src/bin/pio_ws2812.rs | |||
| @@ -12,7 +12,7 @@ use embassy_rp::pio::{ | |||
| 12 | Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine, | 12 | Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine, |
| 13 | }; | 13 | }; |
| 14 | use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef}; | 14 | use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef}; |
| 15 | use embassy_time::Timer; | 15 | use embassy_time::{Duration, Ticker, Timer}; |
| 16 | use fixed::types::U24F8; | 16 | use fixed::types::U24F8; |
| 17 | use fixed_macro::fixed; | 17 | use fixed_macro::fixed; |
| 18 | use smart_leds::RGB8; | 18 | use smart_leds::RGB8; |
| @@ -107,6 +107,8 @@ impl<'d, P: Instance, const S: usize, const N: usize> Ws2812<'d, P, S, N> { | |||
| 107 | 107 | ||
| 108 | // DMA transfer | 108 | // DMA transfer |
| 109 | self.sm.tx().dma_push(self.dma.reborrow(), &words).await; | 109 | self.sm.tx().dma_push(self.dma.reborrow(), &words).await; |
| 110 | |||
| 111 | Timer::after_micros(55).await; | ||
| 110 | } | 112 | } |
| 111 | } | 113 | } |
| 112 | 114 | ||
| @@ -143,6 +145,7 @@ async fn main(_spawner: Spawner) { | |||
| 143 | let mut ws2812 = Ws2812::new(&mut common, sm0, p.DMA_CH0, p.PIN_16); | 145 | let mut ws2812 = Ws2812::new(&mut common, sm0, p.DMA_CH0, p.PIN_16); |
| 144 | 146 | ||
| 145 | // Loop forever making RGB values and pushing them out to the WS2812. | 147 | // Loop forever making RGB values and pushing them out to the WS2812. |
| 148 | let mut ticker = Ticker::every(Duration::from_millis(10)); | ||
| 146 | loop { | 149 | loop { |
| 147 | for j in 0..(256 * 5) { | 150 | for j in 0..(256 * 5) { |
| 148 | debug!("New Colors:"); | 151 | debug!("New Colors:"); |
| @@ -152,7 +155,7 @@ async fn main(_spawner: Spawner) { | |||
| 152 | } | 155 | } |
| 153 | ws2812.write(&data).await; | 156 | ws2812.write(&data).await; |
| 154 | 157 | ||
| 155 | Timer::after_millis(10).await; | 158 | ticker.next().await; |
| 156 | } | 159 | } |
| 157 | } | 160 | } |
| 158 | } | 161 | } |
diff --git a/examples/rp/src/bin/usb_hid_mouse.rs b/examples/rp/src/bin/usb_hid_mouse.rs new file mode 100644 index 000000000..afebd8813 --- /dev/null +++ b/examples/rp/src/bin/usb_hid_mouse.rs | |||
| @@ -0,0 +1,182 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use core::sync::atomic::{AtomicBool, Ordering}; | ||
| 5 | |||
| 6 | use defmt::*; | ||
| 7 | use embassy_executor::Spawner; | ||
| 8 | use embassy_futures::join::join; | ||
| 9 | use embassy_rp::bind_interrupts; | ||
| 10 | use embassy_rp::clocks::RoscRng; | ||
| 11 | use embassy_rp::gpio::{Input, Pull}; | ||
| 12 | use embassy_rp::peripherals::USB; | ||
| 13 | use embassy_rp::usb::{Driver, InterruptHandler}; | ||
| 14 | use embassy_time::Timer; | ||
| 15 | use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; | ||
| 16 | use embassy_usb::control::OutResponse; | ||
| 17 | use embassy_usb::{Builder, Config, Handler}; | ||
| 18 | use rand::Rng; | ||
| 19 | use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; | ||
| 20 | use {defmt_rtt as _, panic_probe as _}; | ||
| 21 | |||
| 22 | bind_interrupts!(struct Irqs { | ||
| 23 | USBCTRL_IRQ => InterruptHandler<USB>; | ||
| 24 | }); | ||
| 25 | |||
| 26 | #[embassy_executor::main] | ||
| 27 | async fn main(_spawner: Spawner) { | ||
| 28 | let p = embassy_rp::init(Default::default()); | ||
| 29 | // Create the driver, from the HAL. | ||
| 30 | let driver = Driver::new(p.USB, Irqs); | ||
| 31 | |||
| 32 | // Create embassy-usb Config | ||
| 33 | let mut config = Config::new(0xc0de, 0xcafe); | ||
| 34 | config.manufacturer = Some("Embassy"); | ||
| 35 | config.product = Some("HID keyboard example"); | ||
| 36 | config.serial_number = Some("12345678"); | ||
| 37 | config.max_power = 100; | ||
| 38 | config.max_packet_size_0 = 64; | ||
| 39 | |||
| 40 | // Create embassy-usb DeviceBuilder using the driver and config. | ||
| 41 | // It needs some buffers for building the descriptors. | ||
| 42 | let mut device_descriptor = [0; 256]; | ||
| 43 | let mut config_descriptor = [0; 256]; | ||
| 44 | let mut bos_descriptor = [0; 256]; | ||
| 45 | // You can also add a Microsoft OS descriptor. | ||
| 46 | let mut msos_descriptor = [0; 256]; | ||
| 47 | let mut control_buf = [0; 64]; | ||
| 48 | let request_handler = MyRequestHandler {}; | ||
| 49 | let mut device_handler = MyDeviceHandler::new(); | ||
| 50 | |||
| 51 | let mut state = State::new(); | ||
| 52 | |||
| 53 | let mut builder = Builder::new( | ||
| 54 | driver, | ||
| 55 | config, | ||
| 56 | &mut device_descriptor, | ||
| 57 | &mut config_descriptor, | ||
| 58 | &mut bos_descriptor, | ||
| 59 | &mut msos_descriptor, | ||
| 60 | &mut control_buf, | ||
| 61 | ); | ||
| 62 | |||
| 63 | builder.handler(&mut device_handler); | ||
| 64 | |||
| 65 | // Create classes on the builder. | ||
| 66 | let config = embassy_usb::class::hid::Config { | ||
| 67 | report_descriptor: MouseReport::desc(), | ||
| 68 | request_handler: Some(&request_handler), | ||
| 69 | poll_ms: 60, | ||
| 70 | max_packet_size: 64, | ||
| 71 | }; | ||
| 72 | let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config); | ||
| 73 | |||
| 74 | // Build the builder. | ||
| 75 | let mut usb = builder.build(); | ||
| 76 | |||
| 77 | // Run the USB device. | ||
| 78 | let usb_fut = usb.run(); | ||
| 79 | |||
| 80 | // Set up the signal pin that will be used to trigger the keyboard. | ||
| 81 | let mut signal_pin = Input::new(p.PIN_16, Pull::None); | ||
| 82 | |||
| 83 | // Enable the schmitt trigger to slightly debounce. | ||
| 84 | signal_pin.set_schmitt(true); | ||
| 85 | |||
| 86 | let (reader, mut writer) = hid.split(); | ||
| 87 | |||
| 88 | // Do stuff with the class! | ||
| 89 | let in_fut = async { | ||
| 90 | let mut rng = RoscRng; | ||
| 91 | |||
| 92 | loop { | ||
| 93 | // every 1 second | ||
| 94 | _ = Timer::after_secs(1).await; | ||
| 95 | let report = MouseReport { | ||
| 96 | buttons: 0, | ||
| 97 | x: rng.gen_range(-100..100), // random small x movement | ||
| 98 | y: rng.gen_range(-100..100), // random small y movement | ||
| 99 | wheel: 0, | ||
| 100 | pan: 0, | ||
| 101 | }; | ||
| 102 | // Send the report. | ||
| 103 | match writer.write_serialize(&report).await { | ||
| 104 | Ok(()) => {} | ||
| 105 | Err(e) => warn!("Failed to send report: {:?}", e), | ||
| 106 | } | ||
| 107 | } | ||
| 108 | }; | ||
| 109 | |||
| 110 | let out_fut = async { | ||
| 111 | reader.run(false, &request_handler).await; | ||
| 112 | }; | ||
| 113 | |||
| 114 | // Run everything concurrently. | ||
| 115 | // If we had made everything `'static` above instead, we could do this using separate tasks instead. | ||
| 116 | join(usb_fut, join(in_fut, out_fut)).await; | ||
| 117 | } | ||
| 118 | |||
| 119 | struct MyRequestHandler {} | ||
| 120 | |||
| 121 | impl RequestHandler for MyRequestHandler { | ||
| 122 | fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { | ||
| 123 | info!("Get report for {:?}", id); | ||
| 124 | None | ||
| 125 | } | ||
| 126 | |||
| 127 | fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { | ||
| 128 | info!("Set report for {:?}: {=[u8]}", id, data); | ||
| 129 | OutResponse::Accepted | ||
| 130 | } | ||
| 131 | |||
| 132 | fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { | ||
| 133 | info!("Set idle rate for {:?} to {:?}", id, dur); | ||
| 134 | } | ||
| 135 | |||
| 136 | fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { | ||
| 137 | info!("Get idle rate for {:?}", id); | ||
| 138 | None | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | struct MyDeviceHandler { | ||
| 143 | configured: AtomicBool, | ||
| 144 | } | ||
| 145 | |||
| 146 | impl MyDeviceHandler { | ||
| 147 | fn new() -> Self { | ||
| 148 | MyDeviceHandler { | ||
| 149 | configured: AtomicBool::new(false), | ||
| 150 | } | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 154 | impl Handler for MyDeviceHandler { | ||
| 155 | fn enabled(&mut self, enabled: bool) { | ||
| 156 | self.configured.store(false, Ordering::Relaxed); | ||
| 157 | if enabled { | ||
| 158 | info!("Device enabled"); | ||
| 159 | } else { | ||
| 160 | info!("Device disabled"); | ||
| 161 | } | ||
| 162 | } | ||
| 163 | |||
| 164 | fn reset(&mut self) { | ||
| 165 | self.configured.store(false, Ordering::Relaxed); | ||
| 166 | info!("Bus reset, the Vbus current limit is 100mA"); | ||
| 167 | } | ||
| 168 | |||
| 169 | fn addressed(&mut self, addr: u8) { | ||
| 170 | self.configured.store(false, Ordering::Relaxed); | ||
| 171 | info!("USB address set to: {}", addr); | ||
| 172 | } | ||
| 173 | |||
| 174 | fn configured(&mut self, configured: bool) { | ||
| 175 | self.configured.store(configured, Ordering::Relaxed); | ||
| 176 | if configured { | ||
| 177 | info!("Device configured, it may now draw up to the configured current limit from Vbus.") | ||
| 178 | } else { | ||
| 179 | info!("Device is no longer configured, the Vbus current limit is 100mA."); | ||
| 180 | } | ||
| 181 | } | ||
| 182 | } | ||
diff --git a/examples/rp/src/bin/usb_serial_with_logger.rs b/examples/rp/src/bin/usb_serial_with_logger.rs new file mode 100644 index 000000000..4ba4fc25c --- /dev/null +++ b/examples/rp/src/bin/usb_serial_with_logger.rs | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | //! This example shows how to use USB (Universal Serial Bus) in the RP2040 chip as well as how to create multiple usb classes for one device | ||
| 2 | //! | ||
| 3 | //! This creates a USB serial port that echos. It will also print out logging information on a separate serial device | ||
| 4 | |||
| 5 | #![no_std] | ||
| 6 | #![no_main] | ||
| 7 | |||
| 8 | use defmt::{info, panic}; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_futures::join::join; | ||
| 11 | use embassy_rp::bind_interrupts; | ||
| 12 | use embassy_rp::peripherals::USB; | ||
| 13 | use embassy_rp::usb::{Driver, Instance, InterruptHandler}; | ||
| 14 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | ||
| 15 | use embassy_usb::driver::EndpointError; | ||
| 16 | use embassy_usb::{Builder, Config}; | ||
| 17 | use {defmt_rtt as _, panic_probe as _}; | ||
| 18 | |||
| 19 | bind_interrupts!(struct Irqs { | ||
| 20 | USBCTRL_IRQ => InterruptHandler<USB>; | ||
| 21 | }); | ||
| 22 | |||
| 23 | #[embassy_executor::main] | ||
| 24 | async fn main(_spawner: Spawner) { | ||
| 25 | info!("Hello there!"); | ||
| 26 | |||
| 27 | let p = embassy_rp::init(Default::default()); | ||
| 28 | |||
| 29 | // Create the driver, from the HAL. | ||
| 30 | let driver = Driver::new(p.USB, Irqs); | ||
| 31 | |||
| 32 | // Create embassy-usb Config | ||
| 33 | let mut config = Config::new(0xc0de, 0xcafe); | ||
| 34 | config.manufacturer = Some("Embassy"); | ||
| 35 | config.product = Some("USB-serial example"); | ||
| 36 | config.serial_number = Some("12345678"); | ||
| 37 | config.max_power = 100; | ||
| 38 | config.max_packet_size_0 = 64; | ||
| 39 | |||
| 40 | // Required for windows compatibility. | ||
| 41 | // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help | ||
| 42 | config.device_class = 0xEF; | ||
| 43 | config.device_sub_class = 0x02; | ||
| 44 | config.device_protocol = 0x01; | ||
| 45 | config.composite_with_iads = true; | ||
| 46 | |||
| 47 | // Create embassy-usb DeviceBuilder using the driver and config. | ||
| 48 | // It needs some buffers for building the descriptors. | ||
| 49 | let mut device_descriptor = [0; 256]; | ||
| 50 | let mut config_descriptor = [0; 256]; | ||
| 51 | let mut bos_descriptor = [0; 256]; | ||
| 52 | let mut control_buf = [0; 64]; | ||
| 53 | |||
| 54 | let mut state = State::new(); | ||
| 55 | let mut logger_state = State::new(); | ||
| 56 | |||
| 57 | let mut builder = Builder::new( | ||
| 58 | driver, | ||
| 59 | config, | ||
| 60 | &mut device_descriptor, | ||
| 61 | &mut config_descriptor, | ||
| 62 | &mut bos_descriptor, | ||
| 63 | &mut [], // no msos descriptors | ||
| 64 | &mut control_buf, | ||
| 65 | ); | ||
| 66 | |||
| 67 | // Create classes on the builder. | ||
| 68 | let mut class = CdcAcmClass::new(&mut builder, &mut state, 64); | ||
| 69 | |||
| 70 | // Create a class for the logger | ||
| 71 | let logger_class = CdcAcmClass::new(&mut builder, &mut logger_state, 64); | ||
| 72 | |||
| 73 | // Creates the logger and returns the logger future | ||
| 74 | // Note: You'll need to use log::info! afterwards instead of info! for this to work (this also applies to all the other log::* macros) | ||
| 75 | let log_fut = embassy_usb_logger::with_class!(1024, log::LevelFilter::Info, logger_class); | ||
| 76 | |||
| 77 | // Build the builder. | ||
| 78 | let mut usb = builder.build(); | ||
| 79 | |||
| 80 | // Run the USB device. | ||
| 81 | let usb_fut = usb.run(); | ||
| 82 | |||
| 83 | // Do stuff with the class! | ||
| 84 | let echo_fut = async { | ||
| 85 | loop { | ||
| 86 | class.wait_connection().await; | ||
| 87 | log::info!("Connected"); | ||
| 88 | let _ = echo(&mut class).await; | ||
| 89 | log::info!("Disconnected"); | ||
| 90 | } | ||
| 91 | }; | ||
| 92 | |||
| 93 | // Run everything concurrently. | ||
| 94 | // If we had made everything `'static` above instead, we could do this using separate tasks instead. | ||
| 95 | join(usb_fut, join(echo_fut, log_fut)).await; | ||
| 96 | } | ||
| 97 | |||
| 98 | struct Disconnected {} | ||
| 99 | |||
| 100 | impl From<EndpointError> for Disconnected { | ||
| 101 | fn from(val: EndpointError) -> Self { | ||
| 102 | match val { | ||
| 103 | EndpointError::BufferOverflow => panic!("Buffer overflow"), | ||
| 104 | EndpointError::Disabled => Disconnected {}, | ||
| 105 | } | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | async fn echo<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> { | ||
| 110 | let mut buf = [0; 64]; | ||
| 111 | loop { | ||
| 112 | let n = class.read_packet(&mut buf).await?; | ||
| 113 | let data = &buf[..n]; | ||
| 114 | info!("data: {:x}", data); | ||
| 115 | class.write_packet(data).await?; | ||
| 116 | } | ||
| 117 | } | ||
diff --git a/examples/rp/src/bin/wifi_ap_tcp_server.rs b/examples/rp/src/bin/wifi_ap_tcp_server.rs index 1bd75607e..b60852359 100644 --- a/examples/rp/src/bin/wifi_ap_tcp_server.rs +++ b/examples/rp/src/bin/wifi_ap_tcp_server.rs | |||
| @@ -14,7 +14,7 @@ use embassy_net::tcp::TcpSocket; | |||
| 14 | use embassy_net::{Config, Stack, StackResources}; | 14 | use embassy_net::{Config, Stack, StackResources}; |
| 15 | use embassy_rp::bind_interrupts; | 15 | use embassy_rp::bind_interrupts; |
| 16 | use embassy_rp::gpio::{Level, Output}; | 16 | use embassy_rp::gpio::{Level, Output}; |
| 17 | use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | 17 | use embassy_rp::peripherals::{DMA_CH0, PIO0}; |
| 18 | use embassy_rp::pio::{InterruptHandler, Pio}; | 18 | use embassy_rp::pio::{InterruptHandler, Pio}; |
| 19 | use embassy_time::Duration; | 19 | use embassy_time::Duration; |
| 20 | use embedded_io_async::Write; | 20 | use embedded_io_async::Write; |
| @@ -26,9 +26,7 @@ bind_interrupts!(struct Irqs { | |||
| 26 | }); | 26 | }); |
| 27 | 27 | ||
| 28 | #[embassy_executor::task] | 28 | #[embassy_executor::task] |
| 29 | async fn wifi_task( | 29 | async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>) -> ! { |
| 30 | runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>, | ||
| 31 | ) -> ! { | ||
| 32 | runner.run().await | 30 | runner.run().await |
| 33 | } | 31 | } |
| 34 | 32 | ||
diff --git a/examples/rp/src/bin/wifi_blinky.rs b/examples/rp/src/bin/wifi_blinky.rs index 1ed74993c..18eefe41f 100644 --- a/examples/rp/src/bin/wifi_blinky.rs +++ b/examples/rp/src/bin/wifi_blinky.rs | |||
| @@ -10,7 +10,7 @@ use defmt::*; | |||
| 10 | use embassy_executor::Spawner; | 10 | use embassy_executor::Spawner; |
| 11 | use embassy_rp::bind_interrupts; | 11 | use embassy_rp::bind_interrupts; |
| 12 | use embassy_rp::gpio::{Level, Output}; | 12 | use embassy_rp::gpio::{Level, Output}; |
| 13 | use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | 13 | use embassy_rp::peripherals::{DMA_CH0, PIO0}; |
| 14 | use embassy_rp::pio::{InterruptHandler, Pio}; | 14 | use embassy_rp::pio::{InterruptHandler, Pio}; |
| 15 | use embassy_time::{Duration, Timer}; | 15 | use embassy_time::{Duration, Timer}; |
| 16 | use static_cell::StaticCell; | 16 | use static_cell::StaticCell; |
| @@ -21,9 +21,7 @@ bind_interrupts!(struct Irqs { | |||
| 21 | }); | 21 | }); |
| 22 | 22 | ||
| 23 | #[embassy_executor::task] | 23 | #[embassy_executor::task] |
| 24 | async fn wifi_task( | 24 | async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>) -> ! { |
| 25 | runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>, | ||
| 26 | ) -> ! { | ||
| 27 | runner.run().await | 25 | runner.run().await |
| 28 | } | 26 | } |
| 29 | 27 | ||
diff --git a/examples/rp/src/bin/wifi_scan.rs b/examples/rp/src/bin/wifi_scan.rs index 45bb5b76c..e0f85a6b0 100644 --- a/examples/rp/src/bin/wifi_scan.rs +++ b/examples/rp/src/bin/wifi_scan.rs | |||
| @@ -13,7 +13,7 @@ use embassy_executor::Spawner; | |||
| 13 | use embassy_net::Stack; | 13 | use embassy_net::Stack; |
| 14 | use embassy_rp::bind_interrupts; | 14 | use embassy_rp::bind_interrupts; |
| 15 | use embassy_rp::gpio::{Level, Output}; | 15 | use embassy_rp::gpio::{Level, Output}; |
| 16 | use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | 16 | use embassy_rp::peripherals::{DMA_CH0, PIO0}; |
| 17 | use embassy_rp::pio::{InterruptHandler, Pio}; | 17 | use embassy_rp::pio::{InterruptHandler, Pio}; |
| 18 | use static_cell::StaticCell; | 18 | use static_cell::StaticCell; |
| 19 | use {defmt_rtt as _, panic_probe as _}; | 19 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -23,9 +23,7 @@ bind_interrupts!(struct Irqs { | |||
| 23 | }); | 23 | }); |
| 24 | 24 | ||
| 25 | #[embassy_executor::task] | 25 | #[embassy_executor::task] |
| 26 | async fn wifi_task( | 26 | async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>) -> ! { |
| 27 | runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>, | ||
| 28 | ) -> ! { | ||
| 29 | runner.run().await | 27 | runner.run().await |
| 30 | } | 28 | } |
| 31 | 29 | ||
| @@ -65,7 +63,7 @@ async fn main(spawner: Spawner) { | |||
| 65 | .set_power_management(cyw43::PowerManagementMode::PowerSave) | 63 | .set_power_management(cyw43::PowerManagementMode::PowerSave) |
| 66 | .await; | 64 | .await; |
| 67 | 65 | ||
| 68 | let mut scanner = control.scan().await; | 66 | let mut scanner = control.scan(Default::default()).await; |
| 69 | while let Some(bss) = scanner.next().await { | 67 | while let Some(bss) = scanner.next().await { |
| 70 | if let Ok(ssid_str) = str::from_utf8(&bss.ssid) { | 68 | if let Ok(ssid_str) = str::from_utf8(&bss.ssid) { |
| 71 | info!("scanned {} == {:x}", ssid_str, bss.bssid); | 69 | info!("scanned {} == {:x}", ssid_str, bss.bssid); |
diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs index c346f1ded..f1afc4a00 100644 --- a/examples/rp/src/bin/wifi_tcp_server.rs +++ b/examples/rp/src/bin/wifi_tcp_server.rs | |||
| @@ -14,7 +14,7 @@ use embassy_net::tcp::TcpSocket; | |||
| 14 | use embassy_net::{Config, Stack, StackResources}; | 14 | use embassy_net::{Config, Stack, StackResources}; |
| 15 | use embassy_rp::bind_interrupts; | 15 | use embassy_rp::bind_interrupts; |
| 16 | use embassy_rp::gpio::{Level, Output}; | 16 | use embassy_rp::gpio::{Level, Output}; |
| 17 | use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | 17 | use embassy_rp::peripherals::{DMA_CH0, PIO0}; |
| 18 | use embassy_rp::pio::{InterruptHandler, Pio}; | 18 | use embassy_rp::pio::{InterruptHandler, Pio}; |
| 19 | use embassy_time::{Duration, Timer}; | 19 | use embassy_time::{Duration, Timer}; |
| 20 | use embedded_io_async::Write; | 20 | use embedded_io_async::Write; |
| @@ -29,9 +29,7 @@ const WIFI_NETWORK: &str = "EmbassyTest"; | |||
| 29 | const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; | 29 | const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; |
| 30 | 30 | ||
| 31 | #[embassy_executor::task] | 31 | #[embassy_executor::task] |
| 32 | async fn wifi_task( | 32 | async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>) -> ! { |
| 33 | runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>, | ||
| 34 | ) -> ! { | ||
| 35 | runner.run().await | 33 | runner.run().await |
| 36 | } | 34 | } |
| 37 | 35 | ||
diff --git a/examples/std/README.md b/examples/std/README.md index adc795928..e3a59d6ea 100644 --- a/examples/std/README.md +++ b/examples/std/README.md | |||
| @@ -13,11 +13,11 @@ sudo ip -6 route add fe80::/64 dev tap0 | |||
| 13 | sudo ip -6 route add fdaa::/64 dev tap0 | 13 | sudo ip -6 route add fdaa::/64 dev tap0 |
| 14 | ``` | 14 | ``` |
| 15 | 15 | ||
| 16 | Second, have something listening there. For example `nc -l 8000` | 16 | Second, have something listening there. For example `nc -lp 8000` |
| 17 | 17 | ||
| 18 | Then run the example located in the `examples` folder: | 18 | Then run the example located in the `examples` folder: |
| 19 | 19 | ||
| 20 | ```sh | 20 | ```sh |
| 21 | cd $EMBASSY_ROOT/examples/std/ | 21 | cd $EMBASSY_ROOT/examples/std/ |
| 22 | cargo run --bin net -- --static-ip | 22 | cargo run --bin net -- --static-ip |
| 23 | ``` \ No newline at end of file | 23 | ``` |
diff --git a/examples/stm32c0/src/bin/button_exti.rs b/examples/stm32c0/src/bin/button_exti.rs index 1e970fdd6..34a08bbc6 100644 --- a/examples/stm32c0/src/bin/button_exti.rs +++ b/examples/stm32c0/src/bin/button_exti.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::exti::ExtiInput; | 6 | use embassy_stm32::exti::ExtiInput; |
| 7 | use embassy_stm32::gpio::{Input, Pull}; | 7 | use embassy_stm32::gpio::Pull; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -12,8 +12,7 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let button = Input::new(p.PC13, Pull::Up); | 15 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); |
| 16 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 17 | 16 | ||
| 18 | info!("Press the USER button..."); | 17 | info!("Press the USER button..."); |
| 19 | 18 | ||
diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml index 71b0eb683..c74980dc4 100644 --- a/examples/stm32f0/Cargo.toml +++ b/examples/stm32f0/Cargo.toml | |||
| @@ -13,7 +13,7 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 13 | cortex-m-rt = "0.7.0" | 13 | cortex-m-rt = "0.7.0" |
| 14 | defmt = "0.3" | 14 | defmt = "0.3" |
| 15 | defmt-rtt = "0.4" | 15 | defmt-rtt = "0.4" |
| 16 | panic-probe = "0.3" | 16 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 17 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 17 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } |
| 18 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } | 18 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } |
| 19 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 19 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
diff --git a/examples/stm32f0/src/bin/adc.rs b/examples/stm32f0/src/bin/adc.rs index 8fef062b3..c2fb143cd 100644 --- a/examples/stm32f0/src/bin/adc.rs +++ b/examples/stm32f0/src/bin/adc.rs | |||
| @@ -19,7 +19,7 @@ async fn main(_spawner: Spawner) { | |||
| 19 | info!("Hello World!"); | 19 | info!("Hello World!"); |
| 20 | 20 | ||
| 21 | let mut adc = Adc::new(p.ADC, Irqs, &mut Delay); | 21 | let mut adc = Adc::new(p.ADC, Irqs, &mut Delay); |
| 22 | adc.set_sample_time(SampleTime::Cycles71_5); | 22 | adc.set_sample_time(SampleTime::CYCLES71_5); |
| 23 | let mut pin = p.PA1; | 23 | let mut pin = p.PA1; |
| 24 | 24 | ||
| 25 | let mut vrefint = adc.enable_vref(&mut Delay); | 25 | let mut vrefint = adc.enable_vref(&mut Delay); |
diff --git a/examples/stm32f0/src/bin/button_controlled_blink.rs b/examples/stm32f0/src/bin/button_controlled_blink.rs index 360d153c3..4465483d9 100644 --- a/examples/stm32f0/src/bin/button_controlled_blink.rs +++ b/examples/stm32f0/src/bin/button_controlled_blink.rs | |||
| @@ -8,7 +8,7 @@ use core::sync::atomic::{AtomicU32, Ordering}; | |||
| 8 | use defmt::info; | 8 | use defmt::info; |
| 9 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 10 | use embassy_stm32::exti::ExtiInput; | 10 | use embassy_stm32::exti::ExtiInput; |
| 11 | use embassy_stm32::gpio::{AnyPin, Input, Level, Output, Pin, Pull, Speed}; | 11 | use embassy_stm32::gpio::{AnyPin, Level, Output, Pin, Pull, Speed}; |
| 12 | use embassy_time::Timer; | 12 | use embassy_time::Timer; |
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 14 | ||
| @@ -36,8 +36,7 @@ async fn main(spawner: Spawner) { | |||
| 36 | 36 | ||
| 37 | // Configure the button pin and obtain handler. | 37 | // Configure the button pin and obtain handler. |
| 38 | // On the Nucleo F091RC there is a button connected to pin PC13. | 38 | // On the Nucleo F091RC there is a button connected to pin PC13. |
| 39 | let button = Input::new(p.PC13, Pull::None); | 39 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::None); |
| 40 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 41 | 40 | ||
| 42 | // Create and initialize a delay variable to manage delay loop | 41 | // Create and initialize a delay variable to manage delay loop |
| 43 | let mut del_var = 2000; | 42 | let mut del_var = 2000; |
diff --git a/examples/stm32f0/src/bin/button_exti.rs b/examples/stm32f0/src/bin/button_exti.rs index ce17c1a48..fd615a215 100644 --- a/examples/stm32f0/src/bin/button_exti.rs +++ b/examples/stm32f0/src/bin/button_exti.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::exti::ExtiInput; | 6 | use embassy_stm32::exti::ExtiInput; |
| 7 | use embassy_stm32::gpio::{Input, Pull}; | 7 | use embassy_stm32::gpio::Pull; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -13,8 +13,7 @@ async fn main(_spawner: Spawner) { | |||
| 13 | let p = embassy_stm32::init(Default::default()); | 13 | let p = embassy_stm32::init(Default::default()); |
| 14 | // Configure the button pin and obtain handler. | 14 | // Configure the button pin and obtain handler. |
| 15 | // On the Nucleo F091RC there is a button connected to pin PC13. | 15 | // On the Nucleo F091RC there is a button connected to pin PC13. |
| 16 | let button = Input::new(p.PC13, Pull::Down); | 16 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); |
| 17 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 18 | 17 | ||
| 19 | info!("Press the USER button..."); | 18 | info!("Press the USER button..."); |
| 20 | loop { | 19 | loop { |
diff --git a/examples/stm32f1/src/bin/hello.rs b/examples/stm32f1/src/bin/hello.rs index 7b761ecc1..3c295612c 100644 --- a/examples/stm32f1/src/bin/hello.rs +++ b/examples/stm32f1/src/bin/hello.rs | |||
| @@ -3,15 +3,13 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::info; | 4 | use defmt::info; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::time::Hertz; | ||
| 7 | use embassy_stm32::Config; | 6 | use embassy_stm32::Config; |
| 8 | use embassy_time::Timer; | 7 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 9 | ||
| 11 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| 12 | async fn main(_spawner: Spawner) -> ! { | 11 | async fn main(_spawner: Spawner) -> ! { |
| 13 | let mut config = Config::default(); | 12 | let config = Config::default(); |
| 14 | config.rcc.sys_ck = Some(Hertz(36_000_000)); | ||
| 15 | let _p = embassy_stm32::init(config); | 13 | let _p = embassy_stm32::init(config); |
| 16 | 14 | ||
| 17 | loop { | 15 | loop { |
diff --git a/examples/stm32f1/src/bin/usb_serial.rs b/examples/stm32f1/src/bin/usb_serial.rs index e28381893..1ae6c1dee 100644 --- a/examples/stm32f1/src/bin/usb_serial.rs +++ b/examples/stm32f1/src/bin/usb_serial.rs | |||
| @@ -21,9 +21,23 @@ bind_interrupts!(struct Irqs { | |||
| 21 | #[embassy_executor::main] | 21 | #[embassy_executor::main] |
| 22 | async fn main(_spawner: Spawner) { | 22 | async fn main(_spawner: Spawner) { |
| 23 | let mut config = Config::default(); | 23 | let mut config = Config::default(); |
| 24 | config.rcc.hse = Some(Hertz(8_000_000)); | 24 | { |
| 25 | config.rcc.sys_ck = Some(Hertz(48_000_000)); | 25 | use embassy_stm32::rcc::*; |
| 26 | config.rcc.pclk1 = Some(Hertz(24_000_000)); | 26 | config.rcc.hse = Some(Hse { |
| 27 | freq: Hertz(8_000_000), | ||
| 28 | // Oscillator for bluepill, Bypass for nucleos. | ||
| 29 | mode: HseMode::Oscillator, | ||
| 30 | }); | ||
| 31 | config.rcc.pll = Some(Pll { | ||
| 32 | src: PllSource::HSE, | ||
| 33 | prediv: PllPreDiv::DIV1, | ||
| 34 | mul: PllMul::MUL9, | ||
| 35 | }); | ||
| 36 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 37 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 38 | config.rcc.apb1_pre = APBPrescaler::DIV2; | ||
| 39 | config.rcc.apb2_pre = APBPrescaler::DIV1; | ||
| 40 | } | ||
| 27 | let mut p = embassy_stm32::init(config); | 41 | let mut p = embassy_stm32::init(config); |
| 28 | 42 | ||
| 29 | info!("Hello World!"); | 43 | info!("Hello World!"); |
diff --git a/examples/stm32f3/src/bin/button_events.rs b/examples/stm32f3/src/bin/button_events.rs index 2f7da4ef5..f5ed5d2c9 100644 --- a/examples/stm32f3/src/bin/button_events.rs +++ b/examples/stm32f3/src/bin/button_events.rs | |||
| @@ -12,21 +12,20 @@ | |||
| 12 | use defmt::*; | 12 | use defmt::*; |
| 13 | use embassy_executor::Spawner; | 13 | use embassy_executor::Spawner; |
| 14 | use embassy_stm32::exti::ExtiInput; | 14 | use embassy_stm32::exti::ExtiInput; |
| 15 | use embassy_stm32::gpio::{AnyPin, Input, Level, Output, Pin, Pull, Speed}; | 15 | use embassy_stm32::gpio::{Level, Output, Pull, Speed}; |
| 16 | use embassy_stm32::peripherals::PA0; | ||
| 17 | use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; | 16 | use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; |
| 18 | use embassy_sync::channel::Channel; | 17 | use embassy_sync::channel::Channel; |
| 19 | use embassy_time::{with_timeout, Duration, Timer}; | 18 | use embassy_time::{with_timeout, Duration, Timer}; |
| 20 | use {defmt_rtt as _, panic_probe as _}; | 19 | use {defmt_rtt as _, panic_probe as _}; |
| 21 | 20 | ||
| 22 | struct Leds<'a> { | 21 | struct Leds<'a> { |
| 23 | leds: [Output<'a, AnyPin>; 8], | 22 | leds: [Output<'a>; 8], |
| 24 | direction: i8, | 23 | direction: i8, |
| 25 | current_led: usize, | 24 | current_led: usize, |
| 26 | } | 25 | } |
| 27 | 26 | ||
| 28 | impl<'a> Leds<'a> { | 27 | impl<'a> Leds<'a> { |
| 29 | fn new(pins: [Output<'a, AnyPin>; 8]) -> Self { | 28 | fn new(pins: [Output<'a>; 8]) -> Self { |
| 30 | Self { | 29 | Self { |
| 31 | leds: pins, | 30 | leds: pins, |
| 32 | direction: 1, | 31 | direction: 1, |
| @@ -100,18 +99,17 @@ static CHANNEL: Channel<ThreadModeRawMutex, ButtonEvent, 4> = Channel::new(); | |||
| 100 | #[embassy_executor::main] | 99 | #[embassy_executor::main] |
| 101 | async fn main(spawner: Spawner) { | 100 | async fn main(spawner: Spawner) { |
| 102 | let p = embassy_stm32::init(Default::default()); | 101 | let p = embassy_stm32::init(Default::default()); |
| 103 | let button = Input::new(p.PA0, Pull::Down); | 102 | let button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Down); |
| 104 | let button = ExtiInput::new(button, p.EXTI0); | ||
| 105 | info!("Press the USER button..."); | 103 | info!("Press the USER button..."); |
| 106 | let leds = [ | 104 | let leds = [ |
| 107 | Output::new(p.PE9.degrade(), Level::Low, Speed::Low), | 105 | Output::new(p.PE9, Level::Low, Speed::Low), |
| 108 | Output::new(p.PE10.degrade(), Level::Low, Speed::Low), | 106 | Output::new(p.PE10, Level::Low, Speed::Low), |
| 109 | Output::new(p.PE11.degrade(), Level::Low, Speed::Low), | 107 | Output::new(p.PE11, Level::Low, Speed::Low), |
| 110 | Output::new(p.PE12.degrade(), Level::Low, Speed::Low), | 108 | Output::new(p.PE12, Level::Low, Speed::Low), |
| 111 | Output::new(p.PE13.degrade(), Level::Low, Speed::Low), | 109 | Output::new(p.PE13, Level::Low, Speed::Low), |
| 112 | Output::new(p.PE14.degrade(), Level::Low, Speed::Low), | 110 | Output::new(p.PE14, Level::Low, Speed::Low), |
| 113 | Output::new(p.PE15.degrade(), Level::Low, Speed::Low), | 111 | Output::new(p.PE15, Level::Low, Speed::Low), |
| 114 | Output::new(p.PE8.degrade(), Level::Low, Speed::Low), | 112 | Output::new(p.PE8, Level::Low, Speed::Low), |
| 115 | ]; | 113 | ]; |
| 116 | let leds = Leds::new(leds); | 114 | let leds = Leds::new(leds); |
| 117 | 115 | ||
| @@ -127,7 +125,7 @@ async fn led_blinker(mut leds: Leds<'static>) { | |||
| 127 | } | 125 | } |
| 128 | 126 | ||
| 129 | #[embassy_executor::task] | 127 | #[embassy_executor::task] |
| 130 | async fn button_waiter(mut button: ExtiInput<'static, PA0>) { | 128 | async fn button_waiter(mut button: ExtiInput<'static>) { |
| 131 | const DOUBLE_CLICK_DELAY: u64 = 250; | 129 | const DOUBLE_CLICK_DELAY: u64 = 250; |
| 132 | const HOLD_DELAY: u64 = 1000; | 130 | const HOLD_DELAY: u64 = 1000; |
| 133 | 131 | ||
diff --git a/examples/stm32f3/src/bin/button_exti.rs b/examples/stm32f3/src/bin/button_exti.rs index 86ff68492..a55530e0e 100644 --- a/examples/stm32f3/src/bin/button_exti.rs +++ b/examples/stm32f3/src/bin/button_exti.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::exti::ExtiInput; | 6 | use embassy_stm32::exti::ExtiInput; |
| 7 | use embassy_stm32::gpio::{Input, Pull}; | 7 | use embassy_stm32::gpio::Pull; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -12,8 +12,7 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let button = Input::new(p.PA0, Pull::Down); | 15 | let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Down); |
| 16 | let mut button = ExtiInput::new(button, p.EXTI0); | ||
| 17 | 16 | ||
| 18 | info!("Press the USER button..."); | 17 | info!("Press the USER button..."); |
| 19 | 18 | ||
diff --git a/examples/stm32f3/src/bin/hello.rs b/examples/stm32f3/src/bin/hello.rs index fd54da53d..3c295612c 100644 --- a/examples/stm32f3/src/bin/hello.rs +++ b/examples/stm32f3/src/bin/hello.rs | |||
| @@ -3,16 +3,13 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::info; | 4 | use defmt::info; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::time::Hertz; | ||
| 7 | use embassy_stm32::Config; | 6 | use embassy_stm32::Config; |
| 8 | use embassy_time::Timer; | 7 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 9 | ||
| 11 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| 12 | async fn main(_spawner: Spawner) -> ! { | 11 | async fn main(_spawner: Spawner) -> ! { |
| 13 | let mut config = Config::default(); | 12 | let config = Config::default(); |
| 14 | config.rcc.hse = Some(Hertz(8_000_000)); | ||
| 15 | config.rcc.sysclk = Some(Hertz(16_000_000)); | ||
| 16 | let _p = embassy_stm32::init(config); | 13 | let _p = embassy_stm32::init(config); |
| 17 | 14 | ||
| 18 | loop { | 15 | loop { |
diff --git a/examples/stm32f3/src/bin/usb_serial.rs b/examples/stm32f3/src/bin/usb_serial.rs index cf9ecedfa..ee1c43afd 100644 --- a/examples/stm32f3/src/bin/usb_serial.rs +++ b/examples/stm32f3/src/bin/usb_serial.rs | |||
| @@ -21,11 +21,22 @@ bind_interrupts!(struct Irqs { | |||
| 21 | #[embassy_executor::main] | 21 | #[embassy_executor::main] |
| 22 | async fn main(_spawner: Spawner) { | 22 | async fn main(_spawner: Spawner) { |
| 23 | let mut config = Config::default(); | 23 | let mut config = Config::default(); |
| 24 | config.rcc.hse = Some(mhz(8)); | 24 | { |
| 25 | config.rcc.sysclk = Some(mhz(48)); | 25 | use embassy_stm32::rcc::*; |
| 26 | config.rcc.pclk1 = Some(mhz(24)); | 26 | config.rcc.hse = Some(Hse { |
| 27 | config.rcc.pclk2 = Some(mhz(24)); | 27 | freq: mhz(8), |
| 28 | config.rcc.pll48 = true; | 28 | mode: HseMode::Bypass, |
| 29 | }); | ||
| 30 | config.rcc.pll = Some(Pll { | ||
| 31 | src: PllSource::HSE, | ||
| 32 | prediv: PllPreDiv::DIV1, | ||
| 33 | mul: PllMul::MUL9, | ||
| 34 | }); | ||
| 35 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 36 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 37 | config.rcc.apb1_pre = APBPrescaler::DIV2; | ||
| 38 | config.rcc.apb2_pre = APBPrescaler::DIV1; | ||
| 39 | } | ||
| 29 | let p = embassy_stm32::init(config); | 40 | let p = embassy_stm32::init(config); |
| 30 | 41 | ||
| 31 | info!("Hello World!"); | 42 | info!("Hello World!"); |
diff --git a/examples/stm32f334/src/bin/adc.rs b/examples/stm32f334/src/bin/adc.rs index 063ee9dac..bd126ce68 100644 --- a/examples/stm32f334/src/bin/adc.rs +++ b/examples/stm32f334/src/bin/adc.rs | |||
| @@ -5,7 +5,6 @@ use defmt::info; | |||
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::adc::{Adc, SampleTime}; | 6 | use embassy_stm32::adc::{Adc, SampleTime}; |
| 7 | use embassy_stm32::peripherals::ADC1; | 7 | use embassy_stm32::peripherals::ADC1; |
| 8 | use embassy_stm32::rcc::{AdcClockSource, Adcpres}; | ||
| 9 | use embassy_stm32::time::mhz; | 8 | use embassy_stm32::time::mhz; |
| 10 | use embassy_stm32::{adc, bind_interrupts, Config}; | 9 | use embassy_stm32::{adc, bind_interrupts, Config}; |
| 11 | use embassy_time::{Delay, Timer}; | 10 | use embassy_time::{Delay, Timer}; |
| @@ -18,19 +17,30 @@ bind_interrupts!(struct Irqs { | |||
| 18 | #[embassy_executor::main] | 17 | #[embassy_executor::main] |
| 19 | async fn main(_spawner: Spawner) -> ! { | 18 | async fn main(_spawner: Spawner) -> ! { |
| 20 | let mut config = Config::default(); | 19 | let mut config = Config::default(); |
| 21 | config.rcc.sysclk = Some(mhz(64)); | 20 | { |
| 22 | config.rcc.hclk = Some(mhz(64)); | 21 | use embassy_stm32::rcc::*; |
| 23 | config.rcc.pclk1 = Some(mhz(32)); | 22 | config.rcc.hse = Some(Hse { |
| 24 | config.rcc.pclk2 = Some(mhz(64)); | 23 | freq: mhz(8), |
| 25 | config.rcc.adc = Some(AdcClockSource::Pll(Adcpres::DIV1)); | 24 | mode: HseMode::Bypass, |
| 26 | 25 | }); | |
| 26 | config.rcc.pll = Some(Pll { | ||
| 27 | src: PllSource::HSE, | ||
| 28 | prediv: PllPreDiv::DIV1, | ||
| 29 | mul: PllMul::MUL9, | ||
| 30 | }); | ||
| 31 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 32 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 33 | config.rcc.apb1_pre = APBPrescaler::DIV2; | ||
| 34 | config.rcc.apb2_pre = APBPrescaler::DIV1; | ||
| 35 | config.rcc.adc = AdcClockSource::Pll(AdcPllPrescaler::DIV1); | ||
| 36 | } | ||
| 27 | let mut p = embassy_stm32::init(config); | 37 | let mut p = embassy_stm32::init(config); |
| 28 | 38 | ||
| 29 | info!("create adc..."); | 39 | info!("create adc..."); |
| 30 | 40 | ||
| 31 | let mut adc = Adc::new(p.ADC1, Irqs, &mut Delay); | 41 | let mut adc = Adc::new(p.ADC1, Irqs, &mut Delay); |
| 32 | 42 | ||
| 33 | adc.set_sample_time(SampleTime::Cycles601_5); | 43 | adc.set_sample_time(SampleTime::CYCLES601_5); |
| 34 | 44 | ||
| 35 | info!("enable vrefint..."); | 45 | info!("enable vrefint..."); |
| 36 | 46 | ||
diff --git a/examples/stm32f334/src/bin/hello.rs b/examples/stm32f334/src/bin/hello.rs index fd54da53d..3c295612c 100644 --- a/examples/stm32f334/src/bin/hello.rs +++ b/examples/stm32f334/src/bin/hello.rs | |||
| @@ -3,16 +3,13 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::info; | 4 | use defmt::info; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::time::Hertz; | ||
| 7 | use embassy_stm32::Config; | 6 | use embassy_stm32::Config; |
| 8 | use embassy_time::Timer; | 7 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 9 | ||
| 11 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| 12 | async fn main(_spawner: Spawner) -> ! { | 11 | async fn main(_spawner: Spawner) -> ! { |
| 13 | let mut config = Config::default(); | 12 | let config = Config::default(); |
| 14 | config.rcc.hse = Some(Hertz(8_000_000)); | ||
| 15 | config.rcc.sysclk = Some(Hertz(16_000_000)); | ||
| 16 | let _p = embassy_stm32::init(config); | 13 | let _p = embassy_stm32::init(config); |
| 17 | 14 | ||
| 18 | loop { | 15 | loop { |
diff --git a/examples/stm32f334/src/bin/opamp.rs b/examples/stm32f334/src/bin/opamp.rs index 850a0e335..a5c710aa2 100644 --- a/examples/stm32f334/src/bin/opamp.rs +++ b/examples/stm32f334/src/bin/opamp.rs | |||
| @@ -6,7 +6,6 @@ use embassy_executor::Spawner; | |||
| 6 | use embassy_stm32::adc::{Adc, SampleTime}; | 6 | use embassy_stm32::adc::{Adc, SampleTime}; |
| 7 | use embassy_stm32::opamp::{OpAmp, OpAmpGain}; | 7 | use embassy_stm32::opamp::{OpAmp, OpAmpGain}; |
| 8 | use embassy_stm32::peripherals::ADC2; | 8 | use embassy_stm32::peripherals::ADC2; |
| 9 | use embassy_stm32::rcc::{AdcClockSource, Adcpres}; | ||
| 10 | use embassy_stm32::time::mhz; | 9 | use embassy_stm32::time::mhz; |
| 11 | use embassy_stm32::{adc, bind_interrupts, Config}; | 10 | use embassy_stm32::{adc, bind_interrupts, Config}; |
| 12 | use embassy_time::{Delay, Timer}; | 11 | use embassy_time::{Delay, Timer}; |
| @@ -19,12 +18,23 @@ bind_interrupts!(struct Irqs { | |||
| 19 | #[embassy_executor::main] | 18 | #[embassy_executor::main] |
| 20 | async fn main(_spawner: Spawner) -> ! { | 19 | async fn main(_spawner: Spawner) -> ! { |
| 21 | let mut config = Config::default(); | 20 | let mut config = Config::default(); |
| 22 | config.rcc.sysclk = Some(mhz(64)); | 21 | { |
| 23 | config.rcc.hclk = Some(mhz(64)); | 22 | use embassy_stm32::rcc::*; |
| 24 | config.rcc.pclk1 = Some(mhz(32)); | 23 | config.rcc.hse = Some(Hse { |
| 25 | config.rcc.pclk2 = Some(mhz(64)); | 24 | freq: mhz(8), |
| 26 | config.rcc.adc = Some(AdcClockSource::Pll(Adcpres::DIV1)); | 25 | mode: HseMode::Bypass, |
| 27 | 26 | }); | |
| 27 | config.rcc.pll = Some(Pll { | ||
| 28 | src: PllSource::HSE, | ||
| 29 | prediv: PllPreDiv::DIV1, | ||
| 30 | mul: PllMul::MUL9, | ||
| 31 | }); | ||
| 32 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 33 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 34 | config.rcc.apb1_pre = APBPrescaler::DIV2; | ||
| 35 | config.rcc.apb2_pre = APBPrescaler::DIV1; | ||
| 36 | config.rcc.adc = AdcClockSource::Pll(AdcPllPrescaler::DIV1); | ||
| 37 | } | ||
| 28 | let mut p = embassy_stm32::init(config); | 38 | let mut p = embassy_stm32::init(config); |
| 29 | 39 | ||
| 30 | info!("create adc..."); | 40 | info!("create adc..."); |
| @@ -32,7 +42,7 @@ async fn main(_spawner: Spawner) -> ! { | |||
| 32 | let mut adc = Adc::new(p.ADC2, Irqs, &mut Delay); | 42 | let mut adc = Adc::new(p.ADC2, Irqs, &mut Delay); |
| 33 | let mut opamp = OpAmp::new(p.OPAMP2); | 43 | let mut opamp = OpAmp::new(p.OPAMP2); |
| 34 | 44 | ||
| 35 | adc.set_sample_time(SampleTime::Cycles601_5); | 45 | adc.set_sample_time(SampleTime::CYCLES601_5); |
| 36 | 46 | ||
| 37 | info!("enable vrefint..."); | 47 | info!("enable vrefint..."); |
| 38 | 48 | ||
diff --git a/examples/stm32f334/src/bin/pwm.rs b/examples/stm32f334/src/bin/pwm.rs index c149cad92..e6d1a6c02 100644 --- a/examples/stm32f334/src/bin/pwm.rs +++ b/examples/stm32f334/src/bin/pwm.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::hrtim::*; | 6 | use embassy_stm32::hrtim::*; |
| 7 | use embassy_stm32::rcc::HrtimClockSource; | ||
| 8 | use embassy_stm32::time::{khz, mhz}; | 7 | use embassy_stm32::time::{khz, mhz}; |
| 9 | use embassy_stm32::Config; | 8 | use embassy_stm32::Config; |
| 10 | use embassy_time::Timer; | 9 | use embassy_time::Timer; |
| @@ -12,14 +11,27 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 12 | 11 | ||
| 13 | #[embassy_executor::main] | 12 | #[embassy_executor::main] |
| 14 | async fn main(_spawner: Spawner) { | 13 | async fn main(_spawner: Spawner) { |
| 15 | let mut config: Config = Default::default(); | 14 | let mut config = Config::default(); |
| 16 | config.rcc.sysclk = Some(mhz(64)); | 15 | { |
| 17 | config.rcc.hclk = Some(mhz(64)); | 16 | use embassy_stm32::rcc::*; |
| 18 | config.rcc.pclk1 = Some(mhz(32)); | 17 | config.rcc.hse = Some(Hse { |
| 19 | config.rcc.pclk2 = Some(mhz(64)); | 18 | freq: mhz(8), |
| 20 | config.rcc.hrtim = HrtimClockSource::PllClk; | 19 | mode: HseMode::Bypass, |
| 20 | }); | ||
| 21 | config.rcc.pll = Some(Pll { | ||
| 22 | src: PllSource::HSE, | ||
| 23 | prediv: PllPreDiv::DIV1, | ||
| 24 | mul: PllMul::MUL9, | ||
| 25 | }); | ||
| 26 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 27 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 28 | config.rcc.apb1_pre = APBPrescaler::DIV2; | ||
| 29 | config.rcc.apb2_pre = APBPrescaler::DIV1; | ||
| 21 | 30 | ||
| 31 | config.rcc.mux.hrtim1sw = embassy_stm32::rcc::mux::Timsw::PLL1_P; | ||
| 32 | } | ||
| 22 | let p = embassy_stm32::init(config); | 33 | let p = embassy_stm32::init(config); |
| 34 | |||
| 23 | info!("Hello World!"); | 35 | info!("Hello World!"); |
| 24 | 36 | ||
| 25 | let ch1 = PwmPin::new_cha(p.PA8); | 37 | let ch1 = PwmPin::new_cha(p.PA8); |
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index cd46fc85b..512158bef 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml | |||
| @@ -27,6 +27,7 @@ heapless = { version = "0.8", default-features = false } | |||
| 27 | nb = "1.0.0" | 27 | nb = "1.0.0" |
| 28 | embedded-storage = "0.3.1" | 28 | embedded-storage = "0.3.1" |
| 29 | micromath = "2.0.0" | 29 | micromath = "2.0.0" |
| 30 | usbd-hid = "0.7.0" | ||
| 30 | static_cell = "2" | 31 | static_cell = "2" |
| 31 | chrono = { version = "^0.4", default-features = false} | 32 | chrono = { version = "^0.4", default-features = false} |
| 32 | 33 | ||
diff --git a/examples/stm32f4/src/bin/button_exti.rs b/examples/stm32f4/src/bin/button_exti.rs index 67751187d..2a546dac5 100644 --- a/examples/stm32f4/src/bin/button_exti.rs +++ b/examples/stm32f4/src/bin/button_exti.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::exti::ExtiInput; | 6 | use embassy_stm32::exti::ExtiInput; |
| 7 | use embassy_stm32::gpio::{Input, Pull}; | 7 | use embassy_stm32::gpio::Pull; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -12,8 +12,7 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let button = Input::new(p.PC13, Pull::Down); | 15 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); |
| 16 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 17 | 16 | ||
| 18 | info!("Press the USER button..."); | 17 | info!("Press the USER button..."); |
| 19 | 18 | ||
diff --git a/examples/stm32f4/src/bin/rtc.rs b/examples/stm32f4/src/bin/rtc.rs index abab07b6b..82d8a37ba 100644 --- a/examples/stm32f4/src/bin/rtc.rs +++ b/examples/stm32f4/src/bin/rtc.rs | |||
| @@ -28,7 +28,7 @@ async fn main(_spawner: Spawner) { | |||
| 28 | loop { | 28 | loop { |
| 29 | let now: NaiveDateTime = rtc.now().unwrap().into(); | 29 | let now: NaiveDateTime = rtc.now().unwrap().into(); |
| 30 | 30 | ||
| 31 | info!("{}", now.timestamp()); | 31 | info!("{}", now.and_utc().timestamp()); |
| 32 | 32 | ||
| 33 | Timer::after_millis(1000).await; | 33 | Timer::after_millis(1000).await; |
| 34 | } | 34 | } |
diff --git a/examples/stm32f4/src/bin/usb_hid_mouse.rs b/examples/stm32f4/src/bin/usb_hid_mouse.rs new file mode 100644 index 000000000..c98792880 --- /dev/null +++ b/examples/stm32f4/src/bin/usb_hid_mouse.rs | |||
| @@ -0,0 +1,148 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::time::Hertz; | ||
| 7 | use embassy_stm32::usb_otg::Driver; | ||
| 8 | use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; | ||
| 9 | use embassy_time::Timer; | ||
| 10 | use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler, State}; | ||
| 11 | use embassy_usb::control::OutResponse; | ||
| 12 | use embassy_usb::Builder; | ||
| 13 | use futures::future::join; | ||
| 14 | use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; | ||
| 15 | use {defmt_rtt as _, panic_probe as _}; | ||
| 16 | |||
| 17 | bind_interrupts!(struct Irqs { | ||
| 18 | OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>; | ||
| 19 | }); | ||
| 20 | |||
| 21 | #[embassy_executor::main] | ||
| 22 | async fn main(_spawner: Spawner) { | ||
| 23 | let mut config = Config::default(); | ||
| 24 | { | ||
| 25 | use embassy_stm32::rcc::*; | ||
| 26 | config.rcc.hse = Some(Hse { | ||
| 27 | freq: Hertz(8_000_000), | ||
| 28 | mode: HseMode::Bypass, | ||
| 29 | }); | ||
| 30 | config.rcc.pll_src = PllSource::HSE; | ||
| 31 | config.rcc.pll = Some(Pll { | ||
| 32 | prediv: PllPreDiv::DIV4, | ||
| 33 | mul: PllMul::MUL168, | ||
| 34 | divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. | ||
| 35 | divq: Some(PllQDiv::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. | ||
| 36 | divr: None, | ||
| 37 | }); | ||
| 38 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 39 | config.rcc.apb1_pre = APBPrescaler::DIV4; | ||
| 40 | config.rcc.apb2_pre = APBPrescaler::DIV2; | ||
| 41 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 42 | } | ||
| 43 | let p = embassy_stm32::init(config); | ||
| 44 | |||
| 45 | // Create the driver, from the HAL. | ||
| 46 | let mut ep_out_buffer = [0u8; 256]; | ||
| 47 | let mut config = embassy_stm32::usb_otg::Config::default(); | ||
| 48 | config.vbus_detection = true; | ||
| 49 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | ||
| 50 | |||
| 51 | // Create embassy-usb Config | ||
| 52 | let mut config = embassy_usb::Config::new(0xc0de, 0xcafe); | ||
| 53 | config.manufacturer = Some("Embassy"); | ||
| 54 | config.product = Some("HID mouse example"); | ||
| 55 | config.serial_number = Some("12345678"); | ||
| 56 | |||
| 57 | // Required for windows compatibility. | ||
| 58 | // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help | ||
| 59 | config.device_class = 0xEF; | ||
| 60 | config.device_sub_class = 0x02; | ||
| 61 | config.device_protocol = 0x01; | ||
| 62 | config.composite_with_iads = true; | ||
| 63 | |||
| 64 | // Create embassy-usb DeviceBuilder using the driver and config. | ||
| 65 | // It needs some buffers for building the descriptors. | ||
| 66 | let mut device_descriptor = [0; 256]; | ||
| 67 | let mut config_descriptor = [0; 256]; | ||
| 68 | let mut bos_descriptor = [0; 256]; | ||
| 69 | let mut control_buf = [0; 64]; | ||
| 70 | |||
| 71 | let request_handler = MyRequestHandler {}; | ||
| 72 | |||
| 73 | let mut state = State::new(); | ||
| 74 | |||
| 75 | let mut builder = Builder::new( | ||
| 76 | driver, | ||
| 77 | config, | ||
| 78 | &mut device_descriptor, | ||
| 79 | &mut config_descriptor, | ||
| 80 | &mut bos_descriptor, | ||
| 81 | &mut [], // no msos descriptors | ||
| 82 | &mut control_buf, | ||
| 83 | ); | ||
| 84 | |||
| 85 | // Create classes on the builder. | ||
| 86 | let config = embassy_usb::class::hid::Config { | ||
| 87 | report_descriptor: MouseReport::desc(), | ||
| 88 | request_handler: Some(&request_handler), | ||
| 89 | poll_ms: 60, | ||
| 90 | max_packet_size: 8, | ||
| 91 | }; | ||
| 92 | |||
| 93 | let mut writer = HidWriter::<_, 5>::new(&mut builder, &mut state, config); | ||
| 94 | |||
| 95 | // Build the builder. | ||
| 96 | let mut usb = builder.build(); | ||
| 97 | |||
| 98 | // Run the USB device. | ||
| 99 | let usb_fut = usb.run(); | ||
| 100 | |||
| 101 | // Do stuff with the class! | ||
| 102 | let hid_fut = async { | ||
| 103 | let mut y: i8 = 5; | ||
| 104 | loop { | ||
| 105 | Timer::after_millis(500).await; | ||
| 106 | |||
| 107 | y = -y; | ||
| 108 | let report = MouseReport { | ||
| 109 | buttons: 0, | ||
| 110 | x: 0, | ||
| 111 | y, | ||
| 112 | wheel: 0, | ||
| 113 | pan: 0, | ||
| 114 | }; | ||
| 115 | match writer.write_serialize(&report).await { | ||
| 116 | Ok(()) => {} | ||
| 117 | Err(e) => warn!("Failed to send report: {:?}", e), | ||
| 118 | } | ||
| 119 | } | ||
| 120 | }; | ||
| 121 | |||
| 122 | // Run everything concurrently. | ||
| 123 | // If we had made everything `'static` above instead, we could do this using separate tasks instead. | ||
| 124 | join(usb_fut, hid_fut).await; | ||
| 125 | } | ||
| 126 | |||
| 127 | struct MyRequestHandler {} | ||
| 128 | |||
| 129 | impl RequestHandler for MyRequestHandler { | ||
| 130 | fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { | ||
| 131 | info!("Get report for {:?}", id); | ||
| 132 | None | ||
| 133 | } | ||
| 134 | |||
| 135 | fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { | ||
| 136 | info!("Set report for {:?}: {=[u8]}", id, data); | ||
| 137 | OutResponse::Accepted | ||
| 138 | } | ||
| 139 | |||
| 140 | fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { | ||
| 141 | info!("Set idle rate for {:?} to {:?}", id, dur); | ||
| 142 | } | ||
| 143 | |||
| 144 | fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { | ||
| 145 | info!("Get idle rate for {:?}", id); | ||
| 146 | None | ||
| 147 | } | ||
| 148 | } | ||
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) { | |||
| 91 | loop { | 91 | loop { |
| 92 | for &color in color_list { | 92 | for &color in color_list { |
| 93 | // with &mut, we can easily reuse same DMA channel multiple times | 93 | // with &mut, we can easily reuse same DMA channel multiple times |
| 94 | ws2812_pwm.gen_waveform(&mut dp.DMA1_CH2, pwm_channel, color).await; | 94 | ws2812_pwm.waveform_up(&mut dp.DMA1_CH2, pwm_channel, color).await; |
| 95 | // ws2812 need at least 50 us low level input to confirm the input data and change it's state | 95 | // ws2812 need at least 50 us low level input to confirm the input data and change it's state |
| 96 | Timer::after_micros(50).await; | 96 | Timer::after_micros(50).await; |
| 97 | // wait until ticker tick | 97 | // wait until ticker tick |
diff --git a/examples/stm32f7/.cargo/config.toml b/examples/stm32f7/.cargo/config.toml index 9088eea6e..086da2d78 100644 --- a/examples/stm32f7/.cargo/config.toml +++ b/examples/stm32f7/.cargo/config.toml | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] |
| 2 | # replace STM32F429ZITx with your chip as listed in `probe-rs chip list` | 2 | # replace STM32F429ZITx with your chip as listed in `probe-rs chip list` |
| 3 | runner = "probe-rs run --chip STM32F767ZITx" | 3 | runner = "probe-rs run --chip STM32F777ZITx" |
| 4 | 4 | ||
| 5 | [build] | 5 | [build] |
| 6 | target = "thumbv7em-none-eabihf" | 6 | target = "thumbv7em-none-eabihf" |
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index 941ba38cd..305816a2b 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml | |||
| @@ -5,8 +5,8 @@ version = "0.1.0" | |||
| 5 | license = "MIT OR Apache-2.0" | 5 | license = "MIT OR Apache-2.0" |
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | # Change stm32f767zi to your chip name, if necessary. | 8 | # Change stm32f777zi to your chip name, if necessary. |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f767zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f777zi", "memory-x", "unstable-pac", "time-driver-any", "exti"] } |
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| @@ -28,6 +28,9 @@ rand_core = "0.6.3" | |||
| 28 | critical-section = "1.1" | 28 | critical-section = "1.1" |
| 29 | embedded-storage = "0.3.1" | 29 | embedded-storage = "0.3.1" |
| 30 | static_cell = "2" | 30 | static_cell = "2" |
| 31 | sha2 = { version = "0.10.8", default-features = false } | ||
| 32 | hmac = "0.12.1" | ||
| 33 | aes-gcm = {version = "0.10.3", default-features = false, features = ["aes", "heapless"] } | ||
| 31 | 34 | ||
| 32 | [profile.release] | 35 | [profile.release] |
| 33 | debug = 2 | 36 | debug = 2 |
diff --git a/examples/stm32f7/src/bin/button_exti.rs b/examples/stm32f7/src/bin/button_exti.rs index 67751187d..2a546dac5 100644 --- a/examples/stm32f7/src/bin/button_exti.rs +++ b/examples/stm32f7/src/bin/button_exti.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::exti::ExtiInput; | 6 | use embassy_stm32::exti::ExtiInput; |
| 7 | use embassy_stm32::gpio::{Input, Pull}; | 7 | use embassy_stm32::gpio::Pull; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -12,8 +12,7 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let button = Input::new(p.PC13, Pull::Down); | 15 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); |
| 16 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 17 | 16 | ||
| 18 | info!("Press the USER button..."); | 17 | info!("Press the USER button..."); |
| 19 | 18 | ||
diff --git a/examples/stm32f7/src/bin/cryp.rs b/examples/stm32f7/src/bin/cryp.rs new file mode 100644 index 000000000..04927841a --- /dev/null +++ b/examples/stm32f7/src/bin/cryp.rs | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use aes_gcm::aead::heapless::Vec; | ||
| 5 | use aes_gcm::aead::{AeadInPlace, KeyInit}; | ||
| 6 | use aes_gcm::Aes128Gcm; | ||
| 7 | use defmt::info; | ||
| 8 | use embassy_executor::Spawner; | ||
| 9 | use embassy_stm32::cryp::*; | ||
| 10 | use embassy_stm32::Config; | ||
| 11 | use embassy_time::Instant; | ||
| 12 | use {defmt_rtt as _, panic_probe as _}; | ||
| 13 | |||
| 14 | #[embassy_executor::main] | ||
| 15 | async fn main(_spawner: Spawner) -> ! { | ||
| 16 | let config = Config::default(); | ||
| 17 | let p = embassy_stm32::init(config); | ||
| 18 | |||
| 19 | let payload: &[u8] = b"hello world"; | ||
| 20 | let aad: &[u8] = b"additional data"; | ||
| 21 | |||
| 22 | let hw_cryp = Cryp::new(p.CRYP); | ||
| 23 | let key: [u8; 16] = [0; 16]; | ||
| 24 | let mut ciphertext: [u8; 11] = [0; 11]; | ||
| 25 | let mut plaintext: [u8; 11] = [0; 11]; | ||
| 26 | let iv: [u8; 12] = [0; 12]; | ||
| 27 | |||
| 28 | let hw_start_time = Instant::now(); | ||
| 29 | |||
| 30 | // Encrypt in hardware using AES-GCM 128-bit | ||
| 31 | let aes_gcm = AesGcm::new(&key, &iv); | ||
| 32 | let mut gcm_encrypt = hw_cryp.start(&aes_gcm, Direction::Encrypt); | ||
| 33 | hw_cryp.aad_blocking(&mut gcm_encrypt, aad, true); | ||
| 34 | hw_cryp.payload_blocking(&mut gcm_encrypt, payload, &mut ciphertext, true); | ||
| 35 | let encrypt_tag = hw_cryp.finish_blocking(gcm_encrypt); | ||
| 36 | |||
| 37 | // Decrypt in hardware using AES-GCM 128-bit | ||
| 38 | let mut gcm_decrypt = hw_cryp.start(&aes_gcm, Direction::Decrypt); | ||
| 39 | hw_cryp.aad_blocking(&mut gcm_decrypt, aad, true); | ||
| 40 | hw_cryp.payload_blocking(&mut gcm_decrypt, &ciphertext, &mut plaintext, true); | ||
| 41 | let decrypt_tag = hw_cryp.finish_blocking(gcm_decrypt); | ||
| 42 | |||
| 43 | let hw_end_time = Instant::now(); | ||
| 44 | let hw_execution_time = hw_end_time - hw_start_time; | ||
| 45 | |||
| 46 | info!("AES-GCM Ciphertext: {:?}", ciphertext); | ||
| 47 | info!("AES-GCM Plaintext: {:?}", plaintext); | ||
| 48 | assert_eq!(payload, plaintext); | ||
| 49 | assert_eq!(encrypt_tag, decrypt_tag); | ||
| 50 | |||
| 51 | let sw_start_time = Instant::now(); | ||
| 52 | |||
| 53 | // Encrypt in software using AES-GCM 128-bit | ||
| 54 | let mut payload_vec: Vec<u8, 32> = Vec::from_slice(&payload).unwrap(); | ||
| 55 | let cipher = Aes128Gcm::new(&key.into()); | ||
| 56 | let _ = cipher.encrypt_in_place(&iv.into(), aad.into(), &mut payload_vec); | ||
| 57 | |||
| 58 | assert_eq!(ciphertext, payload_vec[0..ciphertext.len()]); | ||
| 59 | assert_eq!( | ||
| 60 | encrypt_tag, | ||
| 61 | payload_vec[ciphertext.len()..ciphertext.len() + encrypt_tag.len()] | ||
| 62 | ); | ||
| 63 | |||
| 64 | // Decrypt in software using AES-GCM 128-bit | ||
| 65 | let _ = cipher.decrypt_in_place(&iv.into(), aad.into(), &mut payload_vec); | ||
| 66 | |||
| 67 | let sw_end_time = Instant::now(); | ||
| 68 | let sw_execution_time = sw_end_time - sw_start_time; | ||
| 69 | |||
| 70 | info!("Hardware Execution Time: {:?}", hw_execution_time); | ||
| 71 | info!("Software Execution Time: {:?}", sw_execution_time); | ||
| 72 | |||
| 73 | loop {} | ||
| 74 | } | ||
diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index 5bff48197..9a608e909 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs | |||
| @@ -19,7 +19,7 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 19 | 19 | ||
| 20 | bind_interrupts!(struct Irqs { | 20 | bind_interrupts!(struct Irqs { |
| 21 | ETH => eth::InterruptHandler; | 21 | ETH => eth::InterruptHandler; |
| 22 | RNG => rng::InterruptHandler<peripherals::RNG>; | 22 | HASH_RNG => rng::InterruptHandler<peripherals::RNG>; |
| 23 | }); | 23 | }); |
| 24 | 24 | ||
| 25 | type Device = Ethernet<'static, ETH, GenericSMI>; | 25 | type Device = Ethernet<'static, ETH, GenericSMI>; |
diff --git a/examples/stm32f7/src/bin/hash.rs b/examples/stm32f7/src/bin/hash.rs new file mode 100644 index 000000000..c2d1a7158 --- /dev/null +++ b/examples/stm32f7/src/bin/hash.rs | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::info; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::hash::*; | ||
| 7 | use embassy_stm32::{bind_interrupts, hash, peripherals, Config}; | ||
| 8 | use embassy_time::Instant; | ||
| 9 | use hmac::{Hmac, Mac}; | ||
| 10 | use sha2::{Digest, Sha256}; | ||
| 11 | use {defmt_rtt as _, panic_probe as _}; | ||
| 12 | |||
| 13 | type HmacSha256 = Hmac<Sha256>; | ||
| 14 | |||
| 15 | bind_interrupts!(struct Irqs { | ||
| 16 | HASH_RNG => hash::InterruptHandler<peripherals::HASH>; | ||
| 17 | }); | ||
| 18 | |||
| 19 | #[embassy_executor::main] | ||
| 20 | async fn main(_spawner: Spawner) -> ! { | ||
| 21 | let config = Config::default(); | ||
| 22 | let p = embassy_stm32::init(config); | ||
| 23 | |||
| 24 | let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh"; | ||
| 25 | let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr"; | ||
| 26 | |||
| 27 | let mut hw_hasher = Hash::new(p.HASH, p.DMA2_CH7, Irqs); | ||
| 28 | |||
| 29 | let hw_start_time = Instant::now(); | ||
| 30 | |||
| 31 | // Compute a digest in hardware. | ||
| 32 | let mut context = hw_hasher.start(Algorithm::SHA256, DataType::Width8, None); | ||
| 33 | hw_hasher.update(&mut context, test_1).await; | ||
| 34 | hw_hasher.update(&mut context, test_2).await; | ||
| 35 | let mut hw_digest: [u8; 32] = [0; 32]; | ||
| 36 | hw_hasher.finish(context, &mut hw_digest).await; | ||
| 37 | |||
| 38 | let hw_end_time = Instant::now(); | ||
| 39 | let hw_execution_time = hw_end_time - hw_start_time; | ||
| 40 | |||
| 41 | let sw_start_time = Instant::now(); | ||
| 42 | |||
| 43 | // Compute a digest in software. | ||
| 44 | let mut sw_hasher = Sha256::new(); | ||
| 45 | sw_hasher.update(test_1); | ||
| 46 | sw_hasher.update(test_2); | ||
| 47 | let sw_digest = sw_hasher.finalize(); | ||
| 48 | |||
| 49 | let sw_end_time = Instant::now(); | ||
| 50 | let sw_execution_time = sw_end_time - sw_start_time; | ||
| 51 | |||
| 52 | info!("Hardware Digest: {:?}", hw_digest); | ||
| 53 | info!("Software Digest: {:?}", sw_digest[..]); | ||
| 54 | info!("Hardware Execution Time: {:?}", hw_execution_time); | ||
| 55 | info!("Software Execution Time: {:?}", sw_execution_time); | ||
| 56 | assert_eq!(hw_digest, sw_digest[..]); | ||
| 57 | |||
| 58 | let hmac_key: [u8; 64] = [0x55; 64]; | ||
| 59 | |||
| 60 | // Compute HMAC in hardware. | ||
| 61 | let mut sha256hmac_context = hw_hasher.start(Algorithm::SHA256, DataType::Width8, Some(&hmac_key)); | ||
| 62 | hw_hasher.update(&mut sha256hmac_context, test_1).await; | ||
| 63 | hw_hasher.update(&mut sha256hmac_context, test_2).await; | ||
| 64 | let mut hw_hmac: [u8; 32] = [0; 32]; | ||
| 65 | hw_hasher.finish(sha256hmac_context, &mut hw_hmac).await; | ||
| 66 | |||
| 67 | // Compute HMAC in software. | ||
| 68 | let mut sw_mac = HmacSha256::new_from_slice(&hmac_key).unwrap(); | ||
| 69 | sw_mac.update(test_1); | ||
| 70 | sw_mac.update(test_2); | ||
| 71 | let sw_hmac = sw_mac.finalize().into_bytes(); | ||
| 72 | |||
| 73 | info!("Hardware HMAC: {:?}", hw_hmac); | ||
| 74 | info!("Software HMAC: {:?}", sw_hmac[..]); | ||
| 75 | assert_eq!(hw_hmac, sw_hmac[..]); | ||
| 76 | |||
| 77 | loop {} | ||
| 78 | } | ||
diff --git a/examples/stm32g0/src/bin/button_exti.rs b/examples/stm32g0/src/bin/button_exti.rs index 1e970fdd6..34a08bbc6 100644 --- a/examples/stm32g0/src/bin/button_exti.rs +++ b/examples/stm32g0/src/bin/button_exti.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::exti::ExtiInput; | 6 | use embassy_stm32::exti::ExtiInput; |
| 7 | use embassy_stm32::gpio::{Input, Pull}; | 7 | use embassy_stm32::gpio::Pull; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -12,8 +12,7 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let button = Input::new(p.PC13, Pull::Up); | 15 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); |
| 16 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 17 | 16 | ||
| 18 | info!("Press the USER button..."); | 17 | info!("Press the USER button..."); |
| 19 | 18 | ||
diff --git a/examples/stm32g0/src/bin/hf_timer.rs b/examples/stm32g0/src/bin/hf_timer.rs index 78a779e29..3ea06cdee 100644 --- a/examples/stm32g0/src/bin/hf_timer.rs +++ b/examples/stm32g0/src/bin/hf_timer.rs | |||
| @@ -4,37 +4,36 @@ | |||
| 4 | use defmt::info; | 4 | use defmt::info; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::gpio::OutputType; | 6 | use embassy_stm32::gpio::OutputType; |
| 7 | use embassy_stm32::pac::rcc::vals::Tim1sel; | ||
| 8 | use embassy_stm32::rcc::{ClockSrc, Config as RccConfig, PllConfig, PllSource, Pllm, Plln, Pllq, Pllr}; | ||
| 9 | use embassy_stm32::time::khz; | 7 | use embassy_stm32::time::khz; |
| 10 | use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin}; | 8 | use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin}; |
| 11 | use embassy_stm32::timer::simple_pwm::PwmPin; | 9 | use embassy_stm32::timer::simple_pwm::PwmPin; |
| 12 | use embassy_stm32::timer::Channel; | 10 | use embassy_stm32::timer::Channel; |
| 13 | use embassy_stm32::{pac, Config as PeripheralConfig}; | 11 | use embassy_stm32::Config as PeripheralConfig; |
| 14 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| 15 | 13 | ||
| 16 | #[embassy_executor::main] | 14 | #[embassy_executor::main] |
| 17 | async fn main(_spawner: Spawner) { | 15 | async fn main(_spawner: Spawner) { |
| 18 | let mut rcc_config = RccConfig::default(); | 16 | let mut config = PeripheralConfig::default(); |
| 19 | rcc_config.mux = ClockSrc::PLL(PllConfig { | 17 | { |
| 20 | source: PllSource::HSI, | 18 | use embassy_stm32::rcc::*; |
| 21 | m: Pllm::DIV1, | 19 | config.rcc.hsi = true; |
| 22 | n: Plln::MUL16, | 20 | config.rcc.pll = Some(Pll { |
| 23 | r: Pllr::DIV4, // CPU clock comes from PLLR (HSI (16MHz) / 1 * 16 / 4 = 64MHz) | 21 | source: PllSource::HSI, |
| 24 | q: Some(Pllq::DIV2), // TIM1 or TIM15 can be sourced from PLLQ (HSI (16MHz) / 1 * 16 / 2 = 128MHz) | 22 | prediv: PllPreDiv::DIV1, |
| 25 | p: None, | 23 | mul: PllMul::MUL16, |
| 26 | }); | 24 | divp: None, |
| 27 | 25 | divq: Some(PllQDiv::DIV2), // 16 / 1 * 16 / 2 = 128 Mhz | |
| 28 | let mut peripheral_config = PeripheralConfig::default(); | 26 | divr: Some(PllRDiv::DIV4), // 16 / 1 * 16 / 4 = 64 Mhz |
| 29 | peripheral_config.rcc = rcc_config; | 27 | }); |
| 30 | 28 | config.rcc.sys = Sysclk::PLL1_R; | |
| 31 | let p = embassy_stm32::init(peripheral_config); | 29 | |
| 32 | 30 | // configure TIM1 mux to select PLLQ as clock source | |
| 33 | // configure TIM1 mux to select PLLQ as clock source | 31 | // https://www.st.com/resource/en/reference_manual/rm0444-stm32g0x1-advanced-armbased-32bit-mcus-stmicroelectronics.pdf |
| 34 | // https://www.st.com/resource/en/reference_manual/rm0444-stm32g0x1-advanced-armbased-32bit-mcus-stmicroelectronics.pdf | 32 | // RM0444 page 210 |
| 35 | // RM0444 page 210 | 33 | // RCC - Peripherals Independent Clock Control Register - bit 22 -> 1 |
| 36 | // RCC - Peripherals Independent Clock Control Register - bit 22 -> 1 | 34 | config.rcc.mux.tim1sel = embassy_stm32::rcc::mux::Tim1sel::PLL1_Q; |
| 37 | pac::RCC.ccipr().modify(|w| w.set_tim1sel(Tim1sel::PLL1_Q)); | 35 | } |
| 36 | let p = embassy_stm32::init(config); | ||
| 38 | 37 | ||
| 39 | let ch1 = PwmPin::new_ch1(p.PA8, OutputType::PushPull); | 38 | let ch1 = PwmPin::new_ch1(p.PA8, OutputType::PushPull); |
| 40 | let ch1n = ComplementaryPwmPin::new_ch1(p.PA7, OutputType::PushPull); | 39 | let ch1n = ComplementaryPwmPin::new_ch1(p.PA7, OutputType::PushPull); |
diff --git a/examples/stm32g0/src/bin/usb_serial.rs b/examples/stm32g0/src/bin/usb_serial.rs index f5aaa5624..8b9915626 100644 --- a/examples/stm32g0/src/bin/usb_serial.rs +++ b/examples/stm32g0/src/bin/usb_serial.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_futures::join::join; | 6 | use embassy_futures::join::join; |
| 7 | use embassy_stm32::rcc::{Hsi48Config, UsbSrc}; | ||
| 8 | use embassy_stm32::usb::{Driver, Instance}; | 7 | use embassy_stm32::usb::{Driver, Instance}; |
| 9 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| @@ -19,10 +18,11 @@ bind_interrupts!(struct Irqs { | |||
| 19 | #[embassy_executor::main] | 18 | #[embassy_executor::main] |
| 20 | async fn main(_spawner: Spawner) { | 19 | async fn main(_spawner: Spawner) { |
| 21 | let mut config = Config::default(); | 20 | let mut config = Config::default(); |
| 22 | config.rcc.usb_src = Some(UsbSrc::Hsi48(Hsi48Config { | 21 | { |
| 23 | sync_from_usb: true, | 22 | use embassy_stm32::rcc::*; |
| 24 | ..Default::default() | 23 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); |
| 25 | })); | 24 | config.rcc.mux.usbsel = mux::Usbsel::HSI48; |
| 25 | } | ||
| 26 | let p = embassy_stm32::init(config); | 26 | let p = embassy_stm32::init(config); |
| 27 | 27 | ||
| 28 | info!("Hello World!"); | 28 | info!("Hello World!"); |
diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index 895ad3e7c..64c749b9b 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml | |||
| @@ -12,7 +12,7 @@ embassy-executor = { version = "0.5.0", path = "../../embassy-executor", feature | |||
| 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } |
| 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 15 | usbd-hid = "0.6.0" | 15 | usbd-hid = "0.7.0" |
| 16 | 16 | ||
| 17 | defmt = "0.3" | 17 | defmt = "0.3" |
| 18 | defmt-rtt = "0.4" | 18 | defmt-rtt = "0.4" |
| @@ -20,9 +20,11 @@ defmt-rtt = "0.4" | |||
| 20 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } | 20 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } |
| 21 | cortex-m-rt = "0.7.0" | 21 | cortex-m-rt = "0.7.0" |
| 22 | embedded-hal = "0.2.6" | 22 | embedded-hal = "0.2.6" |
| 23 | embedded-can = { version = "0.4" } | ||
| 23 | panic-probe = { version = "0.3", features = ["print-defmt"] } | 24 | panic-probe = { version = "0.3", features = ["print-defmt"] } |
| 24 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 25 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 25 | heapless = { version = "0.8", default-features = false } | 26 | heapless = { version = "0.8", default-features = false } |
| 27 | static_cell = "2.0.0" | ||
| 26 | 28 | ||
| 27 | [profile.release] | 29 | [profile.release] |
| 28 | debug = 2 | 30 | debug = 2 |
diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs index 35324d931..ae64bc8e4 100644 --- a/examples/stm32g4/src/bin/adc.rs +++ b/examples/stm32g4/src/bin/adc.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::adc::{Adc, SampleTime}; | 6 | use embassy_stm32::adc::{Adc, SampleTime}; |
| 7 | use embassy_stm32::rcc::{AdcClockSource, ClockSrc, Pll, PllM, PllN, PllR, PllSource}; | ||
| 8 | use embassy_stm32::Config; | 7 | use embassy_stm32::Config; |
| 9 | use embassy_time::{Delay, Timer}; | 8 | use embassy_time::{Delay, Timer}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -12,25 +11,25 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 12 | #[embassy_executor::main] | 11 | #[embassy_executor::main] |
| 13 | async fn main(_spawner: Spawner) { | 12 | async fn main(_spawner: Spawner) { |
| 14 | let mut config = Config::default(); | 13 | let mut config = Config::default(); |
| 15 | 14 | { | |
| 16 | config.rcc.pll = Some(Pll { | 15 | use embassy_stm32::rcc::*; |
| 17 | source: PllSource::HSI, | 16 | config.rcc.pll = Some(Pll { |
| 18 | prediv_m: PllM::DIV4, | 17 | source: PllSource::HSI, |
| 19 | mul_n: PllN::MUL85, | 18 | prediv: PllPreDiv::DIV4, |
| 20 | div_p: None, | 19 | mul: PllMul::MUL85, |
| 21 | div_q: None, | 20 | divp: None, |
| 22 | // Main system clock at 170 MHz | 21 | divq: None, |
| 23 | div_r: Some(PllR::DIV2), | 22 | // Main system clock at 170 MHz |
| 24 | }); | 23 | divr: Some(PllRDiv::DIV2), |
| 25 | 24 | }); | |
| 26 | config.rcc.adc12_clock_source = AdcClockSource::SYS; | 25 | config.rcc.mux.adc12sel = mux::Adcsel::SYS; |
| 27 | config.rcc.mux = ClockSrc::PLL; | 26 | config.rcc.sys = Sysclk::PLL1_R; |
| 28 | 27 | } | |
| 29 | let mut p = embassy_stm32::init(config); | 28 | let mut p = embassy_stm32::init(config); |
| 30 | info!("Hello World!"); | 29 | info!("Hello World!"); |
| 31 | 30 | ||
| 32 | let mut adc = Adc::new(p.ADC2, &mut Delay); | 31 | let mut adc = Adc::new(p.ADC2, &mut Delay); |
| 33 | adc.set_sample_time(SampleTime::Cycles32_5); | 32 | adc.set_sample_time(SampleTime::CYCLES32_5); |
| 34 | 33 | ||
| 35 | loop { | 34 | loop { |
| 36 | let measured = adc.read(&mut p.PA7); | 35 | let measured = adc.read(&mut p.PA7); |
diff --git a/examples/stm32g4/src/bin/button_exti.rs b/examples/stm32g4/src/bin/button_exti.rs index 67751187d..2a546dac5 100644 --- a/examples/stm32g4/src/bin/button_exti.rs +++ b/examples/stm32g4/src/bin/button_exti.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::exti::ExtiInput; | 6 | use embassy_stm32::exti::ExtiInput; |
| 7 | use embassy_stm32::gpio::{Input, Pull}; | 7 | use embassy_stm32::gpio::Pull; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -12,8 +12,7 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let button = Input::new(p.PC13, Pull::Down); | 15 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); |
| 16 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 17 | 16 | ||
| 18 | info!("Press the USER button..."); | 17 | info!("Press the USER button..."); |
| 19 | 18 | ||
diff --git a/examples/stm32g4/src/bin/can.rs b/examples/stm32g4/src/bin/can.rs new file mode 100644 index 000000000..4373a89a8 --- /dev/null +++ b/examples/stm32g4/src/bin/can.rs | |||
| @@ -0,0 +1,229 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | use defmt::*; | ||
| 4 | use embassy_executor::Spawner; | ||
| 5 | use embassy_stm32::peripherals::*; | ||
| 6 | use embassy_stm32::time::Hertz; | ||
| 7 | use embassy_stm32::{bind_interrupts, can, Config}; | ||
| 8 | use embassy_time::Timer; | ||
| 9 | use static_cell::StaticCell; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>; | ||
| 14 | FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>; | ||
| 15 | }); | ||
| 16 | |||
| 17 | #[embassy_executor::main] | ||
| 18 | async fn main(_spawner: Spawner) { | ||
| 19 | let mut config = Config::default(); | ||
| 20 | { | ||
| 21 | use embassy_stm32::rcc::*; | ||
| 22 | config.rcc.hse = Some(Hse { | ||
| 23 | freq: Hertz(24_000_000), | ||
| 24 | mode: HseMode::Oscillator, | ||
| 25 | }); | ||
| 26 | config.rcc.pll = Some(Pll { | ||
| 27 | source: PllSource::HSE, | ||
| 28 | prediv: PllPreDiv::DIV6, | ||
| 29 | mul: PllMul::MUL85, | ||
| 30 | divp: None, | ||
| 31 | divq: Some(PllQDiv::DIV8), // 42.5 Mhz for fdcan. | ||
| 32 | divr: Some(PllRDiv::DIV2), // Main system clock at 170 MHz | ||
| 33 | }); | ||
| 34 | config.rcc.mux.fdcansel = mux::Fdcansel::PLL1_Q; | ||
| 35 | config.rcc.sys = Sysclk::PLL1_R; | ||
| 36 | } | ||
| 37 | let peripherals = embassy_stm32::init(config); | ||
| 38 | |||
| 39 | let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); | ||
| 40 | |||
| 41 | can.set_extended_filter( | ||
| 42 | can::filter::ExtendedFilterSlot::_0, | ||
| 43 | can::filter::ExtendedFilter::accept_all_into_fifo1(), | ||
| 44 | ); | ||
| 45 | |||
| 46 | // 250k bps | ||
| 47 | can.set_bitrate(250_000); | ||
| 48 | |||
| 49 | let use_fd = false; | ||
| 50 | |||
| 51 | // 1M bps | ||
| 52 | if use_fd { | ||
| 53 | can.set_fd_data_bitrate(1_000_000, false); | ||
| 54 | } | ||
| 55 | |||
| 56 | info!("Configured"); | ||
| 57 | |||
| 58 | let mut can = can.start(match use_fd { | ||
| 59 | true => can::FdcanOperatingMode::InternalLoopbackMode, | ||
| 60 | false => can::FdcanOperatingMode::NormalOperationMode, | ||
| 61 | }); | ||
| 62 | |||
| 63 | let mut i = 0; | ||
| 64 | let mut last_read_ts = embassy_time::Instant::now(); | ||
| 65 | |||
| 66 | loop { | ||
| 67 | let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); | ||
| 68 | info!("Writing frame"); | ||
| 69 | |||
| 70 | _ = can.write(&frame).await; | ||
| 71 | |||
| 72 | match can.read().await { | ||
| 73 | Ok((rx_frame, ts)) => { | ||
| 74 | let delta = (ts - last_read_ts).as_millis(); | ||
| 75 | last_read_ts = ts; | ||
| 76 | info!( | ||
| 77 | "Rx: {} {:02x} --- {}ms", | ||
| 78 | rx_frame.header().len(), | ||
| 79 | rx_frame.data()[0..rx_frame.header().len() as usize], | ||
| 80 | delta, | ||
| 81 | ) | ||
| 82 | } | ||
| 83 | Err(_err) => error!("Error in frame"), | ||
| 84 | } | ||
| 85 | |||
| 86 | Timer::after_millis(250).await; | ||
| 87 | |||
| 88 | i += 1; | ||
| 89 | if i > 2 { | ||
| 90 | break; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | // Use the FD API's even if we don't get FD packets. | ||
| 95 | |||
| 96 | loop { | ||
| 97 | if use_fd { | ||
| 98 | let frame = can::frame::FdFrame::new_extended(0x123456F, &[i; 16]).unwrap(); | ||
| 99 | info!("Writing frame using FD API"); | ||
| 100 | _ = can.write_fd(&frame).await; | ||
| 101 | } else { | ||
| 102 | let frame = can::frame::FdFrame::new_extended(0x123456F, &[i; 8]).unwrap(); | ||
| 103 | info!("Writing frame using FD API"); | ||
| 104 | _ = can.write_fd(&frame).await; | ||
| 105 | } | ||
| 106 | |||
| 107 | match can.read_fd().await { | ||
| 108 | Ok((rx_frame, ts)) => { | ||
| 109 | let delta = (ts - last_read_ts).as_millis(); | ||
| 110 | last_read_ts = ts; | ||
| 111 | info!( | ||
| 112 | "Rx: {} {:02x} --- using FD API {}ms", | ||
| 113 | rx_frame.header().len(), | ||
| 114 | rx_frame.data()[0..rx_frame.header().len() as usize], | ||
| 115 | delta, | ||
| 116 | ) | ||
| 117 | } | ||
| 118 | Err(_err) => error!("Error in frame"), | ||
| 119 | } | ||
| 120 | |||
| 121 | Timer::after_millis(250).await; | ||
| 122 | |||
| 123 | i += 1; | ||
| 124 | if i > 4 { | ||
| 125 | break; | ||
| 126 | } | ||
| 127 | } | ||
| 128 | i = 0; | ||
| 129 | let (mut tx, mut rx) = can.split(); | ||
| 130 | // With split | ||
| 131 | loop { | ||
| 132 | let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); | ||
| 133 | info!("Writing frame"); | ||
| 134 | _ = tx.write(&frame).await; | ||
| 135 | |||
| 136 | match rx.read().await { | ||
| 137 | Ok((rx_frame, ts)) => { | ||
| 138 | let delta = (ts - last_read_ts).as_millis(); | ||
| 139 | last_read_ts = ts; | ||
| 140 | info!( | ||
| 141 | "Rx: {} {:02x} --- {}ms", | ||
| 142 | rx_frame.header().len(), | ||
| 143 | rx_frame.data()[0..rx_frame.header().len() as usize], | ||
| 144 | delta, | ||
| 145 | ) | ||
| 146 | } | ||
| 147 | Err(_err) => error!("Error in frame"), | ||
| 148 | } | ||
| 149 | |||
| 150 | Timer::after_millis(250).await; | ||
| 151 | |||
| 152 | i += 1; | ||
| 153 | |||
| 154 | if i > 2 { | ||
| 155 | break; | ||
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 159 | let can = can::Fdcan::join(tx, rx); | ||
| 160 | |||
| 161 | info!("\n\n\nBuffered\n"); | ||
| 162 | if use_fd { | ||
| 163 | static TX_BUF: StaticCell<can::TxFdBuf<8>> = StaticCell::new(); | ||
| 164 | static RX_BUF: StaticCell<can::RxFdBuf<10>> = StaticCell::new(); | ||
| 165 | let mut can = can.buffered_fd( | ||
| 166 | TX_BUF.init(can::TxFdBuf::<8>::new()), | ||
| 167 | RX_BUF.init(can::RxFdBuf::<10>::new()), | ||
| 168 | ); | ||
| 169 | loop { | ||
| 170 | let frame = can::frame::FdFrame::new_extended(0x123456F, &[i; 16]).unwrap(); | ||
| 171 | info!("Writing frame"); | ||
| 172 | |||
| 173 | _ = can.write(frame).await; | ||
| 174 | |||
| 175 | match can.read().await { | ||
| 176 | Ok((rx_frame, ts)) => { | ||
| 177 | let delta = (ts - last_read_ts).as_millis(); | ||
| 178 | last_read_ts = ts; | ||
| 179 | info!( | ||
| 180 | "Rx: {} {:02x} --- {}ms", | ||
| 181 | rx_frame.header().len(), | ||
| 182 | rx_frame.data()[0..rx_frame.header().len() as usize], | ||
| 183 | delta, | ||
| 184 | ) | ||
| 185 | } | ||
| 186 | Err(_err) => error!("Error in frame"), | ||
| 187 | } | ||
| 188 | |||
| 189 | Timer::after_millis(250).await; | ||
| 190 | |||
| 191 | i += 1; | ||
| 192 | } | ||
| 193 | } else { | ||
| 194 | static TX_BUF: StaticCell<can::TxBuf<8>> = StaticCell::new(); | ||
| 195 | static RX_BUF: StaticCell<can::RxBuf<10>> = StaticCell::new(); | ||
| 196 | let mut can = can.buffered( | ||
| 197 | TX_BUF.init(can::TxBuf::<8>::new()), | ||
| 198 | RX_BUF.init(can::RxBuf::<10>::new()), | ||
| 199 | ); | ||
| 200 | loop { | ||
| 201 | let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); | ||
| 202 | info!("Writing frame"); | ||
| 203 | |||
| 204 | // You can use any of these approaches to send. The writer makes it | ||
| 205 | // easy to share sending from multiple tasks. | ||
| 206 | //_ = can.write(frame).await; | ||
| 207 | //can.writer().try_write(frame).unwrap(); | ||
| 208 | can.writer().write(frame).await; | ||
| 209 | |||
| 210 | match can.read().await { | ||
| 211 | Ok((rx_frame, ts)) => { | ||
| 212 | let delta = (ts - last_read_ts).as_millis(); | ||
| 213 | last_read_ts = ts; | ||
| 214 | info!( | ||
| 215 | "Rx: {} {:02x} --- {}ms", | ||
| 216 | rx_frame.header().len(), | ||
| 217 | rx_frame.data()[0..rx_frame.header().len() as usize], | ||
| 218 | delta, | ||
| 219 | ) | ||
| 220 | } | ||
| 221 | Err(_err) => error!("Error in frame"), | ||
| 222 | } | ||
| 223 | |||
| 224 | Timer::after_millis(250).await; | ||
| 225 | |||
| 226 | i += 1; | ||
| 227 | } | ||
| 228 | } | ||
| 229 | } | ||
diff --git a/examples/stm32g4/src/bin/pll.rs b/examples/stm32g4/src/bin/pll.rs index 46ebe0b0d..08ed95b34 100644 --- a/examples/stm32g4/src/bin/pll.rs +++ b/examples/stm32g4/src/bin/pll.rs | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::rcc::{ClockSrc, Pll, PllM, PllN, PllR, PllSource}; | ||
| 7 | use embassy_stm32::Config; | 6 | use embassy_stm32::Config; |
| 8 | use embassy_time::Timer; | 7 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -11,19 +10,20 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 11 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| 12 | async fn main(_spawner: Spawner) { | 11 | async fn main(_spawner: Spawner) { |
| 13 | let mut config = Config::default(); | 12 | let mut config = Config::default(); |
| 14 | 13 | { | |
| 15 | config.rcc.pll = Some(Pll { | 14 | use embassy_stm32::rcc::*; |
| 16 | source: PllSource::HSI, | 15 | config.rcc.hsi = true; |
| 17 | prediv_m: PllM::DIV4, | 16 | config.rcc.pll = Some(Pll { |
| 18 | mul_n: PllN::MUL85, | 17 | source: PllSource::HSI, |
| 19 | div_p: None, | 18 | prediv: PllPreDiv::DIV4, |
| 20 | div_q: None, | 19 | mul: PllMul::MUL85, |
| 21 | // Main system clock at 170 MHz | 20 | divp: None, |
| 22 | div_r: Some(PllR::DIV2), | 21 | divq: None, |
| 23 | }); | 22 | // Main system clock at 170 MHz |
| 24 | 23 | divr: Some(PllRDiv::DIV2), | |
| 25 | config.rcc.mux = ClockSrc::PLL; | 24 | }); |
| 26 | 25 | config.rcc.sys = Sysclk::PLL1_R; | |
| 26 | } | ||
| 27 | let _p = embassy_stm32::init(config); | 27 | let _p = embassy_stm32::init(config); |
| 28 | info!("Hello World!"); | 28 | info!("Hello World!"); |
| 29 | 29 | ||
diff --git a/examples/stm32g4/src/bin/usb_serial.rs b/examples/stm32g4/src/bin/usb_serial.rs index c26fa76b7..dc95aa6e5 100644 --- a/examples/stm32g4/src/bin/usb_serial.rs +++ b/examples/stm32g4/src/bin/usb_serial.rs | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::rcc::{Clock48MhzSrc, ClockSrc, Hsi48Config, Pll, PllM, PllN, PllQ, PllR, PllSource}; | ||
| 7 | use embassy_stm32::time::Hertz; | 6 | use embassy_stm32::time::Hertz; |
| 8 | use embassy_stm32::usb::{self, Driver, Instance}; | 7 | use embassy_stm32::usb::{self, Driver, Instance}; |
| 9 | use embassy_stm32::{bind_interrupts, peripherals, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, Config}; |
| @@ -20,31 +19,27 @@ bind_interrupts!(struct Irqs { | |||
| 20 | #[embassy_executor::main] | 19 | #[embassy_executor::main] |
| 21 | async fn main(_spawner: Spawner) { | 20 | async fn main(_spawner: Spawner) { |
| 22 | let mut config = Config::default(); | 21 | let mut config = Config::default(); |
| 23 | 22 | { | |
| 24 | // Change this to `false` to use the HSE clock source for the USB. This example assumes an 8MHz HSE. | 23 | use embassy_stm32::rcc::*; |
| 25 | const USE_HSI48: bool = true; | ||
| 26 | |||
| 27 | let plldivq = if USE_HSI48 { None } else { Some(PllQ::DIV6) }; | ||
| 28 | |||
| 29 | config.rcc.pll = Some(Pll { | ||
| 30 | source: PllSource::HSE(Hertz(8_000_000)), | ||
| 31 | prediv_m: PllM::DIV2, | ||
| 32 | mul_n: PllN::MUL72, | ||
| 33 | div_p: None, | ||
| 34 | div_q: plldivq, | ||
| 35 | // Main system clock at 144 MHz | ||
| 36 | div_r: Some(PllR::DIV2), | ||
| 37 | }); | ||
| 38 | |||
| 39 | config.rcc.mux = ClockSrc::PLL; | ||
| 40 | |||
| 41 | if USE_HSI48 { | ||
| 42 | // Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator. | 24 | // Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator. |
| 43 | config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::Hsi48(Hsi48Config { sync_from_usb: true })); | 25 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); |
| 44 | } else { | 26 | config.rcc.hse = Some(Hse { |
| 45 | config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::PllQ); | 27 | freq: Hertz(8_000_000), |
| 28 | mode: HseMode::Oscillator, | ||
| 29 | }); | ||
| 30 | config.rcc.pll = Some(Pll { | ||
| 31 | source: PllSource::HSE, | ||
| 32 | prediv: PllPreDiv::DIV2, | ||
| 33 | mul: PllMul::MUL72, | ||
| 34 | divp: None, | ||
| 35 | divq: Some(PllQDiv::DIV6), // 48mhz | ||
| 36 | divr: Some(PllRDiv::DIV2), // Main system clock at 144 MHz | ||
| 37 | }); | ||
| 38 | config.rcc.sys = Sysclk::PLL1_R; | ||
| 39 | config.rcc.boost = true; // BOOST! | ||
| 40 | config.rcc.mux.clk48sel = mux::Clk48sel::HSI48; | ||
| 41 | //config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; // uncomment to use PLL1_Q instead. | ||
| 46 | } | 42 | } |
| 47 | |||
| 48 | let p = embassy_stm32::init(config); | 43 | let p = embassy_stm32::init(config); |
| 49 | 44 | ||
| 50 | info!("Hello World!"); | 45 | info!("Hello World!"); |
diff --git a/examples/stm32h5/src/bin/button_exti.rs b/examples/stm32h5/src/bin/button_exti.rs index 67751187d..2a546dac5 100644 --- a/examples/stm32h5/src/bin/button_exti.rs +++ b/examples/stm32h5/src/bin/button_exti.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::exti::ExtiInput; | 6 | use embassy_stm32::exti::ExtiInput; |
| 7 | use embassy_stm32::gpio::{Input, Pull}; | 7 | use embassy_stm32::gpio::Pull; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -12,8 +12,7 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let button = Input::new(p.PC13, Pull::Down); | 15 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); |
| 16 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 17 | 16 | ||
| 18 | info!("Press the USER button..."); | 17 | info!("Press the USER button..."); |
| 19 | 18 | ||
diff --git a/examples/stm32h5/src/bin/can.rs b/examples/stm32h5/src/bin/can.rs new file mode 100644 index 000000000..643df27f9 --- /dev/null +++ b/examples/stm32h5/src/bin/can.rs | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::peripherals::*; | ||
| 7 | use embassy_stm32::{bind_interrupts, can, rcc, Config}; | ||
| 8 | use embassy_time::Timer; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | bind_interrupts!(struct Irqs { | ||
| 12 | FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>; | ||
| 13 | FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>; | ||
| 14 | }); | ||
| 15 | |||
| 16 | #[embassy_executor::main] | ||
| 17 | async fn main(_spawner: Spawner) { | ||
| 18 | let mut config = Config::default(); | ||
| 19 | config.rcc.hse = Some(rcc::Hse { | ||
| 20 | freq: embassy_stm32::time::Hertz(25_000_000), | ||
| 21 | mode: rcc::HseMode::Oscillator, | ||
| 22 | }); | ||
| 23 | config.rcc.mux.fdcan12sel = rcc::mux::Fdcansel::HSE; | ||
| 24 | |||
| 25 | let peripherals = embassy_stm32::init(config); | ||
| 26 | |||
| 27 | let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); | ||
| 28 | |||
| 29 | // 250k bps | ||
| 30 | can.set_bitrate(250_000); | ||
| 31 | |||
| 32 | //let mut can = can.into_internal_loopback_mode(); | ||
| 33 | let mut can = can.into_normal_mode(); | ||
| 34 | |||
| 35 | info!("CAN Configured"); | ||
| 36 | |||
| 37 | let mut i = 0; | ||
| 38 | let mut last_read_ts = embassy_time::Instant::now(); | ||
| 39 | |||
| 40 | loop { | ||
| 41 | let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); | ||
| 42 | info!("Writing frame"); | ||
| 43 | _ = can.write(&frame).await; | ||
| 44 | |||
| 45 | match can.read().await { | ||
| 46 | Ok((rx_frame, ts)) => { | ||
| 47 | let delta = (ts - last_read_ts).as_millis(); | ||
| 48 | last_read_ts = ts; | ||
| 49 | info!( | ||
| 50 | "Rx: {:x} {:x} {:x} {:x} --- NEW {}", | ||
| 51 | rx_frame.data()[0], | ||
| 52 | rx_frame.data()[1], | ||
| 53 | rx_frame.data()[2], | ||
| 54 | rx_frame.data()[3], | ||
| 55 | delta, | ||
| 56 | ) | ||
| 57 | } | ||
| 58 | Err(_err) => error!("Error in frame"), | ||
| 59 | } | ||
| 60 | |||
| 61 | Timer::after_millis(250).await; | ||
| 62 | |||
| 63 | i += 1; | ||
| 64 | if i > 3 { | ||
| 65 | break; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | let (mut tx, mut rx) = can.split(); | ||
| 70 | // With split | ||
| 71 | loop { | ||
| 72 | let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); | ||
| 73 | info!("Writing frame"); | ||
| 74 | _ = tx.write(&frame).await; | ||
| 75 | |||
| 76 | match rx.read().await { | ||
| 77 | Ok((rx_frame, ts)) => { | ||
| 78 | let delta = (ts - last_read_ts).as_millis(); | ||
| 79 | last_read_ts = ts; | ||
| 80 | info!( | ||
| 81 | "Rx: {:x} {:x} {:x} {:x} --- NEW {}", | ||
| 82 | rx_frame.data()[0], | ||
| 83 | rx_frame.data()[1], | ||
| 84 | rx_frame.data()[2], | ||
| 85 | rx_frame.data()[3], | ||
| 86 | delta, | ||
| 87 | ) | ||
| 88 | } | ||
| 89 | Err(_err) => error!("Error in frame"), | ||
| 90 | } | ||
| 91 | |||
| 92 | Timer::after_millis(250).await; | ||
| 93 | |||
| 94 | i += 1; | ||
| 95 | } | ||
| 96 | } | ||
diff --git a/examples/stm32h5/src/bin/usb_serial.rs b/examples/stm32h5/src/bin/usb_serial.rs index 208493d8c..83477c8fa 100644 --- a/examples/stm32h5/src/bin/usb_serial.rs +++ b/examples/stm32h5/src/bin/usb_serial.rs | |||
| @@ -5,7 +5,7 @@ use defmt::{panic, *}; | |||
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::time::Hertz; | 6 | use embassy_stm32::time::Hertz; |
| 7 | use embassy_stm32::usb::{Driver, Instance}; | 7 | use embassy_stm32::usb::{Driver, Instance}; |
| 8 | use embassy_stm32::{bind_interrupts, pac, peripherals, usb, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; |
| 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 10 | use embassy_usb::driver::EndpointError; | 10 | use embassy_usb::driver::EndpointError; |
| 11 | use embassy_usb::Builder; | 11 | use embassy_usb::Builder; |
| @@ -41,15 +41,12 @@ async fn main(_spawner: Spawner) { | |||
| 41 | config.rcc.apb3_pre = APBPrescaler::DIV4; | 41 | config.rcc.apb3_pre = APBPrescaler::DIV4; |
| 42 | config.rcc.sys = Sysclk::PLL1_P; | 42 | config.rcc.sys = Sysclk::PLL1_P; |
| 43 | config.rcc.voltage_scale = VoltageScale::Scale0; | 43 | config.rcc.voltage_scale = VoltageScale::Scale0; |
| 44 | config.rcc.mux.usbsel = mux::Usbsel::HSI48; | ||
| 44 | } | 45 | } |
| 45 | let p = embassy_stm32::init(config); | 46 | let p = embassy_stm32::init(config); |
| 46 | 47 | ||
| 47 | info!("Hello World!"); | 48 | info!("Hello World!"); |
| 48 | 49 | ||
| 49 | pac::RCC.ccipr4().write(|w| { | ||
| 50 | w.set_usbsel(pac::rcc::vals::Usbsel::HSI48); | ||
| 51 | }); | ||
| 52 | |||
| 53 | // Create the driver, from the HAL. | 50 | // Create the driver, from the HAL. |
| 54 | let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11); | 51 | let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11); |
| 55 | 52 | ||
diff --git a/examples/stm32h7/src/bin/adc.rs b/examples/stm32h7/src/bin/adc.rs index fe6fe69a1..a5594d10c 100644 --- a/examples/stm32h7/src/bin/adc.rs +++ b/examples/stm32h7/src/bin/adc.rs | |||
| @@ -38,7 +38,7 @@ async fn main(_spawner: Spawner) { | |||
| 38 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz | 38 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz |
| 39 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz | 39 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz |
| 40 | config.rcc.voltage_scale = VoltageScale::Scale1; | 40 | config.rcc.voltage_scale = VoltageScale::Scale1; |
| 41 | config.rcc.adc_clock_source = AdcClockSource::PLL2_P; | 41 | config.rcc.mux.adcsel = mux::Adcsel::PLL2_P; |
| 42 | } | 42 | } |
| 43 | let mut p = embassy_stm32::init(config); | 43 | let mut p = embassy_stm32::init(config); |
| 44 | 44 | ||
| @@ -46,7 +46,7 @@ async fn main(_spawner: Spawner) { | |||
| 46 | 46 | ||
| 47 | let mut adc = Adc::new(p.ADC3, &mut Delay); | 47 | let mut adc = Adc::new(p.ADC3, &mut Delay); |
| 48 | 48 | ||
| 49 | adc.set_sample_time(SampleTime::Cycles32_5); | 49 | adc.set_sample_time(SampleTime::CYCLES32_5); |
| 50 | 50 | ||
| 51 | let mut vrefint_channel = adc.enable_vrefint(); | 51 | let mut vrefint_channel = adc.enable_vrefint(); |
| 52 | 52 | ||
diff --git a/examples/stm32h7/src/bin/button_exti.rs b/examples/stm32h7/src/bin/button_exti.rs index 67751187d..2a546dac5 100644 --- a/examples/stm32h7/src/bin/button_exti.rs +++ b/examples/stm32h7/src/bin/button_exti.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::exti::ExtiInput; | 6 | use embassy_stm32::exti::ExtiInput; |
| 7 | use embassy_stm32::gpio::{Input, Pull}; | 7 | use embassy_stm32::gpio::Pull; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -12,8 +12,7 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let button = Input::new(p.PC13, Pull::Down); | 15 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); |
| 16 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 17 | 16 | ||
| 18 | info!("Press the USER button..."); | 17 | info!("Press the USER button..."); |
| 19 | 18 | ||
diff --git a/examples/stm32h7/src/bin/can.rs b/examples/stm32h7/src/bin/can.rs new file mode 100644 index 000000000..13a6a5051 --- /dev/null +++ b/examples/stm32h7/src/bin/can.rs | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::peripherals::*; | ||
| 7 | use embassy_stm32::{bind_interrupts, can, rcc, Config}; | ||
| 8 | use embassy_time::Timer; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | bind_interrupts!(struct Irqs { | ||
| 12 | FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>; | ||
| 13 | FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>; | ||
| 14 | }); | ||
| 15 | |||
| 16 | #[embassy_executor::main] | ||
| 17 | async fn main(_spawner: Spawner) { | ||
| 18 | let mut config = Config::default(); | ||
| 19 | config.rcc.hse = Some(rcc::Hse { | ||
| 20 | freq: embassy_stm32::time::Hertz(25_000_000), | ||
| 21 | mode: rcc::HseMode::Oscillator, | ||
| 22 | }); | ||
| 23 | config.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE; | ||
| 24 | |||
| 25 | let peripherals = embassy_stm32::init(config); | ||
| 26 | |||
| 27 | let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs); | ||
| 28 | |||
| 29 | // 250k bps | ||
| 30 | can.set_bitrate(250_000); | ||
| 31 | |||
| 32 | //let mut can = can.into_internal_loopback_mode(); | ||
| 33 | let mut can = can.into_normal_mode(); | ||
| 34 | |||
| 35 | info!("CAN Configured"); | ||
| 36 | |||
| 37 | let mut i = 0; | ||
| 38 | let mut last_read_ts = embassy_time::Instant::now(); | ||
| 39 | |||
| 40 | loop { | ||
| 41 | let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); | ||
| 42 | info!("Writing frame"); | ||
| 43 | _ = can.write(&frame).await; | ||
| 44 | |||
| 45 | match can.read().await { | ||
| 46 | Ok((rx_frame, ts)) => { | ||
| 47 | let delta = (ts - last_read_ts).as_millis(); | ||
| 48 | last_read_ts = ts; | ||
| 49 | info!( | ||
| 50 | "Rx: {:x} {:x} {:x} {:x} --- NEW {}", | ||
| 51 | rx_frame.data()[0], | ||
| 52 | rx_frame.data()[1], | ||
| 53 | rx_frame.data()[2], | ||
| 54 | rx_frame.data()[3], | ||
| 55 | delta, | ||
| 56 | ) | ||
| 57 | } | ||
| 58 | Err(_err) => error!("Error in frame"), | ||
| 59 | } | ||
| 60 | |||
| 61 | Timer::after_millis(250).await; | ||
| 62 | |||
| 63 | i += 1; | ||
| 64 | if i > 3 { | ||
| 65 | break; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | let (mut tx, mut rx) = can.split(); | ||
| 70 | // With split | ||
| 71 | loop { | ||
| 72 | let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); | ||
| 73 | info!("Writing frame"); | ||
| 74 | _ = tx.write(&frame).await; | ||
| 75 | |||
| 76 | match rx.read().await { | ||
| 77 | Ok((rx_frame, ts)) => { | ||
| 78 | let delta = (ts - last_read_ts).as_millis(); | ||
| 79 | last_read_ts = ts; | ||
| 80 | info!( | ||
| 81 | "Rx: {:x} {:x} {:x} {:x} --- NEW {}", | ||
| 82 | rx_frame.data()[0], | ||
| 83 | rx_frame.data()[1], | ||
| 84 | rx_frame.data()[2], | ||
| 85 | rx_frame.data()[3], | ||
| 86 | delta, | ||
| 87 | ) | ||
| 88 | } | ||
| 89 | Err(_err) => error!("Error in frame"), | ||
| 90 | } | ||
| 91 | |||
| 92 | Timer::after_millis(250).await; | ||
| 93 | |||
| 94 | i += 1; | ||
| 95 | } | ||
| 96 | } | ||
diff --git a/examples/stm32h7/src/bin/dac.rs b/examples/stm32h7/src/bin/dac.rs index a9bf46de0..a6f969aba 100644 --- a/examples/stm32h7/src/bin/dac.rs +++ b/examples/stm32h7/src/bin/dac.rs | |||
| @@ -40,7 +40,7 @@ fn main() -> ! { | |||
| 40 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz | 40 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz |
| 41 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz | 41 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz |
| 42 | config.rcc.voltage_scale = VoltageScale::Scale1; | 42 | config.rcc.voltage_scale = VoltageScale::Scale1; |
| 43 | config.rcc.adc_clock_source = AdcClockSource::PLL2_P; | 43 | config.rcc.mux.adcsel = mux::Adcsel::PLL2_P; |
| 44 | } | 44 | } |
| 45 | let p = embassy_stm32::init(config); | 45 | let p = embassy_stm32::init(config); |
| 46 | 46 | ||
diff --git a/examples/stm32h7/src/bin/dac_dma.rs b/examples/stm32h7/src/bin/dac_dma.rs index 8e5c41a43..feec28993 100644 --- a/examples/stm32h7/src/bin/dac_dma.rs +++ b/examples/stm32h7/src/bin/dac_dma.rs | |||
| @@ -8,7 +8,7 @@ use embassy_stm32::pac::timer::vals::Mms; | |||
| 8 | use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; | 8 | use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; |
| 9 | use embassy_stm32::rcc::low_level::RccPeripheral; | 9 | use embassy_stm32::rcc::low_level::RccPeripheral; |
| 10 | use embassy_stm32::time::Hertz; | 10 | use embassy_stm32::time::Hertz; |
| 11 | use embassy_stm32::timer::low_level::Basic16bitInstance; | 11 | use embassy_stm32::timer::low_level::BasicInstance; |
| 12 | use micromath::F32Ext; | 12 | use micromath::F32Ext; |
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 14 | ||
| @@ -42,7 +42,7 @@ async fn main(spawner: Spawner) { | |||
| 42 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz | 42 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz |
| 43 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz | 43 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz |
| 44 | config.rcc.voltage_scale = VoltageScale::Scale1; | 44 | config.rcc.voltage_scale = VoltageScale::Scale1; |
| 45 | config.rcc.adc_clock_source = AdcClockSource::PLL2_P; | 45 | config.rcc.mux.adcsel = mux::Adcsel::PLL2_P; |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | // Initialize the board and obtain a Peripherals instance | 48 | // Initialize the board and obtain a Peripherals instance |
| @@ -75,9 +75,9 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { | |||
| 75 | dac.enable(); | 75 | dac.enable(); |
| 76 | 76 | ||
| 77 | TIM6::enable_and_reset(); | 77 | TIM6::enable_and_reset(); |
| 78 | TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); | 78 | TIM6::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); |
| 79 | TIM6::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); | 79 | TIM6::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); |
| 80 | TIM6::regs().cr1().modify(|w| { | 80 | TIM6::regs_basic().cr1().modify(|w| { |
| 81 | w.set_opm(false); | 81 | w.set_opm(false); |
| 82 | w.set_cen(true); | 82 | w.set_cen(true); |
| 83 | }); | 83 | }); |
| @@ -112,9 +112,9 @@ async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { | |||
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | TIM7::enable_and_reset(); | 114 | TIM7::enable_and_reset(); |
| 115 | TIM7::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); | 115 | TIM7::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); |
| 116 | TIM7::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); | 116 | TIM7::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); |
| 117 | TIM7::regs().cr1().modify(|w| { | 117 | TIM7::regs_basic().cr1().modify(|w| { |
| 118 | w.set_opm(false); | 118 | w.set_opm(false); |
| 119 | w.set_cen(true); | 119 | w.set_cen(true); |
| 120 | }); | 120 | }); |
diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index dcc6e36e2..aeb169e19 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs | |||
| @@ -65,6 +65,7 @@ async fn main(spawner: Spawner) -> ! { | |||
| 65 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | 65 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; |
| 66 | 66 | ||
| 67 | static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); | 67 | static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); |
| 68 | |||
| 68 | let device = Ethernet::new( | 69 | let device = Ethernet::new( |
| 69 | PACKETS.init(PacketQueue::<16, 16>::new()), | 70 | PACKETS.init(PacketQueue::<16, 16>::new()), |
| 70 | p.ETH, | 71 | p.ETH, |
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 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_net::tcp::client::{TcpClient, TcpClientState}; | ||
| 7 | use embassy_net::{Stack, StackResources}; | ||
| 8 | use embassy_stm32::eth::generic_smi::GenericSMI; | ||
| 9 | use embassy_stm32::eth::{Ethernet, PacketQueue}; | ||
| 10 | use embassy_stm32::peripherals::ETH; | ||
| 11 | use embassy_stm32::rng::Rng; | ||
| 12 | use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; | ||
| 13 | use embassy_time::Timer; | ||
| 14 | use embedded_io_async::Write; | ||
| 15 | use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; | ||
| 16 | use rand_core::RngCore; | ||
| 17 | use static_cell::StaticCell; | ||
| 18 | use {defmt_rtt as _, panic_probe as _}; | ||
| 19 | |||
| 20 | bind_interrupts!(struct Irqs { | ||
| 21 | ETH => eth::InterruptHandler; | ||
| 22 | RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 23 | }); | ||
| 24 | |||
| 25 | type Device = Ethernet<'static, ETH, GenericSMI>; | ||
| 26 | |||
| 27 | #[embassy_executor::task] | ||
| 28 | async fn net_task(stack: &'static Stack<Device>) -> ! { | ||
| 29 | stack.run().await | ||
| 30 | } | ||
| 31 | |||
| 32 | #[embassy_executor::main] | ||
| 33 | async fn main(spawner: Spawner) -> ! { | ||
| 34 | let mut config = Config::default(); | ||
| 35 | { | ||
| 36 | use embassy_stm32::rcc::*; | ||
| 37 | config.rcc.hsi = Some(HSIPrescaler::DIV1); | ||
| 38 | config.rcc.csi = true; | ||
| 39 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG | ||
| 40 | config.rcc.pll1 = Some(Pll { | ||
| 41 | source: PllSource::HSI, | ||
| 42 | prediv: PllPreDiv::DIV4, | ||
| 43 | mul: PllMul::MUL50, | ||
| 44 | divp: Some(PllDiv::DIV2), | ||
| 45 | divq: None, | ||
| 46 | divr: None, | ||
| 47 | }); | ||
| 48 | config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz | ||
| 49 | config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz | ||
| 50 | config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz | ||
| 51 | config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz | ||
| 52 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz | ||
| 53 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz | ||
| 54 | config.rcc.voltage_scale = VoltageScale::Scale1; | ||
| 55 | } | ||
| 56 | let p = embassy_stm32::init(config); | ||
| 57 | info!("Hello World!"); | ||
| 58 | |||
| 59 | // Generate random seed. | ||
| 60 | let mut rng = Rng::new(p.RNG, Irqs); | ||
| 61 | let mut seed = [0; 8]; | ||
| 62 | rng.fill_bytes(&mut seed); | ||
| 63 | let seed = u64::from_le_bytes(seed); | ||
| 64 | |||
| 65 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | ||
| 66 | |||
| 67 | static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); | ||
| 68 | |||
| 69 | let device = Ethernet::new_mii( | ||
| 70 | PACKETS.init(PacketQueue::<16, 16>::new()), | ||
| 71 | p.ETH, | ||
| 72 | Irqs, | ||
| 73 | p.PA1, | ||
| 74 | p.PC3, | ||
| 75 | p.PA2, | ||
| 76 | p.PC1, | ||
| 77 | p.PA7, | ||
| 78 | p.PC4, | ||
| 79 | p.PC5, | ||
| 80 | p.PB0, | ||
| 81 | p.PB1, | ||
| 82 | p.PG13, | ||
| 83 | p.PG12, | ||
| 84 | p.PC2, | ||
| 85 | p.PE2, | ||
| 86 | p.PG11, | ||
| 87 | GenericSMI::new(1), | ||
| 88 | mac_addr, | ||
| 89 | ); | ||
| 90 | info!("Device created"); | ||
| 91 | |||
| 92 | let config = embassy_net::Config::dhcpv4(Default::default()); | ||
| 93 | //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { | ||
| 94 | // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), | ||
| 95 | // dns_servers: Vec::new(), | ||
| 96 | // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), | ||
| 97 | //}); | ||
| 98 | |||
| 99 | // Init network stack | ||
| 100 | static STACK: StaticCell<Stack<Device>> = StaticCell::new(); | ||
| 101 | static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); | ||
| 102 | let stack = &*STACK.init(Stack::new( | ||
| 103 | device, | ||
| 104 | config, | ||
| 105 | RESOURCES.init(StackResources::<3>::new()), | ||
| 106 | seed, | ||
| 107 | )); | ||
| 108 | |||
| 109 | // Launch network task | ||
| 110 | unwrap!(spawner.spawn(net_task(stack))); | ||
| 111 | |||
| 112 | // Ensure DHCP configuration is up before trying connect | ||
| 113 | stack.wait_config_up().await; | ||
| 114 | |||
| 115 | info!("Network task initialized"); | ||
| 116 | |||
| 117 | let state: TcpClientState<1, 1024, 1024> = TcpClientState::new(); | ||
| 118 | let client = TcpClient::new(&stack, &state); | ||
| 119 | |||
| 120 | loop { | ||
| 121 | // You need to start a server on the host machine, for example: `nc -l 8000` | ||
| 122 | let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 100, 1), 8000)); | ||
| 123 | |||
| 124 | info!("connecting..."); | ||
| 125 | let r = client.connect(addr).await; | ||
| 126 | if let Err(e) = r { | ||
| 127 | info!("connect error: {:?}", e); | ||
| 128 | Timer::after_secs(1).await; | ||
| 129 | continue; | ||
| 130 | } | ||
| 131 | let mut connection = r.unwrap(); | ||
| 132 | info!("connected!"); | ||
| 133 | loop { | ||
| 134 | let r = connection.write_all(b"Hello\n").await; | ||
| 135 | if let Err(e) = r { | ||
| 136 | info!("write error: {:?}", e); | ||
| 137 | break; | ||
| 138 | } | ||
| 139 | Timer::after_secs(1).await; | ||
| 140 | } | ||
| 141 | } | ||
| 142 | } | ||
diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs index cc508c3cf..049d9967d 100644 --- a/examples/stm32h7/src/bin/low_level_timer_api.rs +++ b/examples/stm32h7/src/bin/low_level_timer_api.rs | |||
| @@ -113,11 +113,11 @@ impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { | |||
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | pub fn get_max_duty(&self) -> u32 { | 115 | pub fn get_max_duty(&self) -> u32 { |
| 116 | T::regs_gp32().arr().read().arr() | 116 | T::regs_gp32().arr().read() |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | pub fn set_duty(&mut self, channel: Channel, duty: u32) { | 119 | pub fn set_duty(&mut self, channel: Channel, duty: u32) { |
| 120 | defmt::assert!(duty < self.get_max_duty()); | 120 | defmt::assert!(duty < self.get_max_duty()); |
| 121 | T::regs_gp32().ccr(channel.index()).modify(|w| w.set_ccr(duty)) | 121 | T::regs_gp32().ccr(channel.index()).write_value(duty) |
| 122 | } | 122 | } |
| 123 | } | 123 | } |
diff --git a/examples/stm32h7/src/bin/rtc.rs b/examples/stm32h7/src/bin/rtc.rs index c6b9cf57e..0adb48877 100644 --- a/examples/stm32h7/src/bin/rtc.rs +++ b/examples/stm32h7/src/bin/rtc.rs | |||
| @@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) { | |||
| 24 | .unwrap(); | 24 | .unwrap(); |
| 25 | 25 | ||
| 26 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | 26 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); |
| 27 | info!("Got RTC! {:?}", now.timestamp()); | 27 | info!("Got RTC! {:?}", now.and_utc().timestamp()); |
| 28 | 28 | ||
| 29 | rtc.set_datetime(now.into()).expect("datetime not set"); | 29 | rtc.set_datetime(now.into()).expect("datetime not set"); |
| 30 | 30 | ||
| @@ -32,5 +32,5 @@ async fn main(_spawner: Spawner) { | |||
| 32 | Timer::after_millis(20000).await; | 32 | Timer::after_millis(20000).await; |
| 33 | 33 | ||
| 34 | let then: NaiveDateTime = rtc.now().unwrap().into(); | 34 | let then: NaiveDateTime = rtc.now().unwrap().into(); |
| 35 | info!("Got RTC! {:?}", then.timestamp()); | 35 | info!("Got RTC! {:?}", then.and_utc().timestamp()); |
| 36 | } | 36 | } |
diff --git a/examples/stm32l0/src/bin/adc.rs b/examples/stm32l0/src/bin/adc.rs new file mode 100644 index 000000000..97d41ca4b --- /dev/null +++ b/examples/stm32l0/src/bin/adc.rs | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::adc::{Adc, SampleTime}; | ||
| 7 | use embassy_stm32::peripherals::ADC; | ||
| 8 | use embassy_stm32::{adc, bind_interrupts}; | ||
| 9 | use embassy_time::{Delay, Timer}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | ADC1_COMP => adc::InterruptHandler<ADC>; | ||
| 14 | }); | ||
| 15 | |||
| 16 | #[embassy_executor::main] | ||
| 17 | async fn main(_spawner: Spawner) { | ||
| 18 | let p = embassy_stm32::init(Default::default()); | ||
| 19 | info!("Hello World!"); | ||
| 20 | |||
| 21 | let mut adc = Adc::new(p.ADC, Irqs, &mut Delay); | ||
| 22 | adc.set_sample_time(SampleTime::CYCLES79_5); | ||
| 23 | let mut pin = p.PA1; | ||
| 24 | |||
| 25 | let mut vrefint = adc.enable_vref(&mut Delay); | ||
| 26 | let vrefint_sample = adc.read(&mut vrefint).await; | ||
| 27 | let convert_to_millivolts = |sample| { | ||
| 28 | // From https://www.st.com/resource/en/datasheet/stm32l051c6.pdf | ||
| 29 | // 6.3.3 Embedded internal reference voltage | ||
| 30 | const VREFINT_MV: u32 = 1224; // mV | ||
| 31 | |||
| 32 | (u32::from(sample) * VREFINT_MV / u32::from(vrefint_sample)) as u16 | ||
| 33 | }; | ||
| 34 | |||
| 35 | loop { | ||
| 36 | let v = adc.read(&mut pin).await; | ||
| 37 | info!("--> {} - {} mV", v, convert_to_millivolts(v)); | ||
| 38 | Timer::after_millis(100).await; | ||
| 39 | } | ||
| 40 | } | ||
diff --git a/examples/stm32l0/src/bin/button_exti.rs b/examples/stm32l0/src/bin/button_exti.rs index f517fce04..4945da7ce 100644 --- a/examples/stm32l0/src/bin/button_exti.rs +++ b/examples/stm32l0/src/bin/button_exti.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::exti::ExtiInput; | 6 | use embassy_stm32::exti::ExtiInput; |
| 7 | use embassy_stm32::gpio::{Input, Pull}; | 7 | use embassy_stm32::gpio::Pull; |
| 8 | use embassy_stm32::Config; | 8 | use embassy_stm32::Config; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 10 | ||
| @@ -13,8 +13,7 @@ async fn main(_spawner: Spawner) { | |||
| 13 | let config = Config::default(); | 13 | let config = Config::default(); |
| 14 | let p = embassy_stm32::init(config); | 14 | let p = embassy_stm32::init(config); |
| 15 | 15 | ||
| 16 | let button = Input::new(p.PB2, Pull::Up); | 16 | let mut button = ExtiInput::new(p.PB2, p.EXTI2, Pull::Up); |
| 17 | let mut button = ExtiInput::new(button, p.EXTI2); | ||
| 18 | 17 | ||
| 19 | info!("Press the USER button..."); | 18 | info!("Press the USER button..."); |
| 20 | 19 | ||
diff --git a/examples/stm32l1/src/bin/usb_serial.rs b/examples/stm32l1/src/bin/usb_serial.rs index 7b1e84cbc..f738ea358 100644 --- a/examples/stm32l1/src/bin/usb_serial.rs +++ b/examples/stm32l1/src/bin/usb_serial.rs | |||
| @@ -27,7 +27,7 @@ async fn main(_spawner: Spawner) { | |||
| 27 | mul: PllMul::MUL6, // PLLVCO = 16*6 = 96Mhz | 27 | mul: PllMul::MUL6, // PLLVCO = 16*6 = 96Mhz |
| 28 | div: PllDiv::DIV3, // 32Mhz clock (16 * 6 / 3) | 28 | div: PllDiv::DIV3, // 32Mhz clock (16 * 6 / 3) |
| 29 | }); | 29 | }); |
| 30 | config.rcc.mux = ClockSrc::PLL1_R; | 30 | config.rcc.sys = Sysclk::PLL1_R; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | let p = embassy_stm32::init(config); | 33 | let p = embassy_stm32::init(config); |
diff --git a/examples/stm32l4/src/bin/adc.rs b/examples/stm32l4/src/bin/adc.rs index d01e9f1b3..a9f4604aa 100644 --- a/examples/stm32l4/src/bin/adc.rs +++ b/examples/stm32l4/src/bin/adc.rs | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_stm32::adc::{Adc, Resolution}; | 5 | use embassy_stm32::adc::{Adc, Resolution}; |
| 6 | use embassy_stm32::pac; | 6 | use embassy_stm32::Config; |
| 7 | use embassy_time::Delay; | 7 | use embassy_time::Delay; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| @@ -11,16 +11,16 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 11 | fn main() -> ! { | 11 | fn main() -> ! { |
| 12 | info!("Hello World!"); | 12 | info!("Hello World!"); |
| 13 | 13 | ||
| 14 | pac::RCC.ccipr().modify(|w| { | 14 | let mut config = Config::default(); |
| 15 | w.set_adcsel(pac::rcc::vals::Adcsel::SYS); | 15 | { |
| 16 | }); | 16 | use embassy_stm32::rcc::*; |
| 17 | pac::RCC.ahb2enr().modify(|w| w.set_adcen(true)); | 17 | config.rcc.mux.adcsel = mux::Adcsel::SYS; |
| 18 | 18 | } | |
| 19 | let p = embassy_stm32::init(Default::default()); | 19 | let p = embassy_stm32::init(config); |
| 20 | 20 | ||
| 21 | let mut adc = Adc::new(p.ADC1, &mut Delay); | 21 | let mut adc = Adc::new(p.ADC1, &mut Delay); |
| 22 | //adc.enable_vref(); | 22 | //adc.enable_vref(); |
| 23 | adc.set_resolution(Resolution::EightBit); | 23 | adc.set_resolution(Resolution::BITS8); |
| 24 | let mut channel = p.PC0; | 24 | let mut channel = p.PC0; |
| 25 | 25 | ||
| 26 | loop { | 26 | loop { |
diff --git a/examples/stm32l4/src/bin/button_exti.rs b/examples/stm32l4/src/bin/button_exti.rs index 1e970fdd6..34a08bbc6 100644 --- a/examples/stm32l4/src/bin/button_exti.rs +++ b/examples/stm32l4/src/bin/button_exti.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::exti::ExtiInput; | 6 | use embassy_stm32::exti::ExtiInput; |
| 7 | use embassy_stm32::gpio::{Input, Pull}; | 7 | use embassy_stm32::gpio::Pull; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -12,8 +12,7 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let button = Input::new(p.PC13, Pull::Up); | 15 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); |
| 16 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 17 | 16 | ||
| 18 | info!("Press the USER button..."); | 17 | info!("Press the USER button..."); |
| 19 | 18 | ||
diff --git a/examples/stm32l4/src/bin/dac_dma.rs b/examples/stm32l4/src/bin/dac_dma.rs index 8e5098557..f227812cd 100644 --- a/examples/stm32l4/src/bin/dac_dma.rs +++ b/examples/stm32l4/src/bin/dac_dma.rs | |||
| @@ -8,7 +8,7 @@ use embassy_stm32::pac::timer::vals::Mms; | |||
| 8 | use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; | 8 | use embassy_stm32::peripherals::{DAC1, DMA1_CH3, DMA1_CH4, TIM6, TIM7}; |
| 9 | use embassy_stm32::rcc::low_level::RccPeripheral; | 9 | use embassy_stm32::rcc::low_level::RccPeripheral; |
| 10 | use embassy_stm32::time::Hertz; | 10 | use embassy_stm32::time::Hertz; |
| 11 | use embassy_stm32::timer::low_level::Basic16bitInstance; | 11 | use embassy_stm32::timer::low_level::BasicInstance; |
| 12 | use micromath::F32Ext; | 12 | use micromath::F32Ext; |
| 13 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 14 | 14 | ||
| @@ -46,9 +46,9 @@ async fn dac_task1(mut dac: DacCh1<'static, DAC1, DMA1_CH3>) { | |||
| 46 | dac.enable(); | 46 | dac.enable(); |
| 47 | 47 | ||
| 48 | TIM6::enable_and_reset(); | 48 | TIM6::enable_and_reset(); |
| 49 | TIM6::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); | 49 | TIM6::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); |
| 50 | TIM6::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); | 50 | TIM6::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); |
| 51 | TIM6::regs().cr1().modify(|w| { | 51 | TIM6::regs_basic().cr1().modify(|w| { |
| 52 | w.set_opm(false); | 52 | w.set_opm(false); |
| 53 | w.set_cen(true); | 53 | w.set_cen(true); |
| 54 | }); | 54 | }); |
| @@ -83,9 +83,9 @@ async fn dac_task2(mut dac: DacCh2<'static, DAC1, DMA1_CH4>) { | |||
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | TIM7::enable_and_reset(); | 85 | TIM7::enable_and_reset(); |
| 86 | TIM7::regs().arr().modify(|w| w.set_arr(reload as u16 - 1)); | 86 | TIM7::regs_basic().arr().modify(|w| w.set_arr(reload as u16 - 1)); |
| 87 | TIM7::regs().cr2().modify(|w| w.set_mms(Mms::UPDATE)); | 87 | TIM7::regs_basic().cr2().modify(|w| w.set_mms(Mms::UPDATE)); |
| 88 | TIM7::regs().cr1().modify(|w| { | 88 | TIM7::regs_basic().cr1().modify(|w| { |
| 89 | w.set_opm(false); | 89 | w.set_opm(false); |
| 90 | w.set_cen(true); | 90 | w.set_cen(true); |
| 91 | }); | 91 | }); |
diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs index 638b3e9e4..14d0e3c1e 100644 --- a/examples/stm32l4/src/bin/rng.rs +++ b/examples/stm32l4/src/bin/rng.rs | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::rcc::{ClockSrc, Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv, PllSource}; | 6 | use embassy_stm32::rcc::{Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv, PllSource, Sysclk}; |
| 7 | use embassy_stm32::rng::Rng; | 7 | use embassy_stm32::rng::Rng; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -15,7 +15,7 @@ bind_interrupts!(struct Irqs { | |||
| 15 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 16 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| 17 | let mut config = Config::default(); | 17 | let mut config = Config::default(); |
| 18 | config.rcc.mux = ClockSrc::PLL1_R; | 18 | config.rcc.sys = Sysclk::PLL1_R; |
| 19 | config.rcc.hsi = true; | 19 | config.rcc.hsi = true; |
| 20 | config.rcc.pll = Some(Pll { | 20 | config.rcc.pll = Some(Pll { |
| 21 | source: PllSource::HSI, | 21 | source: PllSource::HSI, |
diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs index 526620bfb..f554f0f78 100644 --- a/examples/stm32l4/src/bin/rtc.rs +++ b/examples/stm32l4/src/bin/rtc.rs | |||
| @@ -15,7 +15,7 @@ async fn main(_spawner: Spawner) { | |||
| 15 | let mut config = Config::default(); | 15 | let mut config = Config::default(); |
| 16 | { | 16 | { |
| 17 | use embassy_stm32::rcc::*; | 17 | use embassy_stm32::rcc::*; |
| 18 | config.rcc.mux = ClockSrc::PLL1_R; | 18 | config.rcc.sys = Sysclk::PLL1_R; |
| 19 | config.rcc.hse = Some(Hse { | 19 | config.rcc.hse = Some(Hse { |
| 20 | freq: Hertz::mhz(8), | 20 | freq: Hertz::mhz(8), |
| 21 | mode: HseMode::Oscillator, | 21 | mode: HseMode::Oscillator, |
| @@ -40,7 +40,7 @@ async fn main(_spawner: Spawner) { | |||
| 40 | .unwrap(); | 40 | .unwrap(); |
| 41 | 41 | ||
| 42 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | 42 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); |
| 43 | info!("Got RTC! {:?}", now.timestamp()); | 43 | info!("Got RTC! {:?}", now.and_utc().timestamp()); |
| 44 | 44 | ||
| 45 | rtc.set_datetime(now.into()).expect("datetime not set"); | 45 | rtc.set_datetime(now.into()).expect("datetime not set"); |
| 46 | 46 | ||
| @@ -48,5 +48,5 @@ async fn main(_spawner: Spawner) { | |||
| 48 | Timer::after_millis(20000).await; | 48 | Timer::after_millis(20000).await; |
| 49 | 49 | ||
| 50 | let then: NaiveDateTime = rtc.now().unwrap().into(); | 50 | let then: NaiveDateTime = rtc.now().unwrap().into(); |
| 51 | info!("Got RTC! {:?}", then.timestamp()); | 51 | info!("Got RTC! {:?}", then.and_utc().timestamp()); |
| 52 | } | 52 | } |
diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 5b4cdfe5e..32bfab6eb 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs | |||
| @@ -58,9 +58,9 @@ const IP_ADDRESS: Ipv4Cidr = Ipv4Cidr::new(Ipv4Address([192, 168, 1, 5]), 24); | |||
| 58 | const HTTP_LISTEN_PORT: u16 = 80; | 58 | const HTTP_LISTEN_PORT: u16 = 80; |
| 59 | 59 | ||
| 60 | pub type SpeSpi = Spi<'static, peripherals::SPI2, peripherals::DMA1_CH1, peripherals::DMA1_CH2>; | 60 | pub type SpeSpi = Spi<'static, peripherals::SPI2, peripherals::DMA1_CH1, peripherals::DMA1_CH2>; |
| 61 | pub type SpeSpiCs = ExclusiveDevice<SpeSpi, Output<'static, peripherals::PB12>, Delay>; | 61 | pub type SpeSpiCs = ExclusiveDevice<SpeSpi, Output<'static>, Delay>; |
| 62 | pub type SpeInt = exti::ExtiInput<'static, peripherals::PB11>; | 62 | pub type SpeInt = exti::ExtiInput<'static>; |
| 63 | pub type SpeRst = Output<'static, peripherals::PC7>; | 63 | pub type SpeRst = Output<'static>; |
| 64 | pub type Adin1110T = ADIN1110<SpeSpiCs>; | 64 | pub type Adin1110T = ADIN1110<SpeSpiCs>; |
| 65 | pub type TempSensI2c = I2c<'static, peripherals::I2C3, peripherals::DMA1_CH6, peripherals::DMA1_CH7>; | 65 | pub type TempSensI2c = I2c<'static, peripherals::I2C3, peripherals::DMA1_CH6, peripherals::DMA1_CH7>; |
| 66 | 66 | ||
| @@ -75,7 +75,7 @@ async fn main(spawner: Spawner) { | |||
| 75 | use embassy_stm32::rcc::*; | 75 | use embassy_stm32::rcc::*; |
| 76 | // 80Mhz clock (Source: 8 / SrcDiv: 1 * PllMul 20 / ClkDiv 2) | 76 | // 80Mhz clock (Source: 8 / SrcDiv: 1 * PllMul 20 / ClkDiv 2) |
| 77 | // 80MHz highest frequency for flash 0 wait. | 77 | // 80MHz highest frequency for flash 0 wait. |
| 78 | config.rcc.mux = ClockSrc::PLL1_R; | 78 | config.rcc.sys = Sysclk::PLL1_R; |
| 79 | config.rcc.hse = Some(Hse { | 79 | config.rcc.hse = Some(Hse { |
| 80 | freq: Hertz::mhz(8), | 80 | freq: Hertz::mhz(8), |
| 81 | mode: HseMode::Oscillator, | 81 | mode: HseMode::Oscillator, |
| @@ -134,8 +134,7 @@ async fn main(spawner: Spawner) { | |||
| 134 | let spe_cfg1 = Input::new(dp.PC9, Pull::None); | 134 | let spe_cfg1 = Input::new(dp.PC9, Pull::None); |
| 135 | let _spe_ts_capt = Output::new(dp.PC6, Level::Low, Speed::Low); | 135 | let _spe_ts_capt = Output::new(dp.PC6, Level::Low, Speed::Low); |
| 136 | 136 | ||
| 137 | let spe_int = Input::new(dp.PB11, Pull::None); | 137 | let spe_int = exti::ExtiInput::new(dp.PB11, dp.EXTI11, Pull::None); |
| 138 | let spe_int = exti::ExtiInput::new(spe_int, dp.EXTI11); | ||
| 139 | 138 | ||
| 140 | let spe_spi_cs_n = Output::new(dp.PB12, Level::High, Speed::High); | 139 | let spe_spi_cs_n = Output::new(dp.PB12, Level::High, Speed::High); |
| 141 | let spe_spi_sclk = dp.PB13; | 140 | let spe_spi_sclk = dp.PB13; |
| @@ -298,7 +297,7 @@ async fn wait_for_config(stack: &'static Stack<Device<'static>>) -> embassy_net: | |||
| 298 | } | 297 | } |
| 299 | 298 | ||
| 300 | #[embassy_executor::task] | 299 | #[embassy_executor::task] |
| 301 | async fn heartbeat_led(mut led: Output<'static, peripherals::PE6>) { | 300 | async fn heartbeat_led(mut led: Output<'static>) { |
| 302 | let mut tmr = Ticker::every(Duration::from_hz(3)); | 301 | let mut tmr = Ticker::every(Duration::from_hz(3)); |
| 303 | loop { | 302 | loop { |
| 304 | led.toggle(); | 303 | led.toggle(); |
| @@ -308,7 +307,7 @@ async fn heartbeat_led(mut led: Output<'static, peripherals::PE6>) { | |||
| 308 | 307 | ||
| 309 | // ADT7422 | 308 | // ADT7422 |
| 310 | #[embassy_executor::task] | 309 | #[embassy_executor::task] |
| 311 | async fn temp_task(temp_dev_i2c: TempSensI2c, mut led: Output<'static, peripherals::PG15>) -> ! { | 310 | async fn temp_task(temp_dev_i2c: TempSensI2c, mut led: Output<'static>) -> ! { |
| 312 | let mut tmr = Ticker::every(Duration::from_hz(1)); | 311 | let mut tmr = Ticker::every(Duration::from_hz(1)); |
| 313 | let mut temp_sens = ADT7422::new(temp_dev_i2c, 0x48).unwrap(); | 312 | let mut temp_sens = ADT7422::new(temp_dev_i2c, 0x48).unwrap(); |
| 314 | 313 | ||
diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index 8cc9a7aed..9247e56a1 100644 --- a/examples/stm32l4/src/bin/usb_serial.rs +++ b/examples/stm32l4/src/bin/usb_serial.rs | |||
| @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) { | |||
| 23 | 23 | ||
| 24 | let mut config = Config::default(); | 24 | let mut config = Config::default(); |
| 25 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB | 25 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB |
| 26 | config.rcc.mux = ClockSrc::PLL1_R; | 26 | config.rcc.sys = Sysclk::PLL1_R; |
| 27 | config.rcc.hsi = true; | 27 | config.rcc.hsi = true; |
| 28 | config.rcc.pll = Some(Pll { | 28 | config.rcc.pll = Some(Pll { |
| 29 | source: PllSource::HSI, | 29 | source: PllSource::HSI, |
diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 0c6beb72c..5bcee178f 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml | |||
| @@ -13,7 +13,7 @@ embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["de | |||
| 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } |
| 14 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } | 14 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"] } |
| 15 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 15 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 16 | usbd-hid = "0.6.0" | 16 | usbd-hid = "0.7.0" |
| 17 | 17 | ||
| 18 | defmt = "0.3" | 18 | defmt = "0.3" |
| 19 | defmt-rtt = "0.4" | 19 | defmt-rtt = "0.4" |
diff --git a/examples/stm32l5/src/bin/button_exti.rs b/examples/stm32l5/src/bin/button_exti.rs index 91d0ccc2e..e6639d22b 100644 --- a/examples/stm32l5/src/bin/button_exti.rs +++ b/examples/stm32l5/src/bin/button_exti.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::exti::ExtiInput; | 6 | use embassy_stm32::exti::ExtiInput; |
| 7 | use embassy_stm32::gpio::{Input, Pull}; | 7 | use embassy_stm32::gpio::Pull; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -12,8 +12,7 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let button = Input::new(p.PC13, Pull::Down); | 15 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Down); |
| 16 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 17 | 16 | ||
| 18 | info!("Press the USER button..."); | 17 | info!("Press the USER button..."); |
| 19 | 18 | ||
diff --git a/examples/stm32l5/src/bin/rng.rs b/examples/stm32l5/src/bin/rng.rs index 50da6c946..0a644e73d 100644 --- a/examples/stm32l5/src/bin/rng.rs +++ b/examples/stm32l5/src/bin/rng.rs | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::rcc::{ClockSrc, Pll, PllMul, PllPreDiv, PllRDiv, PllSource}; | 6 | use embassy_stm32::rcc::{Pll, PllMul, PllPreDiv, PllRDiv, PllSource, Sysclk}; |
| 7 | use embassy_stm32::rng::Rng; | 7 | use embassy_stm32::rng::Rng; |
| 8 | use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -16,7 +16,7 @@ bind_interrupts!(struct Irqs { | |||
| 16 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| 17 | let mut config = Config::default(); | 17 | let mut config = Config::default(); |
| 18 | config.rcc.hsi = true; | 18 | config.rcc.hsi = true; |
| 19 | config.rcc.mux = ClockSrc::PLL1_R; | 19 | config.rcc.sys = Sysclk::PLL1_R; |
| 20 | config.rcc.pll = Some(Pll { | 20 | config.rcc.pll = Some(Pll { |
| 21 | // 64Mhz clock (16 / 1 * 8 / 2) | 21 | // 64Mhz clock (16 / 1 * 8 / 2) |
| 22 | source: PllSource::HSI, | 22 | source: PllSource::HSI, |
diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index 88060b6b0..f6d8b16d0 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs | |||
| @@ -45,7 +45,7 @@ async fn net_task(stack: &'static Stack<Device<'static, MTU>>) -> ! { | |||
| 45 | async fn main(spawner: Spawner) { | 45 | async fn main(spawner: Spawner) { |
| 46 | let mut config = Config::default(); | 46 | let mut config = Config::default(); |
| 47 | config.rcc.hsi = true; | 47 | config.rcc.hsi = true; |
| 48 | config.rcc.mux = ClockSrc::PLL1_R; | 48 | config.rcc.sys = Sysclk::PLL1_R; |
| 49 | config.rcc.pll = Some(Pll { | 49 | config.rcc.pll = Some(Pll { |
| 50 | // 80Mhz clock (16 / 1 * 10 / 2) | 50 | // 80Mhz clock (16 / 1 * 10 / 2) |
| 51 | source: PllSource::HSI, | 51 | source: PllSource::HSI, |
diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs index 7c8a8ebfb..c51ed96e0 100644 --- a/examples/stm32l5/src/bin/usb_hid_mouse.rs +++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs | |||
| @@ -22,7 +22,7 @@ bind_interrupts!(struct Irqs { | |||
| 22 | async fn main(_spawner: Spawner) { | 22 | async fn main(_spawner: Spawner) { |
| 23 | let mut config = Config::default(); | 23 | let mut config = Config::default(); |
| 24 | config.rcc.hsi = true; | 24 | config.rcc.hsi = true; |
| 25 | config.rcc.mux = ClockSrc::PLL1_R; | 25 | config.rcc.sys = Sysclk::PLL1_R; |
| 26 | config.rcc.pll = Some(Pll { | 26 | config.rcc.pll = Some(Pll { |
| 27 | // 80Mhz clock (16 / 1 * 10 / 2) | 27 | // 80Mhz clock (16 / 1 * 10 / 2) |
| 28 | source: PllSource::HSI, | 28 | source: PllSource::HSI, |
diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs index 75053ce4b..87987f2ce 100644 --- a/examples/stm32l5/src/bin/usb_serial.rs +++ b/examples/stm32l5/src/bin/usb_serial.rs | |||
| @@ -20,7 +20,7 @@ bind_interrupts!(struct Irqs { | |||
| 20 | async fn main(_spawner: Spawner) { | 20 | async fn main(_spawner: Spawner) { |
| 21 | let mut config = Config::default(); | 21 | let mut config = Config::default(); |
| 22 | config.rcc.hsi = true; | 22 | config.rcc.hsi = true; |
| 23 | config.rcc.mux = ClockSrc::PLL1_R; | 23 | config.rcc.sys = Sysclk::PLL1_R; |
| 24 | config.rcc.pll = Some(Pll { | 24 | config.rcc.pll = Some(Pll { |
| 25 | // 80Mhz clock (16 / 1 * 10 / 2) | 25 | // 80Mhz clock (16 / 1 * 10 / 2) |
| 26 | source: PllSource::HSI, | 26 | source: PllSource::HSI, |
diff --git a/examples/stm32u5/src/bin/flash.rs b/examples/stm32u5/src/bin/flash.rs new file mode 100644 index 000000000..e4fd6bb9c --- /dev/null +++ b/examples/stm32u5/src/bin/flash.rs | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::{info, unwrap}; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::flash::Flash; | ||
| 7 | use embassy_time::Timer; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | |||
| 10 | #[embassy_executor::main] | ||
| 11 | async fn main(_spawner: Spawner) { | ||
| 12 | let p = embassy_stm32::init(Default::default()); | ||
| 13 | info!("Hello Flash!"); | ||
| 14 | |||
| 15 | const ADDR: u32 = 0x8_0000; // This is the offset into the third region, the absolute address is 4x32K + 128K + 0x8_0000. | ||
| 16 | |||
| 17 | // wait a bit before accessing the flash | ||
| 18 | Timer::after_millis(300).await; | ||
| 19 | |||
| 20 | let mut f = Flash::new_blocking(p.FLASH).into_blocking_regions().bank1_region; | ||
| 21 | |||
| 22 | info!("Reading..."); | ||
| 23 | let mut buf = [0u8; 32]; | ||
| 24 | unwrap!(f.blocking_read(ADDR, &mut buf)); | ||
| 25 | info!("Read: {=[u8]:x}", buf); | ||
| 26 | |||
| 27 | info!("Erasing..."); | ||
| 28 | unwrap!(f.blocking_erase(ADDR, ADDR + 256 * 1024)); | ||
| 29 | |||
| 30 | info!("Reading..."); | ||
| 31 | let mut buf = [0u8; 32]; | ||
| 32 | unwrap!(f.blocking_read(ADDR, &mut buf)); | ||
| 33 | info!("Read after erase: {=[u8]:x}", buf); | ||
| 34 | |||
| 35 | info!("Writing..."); | ||
| 36 | unwrap!(f.blocking_write( | ||
| 37 | ADDR, | ||
| 38 | &[ | ||
| 39 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, | ||
| 40 | 30, 31, 32 | ||
| 41 | ] | ||
| 42 | )); | ||
| 43 | |||
| 44 | info!("Reading..."); | ||
| 45 | let mut buf = [0u8; 32]; | ||
| 46 | unwrap!(f.blocking_read(ADDR, &mut buf)); | ||
| 47 | info!("Read: {=[u8]:x}", buf); | ||
| 48 | assert_eq!( | ||
| 49 | &buf[..], | ||
| 50 | &[ | ||
| 51 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, | ||
| 52 | 30, 31, 32 | ||
| 53 | ] | ||
| 54 | ); | ||
| 55 | } | ||
diff --git a/examples/stm32u5/src/bin/i2c.rs b/examples/stm32u5/src/bin/i2c.rs new file mode 100644 index 000000000..e376c6bc8 --- /dev/null +++ b/examples/stm32u5/src/bin/i2c.rs | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::{info, unwrap}; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::dma::NoDma; | ||
| 7 | use embassy_stm32::i2c::I2c; | ||
| 8 | use embassy_stm32::time::Hertz; | ||
| 9 | use embassy_stm32::{bind_interrupts, i2c, peripherals}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | const HTS221_ADDRESS: u8 = 0x5F; | ||
| 13 | const WHOAMI: u8 = 0x0F; | ||
| 14 | |||
| 15 | bind_interrupts!(struct Irqs { | ||
| 16 | I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>; | ||
| 17 | I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>; | ||
| 18 | }); | ||
| 19 | |||
| 20 | #[embassy_executor::main] | ||
| 21 | async fn main(_spawner: Spawner) { | ||
| 22 | let p = embassy_stm32::init(Default::default()); | ||
| 23 | let mut i2c = I2c::new( | ||
| 24 | p.I2C2, | ||
| 25 | p.PH4, | ||
| 26 | p.PH5, | ||
| 27 | Irqs, | ||
| 28 | NoDma, | ||
| 29 | NoDma, | ||
| 30 | Hertz(100_000), | ||
| 31 | Default::default(), | ||
| 32 | ); | ||
| 33 | |||
| 34 | let mut data = [0u8; 1]; | ||
| 35 | unwrap!(i2c.blocking_write_read(HTS221_ADDRESS, &[WHOAMI], &mut data)); | ||
| 36 | |||
| 37 | // HTS221 data sheet is here: https://www.st.com/resource/en/datasheet/hts221.pdf | ||
| 38 | // 7.1 WHO_AM_I command is x0F which expected response xBC. | ||
| 39 | info!("Whoami: 0x{:02x}", data[0]); | ||
| 40 | assert_eq!(0xBC, data[0]); | ||
| 41 | } | ||
diff --git a/examples/stm32u5/src/bin/rng.rs b/examples/stm32u5/src/bin/rng.rs new file mode 100644 index 000000000..3a5bce097 --- /dev/null +++ b/examples/stm32u5/src/bin/rng.rs | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::rng::Rng; | ||
| 7 | use embassy_stm32::{bind_interrupts, peripherals, rng}; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | |||
| 10 | bind_interrupts!(struct Irqs { | ||
| 11 | RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 12 | }); | ||
| 13 | |||
| 14 | #[embassy_executor::main] | ||
| 15 | async fn main(_spawner: Spawner) { | ||
| 16 | let p = embassy_stm32::init(Default::default()); | ||
| 17 | |||
| 18 | info!("Hello World!"); | ||
| 19 | |||
| 20 | let mut rng = Rng::new(p.RNG, Irqs); | ||
| 21 | |||
| 22 | let mut buf = [0u8; 16]; | ||
| 23 | unwrap!(rng.async_fill_bytes(&mut buf).await); | ||
| 24 | info!("random bytes: {:02x}", buf); | ||
| 25 | } | ||
diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs index dca34fd0e..61851e5a2 100644 --- a/examples/stm32u5/src/bin/usb_serial.rs +++ b/examples/stm32u5/src/bin/usb_serial.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | use defmt::{panic, *}; | 4 | use defmt::{panic, *}; |
| 5 | use defmt_rtt as _; // global logger | 5 | use defmt_rtt as _; // global logger |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::rcc::*; | ||
| 8 | use embassy_stm32::usb_otg::{Driver, Instance}; | 7 | use embassy_stm32::usb_otg::{Driver, Instance}; |
| 9 | use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; | 8 | use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; |
| 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 9 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| @@ -22,22 +21,28 @@ async fn main(_spawner: Spawner) { | |||
| 22 | info!("Hello World!"); | 21 | info!("Hello World!"); |
| 23 | 22 | ||
| 24 | let mut config = Config::default(); | 23 | let mut config = Config::default(); |
| 25 | config.rcc.mux = ClockSrc::PLL1_R(PllConfig { | 24 | { |
| 26 | source: PllSource::HSI, | 25 | use embassy_stm32::rcc::*; |
| 27 | m: Pllm::DIV2, | 26 | config.rcc.hsi = true; |
| 28 | n: Plln::MUL10, | 27 | config.rcc.pll1 = Some(Pll { |
| 29 | p: Plldiv::DIV1, | 28 | source: PllSource::HSI, // 16 MHz |
| 30 | q: Plldiv::DIV1, | 29 | prediv: PllPreDiv::DIV1, |
| 31 | r: Plldiv::DIV1, | 30 | mul: PllMul::MUL10, |
| 32 | }); | 31 | divp: None, |
| 33 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB | 32 | divq: None, |
| 33 | divr: Some(PllDiv::DIV1), // 160 MHz | ||
| 34 | }); | ||
| 35 | config.rcc.sys = Sysclk::PLL1_R; | ||
| 36 | config.rcc.voltage_range = VoltageScale::RANGE1; | ||
| 37 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB | ||
| 38 | } | ||
| 34 | 39 | ||
| 35 | let p = embassy_stm32::init(config); | 40 | let p = embassy_stm32::init(config); |
| 36 | 41 | ||
| 37 | // Create the driver, from the HAL. | 42 | // Create the driver, from the HAL. |
| 38 | let mut ep_out_buffer = [0u8; 256]; | 43 | let mut ep_out_buffer = [0u8; 256]; |
| 39 | let mut config = embassy_stm32::usb_otg::Config::default(); | 44 | let mut config = embassy_stm32::usb_otg::Config::default(); |
| 40 | config.vbus_detection = true; | 45 | config.vbus_detection = false; |
| 41 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); | 46 | let driver = Driver::new_fs(p.USB_OTG_FS, Irqs, p.PA12, p.PA11, &mut ep_out_buffer, config); |
| 42 | 47 | ||
| 43 | // Create embassy-usb Config | 48 | // Create embassy-usb Config |
diff --git a/examples/stm32wb/src/bin/button_exti.rs b/examples/stm32wb/src/bin/button_exti.rs index d34dde3e9..2871fd55f 100644 --- a/examples/stm32wb/src/bin/button_exti.rs +++ b/examples/stm32wb/src/bin/button_exti.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::exti::ExtiInput; | 6 | use embassy_stm32::exti::ExtiInput; |
| 7 | use embassy_stm32::gpio::{Input, Pull}; | 7 | use embassy_stm32::gpio::Pull; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -12,8 +12,7 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let button = Input::new(p.PC4, Pull::Up); | 15 | let mut button = ExtiInput::new(p.PC4, p.EXTI4, Pull::Up); |
| 16 | let mut button = ExtiInput::new(button, p.EXTI4); | ||
| 17 | 16 | ||
| 18 | info!("Press the USER button..."); | 17 | info!("Press the USER button..."); |
| 19 | 18 | ||
diff --git a/examples/stm32wba/src/bin/button_exti.rs b/examples/stm32wba/src/bin/button_exti.rs index 1e970fdd6..34a08bbc6 100644 --- a/examples/stm32wba/src/bin/button_exti.rs +++ b/examples/stm32wba/src/bin/button_exti.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::exti::ExtiInput; | 6 | use embassy_stm32::exti::ExtiInput; |
| 7 | use embassy_stm32::gpio::{Input, Pull}; | 7 | use embassy_stm32::gpio::Pull; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -12,8 +12,7 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let button = Input::new(p.PC13, Pull::Up); | 15 | let mut button = ExtiInput::new(p.PC13, p.EXTI13, Pull::Up); |
| 16 | let mut button = ExtiInput::new(button, p.EXTI13); | ||
| 17 | 16 | ||
| 18 | info!("Press the USER button..."); | 17 | info!("Press the USER button..."); |
| 19 | 18 | ||
diff --git a/examples/stm32wl/src/bin/button_exti.rs b/examples/stm32wl/src/bin/button_exti.rs index e6ad4b80b..27d5330bd 100644 --- a/examples/stm32wl/src/bin/button_exti.rs +++ b/examples/stm32wl/src/bin/button_exti.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::exti::ExtiInput; | 6 | use embassy_stm32::exti::ExtiInput; |
| 7 | use embassy_stm32::gpio::{Input, Pull}; | 7 | use embassy_stm32::gpio::Pull; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -12,8 +12,7 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_stm32::init(Default::default()); | 12 | let p = embassy_stm32::init(Default::default()); |
| 13 | info!("Hello World!"); | 13 | info!("Hello World!"); |
| 14 | 14 | ||
| 15 | let button = Input::new(p.PA0, Pull::Up); | 15 | let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Up); |
| 16 | let mut button = ExtiInput::new(button, p.EXTI0); | ||
| 17 | 16 | ||
| 18 | info!("Press the USER button..."); | 17 | info!("Press the USER button..."); |
| 19 | 18 | ||
diff --git a/examples/stm32wl/src/bin/random.rs b/examples/stm32wl/src/bin/random.rs index 3610392be..8e9fe02b2 100644 --- a/examples/stm32wl/src/bin/random.rs +++ b/examples/stm32wl/src/bin/random.rs | |||
| @@ -22,7 +22,7 @@ async fn main(_spawner: Spawner) { | |||
| 22 | mode: HseMode::Bypass, | 22 | mode: HseMode::Bypass, |
| 23 | prescaler: HsePrescaler::DIV1, | 23 | prescaler: HsePrescaler::DIV1, |
| 24 | }); | 24 | }); |
| 25 | config.rcc.mux = ClockSrc::PLL1_R; | 25 | config.rcc.sys = Sysclk::PLL1_R; |
| 26 | config.rcc.pll = Some(Pll { | 26 | config.rcc.pll = Some(Pll { |
| 27 | source: PllSource::HSE, | 27 | source: PllSource::HSE, |
| 28 | prediv: PllPreDiv::DIV2, | 28 | prediv: PllPreDiv::DIV2, |
diff --git a/examples/stm32wl/src/bin/rtc.rs b/examples/stm32wl/src/bin/rtc.rs index 4738d5770..cf7d6d220 100644 --- a/examples/stm32wl/src/bin/rtc.rs +++ b/examples/stm32wl/src/bin/rtc.rs | |||
| @@ -21,7 +21,7 @@ async fn main(_spawner: Spawner) { | |||
| 21 | mode: HseMode::Bypass, | 21 | mode: HseMode::Bypass, |
| 22 | prescaler: HsePrescaler::DIV1, | 22 | prescaler: HsePrescaler::DIV1, |
| 23 | }); | 23 | }); |
| 24 | config.rcc.mux = ClockSrc::PLL1_R; | 24 | config.rcc.sys = Sysclk::PLL1_R; |
| 25 | config.rcc.pll = Some(Pll { | 25 | config.rcc.pll = Some(Pll { |
| 26 | source: PllSource::HSE, | 26 | source: PllSource::HSE, |
| 27 | prediv: PllPreDiv::DIV2, | 27 | prediv: PllPreDiv::DIV2, |
| @@ -40,7 +40,7 @@ async fn main(_spawner: Spawner) { | |||
| 40 | .unwrap(); | 40 | .unwrap(); |
| 41 | 41 | ||
| 42 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); | 42 | let mut rtc = Rtc::new(p.RTC, RtcConfig::default()); |
| 43 | info!("Got RTC! {:?}", now.timestamp()); | 43 | info!("Got RTC! {:?}", now.and_utc().timestamp()); |
| 44 | 44 | ||
| 45 | rtc.set_datetime(now.into()).expect("datetime not set"); | 45 | rtc.set_datetime(now.into()).expect("datetime not set"); |
| 46 | 46 | ||
| @@ -48,5 +48,5 @@ async fn main(_spawner: Spawner) { | |||
| 48 | Timer::after_millis(20000).await; | 48 | Timer::after_millis(20000).await; |
| 49 | 49 | ||
| 50 | let then: NaiveDateTime = rtc.now().unwrap().into(); | 50 | let then: NaiveDateTime = rtc.now().unwrap().into(); |
| 51 | info!("Got RTC! {:?}", then.timestamp()); | 51 | info!("Got RTC! {:?}", then.and_utc().timestamp()); |
| 52 | } | 52 | } |
diff --git a/examples/stm32wl/src/bin/uart_async.rs b/examples/stm32wl/src/bin/uart_async.rs index 8e545834c..3637243a0 100644 --- a/examples/stm32wl/src/bin/uart_async.rs +++ b/examples/stm32wl/src/bin/uart_async.rs | |||
| @@ -20,7 +20,7 @@ but can be surely changed for your needs. | |||
| 20 | #[embassy_executor::main] | 20 | #[embassy_executor::main] |
| 21 | async fn main(_spawner: Spawner) { | 21 | async fn main(_spawner: Spawner) { |
| 22 | let mut config = embassy_stm32::Config::default(); | 22 | let mut config = embassy_stm32::Config::default(); |
| 23 | config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; | 23 | config.rcc.sys = embassy_stm32::rcc::Sysclk::HSE; |
| 24 | let p = embassy_stm32::init(config); | 24 | let p = embassy_stm32::init(config); |
| 25 | 25 | ||
| 26 | defmt::info!("Starting system"); | 26 | defmt::info!("Starting system"); |
