diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-04-08 03:15:27 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-04-08 03:15:27 +0200 |
| commit | 0c07d0375406c6079e4b143cd7ac380d0a2bfd5f (patch) | |
| tree | 68de96e3c66e3fd077aae60aa002f2b2941ee4af /examples/stm32wl | |
| parent | 50ff63ab888352b6818898617588cc844250c9b7 (diff) | |
Add missing stm32wl/stm32wb chips except stm32wle
Diffstat (limited to 'examples/stm32wl')
| -rw-r--r-- | examples/stm32wl/.cargo/config.toml | 6 | ||||
| -rw-r--r-- | examples/stm32wl/Cargo.toml | 24 | ||||
| -rw-r--r-- | examples/stm32wl/build.rs | 5 | ||||
| -rw-r--r-- | examples/stm32wl/src/bin/blinky.rs | 28 | ||||
| -rw-r--r-- | examples/stm32wl/src/bin/button.rs | 31 | ||||
| -rw-r--r-- | examples/stm32wl/src/bin/button_exti.rs | 28 | ||||
| -rw-r--r-- | examples/stm32wl/src/bin/lorawan.rs | 72 | ||||
| -rw-r--r-- | examples/stm32wl/src/bin/subghz.rs | 130 |
8 files changed, 324 insertions, 0 deletions
diff --git a/examples/stm32wl/.cargo/config.toml b/examples/stm32wl/.cargo/config.toml new file mode 100644 index 000000000..60076e06b --- /dev/null +++ b/examples/stm32wl/.cargo/config.toml | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | ||
| 2 | # replace your chip as listed in `probe-run --list-chips` | ||
| 3 | runner = "probe-run --chip STM32WLE5JCIx" | ||
| 4 | |||
| 5 | [build] | ||
| 6 | target = "thumbv7em-none-eabihf" | ||
diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml new file mode 100644 index 000000000..e95a009ce --- /dev/null +++ b/examples/stm32wl/Cargo.toml | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | [package] | ||
| 2 | authors = ["Dario Nieuwenhuis <[email protected]>", "Ulf Lilleengen <[email protected]>"] | ||
| 3 | edition = "2018" | ||
| 4 | name = "embassy-stm32wl-examples" | ||
| 5 | version = "0.1.0" | ||
| 6 | resolver = "2" | ||
| 7 | |||
| 8 | [dependencies] | ||
| 9 | embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-timestamp-uptime"] } | ||
| 10 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "subghz", "unstable-pac", "exti"] } | ||
| 11 | embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time"] } | ||
| 12 | |||
| 13 | lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "0de1a2a31933f7c97887b5718c1755fa5ab93a42", default-features = false, features = ["async"] } | ||
| 14 | lorawan-encoding = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "0de1a2a31933f7c97887b5718c1755fa5ab93a42", default-features = false, features = ["default-crypto"] } | ||
| 15 | |||
| 16 | defmt = "0.3" | ||
| 17 | defmt-rtt = "0.3" | ||
| 18 | |||
| 19 | cortex-m = "0.7.3" | ||
| 20 | cortex-m-rt = "0.7.0" | ||
| 21 | embedded-hal = "0.2.6" | ||
| 22 | panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
| 23 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | ||
| 24 | heapless = { version = "0.7.5", default-features = false } | ||
diff --git a/examples/stm32wl/build.rs b/examples/stm32wl/build.rs new file mode 100644 index 000000000..8cd32d7ed --- /dev/null +++ b/examples/stm32wl/build.rs | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | fn main() { | ||
| 2 | println!("cargo:rustc-link-arg-bins=--nmagic"); | ||
| 3 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | ||
| 4 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
| 5 | } | ||
diff --git a/examples/stm32wl/src/bin/blinky.rs b/examples/stm32wl/src/bin/blinky.rs new file mode 100644 index 000000000..78079bfd3 --- /dev/null +++ b/examples/stm32wl/src/bin/blinky.rs | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | use defmt::*; | ||
| 6 | use defmt_rtt as _; // global logger | ||
| 7 | use embassy::executor::Spawner; | ||
| 8 | use embassy::time::{Duration, Timer}; | ||
| 9 | use embassy_stm32::gpio::{Level, Output, Speed}; | ||
| 10 | use embassy_stm32::Peripherals; | ||
| 11 | use panic_probe as _; | ||
| 12 | |||
| 13 | #[embassy::main] | ||
| 14 | async fn main(_spawner: Spawner, p: Peripherals) { | ||
| 15 | info!("Hello World!"); | ||
| 16 | |||
| 17 | let mut led = Output::new(p.PB15, Level::High, Speed::Low); | ||
| 18 | |||
| 19 | loop { | ||
| 20 | info!("high"); | ||
| 21 | led.set_high(); | ||
| 22 | Timer::after(Duration::from_millis(500)).await; | ||
| 23 | |||
| 24 | info!("low"); | ||
| 25 | led.set_low(); | ||
| 26 | Timer::after(Duration::from_millis(500)).await; | ||
| 27 | } | ||
| 28 | } | ||
diff --git a/examples/stm32wl/src/bin/button.rs b/examples/stm32wl/src/bin/button.rs new file mode 100644 index 000000000..f80b9ab4f --- /dev/null +++ b/examples/stm32wl/src/bin/button.rs | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | use defmt::*; | ||
| 6 | use defmt_rtt as _; // global logger | ||
| 7 | use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; | ||
| 8 | use panic_probe as _; | ||
| 9 | |||
| 10 | use cortex_m_rt::entry; | ||
| 11 | |||
| 12 | #[entry] | ||
| 13 | fn main() -> ! { | ||
| 14 | info!("Hello World!"); | ||
| 15 | |||
| 16 | let p = embassy_stm32::init(Default::default()); | ||
| 17 | |||
| 18 | let button = Input::new(p.PA0, Pull::Up); | ||
| 19 | let mut led1 = Output::new(p.PB15, Level::High, Speed::Low); | ||
| 20 | let mut led2 = Output::new(p.PB9, Level::High, Speed::Low); | ||
| 21 | |||
| 22 | loop { | ||
| 23 | if button.is_high() { | ||
| 24 | led1.set_high(); | ||
| 25 | led2.set_low(); | ||
| 26 | } else { | ||
| 27 | led1.set_low(); | ||
| 28 | led2.set_high(); | ||
| 29 | } | ||
| 30 | } | ||
| 31 | } | ||
diff --git a/examples/stm32wl/src/bin/button_exti.rs b/examples/stm32wl/src/bin/button_exti.rs new file mode 100644 index 000000000..9a427c2d3 --- /dev/null +++ b/examples/stm32wl/src/bin/button_exti.rs | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | use defmt::*; | ||
| 6 | use defmt_rtt as _; // global logger | ||
| 7 | use embassy::executor::Spawner; | ||
| 8 | use embassy_stm32::exti::ExtiInput; | ||
| 9 | use embassy_stm32::gpio::{Input, Pull}; | ||
| 10 | use embassy_stm32::Peripherals; | ||
| 11 | use panic_probe as _; | ||
| 12 | |||
| 13 | #[embassy::main] | ||
| 14 | async fn main(_spawner: Spawner, p: Peripherals) { | ||
| 15 | info!("Hello World!"); | ||
| 16 | |||
| 17 | let button = Input::new(p.PA0, Pull::Up); | ||
| 18 | let mut button = ExtiInput::new(button, p.EXTI0); | ||
| 19 | |||
| 20 | info!("Press the USER button..."); | ||
| 21 | |||
| 22 | loop { | ||
| 23 | button.wait_for_falling_edge().await; | ||
| 24 | info!("Pressed!"); | ||
| 25 | button.wait_for_rising_edge().await; | ||
| 26 | info!("Released!"); | ||
| 27 | } | ||
| 28 | } | ||
diff --git a/examples/stm32wl/src/bin/lorawan.rs b/examples/stm32wl/src/bin/lorawan.rs new file mode 100644 index 000000000..db4725630 --- /dev/null +++ b/examples/stm32wl/src/bin/lorawan.rs | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![macro_use] | ||
| 4 | #![allow(dead_code)] | ||
| 5 | #![feature(generic_associated_types)] | ||
| 6 | #![feature(type_alias_impl_trait)] | ||
| 7 | |||
| 8 | use defmt_rtt as _; // global logger | ||
| 9 | use panic_probe as _; | ||
| 10 | |||
| 11 | use embassy_lora::{stm32wl::*, LoraTimer}; | ||
| 12 | use embassy_stm32::{ | ||
| 13 | dma::NoDma, | ||
| 14 | gpio::{Level, Output, Pin, Speed}, | ||
| 15 | interrupt, pac, | ||
| 16 | rng::Rng, | ||
| 17 | subghz::*, | ||
| 18 | Peripherals, | ||
| 19 | }; | ||
| 20 | use lorawan_device::async_device::{region, Device, JoinMode}; | ||
| 21 | use lorawan_encoding::default_crypto::DefaultFactory as Crypto; | ||
| 22 | |||
| 23 | fn config() -> embassy_stm32::Config { | ||
| 24 | let mut config = embassy_stm32::Config::default(); | ||
| 25 | config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI16; | ||
| 26 | config.rcc.enable_lsi = true; | ||
| 27 | config | ||
| 28 | } | ||
| 29 | |||
| 30 | #[embassy::main(config = "config()")] | ||
| 31 | async fn main(_spawner: embassy::executor::Spawner, p: Peripherals) { | ||
| 32 | unsafe { pac::RCC.ccipr().modify(|w| w.set_rngsel(0b01)) } | ||
| 33 | |||
| 34 | let ctrl1 = Output::new(p.PC3.degrade(), Level::High, Speed::High); | ||
| 35 | let ctrl2 = Output::new(p.PC4.degrade(), Level::High, Speed::High); | ||
| 36 | let ctrl3 = Output::new(p.PC5.degrade(), Level::High, Speed::High); | ||
| 37 | let rfs = RadioSwitch::new(ctrl1, ctrl2, ctrl3); | ||
| 38 | |||
| 39 | let radio = SubGhz::new(p.SUBGHZSPI, p.PA5, p.PA7, p.PA6, NoDma, NoDma); | ||
| 40 | |||
| 41 | let irq = interrupt::take!(SUBGHZ_RADIO); | ||
| 42 | static mut RADIO_STATE: SubGhzState<'static> = SubGhzState::new(); | ||
| 43 | let radio = unsafe { SubGhzRadio::new(&mut RADIO_STATE, radio, rfs, irq) }; | ||
| 44 | |||
| 45 | let region = region::EU868::default().into(); | ||
| 46 | let mut radio_buffer = [0; 256]; | ||
| 47 | let mut device: Device<'_, _, Crypto, _, _> = Device::new( | ||
| 48 | region, | ||
| 49 | radio, | ||
| 50 | LoraTimer, | ||
| 51 | Rng::new(p.RNG), | ||
| 52 | &mut radio_buffer[..], | ||
| 53 | ); | ||
| 54 | |||
| 55 | defmt::info!("Joining LoRaWAN network"); | ||
| 56 | |||
| 57 | // TODO: Adjust the EUI and Keys according to your network credentials | ||
| 58 | device | ||
| 59 | .join(&JoinMode::OTAA { | ||
| 60 | deveui: [0, 0, 0, 0, 0, 0, 0, 0], | ||
| 61 | appeui: [0, 0, 0, 0, 0, 0, 0, 0], | ||
| 62 | appkey: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | ||
| 63 | }) | ||
| 64 | .await | ||
| 65 | .ok() | ||
| 66 | .unwrap(); | ||
| 67 | defmt::info!("LoRaWAN network joined"); | ||
| 68 | |||
| 69 | defmt::info!("Sending 'PING'"); | ||
| 70 | device.send(b"PING", 1, false).await.ok().unwrap(); | ||
| 71 | defmt::info!("Message sent!"); | ||
| 72 | } | ||
diff --git a/examples/stm32wl/src/bin/subghz.rs b/examples/stm32wl/src/bin/subghz.rs new file mode 100644 index 000000000..562e25ac0 --- /dev/null +++ b/examples/stm32wl/src/bin/subghz.rs | |||
| @@ -0,0 +1,130 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![macro_use] | ||
| 4 | #![allow(dead_code)] | ||
| 5 | #![feature(generic_associated_types)] | ||
| 6 | #![feature(type_alias_impl_trait)] | ||
| 7 | |||
| 8 | use defmt_rtt as _; // global logger | ||
| 9 | use panic_probe as _; | ||
| 10 | |||
| 11 | use defmt::*; | ||
| 12 | use embassy::channel::signal::Signal; | ||
| 13 | use embassy::interrupt::{Interrupt, InterruptExt}; | ||
| 14 | use embassy_stm32::dma::NoDma; | ||
| 15 | use embassy_stm32::exti::ExtiInput; | ||
| 16 | use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; | ||
| 17 | use embassy_stm32::interrupt; | ||
| 18 | use embassy_stm32::subghz::*; | ||
| 19 | use embassy_stm32::Peripherals; | ||
| 20 | |||
| 21 | const PING_DATA: &str = "PING"; | ||
| 22 | const DATA_LEN: u8 = PING_DATA.len() as u8; | ||
| 23 | const PING_DATA_BYTES: &[u8] = PING_DATA.as_bytes(); | ||
| 24 | const PREAMBLE_LEN: u16 = 5 * 8; | ||
| 25 | |||
| 26 | const RF_FREQ: RfFreq = RfFreq::from_frequency(867_500_000); | ||
| 27 | |||
| 28 | const SYNC_WORD: [u8; 8] = [0x79, 0x80, 0x0C, 0xC0, 0x29, 0x95, 0xF8, 0x4A]; | ||
| 29 | const SYNC_WORD_LEN: u8 = SYNC_WORD.len() as u8; | ||
| 30 | const SYNC_WORD_LEN_BITS: u8 = SYNC_WORD_LEN * 8; | ||
| 31 | |||
| 32 | const TX_BUF_OFFSET: u8 = 128; | ||
| 33 | const RX_BUF_OFFSET: u8 = 0; | ||
| 34 | const LORA_PACKET_PARAMS: LoRaPacketParams = LoRaPacketParams::new() | ||
| 35 | .set_crc_en(true) | ||
| 36 | .set_preamble_len(PREAMBLE_LEN) | ||
| 37 | .set_payload_len(DATA_LEN) | ||
| 38 | .set_invert_iq(false) | ||
| 39 | .set_header_type(HeaderType::Fixed); | ||
| 40 | |||
| 41 | const LORA_MOD_PARAMS: LoRaModParams = LoRaModParams::new() | ||
| 42 | .set_bw(LoRaBandwidth::Bw125) | ||
| 43 | .set_cr(CodingRate::Cr45) | ||
| 44 | .set_ldro_en(true) | ||
| 45 | .set_sf(SpreadingFactor::Sf7); | ||
| 46 | |||
| 47 | // configuration for +10 dBm output power | ||
| 48 | // see table 35 "PA optimal setting and operating modes" | ||
| 49 | const PA_CONFIG: PaConfig = PaConfig::new() | ||
| 50 | .set_pa_duty_cycle(0x1) | ||
| 51 | .set_hp_max(0x0) | ||
| 52 | .set_pa(PaSel::Lp); | ||
| 53 | |||
| 54 | const TCXO_MODE: TcxoMode = TcxoMode::new() | ||
| 55 | .set_txco_trim(TcxoTrim::Volts1pt7) | ||
| 56 | .set_timeout(Timeout::from_duration_sat( | ||
| 57 | core::time::Duration::from_millis(10), | ||
| 58 | )); | ||
| 59 | |||
| 60 | const TX_PARAMS: TxParams = TxParams::new() | ||
| 61 | .set_power(0x0D) | ||
| 62 | .set_ramp_time(RampTime::Micros40); | ||
| 63 | |||
| 64 | fn config() -> embassy_stm32::Config { | ||
| 65 | let mut config = embassy_stm32::Config::default(); | ||
| 66 | config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE32; | ||
| 67 | config | ||
| 68 | } | ||
| 69 | |||
| 70 | #[embassy::main(config = "config()")] | ||
| 71 | async fn main(_spawner: embassy::executor::Spawner, p: Peripherals) { | ||
| 72 | let mut led1 = Output::new(p.PB15, Level::High, Speed::Low); | ||
| 73 | let mut led2 = Output::new(p.PB9, Level::Low, Speed::Low); | ||
| 74 | let mut led3 = Output::new(p.PB11, Level::Low, Speed::Low); | ||
| 75 | |||
| 76 | let button = Input::new(p.PA0, Pull::Up); | ||
| 77 | let mut pin = ExtiInput::new(button, p.EXTI0); | ||
| 78 | |||
| 79 | static IRQ_SIGNAL: Signal<()> = Signal::new(); | ||
| 80 | let radio_irq = interrupt::take!(SUBGHZ_RADIO); | ||
| 81 | radio_irq.set_handler(|_| { | ||
| 82 | IRQ_SIGNAL.signal(()); | ||
| 83 | unsafe { interrupt::SUBGHZ_RADIO::steal() }.disable(); | ||
| 84 | }); | ||
| 85 | |||
| 86 | let mut radio = SubGhz::new(p.SUBGHZSPI, p.PA5, p.PA7, p.PA6, NoDma, NoDma); | ||
| 87 | |||
| 88 | defmt::info!("Radio ready for use"); | ||
| 89 | |||
| 90 | led1.set_low(); | ||
| 91 | |||
| 92 | led2.set_high(); | ||
| 93 | |||
| 94 | unwrap!(radio.set_standby(StandbyClk::Rc)); | ||
| 95 | unwrap!(radio.set_tcxo_mode(&TCXO_MODE)); | ||
| 96 | unwrap!(radio.set_standby(StandbyClk::Hse)); | ||
| 97 | unwrap!(radio.set_regulator_mode(RegMode::Ldo)); | ||
| 98 | unwrap!(radio.set_buffer_base_address(TX_BUF_OFFSET, RX_BUF_OFFSET)); | ||
| 99 | unwrap!(radio.set_pa_config(&PA_CONFIG)); | ||
| 100 | unwrap!(radio.set_pa_ocp(Ocp::Max60m)); | ||
| 101 | unwrap!(radio.set_tx_params(&TX_PARAMS)); | ||
| 102 | unwrap!(radio.set_packet_type(PacketType::LoRa)); | ||
| 103 | unwrap!(radio.set_lora_sync_word(LoRaSyncWord::Public)); | ||
| 104 | unwrap!(radio.set_lora_mod_params(&LORA_MOD_PARAMS)); | ||
| 105 | unwrap!(radio.set_lora_packet_params(&LORA_PACKET_PARAMS)); | ||
| 106 | unwrap!(radio.calibrate_image(CalibrateImage::ISM_863_870)); | ||
| 107 | unwrap!(radio.set_rf_frequency(&RF_FREQ)); | ||
| 108 | |||
| 109 | defmt::info!("Status: {:?}", unwrap!(radio.status())); | ||
| 110 | |||
| 111 | led2.set_low(); | ||
| 112 | |||
| 113 | loop { | ||
| 114 | pin.wait_for_rising_edge().await; | ||
| 115 | led3.set_high(); | ||
| 116 | unwrap!(radio.set_irq_cfg(&CfgIrq::new().irq_enable_all(Irq::TxDone))); | ||
| 117 | unwrap!(radio.write_buffer(TX_BUF_OFFSET, PING_DATA_BYTES)); | ||
| 118 | unwrap!(radio.set_tx(Timeout::DISABLED)); | ||
| 119 | |||
| 120 | radio_irq.enable(); | ||
| 121 | IRQ_SIGNAL.wait().await; | ||
| 122 | |||
| 123 | let (_, irq_status) = unwrap!(radio.irq_status()); | ||
| 124 | if irq_status & Irq::TxDone.mask() != 0 { | ||
| 125 | defmt::info!("TX done"); | ||
| 126 | } | ||
| 127 | unwrap!(radio.clear_irq_status(irq_status)); | ||
| 128 | led3.set_low(); | ||
| 129 | } | ||
| 130 | } | ||
