aboutsummaryrefslogtreecommitdiff
path: root/examples/stm32wl
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-04-08 03:15:27 +0200
committerDario Nieuwenhuis <[email protected]>2022-04-08 03:15:27 +0200
commit0c07d0375406c6079e4b143cd7ac380d0a2bfd5f (patch)
tree68de96e3c66e3fd077aae60aa002f2b2941ee4af /examples/stm32wl
parent50ff63ab888352b6818898617588cc844250c9b7 (diff)
Add missing stm32wl/stm32wb chips except stm32wle
Diffstat (limited to 'examples/stm32wl')
-rw-r--r--examples/stm32wl/.cargo/config.toml6
-rw-r--r--examples/stm32wl/Cargo.toml24
-rw-r--r--examples/stm32wl/build.rs5
-rw-r--r--examples/stm32wl/src/bin/blinky.rs28
-rw-r--r--examples/stm32wl/src/bin/button.rs31
-rw-r--r--examples/stm32wl/src/bin/button_exti.rs28
-rw-r--r--examples/stm32wl/src/bin/lorawan.rs72
-rw-r--r--examples/stm32wl/src/bin/subghz.rs130
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`
3runner = "probe-run --chip STM32WLE5JCIx"
4
5[build]
6target = "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]
2authors = ["Dario Nieuwenhuis <[email protected]>", "Ulf Lilleengen <[email protected]>"]
3edition = "2018"
4name = "embassy-stm32wl-examples"
5version = "0.1.0"
6resolver = "2"
7
8[dependencies]
9embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "subghz", "unstable-pac", "exti"] }
11embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time"] }
12
13lorawan-device = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "0de1a2a31933f7c97887b5718c1755fa5ab93a42", default-features = false, features = ["async"] }
14lorawan-encoding = { git = "https://github.com/ivajloip/rust-lorawan.git", rev = "0de1a2a31933f7c97887b5718c1755fa5ab93a42", default-features = false, features = ["default-crypto"] }
15
16defmt = "0.3"
17defmt-rtt = "0.3"
18
19cortex-m = "0.7.3"
20cortex-m-rt = "0.7.0"
21embedded-hal = "0.2.6"
22panic-probe = { version = "0.3", features = ["print-defmt"] }
23futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
24heapless = { 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 @@
1fn 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
5use defmt::*;
6use defmt_rtt as _; // global logger
7use embassy::executor::Spawner;
8use embassy::time::{Duration, Timer};
9use embassy_stm32::gpio::{Level, Output, Speed};
10use embassy_stm32::Peripherals;
11use panic_probe as _;
12
13#[embassy::main]
14async 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
5use defmt::*;
6use defmt_rtt as _; // global logger
7use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
8use panic_probe as _;
9
10use cortex_m_rt::entry;
11
12#[entry]
13fn 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
5use defmt::*;
6use defmt_rtt as _; // global logger
7use embassy::executor::Spawner;
8use embassy_stm32::exti::ExtiInput;
9use embassy_stm32::gpio::{Input, Pull};
10use embassy_stm32::Peripherals;
11use panic_probe as _;
12
13#[embassy::main]
14async 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
8use defmt_rtt as _; // global logger
9use panic_probe as _;
10
11use embassy_lora::{stm32wl::*, LoraTimer};
12use embassy_stm32::{
13 dma::NoDma,
14 gpio::{Level, Output, Pin, Speed},
15 interrupt, pac,
16 rng::Rng,
17 subghz::*,
18 Peripherals,
19};
20use lorawan_device::async_device::{region, Device, JoinMode};
21use lorawan_encoding::default_crypto::DefaultFactory as Crypto;
22
23fn 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()")]
31async 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
8use defmt_rtt as _; // global logger
9use panic_probe as _;
10
11use defmt::*;
12use embassy::channel::signal::Signal;
13use embassy::interrupt::{Interrupt, InterruptExt};
14use embassy_stm32::dma::NoDma;
15use embassy_stm32::exti::ExtiInput;
16use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
17use embassy_stm32::interrupt;
18use embassy_stm32::subghz::*;
19use embassy_stm32::Peripherals;
20
21const PING_DATA: &str = "PING";
22const DATA_LEN: u8 = PING_DATA.len() as u8;
23const PING_DATA_BYTES: &[u8] = PING_DATA.as_bytes();
24const PREAMBLE_LEN: u16 = 5 * 8;
25
26const RF_FREQ: RfFreq = RfFreq::from_frequency(867_500_000);
27
28const SYNC_WORD: [u8; 8] = [0x79, 0x80, 0x0C, 0xC0, 0x29, 0x95, 0xF8, 0x4A];
29const SYNC_WORD_LEN: u8 = SYNC_WORD.len() as u8;
30const SYNC_WORD_LEN_BITS: u8 = SYNC_WORD_LEN * 8;
31
32const TX_BUF_OFFSET: u8 = 128;
33const RX_BUF_OFFSET: u8 = 0;
34const 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
41const 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"
49const PA_CONFIG: PaConfig = PaConfig::new()
50 .set_pa_duty_cycle(0x1)
51 .set_hp_max(0x0)
52 .set_pa(PaSel::Lp);
53
54const 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
60const TX_PARAMS: TxParams = TxParams::new()
61 .set_power(0x0D)
62 .set_ramp_time(RampTime::Micros40);
63
64fn 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()")]
71async 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}