aboutsummaryrefslogtreecommitdiff
path: root/examples/stm32wle5
diff options
context:
space:
mode:
Diffstat (limited to 'examples/stm32wle5')
-rw-r--r--examples/stm32wle5/.cargo/config.toml9
-rw-r--r--examples/stm32wle5/Cargo.toml38
-rw-r--r--examples/stm32wle5/README.md52
-rw-r--r--examples/stm32wle5/build.rs5
-rw-r--r--examples/stm32wle5/src/bin/adc.rs67
-rw-r--r--examples/stm32wle5/src/bin/blinky.rs58
-rw-r--r--examples/stm32wle5/src/bin/button_exti.rs64
-rw-r--r--examples/stm32wle5/src/bin/i2c.rs77
-rw-r--r--examples/stm32wle5/stm32wle5.code-workspace13
9 files changed, 383 insertions, 0 deletions
diff --git a/examples/stm32wle5/.cargo/config.toml b/examples/stm32wle5/.cargo/config.toml
new file mode 100644
index 000000000..0178d377c
--- /dev/null
+++ b/examples/stm32wle5/.cargo/config.toml
@@ -0,0 +1,9 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace your chip as listed in `probe-rs chip list`
3runner = "probe-rs run --chip STM32WLE5JCIx --connect-under-reset"
4
5[build]
6target = "thumbv7em-none-eabi"
7
8[env]
9DEFMT_LOG = "info"
diff --git a/examples/stm32wle5/Cargo.toml b/examples/stm32wle5/Cargo.toml
new file mode 100644
index 000000000..f2fc4dd3d
--- /dev/null
+++ b/examples/stm32wle5/Cargo.toml
@@ -0,0 +1,38 @@
1[package]
2edition = "2024"
3name = "embassy-stm32wl-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6publish = false
7
8[dependencies]
9# Change stm32wl55jc-cm4 to your chip name, if necessary.
10embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = ["defmt", "stm32wle5jc", "time-driver-any", "memory-x", "unstable-pac", "exti", "low-power"] }
11embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] }
12embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt"] }
13embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-1_000"] }
14embassy-embedded-hal = { version = "0.5.0", path = "../../embassy-embedded-hal" }
15
16defmt = "1.0.1"
17defmt-rtt = { version = "1.1.0", optional = true }
18defmt-serial = { version = "0.10.0", optional = true }
19
20cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
21cortex-m-rt = "0.7.0"
22embedded-hal = "1.0.0"
23embedded-storage = "0.3.1"
24panic-probe = { version = "1.0.0", features = ["print-defmt"] }
25static_cell = { version = "2.1.1", default-features = false }
26
27[profile.release]
28debug = 2
29
30[package.metadata.embassy]
31build = [
32 { target = "thumbv7em-none-eabi", artifact-dir = "out/examples/stm32wl" }
33]
34
35[features]
36default = ["defmt-serial"]
37defmt-rtt = ["dep:defmt-rtt"]
38defmt-serial = ["dep:defmt-serial"]
diff --git a/examples/stm32wle5/README.md b/examples/stm32wle5/README.md
new file mode 100644
index 000000000..18c3b5071
--- /dev/null
+++ b/examples/stm32wle5/README.md
@@ -0,0 +1,52 @@
1# Low Power Examples for STM32WLEx family
2
3Examples in this repo should work with [LoRa-E5 Dev Board](https://www.st.com/en/partner-products-and-services/lora-e5-development-kit.html) board.
4
5## Prerequsits
6
7- Connect a usb serial adapter to LPUart1 (this is where ALL logging will go)
8- Optional: Connect an amp meter that ran measure down to 0.1uA to the power test pins
9- `cargo install defmt-print` so you can print log messahes from LPUart1
10
11## Example Notes
12
13All examples will set all pins to analog mode before configuring pins for the example, if any. This saves about 500uA!!!!
14
15- the `adc` example will sleep in STOP1 betwen samples and the chip will only draw about 13uA while sleeping
16- the `blinky` example will sleep in STOP2 and the chip will only draw 1uA or less while sleeping
17- the `button_exti` example will sleep in STOP2 and the chip will only draw 1uA or less while sleeping
18- the `i2c` examples will sleep in STOP1 between reads and the chip only draw about 10uA while sleeping
19
20For each example you will need to start `defmt-print` with the example binary and the correct serial port in a seperate terminal. Example:
21```
22defmt-print -w -v -e target/thumbv7em-none-eabi/debug/<module-name> serial --path /dev/cu.usbserial-00000000 --baud 115200
23```
24
25Run individual examples with
26```
27cargo flash --chip STM32WLE5JCIx --connect-under-reset --bin <module-name>
28```
29for example
30```
31cargo flash --chip STM32WLE5JCIx --connect-under-reset --bin blinky
32```
33
34You can also run them with with `run`. However in this case expect probe-rs to be disconnected as soon as flashing is done as all IO pins are set to analog input!
35```
36cargo run --bin blinky
37```
38
39## Checklist before running examples
40You might need to adjust `.cargo/config.toml`, `Cargo.toml` and possibly update pin numbers or peripherals to match the specific MCU or board you are using.
41
42* [ ] Update .cargo/config.toml with the correct probe-rs command to use your specific MCU. For example for L432KCU6 it should be `probe-rs run --chip STM32L432KCUx`. (use `probe-rs chip list` to find your chip)
43* [ ] Update Cargo.toml to have the correct `embassy-stm32` feature. For example for L432KCU6 it should be `stm32l432kc`. Look in the `Cargo.toml` file of the `embassy-stm32` project to find the correct feature flag for your chip.
44* [ ] If your board has a special clock or power configuration, make sure that it is set up appropriately.
45* [ ] If your board has different pin mapping, update any pin numbers or peripherals in the given example code to match your schematic
46
47If you are unsure, please drop by the Embassy Matrix chat for support, and let us know:
48
49* Which example you are trying to run
50* Which chip and board you are using
51
52Embassy Chat: https://matrix.to/#/#embassy-rs:matrix.org
diff --git a/examples/stm32wle5/build.rs b/examples/stm32wle5/build.rs
new file mode 100644
index 000000000..8cd32d7ed
--- /dev/null
+++ b/examples/stm32wle5/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/stm32wle5/src/bin/adc.rs b/examples/stm32wle5/src/bin/adc.rs
new file mode 100644
index 000000000..8cc84ccdf
--- /dev/null
+++ b/examples/stm32wle5/src/bin/adc.rs
@@ -0,0 +1,67 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5#[cfg(feature = "defmt-rtt")]
6use defmt_rtt as _;
7use embassy_executor::Spawner;
8use embassy_stm32::adc::{Adc, SampleTime};
9use embassy_stm32::low_power;
10use embassy_time::Timer;
11use panic_probe as _;
12use static_cell::StaticCell;
13
14#[embassy_executor::main(executor = "low_power::Executor")]
15async fn async_main(_spawner: Spawner) {
16 let mut config = embassy_stm32::Config::default();
17 // enable HSI clock
18 config.rcc.hsi = true;
19 // enable LSI clock for RTC
20 config.rcc.ls = embassy_stm32::rcc::LsConfig::default_lsi();
21 config.rcc.msi = Some(embassy_stm32::rcc::MSIRange::RANGE4M);
22 config.rcc.sys = embassy_stm32::rcc::Sysclk::MSI;
23 // enable ADC with HSI clock
24 config.rcc.mux.adcsel = embassy_stm32::pac::rcc::vals::Adcsel::HSI;
25 #[cfg(feature = "defmt-serial")]
26 {
27 // disable debug during sleep to reduce power consumption since we are
28 // using defmt-serial on LPUART1.
29 config.enable_debug_during_sleep = false;
30 // if we are using defmt-serial on LPUART1, we need to use HSI for the clock
31 // so that its registers are preserved during STOP modes.
32 config.rcc.mux.lpuart1sel = embassy_stm32::pac::rcc::vals::Lpuart1sel::HSI;
33 }
34 // Initialize STM32WL peripherals (use default config like wio-e5-async example)
35 let p = embassy_stm32::init(config);
36
37 #[cfg(feature = "defmt-serial")]
38 {
39 use embassy_stm32::mode::Blocking;
40 use embassy_stm32::usart::Uart;
41 let config = embassy_stm32::usart::Config::default();
42 let uart = Uart::new_blocking(p.LPUART1, p.PC0, p.PC1, config).expect("failed to configure UART!");
43 static SERIAL: StaticCell<Uart<'static, Blocking>> = StaticCell::new();
44 defmt_serial::defmt_serial(SERIAL.init(uart));
45 }
46
47 info!("Hello World!");
48
49 let mut adc = Adc::new(p.ADC1);
50 let mut pin = p.PA10;
51
52 let mut vrefint = adc.enable_vrefint();
53 let vrefint_sample = adc.blocking_read(&mut vrefint, SampleTime::CYCLES79_5);
54 let convert_to_millivolts = |sample| {
55 // From https://www.st.com/resource/en/datasheet/stm32g031g8.pdf
56 // 6.3.3 Embedded internal reference voltage
57 const VREFINT_MV: u32 = 1212; // mV
58
59 (u32::from(sample) * VREFINT_MV / u32::from(vrefint_sample)) as u16
60 };
61
62 loop {
63 let v = adc.blocking_read(&mut pin, SampleTime::CYCLES79_5);
64 info!("--> {} - {} mV", v, convert_to_millivolts(v));
65 Timer::after_secs(1).await;
66 }
67}
diff --git a/examples/stm32wle5/src/bin/blinky.rs b/examples/stm32wle5/src/bin/blinky.rs
new file mode 100644
index 000000000..3b7eb7761
--- /dev/null
+++ b/examples/stm32wle5/src/bin/blinky.rs
@@ -0,0 +1,58 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5#[cfg(feature = "defmt-rtt")]
6use defmt_rtt as _;
7use embassy_executor::Spawner;
8use embassy_stm32::gpio::{Level, Output, Speed};
9use embassy_stm32::low_power;
10use embassy_time::Timer;
11use panic_probe as _;
12use static_cell::StaticCell;
13
14#[embassy_executor::main(executor = "low_power::Executor")]
15async fn async_main(_spawner: Spawner) {
16 let mut config = embassy_stm32::Config::default();
17 // enable HSI clock
18 config.rcc.hsi = true;
19 // enable LSI clock for RTC
20 config.rcc.ls = embassy_stm32::rcc::LsConfig::default_lsi();
21 config.rcc.msi = Some(embassy_stm32::rcc::MSIRange::RANGE4M);
22 config.rcc.sys = embassy_stm32::rcc::Sysclk::MSI;
23 #[cfg(feature = "defmt-serial")]
24 {
25 // disable debug during sleep to reduce power consumption since we are
26 // using defmt-serial on LPUART1.
27 config.enable_debug_during_sleep = false;
28 // if we are using defmt-serial on LPUART1, we need to use HSI for the clock
29 // so that its registers are preserved during STOP modes.
30 config.rcc.mux.lpuart1sel = embassy_stm32::pac::rcc::vals::Lpuart1sel::HSI;
31 }
32 // Initialize STM32WL peripherals (use default config like wio-e5-async example)
33 let p = embassy_stm32::init(config);
34
35 #[cfg(feature = "defmt-serial")]
36 {
37 use embassy_stm32::mode::Blocking;
38 use embassy_stm32::usart::Uart;
39 let config = embassy_stm32::usart::Config::default();
40 let uart = Uart::new_blocking(p.LPUART1, p.PC0, p.PC1, config).expect("failed to configure UART!");
41 static SERIAL: StaticCell<Uart<'static, Blocking>> = StaticCell::new();
42 defmt_serial::defmt_serial(SERIAL.init(uart));
43 }
44
45 info!("Hello World!");
46
47 let mut led = Output::new(p.PB5, Level::High, Speed::Low);
48
49 loop {
50 info!("low");
51 led.set_low();
52 Timer::after_millis(15000).await;
53
54 info!("high");
55 led.set_high();
56 Timer::after_millis(15000).await;
57 }
58}
diff --git a/examples/stm32wle5/src/bin/button_exti.rs b/examples/stm32wle5/src/bin/button_exti.rs
new file mode 100644
index 000000000..9ffc39948
--- /dev/null
+++ b/examples/stm32wle5/src/bin/button_exti.rs
@@ -0,0 +1,64 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5#[cfg(feature = "defmt-rtt")]
6use defmt_rtt as _;
7use embassy_executor::Spawner;
8use embassy_stm32::exti::{self, ExtiInput};
9use embassy_stm32::gpio::Pull;
10use embassy_stm32::{bind_interrupts, interrupt, low_power};
11use panic_probe as _;
12use static_cell::StaticCell;
13
14bind_interrupts!(
15 pub struct Irqs{
16 EXTI0 => exti::InterruptHandler<interrupt::typelevel::EXTI0>;
17});
18
19#[embassy_executor::main(executor = "low_power::Executor")]
20async fn async_main(_spawner: Spawner) {
21 let mut config = embassy_stm32::Config::default();
22 // enable HSI clock
23 config.rcc.hsi = true;
24 // enable LSI clock for RTC
25 config.rcc.ls = embassy_stm32::rcc::LsConfig::default_lsi();
26 config.rcc.msi = Some(embassy_stm32::rcc::MSIRange::RANGE4M);
27 config.rcc.sys = embassy_stm32::rcc::Sysclk::MSI;
28 // enable ADC with HSI clock
29 config.rcc.mux.adcsel = embassy_stm32::pac::rcc::vals::Adcsel::HSI;
30 #[cfg(feature = "defmt-serial")]
31 {
32 // disable debug during sleep to reduce power consumption since we are
33 // using defmt-serial on LPUART1.
34 config.enable_debug_during_sleep = false;
35 // if we are using defmt-serial on LPUART1, we need to use HSI for the clock
36 // so that its registers are preserved during STOP modes.
37 config.rcc.mux.lpuart1sel = embassy_stm32::pac::rcc::vals::Lpuart1sel::HSI;
38 }
39 // Initialize STM32WL peripherals (use default config like wio-e5-async example)
40 let p = embassy_stm32::init(config);
41
42 #[cfg(feature = "defmt-serial")]
43 {
44 use embassy_stm32::mode::Blocking;
45 use embassy_stm32::usart::Uart;
46 let config = embassy_stm32::usart::Config::default();
47 let uart = Uart::new_blocking(p.LPUART1, p.PC0, p.PC1, config).expect("failed to configure UART!");
48 static SERIAL: StaticCell<Uart<'static, Blocking>> = StaticCell::new();
49 defmt_serial::defmt_serial(SERIAL.init(uart));
50 }
51
52 info!("Hello World!");
53
54 let mut button = ExtiInput::new(p.PA0, p.EXTI0, Pull::Up, Irqs);
55
56 info!("Press the USER button...");
57
58 loop {
59 button.wait_for_falling_edge().await;
60 info!("Pressed!");
61 button.wait_for_rising_edge().await;
62 info!("Released!");
63 }
64}
diff --git a/examples/stm32wle5/src/bin/i2c.rs b/examples/stm32wle5/src/bin/i2c.rs
new file mode 100644
index 000000000..8e7a6e2d8
--- /dev/null
+++ b/examples/stm32wle5/src/bin/i2c.rs
@@ -0,0 +1,77 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5#[cfg(feature = "defmt-rtt")]
6use defmt_rtt as _;
7use embassy_executor::Spawner;
8use embassy_stm32::i2c::I2c;
9use embassy_stm32::time::Hertz;
10use embassy_stm32::{bind_interrupts, i2c, low_power, peripherals};
11use embassy_time::{Duration, Timer};
12use panic_probe as _;
13use static_cell::StaticCell;
14
15bind_interrupts!(struct IrqsI2C{
16 I2C2_EV => i2c::EventInterruptHandler<peripherals::I2C2>;
17 I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>;
18});
19
20#[embassy_executor::main(executor = "low_power::Executor")]
21async fn async_main(_spawner: Spawner) {
22 let mut config = embassy_stm32::Config::default();
23 // enable HSI clock
24 config.rcc.hsi = true;
25 // enable LSI clock for RTC
26 config.rcc.ls = embassy_stm32::rcc::LsConfig::default_lsi();
27 config.rcc.msi = Some(embassy_stm32::rcc::MSIRange::RANGE4M);
28 config.rcc.sys = embassy_stm32::rcc::Sysclk::MSI;
29 // enable ADC with HSI clock
30 config.rcc.mux.i2c2sel = embassy_stm32::pac::rcc::vals::I2c2sel::HSI;
31 #[cfg(feature = "defmt-serial")]
32 {
33 // disable debug during sleep to reduce power consumption since we are
34 // using defmt-serial on LPUART1.
35 config.enable_debug_during_sleep = false;
36 // if we are using defmt-serial on LPUART1, we need to use HSI for the clock
37 // so that its registers are preserved during STOP modes.
38 config.rcc.mux.lpuart1sel = embassy_stm32::pac::rcc::vals::Lpuart1sel::HSI;
39 }
40 // Initialize STM32WL peripherals (use default config like wio-e5-async example)
41 let p = embassy_stm32::init(config);
42
43 #[cfg(feature = "defmt-serial")]
44 {
45 use embassy_stm32::mode::Blocking;
46 use embassy_stm32::usart::Uart;
47 let config = embassy_stm32::usart::Config::default();
48 let uart = Uart::new_blocking(p.LPUART1, p.PC0, p.PC1, config).expect("failed to configure UART!");
49 static SERIAL: StaticCell<Uart<'static, Blocking>> = StaticCell::new();
50 defmt_serial::defmt_serial(SERIAL.init(uart));
51 }
52
53 info!("Hello World!");
54 let en3v3 = embassy_stm32::gpio::Output::new(
55 p.PA9,
56 embassy_stm32::gpio::Level::High,
57 embassy_stm32::gpio::Speed::High,
58 );
59 core::mem::forget(en3v3); // keep the output pin enabled
60
61 let mut i2c = I2c::new(p.I2C2, p.PB15, p.PA15, IrqsI2C, p.DMA1_CH6, p.DMA1_CH7, {
62 let mut config = i2c::Config::default();
63 config.frequency = Hertz::khz(100);
64 config.timeout = Duration::from_millis(1000);
65 config
66 });
67
68 loop {
69 let mut buffer = [0; 2];
70 // read the temperature register of the onboard lm75
71 match i2c.read(0x48, &mut buffer).await {
72 Ok(_) => info!("--> {:?}", buffer),
73 Err(e) => info!("--> Error: {:?}", e),
74 }
75 Timer::after_secs(5).await;
76 }
77}
diff --git a/examples/stm32wle5/stm32wle5.code-workspace b/examples/stm32wle5/stm32wle5.code-workspace
new file mode 100644
index 000000000..a7c4a0ebd
--- /dev/null
+++ b/examples/stm32wle5/stm32wle5.code-workspace
@@ -0,0 +1,13 @@
1{
2 "folders": [
3 {
4 "path": "."
5 }
6 ],
7 "settings": {
8 "rust-analyzer.cargo.target": "thumbv7em-none-eabi",
9 "rust-analyzer.cargo.allTargets": false,
10 "rust-analyzer.cargo.targetDir": "target/rust-analyzer",
11 "rust-analyzer.checkOnSave": true,
12 }
13}