Skip to content

Commit

Permalink
Added timer support for WL
Browse files Browse the repository at this point in the history
  • Loading branch information
David-OConnor committed Sep 17, 2021
1 parent 28c6842 commit fa02753
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 52 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ of these peripherals using public methods [1]


## Supported MCUs
F3, F4, L4, L5, G0, G4, H7, and WB. U5 is planned once its SVD files and PAC
become available. WL support is a WIP, with many features not implemented.
F3, F4, L4, L5, G0, G4, H7, WB, and WL. U5 is planned once its SVD files and PAC
become available.

Operationally tested on the following devices:
- STM32F303
Expand Down Expand Up @@ -285,3 +285,4 @@ STM32WL radio support is WIP, and will be provided through interaction withnewAM
- WB and WL are missing features relating to second core operations and RF
- WL is missing support for many peripherals
- L4+ MCUs not supported
- WL is missing GPIO port C, and GPIO interrupt support
59 changes: 35 additions & 24 deletions src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
//! including all GPIOx register functions. It also configures GPIO interrupts using SYSCFG and EXTI
//! registers as appropriate.

// todo: WL is missing port C here due to some pins being missing, and this being tough
// todo to change with our current model. Note sure if PAC, or MCU limitation
// todo: WL is also missing interrupt support.

#[cfg(feature = "embedded-hal")]
use core::convert::Infallible;

