From 0c07d0375406c6079e4b143cd7ac380d0a2bfd5f Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 8 Apr 2022 03:15:27 +0200 Subject: Add missing stm32wl/stm32wb chips except stm32wle --- examples/stm32wl/src/bin/blinky.rs | 28 +++++++ examples/stm32wl/src/bin/button.rs | 31 ++++++++ examples/stm32wl/src/bin/button_exti.rs | 28 +++++++ examples/stm32wl/src/bin/lorawan.rs | 72 ++++++++++++++++++ examples/stm32wl/src/bin/subghz.rs | 130 ++++++++++++++++++++++++++++++++ 5 files changed, 289 insertions(+) create mode 100644 examples/stm32wl/src/bin/blinky.rs create mode 100644 examples/stm32wl/src/bin/button.rs create mode 100644 examples/stm32wl/src/bin/button_exti.rs create mode 100644 examples/stm32wl/src/bin/lorawan.rs create mode 100644 examples/stm32wl/src/bin/subghz.rs (limited to 'examples/stm32wl/src') 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 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::*; +use defmt_rtt as _; // global logger +use embassy::executor::Spawner; +use embassy::time::{Duration, Timer}; +use embassy_stm32::gpio::{Level, Output, Speed}; +use embassy_stm32::Peripherals; +use panic_probe as _; + +#[embassy::main] +async fn main(_spawner: Spawner, p: Peripherals) { + info!("Hello World!"); + + let mut led = Output::new(p.PB15, Level::High, Speed::Low); + + loop { + info!("high"); + led.set_high(); + Timer::after(Duration::from_millis(500)).await; + + info!("low"); + led.set_low(); + Timer::after(Duration::from_millis(500)).await; + } +} 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 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::*; +use defmt_rtt as _; // global logger +use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; +use panic_probe as _; + +use cortex_m_rt::entry; + +#[entry] +fn main() -> ! { + info!("Hello World!"); + + let p = embassy_stm32::init(Default::default()); + + let button = Input::new(p.PA0, Pull::Up); + let mut led1 = Output::new(p.PB15, Level::High, Speed::Low); + let mut led2 = Output::new(p.PB9, Level::High, Speed::Low); + + loop { + if button.is_high() { + led1.set_high(); + led2.set_low(); + } else { + led1.set_low(); + led2.set_high(); + } + } +} 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 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::*; +use defmt_rtt as _; // global logger +use embassy::executor::Spawner; +use embassy_stm32::exti::ExtiInput; +use embassy_stm32::gpio::{Input, Pull}; +use embassy_stm32::Peripherals; +use panic_probe as _; + +#[embassy::main] +async fn main(_spawner: Spawner, p: Peripherals) { + info!("Hello World!"); + + let button = Input::new(p.PA0, Pull::Up); + let mut button = ExtiInput::new(button, p.EXTI0); + + info!("Press the USER button..."); + + loop { + button.wait_for_falling_edge().await; + info!("Pressed!"); + button.wait_for_rising_edge().await; + info!("Released!"); + } +} 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 @@ +#![no_std] +#![no_main] +#![macro_use] +#![allow(dead_code)] +#![feature(generic_associated_types)] +#![feature(type_alias_impl_trait)] + +use defmt_rtt as _; // global logger +use panic_probe as _; + +use embassy_lora::{stm32wl::*, LoraTimer}; +use embassy_stm32::{ + dma::NoDma, + gpio::{Level, Output, Pin, Speed}, + interrupt, pac, + rng::Rng, + subghz::*, + Peripherals, +}; +use lorawan_device::async_device::{region, Device, JoinMode}; +use lorawan_encoding::default_crypto::DefaultFactory as Crypto; + +fn config() -> embassy_stm32::Config { + let mut config = embassy_stm32::Config::default(); + config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSI16; + config.rcc.enable_lsi = true; + config +} + +#[embassy::main(config = "config()")] +async fn main(_spawner: embassy::executor::Spawner, p: Peripherals) { + unsafe { pac::RCC.ccipr().modify(|w| w.set_rngsel(0b01)) } + + let ctrl1 = Output::new(p.PC3.degrade(), Level::High, Speed::High); + let ctrl2 = Output::new(p.PC4.degrade(), Level::High, Speed::High); + let ctrl3 = Output::new(p.PC5.degrade(), Level::High, Speed::High); + let rfs = RadioSwitch::new(ctrl1, ctrl2, ctrl3); + + let radio = SubGhz::new(p.SUBGHZSPI, p.PA5, p.PA7, p.PA6, NoDma, NoDma); + + let irq = interrupt::take!(SUBGHZ_RADIO); + static mut RADIO_STATE: SubGhzState<'static> = SubGhzState::new(); + let radio = unsafe { SubGhzRadio::new(&mut RADIO_STATE, radio, rfs, irq) }; + + let region = region::EU868::default().into(); + let mut radio_buffer = [0; 256]; + let mut device: Device<'_, _, Crypto, _, _> = Device::new( + region, + radio, + LoraTimer, + Rng::new(p.RNG), + &mut radio_buffer[..], + ); + + defmt::info!("Joining LoRaWAN network"); + + // TODO: Adjust the EUI and Keys according to your network credentials + device + .join(&JoinMode::OTAA { + deveui: [0, 0, 0, 0, 0, 0, 0, 0], + appeui: [0, 0, 0, 0, 0, 0, 0, 0], + appkey: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + }) + .await + .ok() + .unwrap(); + defmt::info!("LoRaWAN network joined"); + + defmt::info!("Sending 'PING'"); + device.send(b"PING", 1, false).await.ok().unwrap(); + defmt::info!("Message sent!"); +} 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 @@ +#![no_std] +#![no_main] +#![macro_use] +#![allow(dead_code)] +#![feature(generic_associated_types)] +#![feature(type_alias_impl_trait)] + +use defmt_rtt as _; // global logger +use panic_probe as _; + +use defmt::*; +use embassy::channel::signal::Signal; +use embassy::interrupt::{Interrupt, InterruptExt}; +use embassy_stm32::dma::NoDma; +use embassy_stm32::exti::ExtiInput; +use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; +use embassy_stm32::interrupt; +use embassy_stm32::subghz::*; +use embassy_stm32::Peripherals; + +const PING_DATA: &str = "PING"; +const DATA_LEN: u8 = PING_DATA.len() as u8; +const PING_DATA_BYTES: &[u8] = PING_DATA.as_bytes(); +const PREAMBLE_LEN: u16 = 5 * 8; + +const RF_FREQ: RfFreq = RfFreq::from_frequency(867_500_000); + +const SYNC_WORD: [u8; 8] = [0x79, 0x80, 0x0C, 0xC0, 0x29, 0x95, 0xF8, 0x4A]; +const SYNC_WORD_LEN: u8 = SYNC_WORD.len() as u8; +const SYNC_WORD_LEN_BITS: u8 = SYNC_WORD_LEN * 8; + +const TX_BUF_OFFSET: u8 = 128; +const RX_BUF_OFFSET: u8 = 0; +const LORA_PACKET_PARAMS: LoRaPacketParams = LoRaPacketParams::new() + .set_crc_en(true) + .set_preamble_len(PREAMBLE_LEN) + .set_payload_len(DATA_LEN) + .set_invert_iq(false) + .set_header_type(HeaderType::Fixed); + +const LORA_MOD_PARAMS: LoRaModParams = LoRaModParams::new() + .set_bw(LoRaBandwidth::Bw125) + .set_cr(CodingRate::Cr45) + .set_ldro_en(true) + .set_sf(SpreadingFactor::Sf7); + +// configuration for +10 dBm output power +// see table 35 "PA optimal setting and operating modes" +const PA_CONFIG: PaConfig = PaConfig::new() + .set_pa_duty_cycle(0x1) + .set_hp_max(0x0) + .set_pa(PaSel::Lp); + +const TCXO_MODE: TcxoMode = TcxoMode::new() + .set_txco_trim(TcxoTrim::Volts1pt7) + .set_timeout(Timeout::from_duration_sat( + core::time::Duration::from_millis(10), + )); + +const TX_PARAMS: TxParams = TxParams::new() + .set_power(0x0D) + .set_ramp_time(RampTime::Micros40); + +fn config() -> embassy_stm32::Config { + let mut config = embassy_stm32::Config::default(); + config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE32; + config +} + +#[embassy::main(config = "config()")] +async fn main(_spawner: embassy::executor::Spawner, p: Peripherals) { + let mut led1 = Output::new(p.PB15, Level::High, Speed::Low); + let mut led2 = Output::new(p.PB9, Level::Low, Speed::Low); + let mut led3 = Output::new(p.PB11, Level::Low, Speed::Low); + + let button = Input::new(p.PA0, Pull::Up); + let mut pin = ExtiInput::new(button, p.EXTI0); + + static IRQ_SIGNAL: Signal<()> = Signal::new(); + let radio_irq = interrupt::take!(SUBGHZ_RADIO); + radio_irq.set_handler(|_| { + IRQ_SIGNAL.signal(()); + unsafe { interrupt::SUBGHZ_RADIO::steal() }.disable(); + }); + + let mut radio = SubGhz::new(p.SUBGHZSPI, p.PA5, p.PA7, p.PA6, NoDma, NoDma); + + defmt::info!("Radio ready for use"); + + led1.set_low(); + + led2.set_high(); + + unwrap!(radio.set_standby(StandbyClk::Rc)); + unwrap!(radio.set_tcxo_mode(&TCXO_MODE)); + unwrap!(radio.set_standby(StandbyClk::Hse)); + unwrap!(radio.set_regulator_mode(RegMode::Ldo)); + unwrap!(radio.set_buffer_base_address(TX_BUF_OFFSET, RX_BUF_OFFSET)); + unwrap!(radio.set_pa_config(&PA_CONFIG)); + unwrap!(radio.set_pa_ocp(Ocp::Max60m)); + unwrap!(radio.set_tx_params(&TX_PARAMS)); + unwrap!(radio.set_packet_type(PacketType::LoRa)); + unwrap!(radio.set_lora_sync_word(LoRaSyncWord::Public)); + unwrap!(radio.set_lora_mod_params(&LORA_MOD_PARAMS)); + unwrap!(radio.set_lora_packet_params(&LORA_PACKET_PARAMS)); + unwrap!(radio.calibrate_image(CalibrateImage::ISM_863_870)); + unwrap!(radio.set_rf_frequency(&RF_FREQ)); + + defmt::info!("Status: {:?}", unwrap!(radio.status())); + + led2.set_low(); + + loop { + pin.wait_for_rising_edge().await; + led3.set_high(); + unwrap!(radio.set_irq_cfg(&CfgIrq::new().irq_enable_all(Irq::TxDone))); + unwrap!(radio.write_buffer(TX_BUF_OFFSET, PING_DATA_BYTES)); + unwrap!(radio.set_tx(Timeout::DISABLED)); + + radio_irq.enable(); + IRQ_SIGNAL.wait().await; + + let (_, irq_status) = unwrap!(radio.irq_status()); + if irq_status & Irq::TxDone.mask() != 0 { + defmt::info!("TX done"); + } + unwrap!(radio.clear_irq_status(irq_status)); + led3.set_low(); + } +} -- cgit