Skip to content

Commit 8d31893

Browse files
bors[bot]eldruin
andauthored
Merge #251
251: Update reference implementation implementation to stm32f1xx-hal and update examples r=therealprof a=eldruin I think the `stm32f1xx-hal` is a good candidate for a reference implementation. I have also updated the examples accordingly and modernized them a bit. An additional possibility would be to remove the `futures` examples as well, since async handling will be different. Closes #156 Co-authored-by: Diego Barrios Romero <[email protected]>
2 parents 96e6c7c + 0fd1720 commit 8d31893

File tree

2 files changed

+55
-179
lines changed

2 files changed

+55
-179
lines changed

Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,6 @@ nb = "1"
2020
[dev-dependencies]
2121
futures = "0.1.17"
2222

23+
[dev-dependencies.stm32f1]
24+
version = "0.12"
25+
features = ["stm32f103", "rt"]

src/lib.rs

+52-179
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@
3838
//!
3939
//! # Reference implementation
4040
//!
41-
//! The [`stm32f30x-hal`] crate contains a reference implementation of this HAL.
41+
//! The [`stm32f1xx-hal`] crate contains a reference implementation of this HAL.
4242
//!
43-
//! [`stm32f30x-hal`]: https://crates.io/crates/stm32f30x-hal/0.1.0
43+
//! [`stm32f1xx-hal`]: https://crates.io/crates/stm32f1xx-hal
4444
//!
4545
//! # Platform agnostic drivers
4646
//!
@@ -64,7 +64,7 @@
6464
//! Here's how a HAL trait may look like:
6565
//!
6666
//! ```
67-
//! extern crate nb;
67+
//! use nb;
6868
//!
6969
//! /// A serial interface
7070
//! pub trait Serial {
@@ -90,7 +90,7 @@
9090
//! those cases `nb::Result<_, Infallible>` is used.
9191
//!
9292
//! ```
93-
//! extern crate nb;
93+
//! use nb;
9494
//!
9595
//! # use std as core;
9696
//! use ::core::convert::Infallible;
@@ -113,22 +113,20 @@
113113
//!
114114
//! [`svd2rust`]: https://crates.io/crates/svd2rust
115115
//!
116-
//! Shown below is an implementation of some of the HAL traits for the [`stm32f30x`] crate. This
117-
//! single implementation will work for *any* microcontroller in the STM32F30x family.
116+
//! Shown below is an implementation of some of the HAL traits for the [`stm32f1xx-hal`] crate. This
117+
//! single implementation will work for *any* microcontroller in the STM32F1xx family.
118118
//!
119-
//! [`stm32f3`]: https://crates.io/crates/stm32f3
119+
//! [`stm32f1`]: https://crates.io/crates/stm32f1
120120
//!
121121
//! ```not_run
122-
//! // crate: stm32f3xx-hal
123-
//! // An implementation of the `embedded-hal` traits for STM32F3xx microcontrollers
122+
//! // crate: stm32f1xx-hal
123+
//! // An implementation of the `embedded-hal` traits for STM32F1xx microcontrollers
124124
//!
125-
//! extern crate embedded_hal as hal;
126-
//! extern crate nb;
125+
//! use embedded_hal as hal;
126+
//! use nb;
127127
//!
128128
//! // device crate
129-
//! extern crate stm32f3;
130-
//!
131-
//! use stm32f3::stm32f303::USART1;
129+
//! use stm32f1::stm32f103::USART1;
132130
//!
133131
//! /// A serial interface
134132
//! // NOTE generic over the USART peripheral
@@ -185,26 +183,20 @@
185183
//!
186184
//! ## Intended usage
187185
//!
188-
//! Thanks to the [`nb`] crate the HAL API can be used in a blocking manner,
189-
//! with `futures` or with the `await` operator using the [`block!`],
190-
//! [`try_nb!`] and [`await!`] macros respectively.
186+
//! Thanks to the [`nb`] crate the HAL API can be used in a blocking manner
187+
//! with the [`block!`] macro or with `futures`.
191188
//!
192-
//! [`block!`]: https://docs.rs/nb/0.1.0/nb/macro.block.html
193-
//! [`try_nb!`]: https://docs.rs/nb/0.1.0/nb/index.html#how-to-use-this-crate
194-
//! [`await!`]: https://docs.rs/nb/0.1.0/nb/index.html#how-to-use-this-crate
189+
//! [`block!`]: https://docs.rs/nb/1.0.0/nb/macro.block.html
195190
//!
196191
//! ### Blocking mode
197192
//!
198193
//! An example of sending a string over the serial interface in a blocking
199194
//! fashion:
200195
//!
201196
//! ```
202-
//! extern crate embedded_hal;
203-
//! #[macro_use(block)]
204-
//! extern crate nb;
205-
//!
206-
//! use stm32f30x_hal::Serial1;
197+
//! use crate::stm32f1xx_hal::Serial1;
207198
//! use embedded_hal::serial::Write;
199+
//! use nb::block;
208200
//!
209201
//! # fn main() {
210202
//! let mut serial: Serial1 = {
@@ -219,11 +211,12 @@
219211
//! }
220212
//! # }
221213
//!
222-
//! # mod stm32f30x_hal {
214+
//! # mod stm32f1xx_hal {
215+
//! # use nb;
223216
//! # use core::convert::Infallible;
224217
//! # pub struct Serial1;
225218
//! # impl Serial1 {
226-
//! # pub fn try_write(&mut self, _: u8) -> ::nb::Result<(), Infallible> {
219+
//! # pub fn try_write(&mut self, _: u8) -> nb::Result<(), Infallible> {
227220
//! # Ok(())
228221
//! # }
229222
//! # }
@@ -238,20 +231,15 @@
238231
//! the case for many embedded targets.
239232
//!
240233
//! ```no_run
241-
//! extern crate embedded_hal as hal;
242-
//! extern crate futures;
243-
//!
244-
//! #[macro_use(try_nb)]
245-
//! extern crate nb;
246-
//!
247-
//! use hal::prelude::*;
234+
//! use embedded_hal as hal;
235+
//! use crate::hal::prelude::*;
248236
//! use futures::{
249-
//! future,
237+
//! future::{self, Loop},
250238
//! Async,
251239
//! Future,
252240
//! };
253-
//! use futures::future::Loop;
254-
//! use stm32f30x_hal::{Led, Serial1, Timer6};
241+
//! use nb;
242+
//! use stm32f1xx_hal::{Led, Serial1, Timer6};
255243
//! use core::convert::Infallible;
256244
//!
257245
//! /// `futures` version of `CountDown.try_wait`
@@ -263,7 +251,11 @@
263251
//! {
264252
//! let mut timer = Some(timer);
265253
//! future::poll_fn(move || {
266-
//! try_nb!(timer.as_mut().unwrap().try_wait());
254+
//! match timer.as_mut().unwrap().try_wait() {
255+
//! Err(nb::Error::Other(e)) => return Err(e),
256+
//! Err(nb::Error::WouldBlock) => return Ok(Async::NotReady),
257+
//! Ok(_) => (),
258+
//! };
267259
//!
268260
//! Ok(Async::Ready(timer.take().unwrap()))
269261
//! })
@@ -278,7 +270,11 @@
278270
//! {
279271
//! let mut serial = Some(serial);
280272
//! future::poll_fn(move || {
281-
//! let byte = try_nb!(serial.as_mut().unwrap().try_read());
273+
//! let byte = match serial.as_mut().unwrap().try_read() {
274+
//! Err(nb::Error::Other(e)) => return Err(e),
275+
//! Err(nb::Error::WouldBlock) => return Ok(Async::NotReady),
276+
//! Ok(x) => x,
277+
//! };
282278
//!
283279
//! Ok(Async::Ready((serial.take().unwrap(), byte)))
284280
//! })
@@ -293,7 +289,11 @@
293289
//! {
294290
//! let mut serial = Some(serial);
295291
//! future::poll_fn(move || {
296-
//! try_nb!(serial.as_mut().unwrap().try_write(byte));
292+
//! match serial.as_mut().unwrap().try_write(byte) {
293+
//! Err(nb::Error::Other(e)) => return Err(e),
294+
//! Err(nb::Error::WouldBlock) => return Ok(Async::NotReady),
295+
//! Ok(_) => (),
296+
//! };
297297
//!
298298
//! Ok(Async::Ready(serial.take().unwrap()))
299299
//! })
@@ -345,10 +345,11 @@
345345
//! }
346346
//! }
347347
//!
348-
//! # mod stm32f30x_hal {
348+
//! # mod stm32f1xx_hal {
349+
//! # use crate::hal;
349350
//! # use core::convert::Infallible;
350351
//! # pub struct Timer6;
351-
//! # impl ::hal::timer::CountDown for Timer6 {
352+
//! # impl hal::timer::CountDown for Timer6 {
352353
//! # type Error = Infallible;
353354
//! # type Time = ();
354355
//! #
@@ -357,11 +358,11 @@
357358
//! # }
358359
//! #
359360
//! # pub struct Serial1;
360-
//! # impl ::hal::serial::Read<u8> for Serial1 {
361+
//! # impl hal::serial::Read<u8> for Serial1 {
361362
//! # type Error = Infallible;
362363
//! # fn try_read(&mut self) -> ::nb::Result<u8, Infallible> { Err(::nb::Error::WouldBlock) }
363364
//! # }
364-
//! # impl ::hal::serial::Write<u8> for Serial1 {
365+
//! # impl hal::serial::Write<u8> for Serial1 {
365366
//! # type Error = Infallible;
366367
//! # fn try_flush(&mut self) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) }
367368
//! # fn try_write(&mut self, _: u8) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) }
@@ -375,94 +376,6 @@
375376
//! # }
376377
//! ```
377378
//!
378-
//! ### `await`
379-
//!
380-
//! Same example as above but using `await!` instead of `futures`
381-
//! (same remark concerning the availability of `libstd` on the
382-
//! target).
383-
//!
384-
//! ```no_run
385-
//! #![feature(generator_trait)]
386-
//! #![feature(generators)]
387-
//!
388-
//! extern crate embedded_hal as hal;
389-
//!
390-
//! #[macro_use(r#await)]
391-
//! extern crate nb;
392-
//!
393-
//! use core::ops::Generator;
394-
//! use core::pin::Pin;
395-
//!
396-
//! use hal::prelude::*;
397-
//! use stm32f30x_hal::{Led, Serial1, Timer6};
398-
//!
399-
//! fn main() {
400-
//! // HAL implementers
401-
//! let mut timer: Timer6 = {
402-
//! // ..
403-
//! # Timer6
404-
//! };
405-
//! let mut serial: Serial1 = {
406-
//! // ..
407-
//! # Serial1
408-
//! };
409-
//! let mut led: Led = {
410-
//! // ..
411-
//! # Led
412-
//! };
413-
//!
414-
//! // Tasks
415-
//! let mut blinky = (move || {
416-
//! let mut state = false;
417-
//! loop {
418-
//! // `await!` means "suspend / yield here" instead of "block until
419-
//! // completion"
420-
//! nb::r#await!(timer.try_wait()).unwrap(); // NOTE(unwrap) E = Infallible
421-
//!
422-
//! state = !state;
423-
//!
424-
//! if state {
425-
//! led.on();
426-
//! } else {
427-
//! led.off();
428-
//! }
429-
//! }
430-
//! });
431-
//!
432-
//! let mut loopback = (move || {
433-
//! loop {
434-
//! let byte = nb::r#await!(serial.try_read()).unwrap();
435-
//! nb::r#await!(serial.try_write(byte)).unwrap();
436-
//! }
437-
//! });
438-
//!
439-
//! // Event loop
440-
//! loop {
441-
//! Pin::new(&mut blinky).resume(());
442-
//! Pin::new(&mut loopback).resume(());
443-
//! # break;
444-
//! }
445-
//! }
446-
//!
447-
//! # mod stm32f30x_hal {
448-
//! # use core::convert::Infallible;
449-
//! # pub struct Serial1;
450-
//! # impl Serial1 {
451-
//! # pub fn try_read(&mut self) -> ::nb::Result<u8, Infallible> { Err(::nb::Error::WouldBlock) }
452-
//! # pub fn try_write(&mut self, _: u8) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) }
453-
//! # }
454-
//! # pub struct Timer6;
455-
//! # impl Timer6 {
456-
//! # pub fn try_wait(&mut self) -> ::nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) }
457-
//! # }
458-
//! # pub struct Led;
459-
//! # impl Led {
460-
//! # pub fn off(&mut self) {}
461-
//! # pub fn on(&mut self) {}
462-
//! # }
463-
//! # }
464-
//! ```
465-
//!
466379
//! ## Generic programming and higher level abstractions
467380
//!
468381
//! The core of the HAL has been kept minimal on purpose to encourage building **generic** higher
@@ -479,10 +392,8 @@
479392
//! - Write a whole buffer to a serial device in blocking a fashion.
480393
//!
481394
//! ```
482-
//! extern crate embedded_hal as hal;
483-
//! #[macro_use(block)]
484-
//! extern crate nb;
485-
//!
395+
//! use embedded_hal as hal;
396+
//! use nb::block;
486397
//! use hal::prelude::*;
487398
//!
488399
//! fn write_all<S>(serial: &mut S, buffer: &[u8]) -> Result<(), S::Error>
@@ -502,8 +413,8 @@
502413
//! - Blocking serial read with timeout
503414
//!
504415
//! ```
505-
//! extern crate embedded_hal as hal;
506-
//! extern crate nb;
416+
//! use embedded_hal as hal;
417+
//! use nb;
507418
//!
508419
//! use hal::prelude::*;
509420
//!
@@ -552,50 +463,12 @@
552463
//! # fn main() {}
553464
//! ```
554465
//!
555-
//! - Asynchronous SPI transfer
556-
//!
557-
//! ```no_run
558-
//! #![feature(conservative_impl_trait)]
559-
//! #![feature(generators)]
560-
//! #![feature(generator_trait)]
561-
//!
562-
//! extern crate embedded_hal as hal;
563-
//! #[macro_use(r#await)]
564-
//! extern crate nb;
565-
//!
566-
//! use core::ops::Generator;
567-
//!
568-
//! /// Transfers a byte buffer of size N
569-
//! ///
570-
//! /// Returns the same byte buffer but filled with the data received from the
571-
//! /// slave device
572-
//! fn transfer<S, B>(
573-
//! mut spi: S,
574-
//! mut buffer: [u8; 16], // NOTE this should be generic over the size of the array
575-
//! ) -> impl Generator<Return = Result<(S, [u8; 16]), S::Error>, Yield = ()>
576-
//! where
577-
//! S: hal::spi::FullDuplex<u8>,
578-
//! {
579-
//! move || {
580-
//! let n = buffer.len();
581-
//! for i in 0..n {
582-
//! nb::r#await!(spi.try_send(buffer[i]))?;
583-
//! buffer[i] = nb::r#await!(spi.try_read())?;
584-
//! }
585-
//!
586-
//! Ok((spi, buffer))
587-
//! }
588-
//! }
589-
//!
590-
//! # fn main() {}
591-
//! ```
592-
//!
593466
//! - Buffered serial interface with periodic flushing in interrupt handler
594467
//!
595468
//! ```
596469
//! # use std as core;
597-
//! extern crate embedded_hal as hal;
598-
//! extern crate nb;
470+
//! use embedded_hal as hal;
471+
//! use nb;
599472
//!
600473
//! use hal::prelude::*;
601474
//! use ::core::convert::Infallible;
@@ -666,7 +539,7 @@
666539
//! # fn deref_mut(&mut self) -> &mut T { self.0 }
667540
//! # }
668541
//! # struct Serial1;
669-
//! # impl ::hal::serial::Write<u8> for Serial1 {
542+
//! # impl hal::serial::Write<u8> for Serial1 {
670543
//! # type Error = Infallible;
671544
//! # fn try_write(&mut self, _: u8) -> nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) }
672545
//! # fn try_flush(&mut self) -> nb::Result<(), Infallible> { Err(::nb::Error::WouldBlock) }

0 commit comments

Comments
 (0)