Expand Down Expand Up @@ -104,8 +108,9 @@ pub enum ResetState {
pub enum Port {
A,
B,
#[cfg(not(feature = "wl"))]
C,
#[cfg(not(any(feature = "f410")))]
#[cfg(not(any(feature = "f410", feature = "wl")))]
D,
#[cfg(not(any(
feature = "f301",
Expand Down Expand Up @@ -149,8 +154,9 @@ impl Port {
match self {
Self::A => 0,
Self::B => 1,
#[cfg(not(feature = "wl"))]
Self::C => 2,
#[cfg(not(any(feature = "f410")))]
#[cfg(not(any(feature = "f410", feature = "wl")))]
Self::D => 3,
#[cfg(not(any(
feature = "f301",
Expand Down Expand Up @@ -219,6 +225,7 @@ macro_rules! set_field {
_ => panic!("GPIO pins must be 0 - 15."),
}
}
#[cfg(not(feature = "wl"))]
Port::C => {
match $pin {
$(
Expand All @@ -227,7 +234,7 @@ macro_rules! set_field {
_ => panic!("GPIO pins must be 0 - 15."),
}
}
#[cfg(not(any(feature = "f410")))]
#[cfg(not(any(feature = "f410", feature = "wl")))]
Port::D => {
match $pin {
$(
Expand Down Expand Up @@ -300,9 +307,9 @@ macro_rules! set_alt {
$(
$num => {
(*pac::GPIOA::ptr()).moder.modify(|_, w| w.[<moder $num>]().bits(PinMode::Alt(0).val()));
#[cfg(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb", feature = "wl"))]
#[cfg(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb"))]
(*pac::GPIOA::ptr()).[<afr $lh>].modify(|_, w| w.[<$field_af $num>]().bits($val));
#[cfg(not(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb", feature = "wl")))]
#[cfg(not(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb")))]
(*pac::GPIOA::ptr()).[<afr $lh>].modify(|_, w| w.[<$field_af $lh $num>]().bits($val));
}
)+
Expand All @@ -314,38 +321,39 @@ macro_rules! set_alt {
$(
$num => {
(*pac::GPIOB::ptr()).moder.modify(|_, w| w.[<moder $num>]().bits(PinMode::Alt(0).val()));
#[cfg(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb", feature = "wl"))]
#[cfg(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb"))]
(*pac::GPIOB::ptr()).[<afr $lh>].modify(|_, w| w.[<$field_af $num>]().bits($val));
#[cfg(not(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb", feature = "wl")))]
#[cfg(not(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb")))]
(*pac::GPIOB::ptr()).[<afr $lh>].modify(|_, w| w.[<$field_af $lh $num>]().bits($val));
}
)+
_ => panic!("GPIO pins must be 0 - 15."),
}
}
#[cfg(not(feature = "wl"))]
Port::C => {
match $pin {
$(
$num => {
(*pac::GPIOC::ptr()).moder.modify(|_, w| w.[<moder $num>]().bits(PinMode::Alt(0).val()));
#[cfg(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb", feature = "wl"))]
#[cfg(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb"))]
(*pac::GPIOC::ptr()).[<afr $lh>].modify(|_, w| w.[<$field_af $num>]().bits($val));
#[cfg(not(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb", feature = "wl")))]
#[cfg(not(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb")))]
(*pac::GPIOC::ptr()).[<afr $lh>].modify(|_, w| w.[<$field_af $lh $num>]().bits($val));
}
)+
_ => panic!("GPIO pins must be 0 - 15."),
}
}
#[cfg(not(any(feature = "f410")))]
#[cfg(not(any(feature = "f410", feature = "wl")))]
Port::D => {
match $pin {
$(
$num => {
(*pac::GPIOD::ptr()).moder.modify(|_, w| w.[<moder $num>]().bits(PinMode::Alt(0).val()));
#[cfg(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb", feature = "wl"))]
#[cfg(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb"))]
(*pac::GPIOD::ptr()).[<afr $lh>].modify(|_, w| w.[<$field_af $num>]().bits($val));
#[cfg(not(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb", feature = "wl")))]
#[cfg(not(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb")))]
(*pac::GPIOD::ptr()).[<afr $lh>].modify(|_, w| w.[<$field_af $lh $num>]().bits($val));
}
)+
Expand All @@ -358,9 +366,9 @@ macro_rules! set_alt {
$(
$num => {
(*pac::GPIOE::ptr()).moder.modify(|_, w| w.[<moder $num>]().bits(PinMode::Alt(0).val()));
#[cfg(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb", feature = "wl"))]
#[cfg(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb"))]
(*pac::GPIOE::ptr()).[<afr $lh>].modify(|_, w| w.[<$field_af $num>]().bits($val));
#[cfg(not(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb", feature = "wl")))]
#[cfg(not(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb")))]
(*pac::GPIOE::ptr()).[<afr $lh>].modify(|_, w| w.[<$field_af $lh $num>]().bits($val));
}
)+
Expand All @@ -383,9 +391,9 @@ macro_rules! set_alt {
$(
$num => {
(*pac::GPIOF::ptr()).moder.modify(|_, w| w.[<moder $num>]().bits(PinMode::Alt(0).val()));
#[cfg(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb", feature = "wl"))]
#[cfg(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb"))]
(*pac::GPIOF::ptr()).[<afr $lh>].modify(|_, w| w.[<$field_af $num>]().bits($val));
#[cfg(not(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb", feature = "wl")))]
#[cfg(not(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb")))]
(*pac::GPIOF::ptr()).[<afr $lh>].modify(|_, w| w.[<$field_af $lh $num>]().bits($val));
}
)+
Expand All @@ -408,9 +416,9 @@ macro_rules! set_alt {
$(
$num => {
(*pac::GPIOH::ptr()).moder.modify(|_, w| w.[<moder $num>]().bits(PinMode::Alt(0).val()));
#[cfg(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb", feature = "wl"))]
#[cfg(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb"))]
(*pac::GPIOH::ptr()).[<afr $lh>].modify(|_, w| w.[<$field_af $num>]().bits($val));
#[cfg(not(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb", feature = "wl")))]
#[cfg(not(any(feature = "l5", feature = "g0", feature = "h7", feature = "wb")))]
(*pac::GPIOH::ptr()).[<afr $lh>].modify(|_, w| w.[<$field_af $lh $num>]().bits($val));
}
)+
Expand Down Expand Up @@ -447,6 +455,7 @@ macro_rules! get_input_data {
_ => panic!("GPIO pins must be 0 - 15."),
}
}
#[cfg(not(feature = "wl"))]
Port::C => {
match $pin {
$(
Expand All @@ -455,7 +464,7 @@ macro_rules! get_input_data {
_ => panic!("GPIO pins must be 0 - 15."),
}
}
#[cfg(not(any(feature = "f410")))]
#[cfg(not(any(feature = "f410", feature = "wl")))]
Port::D => {
match $pin {
$(
Expand Down Expand Up @@ -539,6 +548,7 @@ macro_rules! set_state {
_ => panic!("GPIO pins must be 0 - 15."),
}
}
#[cfg(not(feature = "wl"))]
Port::C => {
match $pin {
$(
Expand All @@ -547,7 +557,7 @@ macro_rules! set_state {
_ => panic!("GPIO pins must be 0 - 15."),
}
}
#[cfg(not(any(feature = "f410")))]
#[cfg(not(any(feature = "f410", feature = "wl")))]
Port::D => {
match $pin {
$(
Expand Down Expand Up @@ -810,6 +820,7 @@ impl Pin {
}
}
}
#[cfg(not(feature = "wl"))]
Port::C => {
cfg_if! {
if #[cfg(feature = "f3")] {
Expand Down Expand Up @@ -839,7 +850,7 @@ impl Pin {
}
}
}
#[cfg(not(any(feature = "f410")))]
#[cfg(not(any(feature = "f410", feature = "wl")))]
Port::D => {
cfg_if! {
if #[cfg(feature = "f3")] {
Expand Down Expand Up @@ -1102,23 +1113,23 @@ impl Pin {
assert!(value <= 15, "Alt function must be 0 to 15.");

cfg_if! {
if #[cfg(any(feature = "l5", feature = "g0", feature = "wb", feature = "wl"))] {
if #[cfg(any(feature = "l5", feature = "g0", feature = "wb"))] {
set_alt!(self.pin, self.port, afsel, value, [(0, l), (1, l), (2, l),
(3, l), (4, l), (5, l), (6, l), (7, l), (8, h), (9, h), (10, h), (11, h), (12, h),
(13, h), (14, h), (15, h)])
} else if #[cfg(feature = "h7")] {
set_alt!(self.pin, self.port, afr, value, [(0, l), (1, l), (2, l),
(3, l), (4, l), (5, l), (6, l), (7, l), (8, h), (9, h), (10, h), (11, h), (12, h),
(13, h), (14, h), (15, h)])
} else { // f3, f4, l4, g4
} else { // f3, f4, l4, g4, wl(?)
set_alt!(self.pin, self.port, afr, value, [(0, l), (1, l), (2, l),
(3, l), (4, l), (5, l), (6, l), (7, l), (8, h), (9, h), (10, h), (11, h), (12, h),
(13, h), (14, h), (15, h)])
}
}
}

#[cfg(not(feature = "f373"))]
#[cfg(not(any(feature = "f373", feature = "wl")))]
/// Configure this pin as an interrupt source. Set the edge as Rising or Falling.
pub fn enable_interrupt(&mut self, edge: Edge) {
let rise_trigger = match edge {
Expand Down
7 changes: 2 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ pub mod dma;

#[cfg(not(feature = "h7"))] // todo
pub mod flash;
#[cfg(not(feature = "wl"))] // todo

pub mod gpio;

#[cfg(feature = "wb")]
Expand Down Expand Up @@ -407,7 +407,6 @@ feature = "wl",
)))]
pub mod qspi;

#[cfg(not(feature = "wl"))] // todo
pub mod rtc;

#[cfg(not(any(
Expand All @@ -421,10 +420,8 @@ pub mod rtc;
pub mod sai;

pub mod spi;

#[cfg(not(feature = "wl"))] // todo
// #[cfg(not(feature = "wl"))] // todo
pub mod timer;
#[cfg(not(feature = "wl"))] // todo
pub mod usart;

// See note at top of `usb` module for info on G0; not avail on modules the PAC has avail.
Expand Down
28 changes: 21 additions & 7 deletions src/rtc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use chrono::{Datelike, NaiveDate, NaiveDateTime, NaiveTime, Timelike};

use cfg_if::cfg_if;

// todo: QC use of ICSR vice SR and ISR wherever used in this module!

/// RTC Clock source.
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(u8)]
Expand Down Expand Up @@ -174,7 +176,7 @@ impl Rtc {
match config.clock_source {
RtcClockSource::Lsi => {
cfg_if! {
if #[cfg(any(feature = "wb", feature = "wl"))] {
if #[cfg(feature = "wb")] {
// todo: LSI2?
rcc.csr.modify(|_, w| w.lsi1on().set_bit());
while rcc.csr.read().lsi1rdy().bit_is_clear() {}
Expand Down Expand Up @@ -425,7 +427,7 @@ impl Rtc {
// Ensure access to Wakeup auto-reload counter and bits WUCKSEL[2:0] is allowed.
// Poll WUTWF until it is set in RTC_ISR (RTC2)/RTC_ICSR (RTC3) (May not be avail on F3)
cfg_if! {
if #[cfg(any(feature = "l5", feature = "g0", feature = "g4", feature = "l412"))] {
if #[cfg(any(feature = "l5", feature = "g0", feature = "g4", feature = "l412", feature = "wl"))] {
while self.regs.icsr.read().wutwf().bit_is_clear() {}
} else {
while self.regs.isr.read().wutwf().bit_is_clear() {}
Expand All @@ -441,7 +443,7 @@ impl Rtc {
self.regs.cr.modify(|_, w| w.wutie().set_bit());

cfg_if! {
if #[cfg(any(feature = "l412", feature = "l5", feature = "g0", feature = "g4", feature = "l412"))] {
if #[cfg(any(feature = "l412", feature = "l5", feature = "g0", feature = "g4", feature = "l412", feature = "wl"))] {
self.regs.scr.write(|w| w.cwutf().set_bit());
} else {
self.regs.isr.modify(|_, w| w.wutf().clear_bit());
Expand Down Expand Up @@ -488,7 +490,7 @@ impl Rtc {
}

cfg_if! {
if #[cfg(any(feature = "l5", feature = "g0", feature = "g4", feature = "l412"))] {
if #[cfg(any(feature = "l5", feature = "g0", feature = "g4", feature = "l412", feature = "wl"))] {
while self.regs.icsr.read().wutwf().bit_is_clear() {}
} else {
while self.regs.isr.read().wutwf().bit_is_clear() {}
Expand All @@ -511,7 +513,7 @@ impl Rtc {
regs.cr.modify(|_, w| w.wute().clear_bit());

cfg_if! {
if #[cfg(any(feature = "l412", feature = "l5", feature = "g0", feature = "g4", feature = "l412"))] {
if #[cfg(any(feature = "l412", feature = "l5", feature = "g0", feature = "g4", feature = "l412", feature = "wl"))] {
regs.scr.write(|w| w.cwutf().set_bit());
} else {
// Note that we clear this by writing 0, which isn't
Expand Down Expand Up @@ -540,7 +542,7 @@ impl Rtc {
// todo: L4 has ICSR and ISR regs. Maybe both for backwards compat?

cfg_if! {
if #[cfg(any(feature = "l5", feature = "g0", feature = "g4", feature = "l412"))] {
if #[cfg(any(feature = "l5", feature = "g0", feature = "g4", feature = "l412", feature = "wl"))] {
// Enter init mode if required. This is generally used to edit the clock or calendar,
// but not for initial enabling steps.
if init_mode && self.regs.icsr.read().initf().bit_is_clear() {
Expand All @@ -556,7 +558,19 @@ impl Rtc {
self.regs.icsr.modify(|_, w| w.init().clear_bit()); // Exits init mode
while self.regs.icsr.read().initf().bit_is_set() {}
}
} else {
// } else if #[cfg(feature = "wl")] {
// if init_mode && self.regs.isr.read().initf().bit_is_clear() {
// self.regs.icsr.modify(|_, w| w.init().set_bit());
// while self.regs.icsr.read().initf().bit_is_clear() {} // wait to return to init state
// }

// closure(&mut self.regs);

// if init_mode {
// self.regs.icsr.modify(|_, w| w.init().clear_bit()); // Exits init mode
// while self.regs.sr.read().initf().bit_is_set() {}
// }
} else {
if init_mode && self.regs.isr.read().initf().bit_is_clear() {
self.regs.isr.modify(|_, w| w.init().set_bit());
while self.regs.isr.read().initf().bit_is_clear() {} // wait to return to init state
Expand Down
Loading

0 comments on commit fa02753

Please sign in to comment.