Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use bare_metal::CriticalSection for GPIO configuration #180

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Changed

- Updated the `cast` dependency from 0.2 to 0.3
- Use `bare_metal::CriticalSection` for GPIO configuration (breaking change)

### Added

Expand Down
19 changes: 15 additions & 4 deletions examples/adc_values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use stm32f0xx_hal as hal;

use crate::hal::{pac, prelude::*};

use cortex_m::{interrupt::Mutex, peripheral::syst::SystClkSource::Core};
use bare_metal::Mutex;
use cortex_m::peripheral::syst::SystClkSource::Core;
use cortex_m_rt::{entry, exception};

use core::{cell::RefCell, fmt::Write};
Expand All @@ -25,7 +26,12 @@ fn main() -> ! {
hal::pac::Peripherals::take(),
cortex_m::peripheral::Peripherals::take(),
) {
cortex_m::interrupt::free(move |cs| {
cortex_m::interrupt::free(move |_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { &bare_metal::CriticalSection::new() };

let mut flash = p.FLASH;
let mut rcc = p.RCC.configure().sysclk(8.mhz()).freeze(&mut flash);

Expand Down Expand Up @@ -60,7 +66,7 @@ fn main() -> ! {
tx.write_str("\n\rThis ADC example will read various values using the ADC and print them out to the serial terminal\r\n").ok();

// Move all components under Mutex supervision
*SHARED.borrow(cs).borrow_mut() = Some(Shared { adc, tx });
*SHARED.borrow(*cs).borrow_mut() = Some(Shared { adc, tx });
});
}

Expand All @@ -74,7 +80,12 @@ fn SysTick() {
use core::ops::DerefMut;

// Enter critical section
cortex_m::interrupt::free(|cs| {
cortex_m::interrupt::free(|_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { bare_metal::CriticalSection::new() };

// Get access to the Mutex protected shared data
if let Some(ref mut shared) = SHARED.borrow(cs).borrow_mut().deref_mut() {
// Read temperature data from internal sensor using ADC
Expand Down
8 changes: 7 additions & 1 deletion examples/blinky.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ fn main() -> ! {
let gpioa = p.GPIOA.split(&mut rcc);

// (Re-)configure PA1 as output
let mut led = cortex_m::interrupt::free(|cs| gpioa.pa1.into_push_pull_output(cs));
let mut led = cortex_m::interrupt::free(|_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { &bare_metal::CriticalSection::new() };
gpioa.pa1.into_push_pull_output(cs)
});

loop {
// Turn PA1 on a million times in a row
Expand Down
7 changes: 6 additions & 1 deletion examples/blinky_adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ fn main() -> ! {

let gpioa = p.GPIOA.split(&mut rcc);

let (mut led, mut an_in) = cortex_m::interrupt::free(move |cs| {
let (mut led, mut an_in) = cortex_m::interrupt::free(move |_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { &bare_metal::CriticalSection::new() };

(
// (Re-)configure PA1 as output
gpioa.pa1.into_push_pull_output(cs),
Expand Down
8 changes: 7 additions & 1 deletion examples/blinky_delay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ fn main() -> ! {
let gpioa = p.GPIOA.split(&mut rcc);

// (Re-)configure PA1 as output
let mut led = cortex_m::interrupt::free(move |cs| gpioa.pa1.into_push_pull_output(cs));
let mut led = cortex_m::interrupt::free(move |_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { &bare_metal::CriticalSection::new() };
gpioa.pa1.into_push_pull_output(cs)
});

// Get delay provider
let mut delay = Delay::new(cp.SYST, &rcc);
Expand Down
7 changes: 6 additions & 1 deletion examples/blinky_multiple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ fn main() -> ! {
let gpioa = p.GPIOA.split(&mut rcc);
let gpiob = p.GPIOB.split(&mut rcc);

let (led1, led2) = cortex_m::interrupt::free(move |cs| {
let (led1, led2) = cortex_m::interrupt::free(move |_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { &bare_metal::CriticalSection::new() };

(
// (Re-)configure PA1 as output
gpioa.pa1.into_push_pull_output(cs),
Expand Down
8 changes: 7 additions & 1 deletion examples/blinky_timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ fn main() -> ! {
let gpioa = p.GPIOA.split(&mut rcc);

// (Re-)configure PA1 as output
let mut led = cortex_m::interrupt::free(move |cs| gpioa.pa1.into_push_pull_output(cs));
let mut led = cortex_m::interrupt::free(move |_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { &bare_metal::CriticalSection::new() };
gpioa.pa1.into_push_pull_output(cs)
});

// Set up a timer expiring after 1s
let mut timer = Timer::tim1(p.TIM1, Hertz(1), &mut rcc);
Expand Down
28 changes: 22 additions & 6 deletions examples/blinky_timer_irq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ use crate::hal::{

use cortex_m_rt::entry;

use bare_metal::Mutex;
use core::cell::RefCell;
use cortex_m::{interrupt::Mutex, peripheral::Peripherals as c_m_Peripherals};
use cortex_m::peripheral::Peripherals as c_m_Peripherals;

// A type definition for the GPIO pin to be used for our LED
type LEDPIN = gpioa::PA5<Output<PushPull>>;
Expand All @@ -35,14 +36,24 @@ fn TIM7() {
static mut INT: Option<Timer<TIM7>> = None;

let led = LED.get_or_insert_with(|| {
cortex_m::interrupt::free(|cs| {
cortex_m::interrupt::free(|_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { bare_metal::CriticalSection::new() };

// Move LED pin here, leaving a None in its place
GLED.borrow(cs).replace(None).unwrap()
})
});

let int = INT.get_or_insert_with(|| {
cortex_m::interrupt::free(|cs| {
cortex_m::interrupt::free(|_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { bare_metal::CriticalSection::new() };

// Move LED pin here, leaving a None in its place
GINT.borrow(cs).replace(None).unwrap()
})
Expand All @@ -55,7 +66,12 @@ fn TIM7() {
#[entry]
fn main() -> ! {
if let (Some(mut p), Some(cp)) = (Peripherals::take(), c_m_Peripherals::take()) {
cortex_m::interrupt::free(move |cs| {
cortex_m::interrupt::free(move |_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { &bare_metal::CriticalSection::new() };

let mut rcc = p
.RCC
.configure()
Expand All @@ -71,7 +87,7 @@ fn main() -> ! {
let led = gpioa.pa5.into_push_pull_output(cs);

// Move the pin into our global storage
*GLED.borrow(cs).borrow_mut() = Some(led);
*GLED.borrow(*cs).borrow_mut() = Some(led);

// Set up a timer expiring after 1s
let mut timer = Timer::tim7(p.TIM7, Hertz(1), &mut rcc);
Expand All @@ -80,7 +96,7 @@ fn main() -> ! {
timer.listen(Event::TimeOut);

// Move the timer into our global storage
*GINT.borrow(cs).borrow_mut() = Some(timer);
*GINT.borrow(*cs).borrow_mut() = Some(timer);

// Enable TIM7 IRQ, set prio 1 and clear any pending IRQs
let mut nvic = cp.NVIC;
Expand Down
8 changes: 7 additions & 1 deletion examples/dac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@ fn main() -> ! {
let mut rcc = dp.RCC.configure().sysclk(8.mhz()).freeze(&mut dp.FLASH);
let gpioa = dp.GPIOA.split(&mut rcc);

let pa4 = cortex_m::interrupt::free(move |cs| gpioa.pa4.into_analog(cs));
let pa4 = cortex_m::interrupt::free(move |_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { &bare_metal::CriticalSection::new() };
gpioa.pa4.into_analog(cs)
});

let mut dac = dac(dp.DAC, pa4, &mut rcc);

Expand Down
19 changes: 15 additions & 4 deletions examples/flash_systick.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use stm32f0xx_hal as hal;

use crate::hal::{gpio::*, pac, prelude::*};

use cortex_m::{interrupt::Mutex, peripheral::syst::SystClkSource::Core, Peripherals};
use bare_metal::Mutex;
use cortex_m::{peripheral::syst::SystClkSource::Core, Peripherals};
use cortex_m_rt::{entry, exception};

use core::cell::RefCell;
Expand All @@ -19,7 +20,12 @@ static GPIO: Mutex<RefCell<Option<gpioa::PA1<Output<PushPull>>>>> = Mutex::new(R
#[entry]
fn main() -> ! {
if let (Some(mut p), Some(cp)) = (pac::Peripherals::take(), Peripherals::take()) {
cortex_m::interrupt::free(move |cs| {
cortex_m::interrupt::free(move |_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { &bare_metal::CriticalSection::new() };

let mut rcc = p.RCC.configure().sysclk(48.mhz()).freeze(&mut p.FLASH);

let gpioa = p.GPIOA.split(&mut rcc);
Expand All @@ -28,7 +34,7 @@ fn main() -> ! {
let led = gpioa.pa1.into_push_pull_output(cs);

// Transfer GPIO into a shared structure
*GPIO.borrow(cs).borrow_mut() = Some(led);
*GPIO.borrow(*cs).borrow_mut() = Some(led);

let mut syst = cp.SYST;

Expand Down Expand Up @@ -62,7 +68,12 @@ fn SysTick() {
static mut STATE: u8 = 1;

// Enter critical section
cortex_m::interrupt::free(|cs| {
cortex_m::interrupt::free(|_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { bare_metal::CriticalSection::new() };

// Borrow access to our GPIO pin from the shared structure
if let Some(ref mut led) = *GPIO.borrow(cs).borrow_mut().deref_mut() {
// Check state variable, keep LED off most of the time and turn it on every 10th tick
Expand Down
19 changes: 15 additions & 4 deletions examples/flash_systick_fancier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use stm32f0xx_hal as hal;

use crate::hal::{gpio::*, pac, prelude::*};

use cortex_m::{interrupt::Mutex, peripheral::syst::SystClkSource::Core, Peripherals};
use bare_metal::Mutex;
use cortex_m::{peripheral::syst::SystClkSource::Core, Peripherals};
use cortex_m_rt::{entry, exception};

use core::cell::RefCell;
Expand All @@ -22,7 +23,12 @@ static GPIO: Mutex<RefCell<Option<LEDPIN>>> = Mutex::new(RefCell::new(None));
#[entry]
fn main() -> ! {
if let (Some(mut p), Some(cp)) = (pac::Peripherals::take(), Peripherals::take()) {
cortex_m::interrupt::free(move |cs| {
cortex_m::interrupt::free(move |_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { &bare_metal::CriticalSection::new() };

let mut rcc = p.RCC.configure().sysclk(48.mhz()).freeze(&mut p.FLASH);

// Get access to individual pins in the GPIO port
Expand All @@ -32,7 +38,7 @@ fn main() -> ! {
let led = gpioa.pb3.into_push_pull_output(cs);

// Transfer GPIO into a shared structure
swap(&mut Some(led), &mut GPIO.borrow(cs).borrow_mut());
swap(&mut Some(led), &mut GPIO.borrow(*cs).borrow_mut());

let mut syst = cp.SYST;

Expand Down Expand Up @@ -88,7 +94,12 @@ fn SysTick() {
// Otherwise move it out of the Mutex protected shared region into our exception handler
else {
// Enter critical section
cortex_m::interrupt::free(|cs| {
cortex_m::interrupt::free(|_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { bare_metal::CriticalSection::new() };

// Swap globally stored data with SysTick private data
swap(LED, &mut GPIO.borrow(cs).borrow_mut());
});
Expand Down
7 changes: 6 additions & 1 deletion examples/i2c_find_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
if let Some(p) = pac::Peripherals::take() {
cortex_m::interrupt::free(move |cs| {
cortex_m::interrupt::free(move |_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { &bare_metal::CriticalSection::new() };

let mut flash = p.FLASH;
let mut rcc = p.RCC.configure().freeze(&mut flash);

Expand Down
23 changes: 17 additions & 6 deletions examples/led_hal_button_irq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ use crate::hal::{
prelude::*,
};

use cortex_m::{interrupt::Mutex, peripheral::Peripherals as c_m_Peripherals};
use bare_metal::Mutex;
use cortex_m::peripheral::Peripherals as c_m_Peripherals;
use cortex_m_rt::entry;

use core::{cell::RefCell, ops::DerefMut};
Expand All @@ -29,7 +30,12 @@ static INT: Mutex<RefCell<Option<EXTI>>> = Mutex::new(RefCell::new(None));
#[entry]
fn main() -> ! {
if let (Some(p), Some(cp)) = (Peripherals::take(), c_m_Peripherals::take()) {
cortex_m::interrupt::free(move |cs| {
cortex_m::interrupt::free(move |_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { &bare_metal::CriticalSection::new() };

// Enable clock for SYSCFG
let rcc = p.RCC;
rcc.apb2enr.modify(|_, w| w.syscfgen().set_bit());
Expand Down Expand Up @@ -64,9 +70,9 @@ fn main() -> ! {
exti.rtsr.modify(|_, w| w.tr1().set_bit());

// Move control over LED and DELAY and EXTI into global mutexes
*LED.borrow(cs).borrow_mut() = Some(led);
*DELAY.borrow(cs).borrow_mut() = Some(delay);
*INT.borrow(cs).borrow_mut() = Some(exti);
*LED.borrow(*cs).borrow_mut() = Some(led);
*DELAY.borrow(*cs).borrow_mut() = Some(delay);
*INT.borrow(*cs).borrow_mut() = Some(exti);

// Enable EXTI IRQ, set prio 1 and clear any pending IRQs
let mut nvic = cp.NVIC;
Expand All @@ -88,7 +94,12 @@ fn main() -> ! {
#[interrupt]
fn EXTI0_1() {
// Enter critical section
cortex_m::interrupt::free(|cs| {
cortex_m::interrupt::free(|_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { bare_metal::CriticalSection::new() };

// Obtain all Mutex protected resources
if let (&mut Some(ref mut led), &mut Some(ref mut delay), &mut Some(ref mut exti)) = (
LED.borrow(cs).borrow_mut().deref_mut(),
Expand Down
8 changes: 6 additions & 2 deletions examples/pwm.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![deny(unsafe_code)]
#![no_main]
#![no_std]

Expand All @@ -18,7 +17,12 @@ fn main() -> ! {
let mut rcc = dp.RCC.configure().sysclk(8.mhz()).freeze(&mut dp.FLASH);

let gpioa = dp.GPIOA.split(&mut rcc);
let channels = cortex_m::interrupt::free(move |cs| {
let channels = cortex_m::interrupt::free(move |_| {
// SAFETY: We are in a critical section, but the `cortex_m` critical section
// token is not compatible with the `bare_metal` token. Future version of the
// `cortex_m` crate will not supply *any* token to this callback!
let cs = unsafe { &bare_metal::CriticalSection::new() };

(
gpioa.pa8.into_alternate_af2(cs),
gpioa.pa9.into_alternate_af2(cs),
Expand Down
Loading
Loading