Added "device-selected" meta-feature and simplified feature gates

Also reworked some use statements to reduce amount of meta code

Signed-off-by: Daniel Egger <daniel@eggers-club.de>
This commit is contained in:
Daniel Egger 2018-12-24 14:27:51 +01:00
parent 476eb404af
commit ef855a0829
11 changed files with 85 additions and 212 deletions

View File

@ -10,8 +10,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Added
- Added Sync & Send ability to Pin
- Added overflow guards to delay
- Added initial implementation of an ADC interface (#13) - @HarkonenBade
- Added virtual-feature "device-selected" to simplify feature gating
### Changed
- Added overflow guards to delay
## [v0.10.0] - 2018-12-23

View File

@ -44,16 +44,17 @@ version = "0.2.2"
panic-halt = "0.2.0"
[features]
device-selected = []
rt = ["stm32f0/rt"]
stm32f042 = ["stm32f0/stm32f0x2"]
stm32f030 = ["stm32f0/stm32f0x0"]
stm32f030x4 = ["stm32f030x6"]
stm32f030x6 = ["stm32f030"]
stm32f030x8 = ["stm32f030"]
stm32f030xc = ["stm32f030"]
stm32f070 = ["stm32f0/stm32f0x0"]
stm32f070x6 = ["stm32f070"]
stm32f070xb = ["stm32f070"]
stm32f042 = ["stm32f0/stm32f0x2", "device-selected"]
stm32f030 = ["stm32f0/stm32f0x0", "device-selected"]
stm32f030x4 = ["stm32f030x6", "device-selected"]
stm32f030x6 = ["stm32f030", "device-selected"]
stm32f030x8 = ["stm32f030", "device-selected"]
stm32f030xc = ["stm32f030", "device-selected"]
stm32f070 = ["stm32f0/stm32f0x0", "device-selected"]
stm32f070x6 = ["stm32f070", "device-selected"]
stm32f070xb = ["stm32f070", "device-selected"]
[profile.dev]
debug = true

View File

@ -33,12 +33,13 @@
//! }
//! ```
#[cfg(feature = "device-selected")]
use embedded_hal::adc::{Channel, OneShot};
use crate::stm32;
use crate::gpio::*;
#[cfg(feature = "device-selected")]
use crate::{stm32, gpio::*};
#[cfg(feature = "device-selected")]
/// Analog to Digital converter interface
pub struct Adc {
rb: stm32::ADC,
@ -70,6 +71,7 @@ pub enum AdcSampleTime {
T_239,
}
#[cfg(feature = "device-selected")]
impl AdcSampleTime {
fn write_bits(&self, adc: &mut stm32::ADC) {
unsafe {
@ -117,6 +119,7 @@ pub enum AdcAlign {
LeftAsRM,
}
#[cfg(feature = "device-selected")]
impl AdcAlign {
fn write_bits(&self, adc: &mut stm32::ADC) {
adc.cfgr1.write(|w| {
@ -147,6 +150,7 @@ pub enum AdcPrecision {
B_6,
}
#[cfg(feature = "device-selected")]
impl AdcPrecision {
fn write_bits(&self, adc: &mut stm32::ADC) {
unsafe {
@ -167,6 +171,7 @@ impl AdcPrecision {
}
}
#[cfg(feature = "device-selected")]
macro_rules! adc_pins {
($($pin:ty => $chan:expr),+ $(,)*) => {
$(
@ -179,7 +184,7 @@ macro_rules! adc_pins {
};
}
#[cfg(any(feature = "stm32f042", feature = "stm32f030", feature = "stm32f070",))]
#[cfg(feature = "device-selected")]
adc_pins!(
gpioa::PA0<Analog> => 0_u8,
gpioa::PA1<Analog> => 1_u8,
@ -211,11 +216,13 @@ pub struct VTemp;
/// Internal voltage reference (ADC Channel 17)
pub struct VRef;
#[cfg(feature = "device-selected")]
adc_pins!(
VTemp => 16_u8,
VRef => 17_u8,
);
#[cfg(feature = "device-selected")]
impl VTemp {
/// Init a new VTemp
pub fn new() -> Self {
@ -236,6 +243,7 @@ impl VTemp {
}
}
#[cfg(feature = "device-selected")]
impl VRef {
/// Init a new VRef
pub fn new() -> Self {
@ -253,17 +261,17 @@ impl VRef {
}
}
#[cfg(any(feature = "stm32f042",))]
#[cfg(feature = "stm32f042")]
#[derive(Debug)]
/// Battery reference voltage (ADC Channel 18)
pub struct VBat;
#[cfg(any(feature = "stm32f042",))]
#[cfg(feature = "stm32f042")]
adc_pins!(
VBat => 18_u8,
);
#[cfg(any(feature = "stm32f042",))]
#[cfg(feature = "stm32f042")]
impl VBat {
/// Init a new VBat
pub fn new() -> Self {
@ -282,6 +290,7 @@ impl VBat {
}
}
#[cfg(feature = "device-selected")]
impl Adc {
/// Init a new Adc
///
@ -381,6 +390,7 @@ impl Adc {
}
}
#[cfg(feature = "device-selected")]
impl<WORD, PIN> OneShot<Adc, WORD, PIN> for Adc
where
WORD: From<u16>,

View File

@ -143,18 +143,10 @@ macro_rules! gpio_trait {
};
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
gpio_trait!(gpioa);
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
gpio_trait!(gpiof);
#[allow(unused)]
@ -535,11 +527,7 @@ macro_rules! gpio {
}
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
gpio!(GPIOA, gpioa, iopaen, PA, [
PA0: (pa0, 0, Input<Floating>),
PA1: (pa1, 1, Input<Floating>),
@ -559,11 +547,7 @@ gpio!(GPIOA, gpioa, iopaen, PA, [
PA15: (pa15, 15, Input<Floating>),
]);
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
gpio!(GPIOB, gpiob, iopben, PB, [
PB0: (pb0, 0, Input<Floating>),
PB1: (pb1, 1, Input<Floating>),

View File

@ -7,7 +7,6 @@ use embedded_hal::blocking::i2c::{Write, WriteRead};
#[allow(unused)]
use crate::{
gpio::*,
stm32,
time::{KiloHertz, U32Ext},
};
@ -29,10 +28,10 @@ macro_rules! i2c_pins {
})+) => {
$(
$(
impl SclPin<stm32::$I2C> for $scl {}
impl SclPin<crate::stm32::$I2C> for $scl {}
)+
$(
impl SdaPin<stm32::$I2C> for $sda {}
impl SdaPin<crate::stm32::$I2C> for $sda {}
)+
)+
}
@ -121,7 +120,7 @@ macro_rules! i2c {
SDAPIN: SdaPin<$I2C>,
{
// NOTE(unsafe) This executes only during initialisation
let rcc = unsafe { &(*stm32::RCC::ptr()) };
let rcc = unsafe { &(*crate::stm32::RCC::ptr()) };
/* Enable clock for I2C */
rcc.$apbenr.modify(|_, w| w.$i2cXen().set_bit());
@ -135,14 +134,12 @@ macro_rules! i2c {
)+
}
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
i2c! {
I2C1: (i2c1, i2c1en, i2c1rst, apb1enr, apb1rstr),
}
#[cfg(any(
feature = "stm32f030xc",
// XXX: This can't be right
@ -153,20 +150,12 @@ i2c! {
I2C2: (i2c2, i2c2en, i2c2rst, apb1enr, apb1rstr),
}
#[cfg(feature = "device-selected")]
// It's s needed for the impls, but rustc doesn't recognize that
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[allow(dead_code)]
type I2cRegisterBlock = stm32::i2c1::RegisterBlock;
type I2cRegisterBlock = crate::stm32::i2c1::RegisterBlock;
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
impl<I2C, SCLPIN, SDAPIN> I2c<I2C, SCLPIN, SDAPIN>
where
I2C: Deref<Target = I2cRegisterBlock>,
@ -251,11 +240,7 @@ where
}
}
#[cfg(any(
feature = "stm32f042",
feature = "stm32f030",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
impl<I2C, SCLPIN, SDAPIN> WriteRead for I2c<I2C, SCLPIN, SDAPIN>
where
I2C: Deref<Target = I2cRegisterBlock>,
@ -336,11 +321,7 @@ where
}
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
impl<I2C, SCLPIN, SDAPIN> Write for I2c<I2C, SCLPIN, SDAPIN>
where
I2C: Deref<Target = I2cRegisterBlock>,

View File

@ -9,14 +9,6 @@ pub use stm32f0::stm32f0x2 as stm32;
#[cfg(any(feature = "stm32f030", feature = "stm32f070"))]
pub use stm32f0::stm32f0x0 as stm32;
#[cfg(not(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
)))]
pub mod stm32 {}
pub mod adc;
pub mod delay;
pub mod gpio;

View File

@ -1,10 +1,3 @@
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
use crate::stm32::{FLASH, RCC};
use crate::time::Hertz;
/// Extension trait that constrains the `RCC` peripheral
@ -13,12 +6,8 @@ pub trait RccExt {
fn constrain(self) -> Rcc;
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
impl RccExt for RCC {
#[cfg(feature = "device-selected")]
impl RccExt for crate::stm32::RCC {
fn constrain(self) -> Rcc {
Rcc {
cfgr: CFGR {
@ -45,11 +34,7 @@ pub struct CFGR {
sysclk: Option<u32>,
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
impl CFGR {
pub fn hclk<F>(mut self, freq: F) -> Self
where
@ -121,7 +106,7 @@ impl CFGR {
// adjust flash wait states
unsafe {
let flash = &*FLASH::ptr();
let flash = &*crate::stm32::FLASH::ptr();
flash.acr.write(|w| {
w.latency().bits(if sysclk <= 24_000_000 {
0b000
@ -133,7 +118,7 @@ impl CFGR {
})
}
let rcc = unsafe { &*RCC::ptr() };
let rcc = unsafe { &*crate::stm32::RCC::ptr() };
if let Some(pllmul_bits) = pllmul_bits {
// use PLL as source

View File

@ -34,7 +34,7 @@ use core::{
use embedded_hal::prelude::*;
#[allow(unused)]
use crate::{gpio::*, rcc::Clocks, stm32, time::Bps};
use crate::{gpio::*, rcc::Clocks, time::Bps};
/// Interrupt event
pub enum Event {
@ -62,7 +62,7 @@ pub enum Error {
pub trait TxPin<USART> {}
pub trait RxPin<USART> {}
#[allow(unused)]
#[cfg(feature = "device-selected")]
macro_rules! usart_pins {
($($USART:ident => {
tx => [$($tx:ty),+ $(,)*],
@ -70,10 +70,10 @@ macro_rules! usart_pins {
})+) => {
$(
$(
impl TxPin<stm32::$USART> for $tx {}
impl TxPin<crate::stm32::$USART> for $tx {}
)+
$(
impl RxPin<stm32::$USART> for $rx {}
impl RxPin<crate::stm32::$USART> for $rx {}
)+
)+
}
@ -163,7 +163,7 @@ pub struct Tx<USART> {
// NOTE(unsafe) Required to allow protected shared access in handlers
unsafe impl<USART> Send for Tx<USART> {}
#[allow(unused)]
#[cfg(feature = "device-selected")]
macro_rules! usart {
($($USART:ident: ($usart:ident, $usartXen:ident, $apbenr:ident),)+) => {
$(
@ -176,7 +176,7 @@ macro_rules! usart {
RXPIN: RxPin<$USART>,
{
// NOTE(unsafe) This executes only during initialisation
let rcc = unsafe { &(*stm32::RCC::ptr()) };
let rcc = unsafe { &(*crate::stm32::RCC::ptr()) };
/* Enable clock for USART */
rcc.$apbenr.modify(|_, w| w.$usartXen().set_bit());
@ -199,11 +199,7 @@ macro_rules! usart {
}
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
usart! {
USART1: (usart1, usart1en, apb2enr),
}
@ -229,18 +225,10 @@ usart! {
// It's s needed for the impls, but rustc doesn't recognize that
#[allow(dead_code)]
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
type SerialRegisterBlock = stm32::usart1::RegisterBlock;
#[cfg(feature = "device-selected")]
type SerialRegisterBlock = crate::stm32::usart1::RegisterBlock;
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
impl<USART> embedded_hal::serial::Read<u8> for Rx<USART>
where
USART: Deref<Target = SerialRegisterBlock>,
@ -269,11 +257,7 @@ where
}
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
impl<USART> embedded_hal::serial::Write<u8> for Tx<USART>
where
USART: Deref<Target = SerialRegisterBlock>,
@ -309,11 +293,7 @@ where
}
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
impl<USART, TXPIN, RXPIN> Serial<USART, TXPIN, RXPIN>
where
USART: Deref<Target = SerialRegisterBlock>,
@ -335,11 +315,7 @@ where
}
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
impl<USART> Write for Tx<USART>
where
Tx<USART>: embedded_hal::serial::Write<u8>,

View File

@ -6,23 +6,15 @@ use nb;
pub use embedded_hal::spi::{Mode, Phase, Polarity};
#[allow(unused)]
use crate::stm32;
// TODO Put this inside the macro
// Currently that causes a compiler panic
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
use crate::stm32::SPI1;
#[cfg(any(
feature = "stm32f030x8",
feature = "stm32f030xc",
feature = "stm32f070xb"
))]
#[allow(unused)]
use crate::stm32::SPI2;
#[allow(unused)]
@ -58,7 +50,7 @@ pub trait SckPin<SPI> {}
pub trait MisoPin<SPI> {}
pub trait MosiPin<SPI> {}
#[allow(unused)]
#[cfg(feature = "device-selected")]
macro_rules! spi_pins {
($($SPI:ident => {
sck => [$($sck:ty),+ $(,)*],
@ -67,23 +59,19 @@ macro_rules! spi_pins {
})+) => {
$(
$(
impl SckPin<stm32::$SPI> for $sck {}
impl SckPin<crate::stm32::$SPI> for $sck {}
)+
$(
impl MisoPin<stm32::$SPI> for $miso {}
impl MisoPin<crate::stm32::$SPI> for $miso {}
)+
$(
impl MosiPin<stm32::$SPI> for $mosi {}
impl MosiPin<crate::stm32::$SPI> for $mosi {}
)+
)+
}
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
spi_pins! {
SPI1 => {
sck => [gpioa::PA5<Alternate<AF0>>, gpiob::PB3<Alternate<AF0>>],
@ -139,7 +127,7 @@ macro_rules! spi {
F: Into<Hertz>,
{
// NOTE(unsafe) This executes only during initialisation
let rcc = unsafe { &(*stm32::RCC::ptr()) };
let rcc = unsafe { &(*crate::stm32::RCC::ptr()) };
/* Enable clock for SPI */
rcc.$apbenr.modify(|_, w| w.$spiXen().set_bit());
@ -154,11 +142,7 @@ macro_rules! spi {
}
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
spi! {
SPI1: (spi1, spi1en, spi1rst, apb2enr, apb2rstr),
}
@ -173,18 +157,10 @@ spi! {
// It's s needed for the impls, but rustc doesn't recognize that
#[allow(dead_code)]
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
type SpiRegisterBlock = stm32::spi1::RegisterBlock;
#[cfg(feature = "device-selected")]
type SpiRegisterBlock = crate::stm32::spi1::RegisterBlock;
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> Spi<SPI, SCKPIN, MISOPIN, MOSIPIN>
where
SPI: Deref<Target = SpiRegisterBlock>,
@ -255,11 +231,7 @@ where
}
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::spi::FullDuplex<u8>
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN>
where
@ -304,22 +276,14 @@ where
}
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::blocking::spi::transfer::Default<u8>
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN>
where
SPI: Deref<Target = SpiRegisterBlock>,
{}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::blocking::spi::write::Default<u8>
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN>
where

View File

@ -211,11 +211,7 @@ macro_rules! timers {
}
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
timers! {
TIM1: (tim1, tim1en, tim1rst, apb2enr, apb2rstr),
TIM3: (tim3, tim3en, tim3rst, apb1enr, apb1rstr),

View File

@ -44,29 +44,17 @@
#[allow(unused)]
use embedded_hal::watchdog;
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
use crate::stm32::IWDG;
use crate::time::Hertz;
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
/// Watchdog instance
pub struct Watchdog {
iwdg: IWDG,
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
impl watchdog::Watchdog for Watchdog {
/// Feed the watchdog, so that at least one `period` goes by before the next
/// reset
@ -105,22 +93,14 @@ impl Into<IwdgTimeout> for Hertz {
}
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
impl Watchdog {
pub fn new(iwdg: IWDG) -> Self {
Self { iwdg }
}
}
#[cfg(any(
feature = "stm32f030",
feature = "stm32f042",
feature = "stm32f070"
))]
#[cfg(feature = "device-selected")]
impl watchdog::WatchdogEnable for Watchdog {
type Time = IwdgTimeout;
fn start<T>(&mut self, period: T)