Skip to content

Commit 303b679

Browse files
bors[bot]burrbull
andauthored
Merge #404
404: Move embedded-hal implementations to subdirs r=therealprof a=burrbull Part of #388 Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents f4cfefd + 4678607 commit 303b679

23 files changed

+1361
-1186
lines changed

CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2626

2727
### Changed
2828

29+
- Move `embedded-hal` implementations to subdirs [#404]
2930
- Qei macro cleanups [#403]
3031
- Update RTIC to 1.0 [#401]
3132
- Finish SDIO data transmission before querying card status in `write_block` [#395]
@@ -51,7 +52,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
5152
[#393]: https://github.com/stm32-rs/stm32f4xx-hal/pull/393
5253
[#395]: https://github.com/stm32-rs/stm32f4xx-hal/pull/395
5354
[#401]: https://github.com/stm32-rs/stm32f4xx-hal/pull/401
54-
[#401]: https://github.com/stm32-rs/stm32f4xx-hal/pull/403
55+
[#403]: https://github.com/stm32-rs/stm32f4xx-hal/pull/403
56+
[#404]: https://github.com/stm32-rs/stm32f4xx-hal/pull/404
5557

5658
## [v0.10.1] - 2021-10-26
5759

src/adc.rs

+18-11
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use crate::dma::traits::PeriAddress;
1212
use crate::rcc::{Enable, Reset};
1313
use crate::{gpio::*, pac, signature::VrefCal, signature::VDDA_CALIB};
1414
use core::fmt;
15-
use embedded_hal::adc::{Channel, OneShot};
1615

1716
/// Vref internal signal, used for calibration
1817
pub struct Vref;
@@ -26,7 +25,7 @@ pub struct Temperature;
2625
macro_rules! adc_pins {
2726
($($pin:ty => ($adc:ident, $chan:expr)),+ $(,)*) => {
2827
$(
29-
impl Channel<pac::$adc> for $pin {
28+
impl embedded_hal::adc::Channel<pac::$adc> for $pin {
3029
type ID = u8;
3130
fn channel() -> u8 { $chan }
3231
}
@@ -897,7 +896,7 @@ macro_rules! adc {
897896
/// to sample for at a given ADC clock frequency
898897
pub fn configure_channel<CHANNEL>(&mut self, _channel: &CHANNEL, sequence: config::Sequence, sample_time: config::SampleTime)
899898
where
900-
CHANNEL: Channel<pac::$adc_type, ID=u8>
899+
CHANNEL: embedded_hal::adc::Channel<pac::$adc_type, ID=u8>
901900
{
902901
//Check the sequence is long enough
903902
self.adc_reg.sqr1.modify(|r, w| {
@@ -977,7 +976,7 @@ macro_rules! adc {
977976
/// Note that it reconfigures the adc sequence and doesn't restore it
978977
pub fn convert<PIN>(&mut self, pin: &PIN, sample_time: config::SampleTime) -> u16
979978
where
980-
PIN: Channel<pac::$adc_type, ID=u8>
979+
PIN: embedded_hal::adc::Channel<pac::$adc_type, ID=u8>
981980
{
982981
self.adc_reg.cr2.modify(|_, w| w
983982
.dma().clear_bit() //Disable dma
@@ -1008,13 +1007,10 @@ macro_rules! adc {
10081007
}
10091008
}
10101009

1011-
impl<PIN> OneShot<pac::$adc_type, u16, PIN> for Adc<pac::$adc_type>
1012-
where
1013-
PIN: Channel<pac::$adc_type, ID=u8>,
1014-
{
1015-
type Error = ();
1016-
1017-
fn read(&mut self, pin: &mut PIN) -> nb::Result<u16, Self::Error> {
1010+
impl Adc<pac::$adc_type> {
1011+
fn read<PIN>(&mut self, pin: &mut PIN) -> nb::Result<u16, ()>
1012+
where PIN: embedded_hal::adc::Channel<pac::$adc_type, ID=u8>,
1013+
{
10181014
let enabled = self.is_enabled();
10191015
if !enabled {
10201016
self.enable();
@@ -1030,6 +1026,17 @@ macro_rules! adc {
10301026
}
10311027
}
10321028

1029+
impl<PIN> embedded_hal::adc::OneShot<pac::$adc_type, u16, PIN> for Adc<pac::$adc_type>
1030+
where
1031+
PIN: embedded_hal::adc::Channel<pac::$adc_type, ID=u8>,
1032+
{
1033+
type Error = ();
1034+
1035+
fn read(&mut self, pin: &mut PIN) -> nb::Result<u16, Self::Error> {
1036+
self.read::<PIN>(pin)
1037+
}
1038+
}
1039+
10331040
unsafe impl PeriAddress for Adc<pac::$adc_type> {
10341041
#[inline(always)]
10351042
fn address(&self) -> u32 {

src/delay/hal_02.rs

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
//! Delay implementation based on general-purpose 32 bit timers and System timer (SysTick).
2+
//!
3+
//! TIM2 and TIM5 are a general purpose 32-bit auto-reload up/downcounter with
4+
//! a 16-bit prescaler.
5+
6+
use cast::{u16, u32};
7+
use cortex_m::peripheral::SYST;
8+
use embedded_hal::blocking::delay::{DelayMs, DelayUs};
9+
10+
use super::{Delay, Wait};
11+
12+
impl DelayUs<u32> for Delay<SYST> {
13+
fn delay_us(&mut self, us: u32) {
14+
// The SysTick Reload Value register supports values between 1 and 0x00FFFFFF.
15+
const MAX_RVR: u32 = 0x00FF_FFFF;
16+
17+
let mut total_rvr = us * (self.clk.0 / 8_000_000);
18+
19+
while total_rvr != 0 {
20+
let current_rvr = if total_rvr <= MAX_RVR {
21+
total_rvr
22+
} else {
23+
MAX_RVR
24+
};
25+
26+
self.tim.set_reload(current_rvr);
27+
self.tim.clear_current();
28+
self.tim.enable_counter();
29+
30+
// Update the tracking variable while we are waiting...
31+
total_rvr -= current_rvr;
32+
33+
while !self.tim.has_wrapped() {}
34+
35+
self.tim.disable_counter();
36+
}
37+
}
38+
}
39+
40+
impl DelayMs<u32> for Delay<SYST> {
41+
fn delay_ms(&mut self, ms: u32) {
42+
self.delay_us(ms * 1_000);
43+
}
44+
}
45+
46+
impl DelayUs<u16> for Delay<SYST> {
47+
fn delay_us(&mut self, us: u16) {
48+
self.delay_us(u32(us))
49+
}
50+
}
51+
52+
impl DelayMs<u16> for Delay<SYST> {
53+
fn delay_ms(&mut self, ms: u16) {
54+
self.delay_ms(u32(ms));
55+
}
56+
}
57+
58+
impl DelayUs<u8> for Delay<SYST> {
59+
fn delay_us(&mut self, us: u8) {
60+
self.delay_us(u32(us))
61+
}
62+
}
63+
64+
impl DelayMs<u8> for Delay<SYST> {
65+
fn delay_ms(&mut self, ms: u8) {
66+
self.delay_ms(u32(ms));
67+
}
68+
}
69+
70+
impl<TIM> DelayUs<u32> for Delay<TIM>
71+
where
72+
Self: Wait,
73+
{
74+
/// Sleep for up to 2^32-1 microseconds (~71 minutes).
75+
fn delay_us(&mut self, us: u32) {
76+
// Set up prescaler so that a tick takes exactly 1 µs.
77+
//
78+
// For example, if the clock is set to 48 MHz, with a prescaler of 48
79+
// we'll get ticks that are 1 µs long. This means that we can write the
80+
// delay value directly to the auto-reload register (ARR).
81+
let psc = u16(self.clk.0 / 1_000_000).expect("Prescaler does not fit in u16");
82+
let arr = us;
83+
self.wait(psc, arr);
84+
}
85+
}
86+
87+
impl<TIM> DelayMs<u32> for Delay<TIM>
88+
where
89+
Self: Wait,
90+
{
91+
/// Sleep for up to (2^32)/2-1 milliseconds (~24 days).
92+
/// If the `ms` value is larger than 2147483647, the code will panic.
93+
fn delay_ms(&mut self, ms: u32) {
94+
// See next section for explanation why the usable range is reduced.
95+
assert!(ms <= 2_147_483_647); // (2^32)/2-1
96+
97+
// Set up prescaler so that a tick takes exactly 0.5 ms.
98+
//
99+
// For example, if the clock is set to 48 MHz, with a prescaler of 24'000
100+
// we'll get ticks that are 0.5 ms long. This means that we can write the
101+
// delay value multipled by two to the auto-reload register (ARR).
102+
//
103+
// Note that we cannot simply use a prescaler value where the tick corresponds
104+
// to 1 ms, because then a clock of 100 MHz would correspond to a prescaler
105+
// value of 100'000, which doesn't fit in the 16-bit PSC register.
106+
//
107+
// Unfortunately this means that only one half of the full 32-bit range
108+
// can be used, but 24 days should be plenty of usable delay time.
109+
let psc = u16(self.clk.0 / 1000 / 2).expect("Prescaler does not fit in u16");
110+
111+
// Since PSC = 0.5 ms, double the value for the ARR
112+
let arr = ms << 1;
113+
114+
self.wait(psc, arr);
115+
}
116+
}
117+
118+
impl<TIM> DelayUs<u16> for Delay<TIM>
119+
where
120+
Self: Wait,
121+
{
122+
/// Sleep for up to 2^16-1 microseconds (~65 milliseconds).
123+
fn delay_us(&mut self, us: u16) {
124+
// See DelayUs<u32> for explanations.
125+
let psc = u16(self.clk.0 / 1_000_000).expect("Prescaler does not fit in u16");
126+
let arr = u32(us);
127+
self.wait(psc, arr);
128+
}
129+
}
130+
131+
impl<TIM> DelayMs<u16> for Delay<TIM>
132+
where
133+
Self: Wait,
134+
{
135+
/// Sleep for up to (2^16)-1 milliseconds (~65 seconds).
136+
fn delay_ms(&mut self, ms: u16) {
137+
// See DelayMs<u32> for explanations. Since the value range is only 16 bit,
138+
// we don't need an assert here.
139+
let psc = u16(self.clk.0 / 1000 / 2).expect("Prescaler does not fit in u16");
140+
let arr = u32(ms) << 1;
141+
self.wait(psc, arr);
142+
}
143+
}

src/delay/mod.rs

+82-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
//! Delays
22
3-
mod syst;
3+
mod hal_02;
44

5+
use crate::{
6+
pac,
7+
rcc::Clocks,
8+
timer::{General, Timer},
9+
};
10+
use core::cmp::max;
11+
use cortex_m::peripheral::syst::SystClkSource;
512
use cortex_m::peripheral::SYST;
613

714
use crate::time::Hertz;
@@ -19,4 +26,77 @@ impl<T> Delay<T> {
1926
}
2027
}
2128

22-
mod timer;
29+
impl Delay<SYST> {
30+
/// Configures the system timer (SysTick) as a delay provider
31+
pub fn new(mut tim: SYST, clocks: &Clocks) -> Self {
32+
tim.set_clock_source(SystClkSource::External);
33+
Self {
34+
tim,
35+
clk: clocks.hclk(),
36+
}
37+
}
38+
}
39+
40+
mod sealed {
41+
pub trait Wait {
42+
fn wait(&mut self, prescaler: u16, auto_reload_register: u32);
43+
}
44+
}
45+
use sealed::Wait;
46+
47+
macro_rules! hal {
48+
($($TIM:ty: ($tim:ident),)+) => {
49+
$(
50+
impl Timer<$TIM> {
51+
pub fn delay(self) -> Delay<$TIM> {
52+
let Self { tim, clk } = self;
53+
54+
// Enable one-pulse mode (counter stops counting at the next update
55+
// event, clearing the CEN bit)
56+
tim.cr1.modify(|_, w| w.opm().enabled());
57+
58+
Delay { tim, clk }
59+
}
60+
}
61+
62+
impl Delay<$TIM> {
63+
/// Configures the timer as a delay provider
64+
pub fn $tim(tim: $TIM, clocks: &Clocks) -> Self {
65+
Timer::new(tim, clocks).delay()
66+
}
67+
}
68+
69+
impl Wait for Delay<$TIM> {
70+
fn wait(&mut self, prescaler: u16, auto_reload_register: u32) {
71+
// Write Prescaler (PSC)
72+
self.tim.set_prescaler(prescaler);
73+
74+
// Write Auto-Reload Register (ARR)
75+
// Note: Make it impossible to set the ARR value to 0, since this
76+
// would cause an infinite loop.
77+
self.tim.set_auto_reload(max(1, auto_reload_register)).unwrap();
78+
79+
// Trigger update event (UEV) in the event generation register (EGR)
80+
// in order to immediately apply the config
81+
self.tim.trigger_update();
82+
83+
// Configure the counter in one-pulse mode (counter stops counting at
84+
// the next updateevent, clearing the CEN bit) and enable the counter.
85+
self.tim.cr1.write(|w| w.opm().set_bit().cen().set_bit());
86+
87+
// Wait for CEN bit to clear
88+
while self.tim.is_counter_enabled() { /* wait */ }
89+
}
90+
}
91+
)+
92+
}
93+
}
94+
95+
hal! {
96+
pac::TIM5: (tim5),
97+
}
98+
99+
#[cfg(feature = "tim2")]
100+
hal! {
101+
pac::TIM2: (tim2),
102+
}

0 commit comments

Comments
 (0)