summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Lilleengen <ulf.lilleengen@gmail.com>2021-06-09 15:22:52 +0200
committerDario Nieuwenhuis <dirbaio@dirbaio.net>2021-06-09 23:09:48 +0200
commit1bb712315646a333bca0fb3724dab9c17e3a2b0f (patch)
tree33fb06edc0fb702a251e66c6ece3b68dda85f1cd
parent3d16e922d5fc87453f9c8eb43c6414b959e3da80 (diff)
downloadembassy-1bb712315646a333bca0fb3724dab9c17e3a2b0f.zip
Add examples for STM32L0
-rw-r--r--.github/workflows/rust.yml2
-rw-r--r--embassy-stm32/src/rcc/l0/mod.rs4
-rw-r--r--examples/stm32l0/.cargo/config.toml21
-rw-r--r--examples/stm32l0/Cargo.toml34
-rw-r--r--examples/stm32l0/build.rs31
-rw-r--r--examples/stm32l0/memory.x5
-rw-r--r--examples/stm32l0/src/bin/blinky.rs36
-rw-r--r--examples/stm32l0/src/bin/button.rs40
-rw-r--r--examples/stm32l0/src/bin/button_exti.rs64
-rw-r--r--examples/stm32l0/src/bin/spi.rs49
-rw-r--r--examples/stm32l0/src/example_common.rs17
11 files changed, 300 insertions, 3 deletions
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index d95c388f..b48b9feb 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -84,6 +84,8 @@ jobs:
target: thumbv7em-none-eabi
- package: examples/stm32h7
target: thumbv7em-none-eabi
+ - package: examples/stm32l0
+ target: thumbv6m-none-eabi
steps:
- uses: actions/checkout@v2
diff --git a/embassy-stm32/src/rcc/l0/mod.rs b/embassy-stm32/src/rcc/l0/mod.rs
index ac32a6c4..d08c32b1 100644
--- a/embassy-stm32/src/rcc/l0/mod.rs
+++ b/embassy-stm32/src/rcc/l0/mod.rs
@@ -263,9 +263,7 @@ impl<'d> Rcc<'d> {
pub fn enable_debug_wfe(&mut self, _dbg: &mut peripherals::DBGMCU, enable_dma: bool) {
// NOTE(unsafe) We have exclusive access to the RCC and DBGMCU
unsafe {
- if enable_dma {
- pac::RCC.ahbenr().modify(|w| w.set_dmaen(true));
- }
+ pac::RCC.ahbenr().modify(|w| w.set_dmaen(enable_dma));
pac::DBGMCU.cr().modify(|w| {
w.set_dbg_sleep(DbgSleep::ENABLED);
diff --git a/examples/stm32l0/.cargo/config.toml b/examples/stm32l0/.cargo/config.toml
new file mode 100644
index 00000000..0528db9f
--- /dev/null
+++ b/examples/stm32l0/.cargo/config.toml
@@ -0,0 +1,21 @@
+[unstable]
+build-std = ["core"]
+
+[target.'cfg(all(target_arch = "arm", target_os = "none"))']
+# replace your chip as listed in `probe-run --list-chips`
+runner = "probe-run --chip STM32L072CZ"
+
+rustflags = [
+ # LLD (shipped with the Rust toolchain) is used as the default linker
+ "-C", "link-arg=--nmagic",
+ "-C", "link-arg=-Tlink.x",
+ "-C", "link-arg=-Tdefmt.x",
+
+ # Code-size optimizations.
+ "-Z", "trap-unreachable=no",
+ "-C", "inline-threshold=5",
+ "-C", "no-vectorize-loops",
+]
+
+[build]
+target = "thumbv6m-none-eabi"
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml
new file mode 100644
index 00000000..68291b00
--- /dev/null
+++ b/examples/stm32l0/Cargo.toml
@@ -0,0 +1,34 @@
+[package]
+authors = ["Dario Nieuwenhuis <dirbaio@dirbaio.net>", "Ulf Lilleengen <ulf.lilleengen@gmail.com>"]
+edition = "2018"
+name = "embassy-stm32l0-examples"
+version = "0.1.0"
+resolver = "2"
+
+[features]
+default = [
+ "defmt-default",
+]
+defmt-default = []
+defmt-trace = []
+defmt-debug = []
+defmt-info = []
+defmt-warn = []
+defmt-error = []
+
+[dependencies]
+embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-trace"] }
+embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "defmt-trace", "stm32l072cz"] }
+embassy-extras = {version = "0.1.0", path = "../../embassy-extras" }
+
+defmt = "0.2.0"
+defmt-rtt = "0.2.0"
+
+cortex-m = "0.7.1"
+cortex-m-rt = "0.6.14"
+embedded-hal = { version = "0.2.4" }
+panic-probe = { version = "0.2.0", features= ["print-defmt"] }
+futures = { version = "0.3.8", default-features = false, features = ["async-await"] }
+rtt-target = { version = "0.3", features = ["cortex-m"] }
+heapless = { version = "0.7.1", default-features = false }
diff --git a/examples/stm32l0/build.rs b/examples/stm32l0/build.rs
new file mode 100644
index 00000000..d534cc3d
--- /dev/null
+++ b/examples/stm32l0/build.rs
@@ -0,0 +1,31 @@
+//! This build script copies the `memory.x` file from the crate root into
+//! a directory where the linker can always find it at build time.
+//! For many projects this is optional, as the linker always searches the
+//! project root directory -- wherever `Cargo.toml` is. However, if you
+//! are using a workspace or have a more complicated build setup, this
+//! build script becomes required. Additionally, by requesting that
+//! Cargo re-run the build script whenever `memory.x` is changed,
+//! updating `memory.x` ensures a rebuild of the application with the
+//! new memory settings.
+
+use std::env;
+use std::fs::File;
+use std::io::Write;
+use std::path::PathBuf;
+
+fn main() {
+ // Put `memory.x` in our output directory and ensure it's
+ // on the linker search path.
+ let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+ File::create(out.join("memory.x"))
+ .unwrap()
+ .write_all(include_bytes!("memory.x"))
+ .unwrap();
+ println!("cargo:rustc-link-search={}", out.display());
+
+ // By default, Cargo will re-run a build script whenever
+ // any file in the project changes. By specifying `memory.x`
+ // here, we ensure the build script is only re-run when
+ // `memory.x` is changed.
+ println!("cargo:rerun-if-changed=memory.x");
+}
diff --git a/examples/stm32l0/memory.x b/examples/stm32l0/memory.x
new file mode 100644
index 00000000..67a50a5f
--- /dev/null
+++ b/examples/stm32l0/memory.x
@@ -0,0 +1,5 @@
+MEMORY
+{
+ FLASH : ORIGIN = 0x08000000, LENGTH = 192K
+ RAM : ORIGIN = 0x20000000, LENGTH = 20K
+}
diff --git a/examples/stm32l0/src/bin/blinky.rs b/examples/stm32l0/src/bin/blinky.rs
new file mode 100644
index 00000000..e7433c26
--- /dev/null
+++ b/examples/stm32l0/src/bin/blinky.rs
@@ -0,0 +1,36 @@
+#![no_std]
+#![no_main]
+#![feature(trait_alias)]
+#![feature(min_type_alias_impl_trait)]
+#![feature(impl_trait_in_bindings)]
+#![feature(type_alias_impl_trait)]
+#![allow(incomplete_features)]
+
+#[path = "../example_common.rs"]
+mod example_common;
+use embassy_stm32::{rcc::*, gpio::{Level, Output}};
+use embedded_hal::digital::v2::OutputPin;
+use example_common::*;
+
+use cortex_m_rt::entry;
+
+#[entry]
+fn main() -> ! {
+ info!("Hello World!");
+
+ let mut p = embassy_stm32::init(Default::default());
+
+ Rcc::new(p.RCC).enable_debug_wfe(&mut p.DBGMCU, true);
+
+ let mut led = Output::new(p.PB5, Level::High);
+
+ loop {
+ info!("high");
+ led.set_high().unwrap();
+ cortex_m::asm::delay(1_000_000);
+
+ info!("low");
+ led.set_low().unwrap();
+ cortex_m::asm::delay(1_000_000);
+ }
+}
diff --git a/examples/stm32l0/src/bin/button.rs b/examples/stm32l0/src/bin/button.rs
new file mode 100644
index 00000000..1a2e20b1
--- /dev/null
+++ b/examples/stm32l0/src/bin/button.rs
@@ -0,0 +1,40 @@
+#![no_std]
+#![no_main]
+#![feature(trait_alias)]
+#![feature(min_type_alias_impl_trait)]
+#![feature(impl_trait_in_bindings)]
+#![feature(type_alias_impl_trait)]
+#![allow(incomplete_features)]
+
+#[path = "../example_common.rs"]
+mod example_common;
+use embassy_stm32::{rcc::*, gpio::{Input, Level, Output, Pull}};
+use embedded_hal::digital::v2::{InputPin, OutputPin};
+use example_common::*;
+
+use cortex_m_rt::entry;
+
+
+#[entry]
+fn main() -> ! {
+ info!("Hello World!");
+
+ let mut p = embassy_stm32::init(Default::default());
+ Rcc::new(p.RCC).enable_debug_wfe(&mut p.DBGMCU, true);
+
+ let button = Input::new(p.PB2, Pull::Up);
+ let mut led1 = Output::new(p.PA5, Level::High);
+ let mut led2 = Output::new(p.PB5, Level::High);
+
+ loop {
+ if button.is_high().unwrap() {
+ info!("high");
+ led1.set_high().unwrap();
+ led2.set_low().unwrap();
+ } else {
+ info!("low");
+ led1.set_low().unwrap();
+ led2.set_high().unwrap();
+ }
+ }
+}
diff --git a/examples/stm32l0/src/bin/button_exti.rs b/examples/stm32l0/src/bin/button_exti.rs
new file mode 100644
index 00000000..a7f73494
--- /dev/null
+++ b/examples/stm32l0/src/bin/button_exti.rs
@@ -0,0 +1,64 @@
+#![no_std]
+#![no_main]
+#![feature(trait_alias)]
+#![feature(min_type_alias_impl_trait)]
+#![feature(impl_trait_in_bindings)]
+#![feature(type_alias_impl_trait)]
+#![allow(incomplete_features)]
+
+#[path = "../example_common.rs"]
+mod example_common;
+use embassy::executor::Executor;
+use embassy::time::Clock;
+use embassy::util::Forever;
+use embassy_stm32::exti::ExtiInput;
+use embassy_stm32::gpio::{Input, Pull};
+use embassy_stm32::rcc;
+use embassy_traits::gpio::{WaitForFallingEdge, WaitForRisingEdge};
+use example_common::*;
+
+use cortex_m_rt::entry;
+
+#[embassy::task]
+async fn main_task() {
+ let mut p = embassy_stm32::init(Default::default());
+ let mut rcc = rcc::Rcc::new(p.RCC);
+ rcc.enable_debug_wfe(&mut p.DBGMCU, true);
+ // Enables SYSCFG
+ let _ = rcc.enable_hsi48(&mut p.SYSCFG, p.CRS);
+
+ let button = Input::new(p.PB2, Pull::Up);
+ let mut button = ExtiInput::new(button, p.EXTI2);
+
+ info!("Press the USER button...");
+
+ loop {
+ button.wait_for_falling_edge().await;
+ info!("Pressed!");
+ button.wait_for_rising_edge().await;
+ info!("Released!");
+ }
+}
+
+struct ZeroClock;
+
+impl Clock for ZeroClock {
+ fn now(&self) -> u64 {
+ 0
+ }
+}
+
+static EXECUTOR: Forever<Executor> = Forever::new();
+
+#[entry]
+fn main() -> ! {
+ info!("Hello World!");
+
+ unsafe { embassy::time::set_clock(&ZeroClock) };
+
+ let executor = EXECUTOR.put(Executor::new());
+
+ executor.run(|spawner| {
+ unwrap!(spawner.spawn(main_task()));
+ })
+}
diff --git a/examples/stm32l0/src/bin/spi.rs b/examples/stm32l0/src/bin/spi.rs
new file mode 100644
index 00000000..4eb9bfdd
--- /dev/null
+++ b/examples/stm32l0/src/bin/spi.rs
@@ -0,0 +1,49 @@
+#![no_std]
+#![no_main]
+#![feature(trait_alias)]
+#![feature(min_type_alias_impl_trait)]
+#![feature(impl_trait_in_bindings)]
+#![feature(type_alias_impl_trait)]
+#![allow(incomplete_features)]
+
+#[path = "../example_common.rs"]
+mod example_common;
+
+use embassy_stm32::gpio::{Level, Output};
+use embedded_hal::digital::v2::OutputPin;
+use example_common::*;
+
+use cortex_m_rt::entry;
+use embassy_stm32::rcc;
+use embassy_stm32::spi::{Config, Spi};
+use embassy_stm32::time::Hertz;
+use embedded_hal::blocking::spi::Transfer;
+
+#[entry]
+fn main() -> ! {
+ info!("Hello World, dude!");
+
+ let mut p = embassy_stm32::init(Default::default());
+ let mut rcc = rcc::Rcc::new(p.RCC);
+ rcc.enable_debug_wfe(&mut p.DBGMCU, true);
+
+ let mut spi = Spi::new(
+ Hertz(16_000_000),
+ p.SPI1,
+ p.PB3,
+ p.PA7,
+ p.PA6,
+ Hertz(1_000_000),
+ Config::default(),
+ );
+
+ let mut cs = Output::new(p.PA15, Level::High);
+
+ loop {
+ let mut buf = [0x0A; 4];
+ unwrap!(cs.set_low());
+ unwrap!(spi.transfer(&mut buf));
+ unwrap!(cs.set_high());
+ info!("xfer {=[u8]:x}", buf);
+ }
+}
diff --git a/examples/stm32l0/src/example_common.rs b/examples/stm32l0/src/example_common.rs
new file mode 100644
index 00000000..54d63383
--- /dev/null
+++ b/examples/stm32l0/src/example_common.rs
@@ -0,0 +1,17 @@
+#![macro_use]
+
+use defmt_rtt as _; // global logger
+use panic_probe as _;
+
+pub use defmt::*;
+
+use core::sync::atomic::{AtomicUsize, Ordering};
+
+defmt::timestamp! {"{=u64}", {
+ static COUNT: AtomicUsize = AtomicUsize::new(0);
+ // NOTE(no-CAS) `timestamps` runs with interrupts disabled
+ let n = COUNT.load(Ordering::Relaxed);
+ COUNT.store(n + 1, Ordering::Relaxed);
+ n as u64
+ }
+}