Add documentation about the different embassy abstraction layers

The guide demonstrates the functionality offered by each
layer in Embassy, using code examples.
This commit is contained in:
Ulf Lilleengen
2022-02-23 09:48:32 +01:00
parent 4c6e61b3b1
commit 092eef3ae7
13 changed files with 398 additions and 0 deletions

View File

@ -0,0 +1,11 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = "probe-run --chip STM32L475VG"
rustflags = [
"-C", "link-arg=--nmagic",
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
]
[build]
target = "thumbv7em-none-eabihf"

View File

@ -0,0 +1,22 @@
[workspace]
resolver = "2"
members = [
"blinky-pac",
"blinky-hal",
"blinky-irq",
"blinky-async",
]
[patch.crates-io]
embassy = { path = "../../../../../embassy" }
embassy-stm32 = { path = "../../../../../embassy-stm32" }
stm32-metapac = { path = "../../../../../stm32-metapac" }
[profile.release]
codegen-units = 1
debug = 2
debug-assertions = false
incremental = false
lto = "fat"
opt-level = 's'
overflow-checks = false

View File

@ -0,0 +1,14 @@
[package]
name = "blinky-async"
version = "0.1.0"
edition = "2021"
[dependencies]
cortex-m = "0.7"
cortex-m-rt = "0.7"
embassy-stm32 = { version = "0.1.0", features = ["stm32l475vg", "memory-x", "exti"], default-features = false }
embassy = { version = "0.1.0", default-features = false, features = ["nightly"] }
defmt = "0.3.0"
defmt-rtt = "0.3.0"
panic-probe = { version = "0.3.0", features = ["print-defmt"] }

View File

@ -0,0 +1,28 @@
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use defmt_rtt as _;
use panic_probe as _;
use embassy::executor::Spawner;
use embassy_stm32::{
exti::ExtiInput,
gpio::{Input, Level, Output, Pull, Speed},
Peripherals,
};
#[embassy::main]
async fn main(_s: Spawner, p: Peripherals) {
let mut led = Output::new(p.PB14, Level::Low, Speed::VeryHigh);
let mut button = ExtiInput::new(Input::new(p.PC13, Pull::Up), p.EXTI13);
loop {
button.wait_for_any_edge().await;
if button.is_low() {
led.set_high();
} else {
led.set_low();
}
}
}

View File

@ -0,0 +1,13 @@
[package]
name = "blinky-hal"
version = "0.1.0"
edition = "2021"
[dependencies]
cortex-m = "0.7"
cortex-m-rt = "0.7"
embassy-stm32 = { version = "0.1.0", features = ["stm32l475vg", "memory-x"], default-features = false }
defmt = "0.3.0"
defmt-rtt = "0.3.0"
panic-probe = { version = "0.3.0", features = ["print-defmt"] }

View File

@ -0,0 +1,23 @@
#![no_std]
#![no_main]
use cortex_m_rt::entry;
use defmt_rtt as _;
use panic_probe as _;
use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
#[entry]
fn main() -> ! {
let p = embassy_stm32::init(Default::default());
let mut led = Output::new(p.PB14, Level::High, Speed::VeryHigh);
let button = Input::new(p.PC13, Pull::Up);
loop {
if button.is_low() {
led.set_high();
} else {
led.set_low();
}
}
}

View File

@ -0,0 +1,13 @@
[package]
name = "blinky-irq"
version = "0.1.0"
edition = "2021"
[dependencies]
cortex-m = "0.7"
cortex-m-rt = { version = "0.7" }
embassy-stm32 = { version = "0.1.0", features = ["stm32l475vg", "memory-x", "unstable-pac"] }
defmt = "0.3.0"
defmt-rtt = "0.3.0"
panic-probe = { version = "0.3.0", features = ["print-defmt"] }

View File

