Skip to content

Commit

Permalink
Remove RefCells in blinky
Browse files Browse the repository at this point in the history
  • Loading branch information
gdobato committed Nov 5, 2023
1 parent a09bcf0 commit c3a4cfb
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 53 deletions.
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ embassy-stm32 = { version = "0.1.0", git = "https://github.com/embassy-rs/embass
"embedded-sdmmc",
"chrono",
] }
embassy-sync = { version = "0.2.0", git = "https://github.com/embassy-rs/embassy.git", features = [
embassy-sync = { version = "0.4.0", git = "https://github.com/embassy-rs/embassy.git", features = [
"defmt",
] }
embassy-executor = { version = "0.2.0", git = "https://github.com/embassy-rs/embassy.git", features = [
embassy-executor = { version = "0.3.1", git = "https://github.com/embassy-rs/embassy.git", features = [
"nightly",
"arch-cortex-m",
"executor-thread",
Expand All @@ -42,10 +42,10 @@ embassy-time = { version = "0.1.2", git = "https://github.com/embassy-rs/embassy
embassy-usb = { version = "0.1.0", git = "https://github.com/embassy-rs/embassy.git", features = [
"defmt",
] }
defmt = "0.3"
defmt = "0.3.5"
defmt-rtt = "0.4"
embedded-hal = "0.2.6"
embedded-io = "0.5.0"
embedded-io = "0.6.1"
panic-probe = { version = "0.3", features = ["print-defmt"] }
futures = { version = "0.3.17", default-features = false, features = [
"async-await",
Expand All @@ -54,7 +54,7 @@ heapless = { version = "0.7.5", default-features = false }
nb = "1.0.0"
embedded-storage = "0.3.0"
micromath = "2.0.0"
static_cell = { version = "1.1", features = ["nightly"] }
static_cell = { version = "2.0.0", features = ["nightly"] }
chrono = { version = "^0.4", default-features = false }

[profile.dev]
Expand Down
72 changes: 24 additions & 48 deletions examples/blinky.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,51 @@
#![no_main]
#![feature(type_alias_impl_trait)]

use core::cell::RefCell;
use cortex_m::interrupt::Mutex;
use defmt::info;
use defmt_rtt as _;
use embassy_executor::Spawner;
use embassy_stm32::gpio::Output;
use embassy_time::{Duration, Timer};
use embassy_executor::{main, task, Spawner};
use embassy_time::Timer;
use portenta_h7_async::led;

static LED_RED: Mutex<RefCell<Option<Output<'static, embassy_stm32::peripherals::PK5>>>> =
Mutex::new(RefCell::new(None));
static LED_GREEN: Mutex<RefCell<Option<Output<'static, embassy_stm32::peripherals::PK6>>>> =
Mutex::new(RefCell::new(None));
static LED_BLUE: Mutex<RefCell<Option<Output<'static, embassy_stm32::peripherals::PK7>>>> =
Mutex::new(RefCell::new(None));

#[embassy_executor::main]
#[main]
async fn main(spawner: Spawner) {
info!("Starting");
let portenta_h7_async::Board {
led_red,
led_green,
led_blue,
led_green,
..
} = portenta_h7_async::Board::take();

cortex_m::interrupt::free(|cs| {
LED_RED.borrow(cs).replace(Some(led_red));
LED_GREEN.borrow(cs).replace(Some(led_green));
LED_BLUE.borrow(cs).replace(Some(led_blue));
});

spawner.spawn(blink_led_red()).unwrap();
spawner.spawn(blink_led_green()).unwrap();
spawner.spawn(blink_led_blue()).unwrap();
spawner.spawn(blink_led_red(led_red)).unwrap();
spawner.spawn(blink_led_green(led_green)).unwrap();
spawner.spawn(blink_led_blue(led_blue)).unwrap();

loop {
Timer::after(Duration::from_millis(100)).await;
Timer::after_millis(100).await;
}
}

#[embassy_executor::task]
async fn blink_led_red() {
#[task]
async fn blink_led_red(mut led: led::user::Red) {
loop {
cortex_m::interrupt::free(|cs| {
if let Some(led_red) = LED_RED.borrow(cs).borrow_mut().as_mut() {
led_red.toggle();
}
});
Timer::after(Duration::from_millis(500)).await;
led.toggle();
Timer::after_millis(250).await;
}
}

#[embassy_executor::task]
async fn blink_led_green() {
#[task]
async fn blink_led_green(mut led: led::user::Green) {
loop {
cortex_m::interrupt::free(|cs| {
if let Some(led_green) = LED_GREEN.borrow(cs).borrow_mut().as_mut() {
led_green.toggle();
}
});
Timer::after(Duration::from_millis(1_000)).await;
led.toggle();
Timer::after_millis(500).await;
}
}

#[embassy_executor::task]
async fn blink_led_blue() {
#[task]
async fn blink_led_blue(mut led: led::user::Blue) {
loop {
cortex_m::interrupt::free(|cs| {
if let Some(led_blue) = LED_BLUE.borrow(cs).borrow_mut().as_mut() {
led_blue.toggle();
}
});
Timer::after(Duration::from_millis(2_000)).await;
led.toggle();
Timer::after_millis(1_000).await;
}
}
47 changes: 47 additions & 0 deletions src/led.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//! led
use embassy_stm32::{
gpio::{Output, Pin},
peripherals,
};

pub trait Led {
fn on(&mut self);
fn off(&mut self);
fn toggle(&mut self);
}

pub mod user {
use super::*;

pub type Red = Output<'static, peripherals::PK5>;
pub type Green = Output<'static, peripherals::PK6>;
pub type Blue = Output<'static, peripherals::PK7>;

// Marker trait
trait BoardLed {}
impl BoardLed for Red {}
impl BoardLed for Green {}
impl BoardLed for Blue {}

impl<T> Led for Output<'static, T>
where
T: Pin,
Output<'static, T>: BoardLed,
{
#[inline]
fn on(&mut self) {
self.set_low();
}

#[inline]
fn off(&mut self) {
self.set_high();
}

#[inline]
fn toggle(&mut self) {
self.toggle();
}
}
}
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#![no_std]

pub mod led;
pub mod panic;
mod sys;
use embassy_stm32::{
gpio::{Level, Output, Speed},
peripherals,
Expand All @@ -22,6 +24,7 @@ impl<'a> Board<'a> {
}

pub fn setup() -> Self {
sys::Clk::new().reset().enable_ext_clock();
let p = embassy_stm32::init(Default::default());
let led_red = Output::new(p.PK5, Level::High, Speed::Low);
let led_green = Output::new(p.PK6, Level::High, Speed::Low);
Expand Down
106 changes: 106 additions & 0 deletions src/sys.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
//! sys
//!
//! Clear up previous clock initialization done in bootloader
//! Enable external oscillator for HSE sourcing (25 MHz)
//!
#![allow(dead_code)]

use cortex_m::asm;
use embassy_stm32::pac::{self, gpio, rcc};

pub struct Unreset;
pub struct Reset;

pub struct Clk<State> {
_state: State,
}

pub type ClkSource = pac::rcc::vals::Sw;
pub type PllSource = pac::rcc::vals::Pllsrc;

impl Clk<Unreset> {
pub fn new() -> Clk<Unreset> {
Clk { _state: Unreset }
}

pub fn get_source() -> ClkSource {
pac::RCC.cfgr().read().sws()
}

pub fn get_pll_source() -> PllSource {
pac::RCC.pllckselr().read().pllsrc()
}

pub fn reset(self) -> Clk<Reset> {
let rcc = pac::RCC;

// Enable HSI and load reset values
rcc.cr().modify(|w| w.set_hsion(true));
rcc.hsicfgr().modify(|w| w.set_hsitrim(0b100000));

// Reset clock configuration and wait for clock switch
rcc.cfgr().write_value(Default::default());
while rcc.cfgr().read() != Default::default() {}

// Reset CSI, HSE, HSI48 and dividers
rcc.cr().modify(|w| {
w.set_hsikeron(false);
w.set_hsidiv(rcc::vals::Hsidiv::DIV1);
w.set_hsidivf(false);
w.set_csion(false);
w.set_csikeron(false);
w.set_hsi48on(false);
w.set_hsecsson(false);
w.set_hsebyp(false);
});

// Disable PLL1, PLL2, PLL3
for n in 0..3usize {
rcc.cr().modify(|w| w.set_pllon(n, false));
while rcc.cr().read().pllon(n) {}
}

// Reset domain configurations
rcc.d1cfgr().write_value(Default::default());
rcc.d2cfgr().write_value(Default::default());
rcc.d3cfgr().write_value(Default::default());

// Reset PLLs configurations
for n in 0..3usize {
rcc.pllckselr()
.write(|w| w.set_divm(n, rcc::vals::Pllm::DIV32));
rcc.plldivr(n)
.write(|w| w.set_pllr(rcc::vals::Plldiv::DIV2));
rcc.pllfracr(n).write(|w| w.set_fracn(0x00));
}
Clk { _state: Reset }
}
}

impl Clk<Reset> {
pub fn enable_ext_clock(self) -> Clk<Reset> {
let rcc = pac::RCC;
// Enable GPIOH clock
rcc.ahb4enr().modify(|w| w.set_gpiohen(true));

// Enable oscilator via push pulled GPIOH_1 output
let gpioh = pac::GPIOH;
gpioh.bsrr().write(|w| w.set_bs(1, true));
gpioh
.moder()
.modify(|w| w.set_moder(1, gpio::vals::Moder::OUTPUT));
gpioh
.otyper()
.modify(|w| w.set_ot(1, gpio::vals::Ot::PUSHPULL));
gpioh
.ospeedr()
.modify(|w| w.set_ospeedr(1, gpio::vals::Ospeedr::LOWSPEED));
gpioh
.pupdr()
.modify(|w| w.set_pupdr(1, gpio::vals::Pupdr::PULLUP));

asm::delay(1_000);
Clk { _state: Reset }
}
}

0 comments on commit c3a4cfb

Please sign in to comment.