Skip to content

Commit aa934ca

Browse files
bors[bot]burrbull
andauthored
Merge #443
443: e-hal alpha.7 r=burrbull a=burrbull Same as #388, but uses alpha.7 Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents 22f1e8f + c9f823e commit aa934ca

19 files changed

+1111
-88
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2828
### Added
2929

3030
- Missing `DelayMs<u8>` / `DelayUs<u8>` impls for fugit::Delay
31+
- Support of embedded-hal 1.0.0-alpha.7 [#443]
3132
- Aliases for peripheral wrappers [#434]
3233
- `WithPwm` trait implemented for timers with channels (internals) [#425]
3334
- `Pwm` struct with `split` method and implementation of embedded-hal::Pwm (similar to f1xx-hal) [#425]
@@ -50,6 +51,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
5051
[#438]: https://github.com/stm32-rs/stm32f4xx-hal/pull/438
5152
[#439]: https://github.com/stm32-rs/stm32f4xx-hal/pull/439
5253
[#440]: https://github.com/stm32-rs/stm32f4xx-hal/pull/440
54+
[#443]: https://github.com/stm32-rs/stm32f4xx-hal/pull/443
5355

5456
### Changed
5557

Cargo.toml

+5-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ embedded-dma = "0.2.0"
3939
bare-metal = { version = "1" }
4040
cast = { default-features = false, version = "0.3.0" }
4141
void = { default-features = false, version = "1.0.2" }
42-
embedded-hal = { features = ["unproven"], version = "0.2.6" }
42+
embedded-hal = { features = ["unproven"], version = "0.2.7" }
4343
display-interface = { version = "0.4.1", optional = true }
4444
fugit = "0.3.3"
4545
fugit-timer = "0.1.3"
@@ -51,6 +51,10 @@ embedded-storage = "0.2"
5151
version = "0.3"
5252
default-features = false
5353

54+
[dependencies.embedded-hal-one]
55+
version = "1.0.0-alpha.7"
56+
package = "embedded-hal"
57+
5458
[dependencies.stm32_i2s_v12x]
5559
version = "0.2.0"
5660
optional = true

src/adc.rs

+16
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ macro_rules! adc_pins {
3434
type ID = u8;
3535
fn channel() -> u8 { $chan }
3636
}
37+
38+
impl embedded_hal_one::adc::nb::Channel<pac::$adc> for $pin {
39+
type ID = u8;
40+
fn channel(&self) -> u8 { $chan }
41+
}
3742
)+
3843
};
3944
}
@@ -1070,6 +1075,17 @@ macro_rules! adc {
10701075
}
10711076
}
10721077

1078+
impl<PIN> embedded_hal_one::adc::nb::OneShot<pac::$adc_type, u16, PIN> for Adc<pac::$adc_type>
1079+
where
1080+
PIN: embedded_hal::adc::Channel<pac::$adc_type, ID=u8> + embedded_hal_one::adc::nb::Channel<pac::$adc_type, ID=u8>,
1081+
{
1082+
type Error = ();
1083+
1084+
fn read(&mut self, pin: &mut PIN) -> nb::Result<u16, Self::Error> {
1085+
self.read::<PIN>(pin)
1086+
}
1087+
}
1088+
10731089
unsafe impl PeriAddress for Adc<pac::$adc_type> {
10741090
#[inline(always)]
10751091
fn address(&self) -> u32 {

src/delay/hal_1.rs

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
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;
7+
use core::convert::Infallible;
8+
use cortex_m::peripheral::SYST;
9+
use embedded_hal_one::delay::blocking::DelayUs;
10+
11+
use super::{Delay, Wait};
12+
13+
impl DelayUs for Delay<SYST> {
14+
type Error = Infallible;
15+
16+
fn delay_us(&mut self, us: u32) -> Result<(), Self::Error> {
17+
// The SysTick Reload Value register supports values between 1 and 0x00FFFFFF.
18+
const MAX_RVR: u32 = 0x00FF_FFFF;
19+
20+
let mut total_rvr = us * (self.clk.0 / 8_000_000);
21+
22+
while total_rvr != 0 {
23+
let current_rvr = if total_rvr <= MAX_RVR {
24+
total_rvr
25+
} else {
26+
MAX_RVR
27+
};
28+
29+
self.tim.set_reload(current_rvr);
30+
self.tim.clear_current();
31+
self.tim.enable_counter();
32+
33+
// Update the tracking variable while we are waiting...
34+
total_rvr -= current_rvr;
35+
36+
while !self.tim.has_wrapped() {}
37+
38+
self.tim.disable_counter();
39+
}
40+
41+
Ok(())
42+
}
43+
44+
fn delay_ms(&mut self, ms: u32) -> Result<(), Self::Error> {
45+
self.delay_us(ms * 1_000)
46+
}
47+
}
48+
49+
impl<TIM> DelayUs for Delay<TIM>
50+
where
51+
Self: Wait,
52+
{
53+
type Error = Infallible;
54+
55+
/// Sleep for up to 2^32-1 microseconds (~71 minutes).
56+
fn delay_us(&mut self, us: u32) -> Result<(), Self::Error> {
57+
// Set up prescaler so that a tick takes exactly 1 µs.
58+
//
59+
// For example, if the clock is set to 48 MHz, with a prescaler of 48
60+
// we'll get ticks that are 1 µs long. This means that we can write the
61+
// delay value directly to the auto-reload register (ARR).
62+
let psc = u16(self.clk.0 / 1_000_000).expect("Prescaler does not fit in u16");
63+
let arr = us;
64+
self.wait(psc, arr);
65+
66+
Ok(())
67+
}
68+
69+
/// Sleep for up to (2^32)/2-1 milliseconds (~24 days).
70+
/// If the `ms` value is larger than 2147483647, the code will panic.
71+
fn delay_ms(&mut self, ms: u32) -> Result<(), Self::Error> {
72+
// See next section for explanation why the usable range is reduced.
73+
assert!(ms <= 2_147_483_647); // (2^32)/2-1
74+
75+
// Set up prescaler so that a tick takes exactly 0.5 ms.
76+
//
77+
// For example, if the clock is set to 48 MHz, with a prescaler of 24'000
78+
// we'll get ticks that are 0.5 ms long. This means that we can write the
79+
// delay value multipled by two to the auto-reload register (ARR).
80+
//
81+
// Note that we cannot simply use a prescaler value where the tick corresponds
82+
// to 1 ms, because then a clock of 100 MHz would correspond to a prescaler
83+
// value of 100'000, which doesn't fit in the 16-bit PSC register.
84+
//
85+
// Unfortunately this means that only one half of the full 32-bit range
86+
// can be used, but 24 days should be plenty of usable delay time.
87+
let psc = u16(self.clk.0 / 1000 / 2).expect("Prescaler does not fit in u16");
88+
89+
// Since PSC = 0.5 ms, double the value for the ARR
90+
let arr = ms << 1;
91+
92+
self.wait(psc, arr);
93+
94+
Ok(())
95+
}
96+
}

src/delay/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Delays
22
33
mod hal_02;
4+
mod hal_1;
45

56
use crate::{
67
pac,

src/dwt.rs

+20
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,26 @@ impl<T: Into<u64>> embedded_hal::blocking::delay::DelayMs<T> for Delay {
114114
}
115115
}
116116

117+
impl embedded_hal_one::delay::blocking::DelayUs for Delay {
118+
type Error = core::convert::Infallible;
119+
120+
fn delay_us(&mut self, us: u32) -> Result<(), Self::Error> {
121+
// Convert us to ticks
122+
let start = DWT::cycle_count();
123+
let ticks = (us as u64 * self.clock.0 as u64) / 1_000_000;
124+
Delay::delay_ticks(start, ticks);
125+
Ok(())
126+
}
127+
128+
fn delay_ms(&mut self, ms: u32) -> Result<(), Self::Error> {
129+
// Convert ms to ticks
130+
let start = DWT::cycle_count();
131+
let ticks = (ms as u64 * self.clock.0 as u64) / 1_000;
132+
Delay::delay_ticks(start, ticks);
133+
Ok(())
134+
}
135+
}
136+
117137
/// Very simple stopwatch which reads from DWT Cycle Counter to record timing.
118138
///
119139
/// Since DWT Cycle Counter is a 32-bit counter that wraps around to 0 on overflow,

src/fmpi2c.rs

+28-30
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use core::ops::Deref;
22

3-
use crate::gpio::{Const, OpenDrain, PinA, SetAlternate};
4-
use crate::i2c::{Error, Scl, Sda};
3+
use crate::i2c::{Error, NoAcknowledgeSource, Pins};
54
use crate::pac::{fmpi2c1, FMPI2C1, RCC};
65
use crate::rcc::{Enable, Reset};
76
use crate::time::{Hertz, U32Ext};
87

98
mod hal_02;
9+
mod hal_1;
1010

1111
/// I2C FastMode+ abstraction
1212
pub struct FMPI2c<I2C, PINS> {
@@ -67,12 +67,11 @@ where
6767
}
6868
}
6969

70-
impl<SCL, SDA, const SCLA: u8, const SDAA: u8> FMPI2c<FMPI2C1, (SCL, SDA)>
70+
impl<PINS> FMPI2c<FMPI2C1, PINS>
7171
where
72-
SCL: PinA<Scl, FMPI2C1, A = Const<SCLA>> + SetAlternate<OpenDrain, SCLA>,
73-
SDA: PinA<Sda, FMPI2C1, A = Const<SDAA>> + SetAlternate<OpenDrain, SDAA>,
72+
PINS: Pins<FMPI2C1>,
7473
{
75-
pub fn new<M: Into<FmpMode>>(i2c: FMPI2C1, mut pins: (SCL, SDA), mode: M) -> Self {
74+
pub fn new<M: Into<FmpMode>>(i2c: FMPI2C1, mut pins: PINS, mode: M) -> Self {
7675
unsafe {
7776
// NOTE(unsafe) this reference will only be used for atomic writes with no side effects.
7877
let rcc = &(*RCC::ptr());
@@ -84,17 +83,15 @@ where
8483
rcc.dckcfgr2.modify(|_, w| w.fmpi2c1sel().hsi());
8584
}
8685

87-
pins.0.set_alt_mode();
88-
pins.1.set_alt_mode();
86+
pins.set_alt_mode();
8987

9088
let i2c = FMPI2c { i2c, pins };
9189
i2c.i2c_init(mode);
9290
i2c
9391
}
9492

95-
pub fn release(mut self) -> (FMPI2C1, (SCL, SDA)) {
96-
self.pins.0.restore_mode();
97-
self.pins.1.restore_mode();
93+
pub fn release(mut self) -> (FMPI2C1, PINS) {
94+
self.pins.restore_mode();
9895

9996
(self.i2c, self.pins)
10097
}
@@ -171,31 +168,39 @@ where
171168
self.i2c
172169
.icr
173170
.write(|w| w.stopcf().set_bit().nackcf().set_bit());
174-
return Err(Error::NACK);
171+
return Err(Error::NoAcknowledge(NoAcknowledgeSource::Unknown));
175172
}
176173

177174
Ok(())
178175
}
179176

177+
fn end_transaction(&self) -> Result<(), Error> {
178+
// Check and clear flags if they somehow ended up set
179+
self.check_and_clear_error_flags(&self.i2c.isr.read())
180+
.map_err(Error::nack_data)?;
181+
Ok(())
182+
}
183+
180184
fn send_byte(&self, byte: u8) -> Result<(), Error> {
181185
// Wait until we're ready for sending
182186
while {
183187
let isr = self.i2c.isr.read();
184-
self.check_and_clear_error_flags(&isr)?;
188+
self.check_and_clear_error_flags(&isr)
189+
.map_err(Error::nack_addr)?;
185190
isr.txis().bit_is_clear()
186191
} {}
187192

188193
// Push out a byte of data
189194
self.i2c.txdr.write(|w| unsafe { w.bits(u32::from(byte)) });
190195

191-
self.check_and_clear_error_flags(&self.i2c.isr.read())?;
192-
Ok(())
196+
self.end_transaction()
193197
}
194198

195199
fn recv_byte(&self) -> Result<u8, Error> {
196200
while {
197201
let isr = self.i2c.isr.read();
198-
self.check_and_clear_error_flags(&isr)?;
202+
self.check_and_clear_error_flags(&isr)
203+
.map_err(Error::nack_data)?;
199204
isr.rxne().bit_is_clear()
200205
} {}
201206

@@ -225,10 +230,7 @@ where
225230
*c = self.recv_byte()?;
226231
}
227232

228-
// Check and clear flags if they somehow ended up set
229-
self.check_and_clear_error_flags(&self.i2c.isr.read())?;
230-
231-
Ok(())
233+
self.end_transaction()
232234
}
233235

234236
pub fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
@@ -252,10 +254,7 @@ where
252254
self.send_byte(*c)?;
253255
}
254256

255-
// Check and clear flags if they somehow ended up set
256-
self.check_and_clear_error_flags(&self.i2c.isr.read())?;
257-
258-
Ok(())
257+
self.end_transaction()
259258
}
260259

261260
pub fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
@@ -277,7 +276,8 @@ where
277276
// Wait until the transmit buffer is empty and there hasn't been any error condition
278277
while {
279278
let isr = self.i2c.isr.read();
280-
self.check_and_clear_error_flags(&isr)?;
279+
self.check_and_clear_error_flags(&isr)
280+
.map_err(Error::nack_addr)?;
281281
isr.txis().bit_is_clear() && isr.tc().bit_is_clear()
282282
} {}
283283

@@ -289,7 +289,8 @@ where
289289
// Wait until data was sent
290290
while {
291291
let isr = self.i2c.isr.read();
292-
self.check_and_clear_error_flags(&isr)?;
292+
self.check_and_clear_error_flags(&isr)
293+
.map_err(Error::nack_data)?;
293294
isr.tc().bit_is_clear()
294295
} {}
295296

@@ -314,9 +315,6 @@ where
314315
*c = self.recv_byte()?;
315316
}
316317

317-
// Check and clear flags if they somehow ended up set
318-
self.check_and_clear_error_flags(&self.i2c.isr.read())?;
319-
320-
Ok(())
318+
self.end_transaction()
321319
}
322320
}

0 commit comments

Comments
 (0)