@ -0,0 +1,101 @@
#![no_std]
#![no_main]
use defmt_rtt as _;
use panic_probe as _;
use core::cell::RefCell;
use cortex_m::interrupt::Mutex;
use cortex_m::peripheral::NVIC;
use cortex_m_rt::entry;
use embassy_stm32::{
gpio::{Input, Level, Output, Pin, Pull, Speed},
interrupt, pac,
peripherals::{PB14, PC13},
};
static BUTTON: Mutex<RefCell<Option<Input<'static, PC13>>>> = Mutex::new(RefCell::new(None));
static LED: Mutex<RefCell<Option<Output<'static, PB14>>>> = Mutex::new(RefCell::new(None));
#[entry]
fn main() -> ! {
let p = embassy_stm32::init(Default::default());
let led = Output::new(p.PB14, Level::Low, Speed::Low);
let mut button = Input::new(p.PC13, Pull::Up);
cortex_m::interrupt::free(|cs| unsafe {
enable_interrupt(&mut button);
LED.borrow(cs).borrow_mut().replace(led);
BUTTON.borrow(cs).borrow_mut().replace(button);
NVIC::unmask(pac::Interrupt::EXTI15_10);
});
loop {
cortex_m::asm::wfe();
}
}
#[interrupt]
fn EXTI15_10() {
cortex_m::interrupt::free(|cs| {
let mut button = BUTTON.borrow(cs).borrow_mut();
let button = button.as_mut().unwrap();
let mut led = LED.borrow(cs).borrow_mut();
let led = led.as_mut().unwrap();
if check_interrupt(button) {
if button.is_low() {
led.set_high();
} else {
led.set_low();
}
}
clear_interrupt(button);
});
}
//
//
//
//
//
//
// "Hidden" HAL-like methods for doing interrupts with embassy. Hardcode pin just to give audience an idea of what it looks like
const PORT: u8 = 2;
const PIN: usize = 13;
fn check_interrupt<P: Pin>(_pin: &mut Input<'static, P>) -> bool {
let exti = pac::EXTI;
unsafe {
let pin = PIN;
let lines = exti.pr(0).read();
lines.line(pin)
}
}
fn clear_interrupt<P: Pin>(_pin: &mut Input<'static, P>) {
let exti = pac::EXTI;
unsafe {
let pin = PIN;
let mut lines = exti.pr(0).read();
lines.set_line(pin, true);
exti.pr(0).write_value(lines);
}
}
fn enable_interrupt<P: Pin>(_pin: &mut Input<'static, P>) {
cortex_m::interrupt::free(|_| unsafe {
let rcc = pac::RCC;
rcc.apb2enr().modify(|w| w.set_syscfgen(true));
let port = PORT;
let pin = PIN;
let syscfg = pac::SYSCFG;
let exti = pac::EXTI;
syscfg.exticr(pin / 4).modify(|w| w.set_exti(pin % 4, port));
exti.imr(0).modify(|w| w.set_line(pin, true));
exti.rtsr(0).modify(|w| w.set_line(pin, true));
exti.ftsr(0).modify(|w| w.set_line(pin, true));
});
}

View File

@ -0,0 +1,13 @@
[package]
name = "blinky-pac"
version = "0.1.0"
edition = "2021"
[dependencies]
cortex-m = "0.7"
cortex-m-rt = "0.7"
stm32-metapac = { version = "0.1.0", features = ["stm32l475vg", "memory-x"] }
defmt = "0.3.0"
defmt-rtt = "0.3.0"
panic-probe = { version = "0.3.0", features = ["print-defmt"] }

View File

@ -0,0 +1,69 @@
#![no_std]
#![no_main]
use defmt_rtt as _;
use panic_probe as _;
use stm32_metapac as pac;
use pac::gpio::vals;
#[cortex_m_rt::entry]
fn main() -> ! {
// Enable GPIO clock
let rcc = pac::RCC;
unsafe {
rcc.ahb2enr().modify(|w| {
w.set_gpioben(true);
w.set_gpiocen(true);
});
rcc.ahb2rstr().modify(|w| {
w.set_gpiobrst(true);
w.set_gpiocrst(true);
w.set_gpiobrst(false);
w.set_gpiocrst(false);
});
}
// Setup button
let gpioc = pac::GPIOC;
const BUTTON_PIN: usize = 13;
unsafe {
gpioc
.pupdr()
.modify(|w| w.set_pupdr(BUTTON_PIN, vals::Pupdr::PULLUP));
gpioc
.otyper()
.modify(|w| w.set_ot(BUTTON_PIN, vals::Ot::PUSHPULL));
gpioc
.moder()
.modify(|w| w.set_moder(BUTTON_PIN, vals::Moder::INPUT));
}
// Setup LED
let gpiob = pac::GPIOB;
const LED_PIN: usize = 14;
unsafe {
gpiob
.pupdr()
.modify(|w| w.set_pupdr(LED_PIN, vals::Pupdr::FLOATING));
gpiob
.otyper()
.modify(|w| w.set_ot(LED_PIN, vals::Ot::PUSHPULL));
gpiob
.moder()
.modify(|w| w.set_moder(LED_PIN, vals::Moder::OUTPUT));
}
// Main loop
loop {
unsafe {
if gpioc.idr().read().idr(BUTTON_PIN) == vals::Idr::LOW {
gpiob.bsrr().write(|w| w.set_bs(LED_PIN, true));
} else {
gpiob.bsrr().write(|w| w.set_br(LED_PIN, true));
}
}
}
}