Update to stm32f0 - 0.6.0 (#52)

* Updated stm32f0 to 0.6.0 and neatened other deps

* Adjusted names and removed unneeded unsafe blocks

* Overhauled RCC to gate HSI48 correctly and add a selector function for it to CFGR
This commit is contained in:
Tom 2019-01-14 23:43:08 +00:00 committed by Daniel Egger
parent cc5dbe03e5
commit 1524cb1967
6 changed files with 208 additions and 92 deletions

View File

@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Support for stm32f0x8 line - @jessebraham
### Changed
- Updated to stm32-rs v0.6.0 - @HarkonenBade
## [v0.12.0] - 2019-01-13
### Added

View File

@ -30,19 +30,13 @@ features = ["stm32f042", "rt"]
[dependencies]
bare-metal = { version = "0.2.4", features = ["const-fn"] }
cast = { version = "0.2.2", default-features = false }
cortex-m = "0.5.8"
cortex-m-rt = "0.6.7"
embedded-hal = { version = "0.2.2", features = ["unproven"] }
stm32f0 = "0.6.0"
nb = "0.1.1"
void = { version = "1.0.2", default-features = false }
stm32f0 = "0.5.0"
[dependencies.cast]
default-features = false
version = "0.2.2"
[dependencies.embedded-hal]
features = ["unproven"]
version = "0.2.2"
[dev-dependencies]
panic-halt = "0.2.0"

View File

@ -40,7 +40,7 @@ fn main() -> ! {
let gpioa = p.GPIOA.split(&mut rcc);
let gpiob = p.GPIOB.split(&mut rcc);
let syscfg = p.SYSCFG_COMP;
let syscfg = p.SYSCFG;
let exti = p.EXTI;
// Configure PB1 as input (button)
@ -57,7 +57,7 @@ fn main() -> ! {
// Enable external interrupt for PB1
syscfg
.syscfg_exticr1
.exticr1
.modify(|_, w| unsafe { w.exti1().bits(1) });
// Set interrupt request mask for line 1

View File

@ -84,20 +84,18 @@ pub enum AdcSampleTime {
impl AdcSampleTime {
fn write_bits(self, adc: &mut stm32::ADC) {
unsafe {
adc.smpr.write(|w| {
w.smpr().bits(match self {
AdcSampleTime::T_1 => 0b000_u8,
AdcSampleTime::T_7 => 0b001_u8,
AdcSampleTime::T_13 => 0b010_u8,
AdcSampleTime::T_28 => 0b011_u8,
AdcSampleTime::T_41 => 0b100_u8,
AdcSampleTime::T_55 => 0b101_u8,
AdcSampleTime::T_71 => 0b110_u8,
AdcSampleTime::T_239 => 0b111_u8,
})
});
}
adc.smpr.write(|w| {
w.smp().bits(match self {
AdcSampleTime::T_1 => 0b000_u8,
AdcSampleTime::T_7 => 0b001_u8,
AdcSampleTime::T_13 => 0b010_u8,
AdcSampleTime::T_28 => 0b011_u8,
AdcSampleTime::T_41 => 0b100_u8,
AdcSampleTime::T_55 => 0b101_u8,
AdcSampleTime::T_71 => 0b110_u8,
AdcSampleTime::T_239 => 0b111_u8,
})
});
}
/// Get the default sample time (currently 239.5 cycles)
@ -161,16 +159,14 @@ pub enum AdcPrecision {
impl AdcPrecision {
fn write_bits(self, adc: &mut stm32::ADC) {
unsafe {
adc.cfgr1.write(|w| {
w.res().bits(match self {
AdcPrecision::B_12 => 0b00_u8,
AdcPrecision::B_10 => 0b01_u8,
AdcPrecision::B_8 => 0b10_u8,
AdcPrecision::B_6 => 0b11_u8,
})
});
}
adc.cfgr1.write(|w| {
w.res().bits(match self {
AdcPrecision::B_12 => 0b00_u8,
AdcPrecision::B_10 => 0b01_u8,
AdcPrecision::B_8 => 0b10_u8,
AdcPrecision::B_6 => 0b11_u8,
})
});
}
/// Get the default precision (currently 12 bit precision)

View File

@ -1,4 +1,4 @@
use crate::stm32::rcc::cfgr::SWW;
use crate::stm32::RCC;
use crate::time::Hertz;
/// Extension trait that sets up the `RCC` peripheral
@ -7,7 +7,7 @@ pub trait RccExt {
fn configure(self) -> CFGR;
}
impl RccExt for crate::stm32::RCC {
impl RccExt for RCC {
fn configure(self) -> CFGR {
CFGR {
hclk: None,
@ -22,24 +22,169 @@ impl RccExt for crate::stm32::RCC {
/// Constrained RCC peripheral
pub struct Rcc {
pub clocks: Clocks,
pub(crate) regs: crate::stm32::RCC,
pub(crate) regs: RCC,
}
const HSI: u32 = 8_000_000; // Hz
const HSI48: u32 = 48_000_000; // Hz - (available on STM32F04x, STM32F07x and STM32F09x devices only)
#[cfg(any(feature = "stm32f030",
feature = "stm32f070",
))]
mod inner {
use crate::stm32::{
RCC,
rcc::{
cfgr::SWW
}
};
enum SysClkSource {
HSI,
HSE(u32),
HSI48,
pub(super) const HSI: u32 = 8_000_000; // Hz
pub(super) enum SysClkSource {
HSI,
HSE(u32),
}
pub(super) fn get_freq(c_src: &SysClkSource) -> u32 {
// Select clock source based on user input and capability
// Highest selected frequency source available takes precedent.
match c_src {
SysClkSource::HSE(freq) => *freq,
_ => HSI,
}
}
pub(super) fn enable_clock(rcc: &mut RCC, c_src: &SysClkSource) {
// Enable the requested clock
match c_src {
SysClkSource::HSE(_) => {
rcc.cr.modify(|_, w| w.csson().on().hseon().on().hsebyp().not_bypassed());
while !rcc.cr.read().hserdy().bit_is_set() {}
}
SysClkSource::HSI => {
rcc.cr.write(|w| w.hsion().set_bit());
while rcc.cr.read().hsirdy().bit_is_clear() {}
}
}
}
pub(super) fn enable_pll(rcc: &mut RCC, c_src: &SysClkSource, pllmul_bits: u8, ppre_bits: u8, hpre_bits: u8) {
let pllsrc_bit: bool = match c_src {
SysClkSource::HSI => false,
SysClkSource::HSE(_) => true,
};
// Set PLL source and multiplier
rcc.cfgr.modify(|_, w| unsafe { w.pllsrc().bit(pllsrc_bit).pllmul().bits(pllmul_bits) });
rcc.cr.write(|w| w.pllon().set_bit());
while rcc.cr.read().pllrdy().bit_is_clear() {}
rcc.cfgr.modify(|_, w| unsafe {
w.ppre().bits(ppre_bits).hpre().bits(hpre_bits).sw().pll()
});
}
pub(super) fn get_sww(c_src: &SysClkSource) -> SWW {
match c_src {
SysClkSource::HSI => SWW::HSI,
SysClkSource::HSE(_) => SWW::HSE,
}
}
}
#[cfg(any(feature = "stm32f031", // TODO: May be an SVD bug
feature = "stm32f038",
feature = "stm32f042",
feature = "stm32f048",
feature = "stm32f051",
feature = "stm32f058",
feature = "stm32f071",
feature = "stm32f072",
feature = "stm32f078",
feature = "stm32f091",
feature = "stm32f098",
))]
mod inner {
use crate::stm32::{
RCC,
rcc::{
cfgr::SWW
}
};
pub(super) const HSI: u32 = 8_000_000; // Hz
pub(super) const HSI48: u32 = 48_000_000; // Hz
pub(super) enum SysClkSource {
HSI,
HSE(u32),
HSI48,
}
pub(super) fn get_freq(c_src: &SysClkSource) -> u32 {
// Select clock source based on user input and capability
// Highest selected frequency source available takes precedent.
match c_src {
SysClkSource::HSE(freq) => *freq,
SysClkSource::HSI48 => HSI48,
_ => HSI,
}
}
pub(super) fn enable_clock(rcc: &mut RCC, c_src: &SysClkSource) {
// Enable the requested clock
match c_src {
SysClkSource::HSE(_) => {
rcc.cr.modify(|_, w| w.csson().on().hseon().on().hsebyp().not_bypassed());
while !rcc.cr.read().hserdy().bit_is_set() {}
}
SysClkSource::HSI48 => {
rcc.cr2.modify(|_, w| w.hsi48on().set_bit());
while rcc.cr2.read().hsi48rdy().bit_is_clear() {}
}
SysClkSource::HSI => {
rcc.cr.write(|w| w.hsion().set_bit());
while rcc.cr.read().hsirdy().bit_is_clear() {}
}
}
}
pub(super) fn enable_pll(rcc: &mut RCC, c_src: &SysClkSource, pllmul_bits: u8, ppre_bits: u8, hpre_bits: u8) {
let pllsrc_bit: u8 = match c_src {
SysClkSource::HSI => 0b00,
SysClkSource::HSI48 => 0b11,
SysClkSource::HSE(_) => 0b01,
};
// Set PLL source and multiplier
rcc.cfgr.modify(|_, w| unsafe { w.pllsrc().bits(pllsrc_bit).pllmul().bits(pllmul_bits) });
rcc.cr.write(|w| w.pllon().set_bit());
while rcc.cr.read().pllrdy().bit_is_clear() {}
rcc.cfgr.modify(|_, w| unsafe {
w.ppre().bits(ppre_bits).hpre().bits(hpre_bits).sw().pll()
});
}
pub(super) fn get_sww(c_src: &SysClkSource) -> SWW {
match c_src {
SysClkSource::HSI => SWW::HSI,
SysClkSource::HSI48 => SWW::HSI48,
SysClkSource::HSE(_) => SWW::HSE,
}
}
}
use self::inner::SysClkSource;
pub struct CFGR {
hclk: Option<u32>,
pclk: Option<u32>,
sysclk: Option<u32>,
clock_src: SysClkSource,
rcc: crate::stm32::RCC,
rcc: RCC,
}
impl CFGR {
@ -51,6 +196,23 @@ impl CFGR {
self
}
#[cfg(any(feature = "stm32f031", // TODO: May be an SVD bug
feature = "stm32f038",
feature = "stm32f042",
feature = "stm32f048",
feature = "stm32f051",
feature = "stm32f058",
feature = "stm32f071",
feature = "stm32f072",
feature = "stm32f078",
feature = "stm32f091",
feature = "stm32f098",
))]
pub fn hsi48(mut self) -> Self {
self.clock_src = SysClkSource::HSI48;
self
}
pub fn hclk<F>(mut self, freq: F) -> Self
where
F: Into<Hertz>,
@ -75,9 +237,9 @@ impl CFGR {
self
}
pub fn freeze(self, flash: &mut crate::stm32::FLASH) -> Rcc {
pub fn freeze(mut self, flash: &mut crate::stm32::FLASH) -> Rcc {
// Default to lowest frequency clock on all systems.
let sysclk = self.sysclk.unwrap_or(HSI);
let sysclk = self.sysclk.unwrap_or(self::inner::HSI);
let r_sysclk; // The "real" sysclock value, calculated below
let pllmul_bits;
@ -85,11 +247,7 @@ impl CFGR {
// Select clock source based on user input and capability
// Highest selected frequency source available takes precedent.
// For F04x, F07x, F09x parts, use HSI48 if requested.
let src_clk_freq = match self.clock_src {
SysClkSource::HSE(freq) => freq,
SysClkSource::HSI48 => HSI48,
_ => HSI,
};
let src_clk_freq = self::inner::get_freq(&self.clock_src);
// Pll check
if sysclk == src_clk_freq {
@ -158,51 +316,15 @@ impl CFGR {
}
// Enable the requested clock
match self.clock_src {
SysClkSource::HSE(_) => {
self.rcc
.cr
.modify(|_, w| w.csson().on().hseon().on().hsebyp().not_bypassed());
while !self.rcc.cr.read().hserdy().bit_is_set() {}
}
SysClkSource::HSI48 => {
self.rcc.cr2.modify(|_, w| w.hsi48on().set_bit());
while self.rcc.cr2.read().hsi48rdy().bit_is_clear() {}
}
SysClkSource::HSI => {
self.rcc.cr.write(|w| w.hsion().set_bit());
while self.rcc.cr.read().hsirdy().bit_is_clear() {}
}
};
self::inner::enable_clock(&mut self.rcc, &self.clock_src);
// Set up rcc based on above calculated configuration.
// Enable PLL
if let Some(pllmul_bits) = pllmul_bits {
let pllsrc_bit: u8 = match self.clock_src {
SysClkSource::HSI => 0b00,
SysClkSource::HSI48 => 0b11,
SysClkSource::HSE(_) => 0b01,
};
// Set PLL source and multiplier
self.rcc
.cfgr
.write(|w| unsafe { w.pllsrc().bits(pllsrc_bit).pllmul().bits(pllmul_bits) });
self.rcc.cr.write(|w| w.pllon().set_bit());
while self.rcc.cr.read().pllrdy().bit_is_clear() {}
self.rcc.cfgr.modify(|_, w| unsafe {
w.ppre().bits(ppre_bits).hpre().bits(hpre_bits).sw().pll()
});
self::inner::enable_pll(&mut self.rcc, &self.clock_src, pllmul_bits, ppre_bits, hpre_bits);
} else {
let sw_var = match self.clock_src {
SysClkSource::HSI => SWW::HSI,
SysClkSource::HSI48 => SWW::HSI48,
SysClkSource::HSE(_) => SWW::HSE,
};
let sw_var = self::inner::get_sww(&self.clock_src);
// use HSI as source
self.rcc.cfgr.write(|w| unsafe {

View File

@ -298,7 +298,7 @@ where
// dff: 8 bit frames
// bidimode: 2-line unidirectional
// spe: enable the SPI bus
self.spi.cr1.write(|w| unsafe {
self.spi.cr1.write(|w| {
w.cpha()
.bit(mode.phase == Phase::CaptureOnSecondTransition)
.cpol()