Compare commits

..

7 Commits

Author SHA1 Message Date
Marc Poulhiès 34d2ee36e2 Implement FullDuplex for SPI and add check_errors method
check_errors only checks for Overrun, CRC error and ModeFault flags.
2 years ago
Daniel Egger 2bb8bb9637
Merge pull request #126 from matoushybl/update-dependencies
Update dependency versions.
2 years ago
Matous Hybl 5f656df6dc Update dependency versions. 2 years ago
Daniel Egger e679ab190f Bump version to 0.17.1 and release it
Signed-off-by: Daniel Egger <daniel@eggers-club.de>
3 years ago
Daniel Egger 48d1b9a161
Merge pull request #120 from evils/complete_TscPin
implement TscPin for remaining touch pins
3 years ago
Evils 0246e90e57 implement TscPin for remaining touch pins 3 years ago
Roman Valls Guimera 0bbb50f5fa
Move usb-remap internals for certain ICs to USB enable() (#119)
Move usb-remap internals for certain ICs to USB enable()
3 years ago

@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
## [v0.17.1] - 2020-08-30
### Changed
- Simplify USB PA11/12 remapping for STM32F042x via `usb_bus.usb_remap()` function.
### Added
- Complete the `TscPin` trait implementation for all touch pins in the f0 family
## [v0.17.0] - 2020-06-27
### Changed
@ -204,7 +214,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Updated stm32f0 dependency to v0.5.0.
- Interrupt handler to new #[interrupt] attribute
[Unreleased]: https://github.com/stm32-rs/stm32f0xx-hal/compare/v0.17.0...HEAD
[Unreleased]: https://github.com/stm32-rs/stm32f0xx-hal/compare/v0.17.1...HEAD
[v0.17.1]: https://github.com/stm32-rs/stm32f0xx-hal/compare/v0.17.0...v0.17.1
[v0.17.0]: https://github.com/stm32-rs/stm32f0xx-hal/compare/v0.16.0...v0.17.0
[v0.16.0]: https://github.com/stm32-rs/stm32f0xx-hal/compare/v0.15.2...v0.16.0
[v0.15.2]: https://github.com/stm32-rs/stm32f0xx-hal/compare/v0.15.1...v0.15.2

@ -23,27 +23,27 @@ license = "0BSD"
name = "stm32f0xx-hal"
readme = "README.md"
repository = "https://github.com/stm32-rs/stm32f0xx-hal"
version = "0.17.0"
version = "0.17.1"
[package.metadata.docs.rs]
features = ["stm32f042", "rt", "stm32-usbd"]
targets = ["thumbv6m-none-eabi"]
[dependencies]
bare-metal = { version = "0.2" }
bare-metal = { version = "1.0.0" }
cast = { version = "0.2", default-features = false }
cortex-m = "0.6"
embedded-hal = { version = "1.0.0-alpha.1" }
stm32f0 = "0.11"
nb = "0.1"
embedded-hal = { version = "0.2", features = ["unproven"] }
stm32f0 = "0.12.1"
nb = "1.0"
void = { version = "1.0", default-features = false }
stm32-usbd = { version = "0.5.0", features = ["ram_access_2x16"], optional = true }
stm32-usbd = { version = "0.5.1", features = ["ram_access_2x16"], optional = true }
[dev-dependencies]
cortex-m-rt = "0.6"
panic-halt = "0.2"
usb-device = "0.2.3"
usbd-serial = "0.1.0"
usb-device = "0.2.7"
usbd-serial = "0.1.1"
[features]
device-selected = []

@ -22,11 +22,11 @@ fn main() -> ! {
loop {
// Turn PA1 on a million times in a row
for _ in 0..1_000_000 {
led.try_set_high().ok();
led.set_high().ok();
}
// Then turn PA1 off a million times in a row
for _ in 0..1_000_000 {
led.try_set_low().ok();
led.set_low().ok();
}
}
}

@ -33,9 +33,9 @@ fn main() -> ! {
let mut adc = Adc::new(p.ADC, &mut rcc);
loop {
led.try_toggle().ok();
led.toggle().ok();
let time: u16 = if let Ok(val) = adc.try_read(&mut an_in) as Result<u16, _> {
let time: u16 = if let Ok(val) = adc.read(&mut an_in) as Result<u16, _> {
/* shift the value right by 3, same as divide by 8, reduces
the 0-4095 range into something approximating 1-512 */
(val >> 3) + 1
@ -43,7 +43,7 @@ fn main() -> ! {
1000
};
delay.try_delay_ms(time).ok();
delay.delay_ms(time);
}
}

@ -24,8 +24,8 @@ fn main() -> ! {
let mut delay = Delay::new(cp.SYST, &rcc);
loop {
led.try_toggle().ok();
delay.try_delay_ms(1_000_u16).ok();
led.toggle().ok();
delay.delay_ms(1_000_u16);
}
}

@ -13,7 +13,7 @@ use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
if let (Some(mut p), Some(cp)) = (pac::Peripherals::take(), Peripherals::take()) {
let mut rcc = p.RCC.configure().sysclk(8_u32.mhz()).freeze(&mut p.FLASH);
let mut rcc = p.RCC.configure().sysclk(8.mhz()).freeze(&mut p.FLASH);
let gpioa = p.GPIOA.split(&mut rcc);
let gpiob = p.GPIOB.split(&mut rcc);
@ -34,14 +34,14 @@ fn main() -> ! {
let mut leds = [led1.downgrade(), led2.downgrade()];
loop {
for l in &mut leds {
l.try_set_high().ok();
l.set_high().ok();
}
delay.try_delay_ms(1_000_u16).ok();
delay.delay_ms(1_000_u16);
for l in &mut leds {
l.try_set_low().ok();
l.set_low().ok();
}
delay.try_delay_ms(1_000_u16).ok();
delay.delay_ms(1_000_u16);
}
}

@ -23,10 +23,10 @@ fn main() -> ! {
let mut timer = Timer::tim1(p.TIM1, Hertz(1), &mut rcc);
loop {
led.try_toggle().ok();
led.toggle().ok();
// Wait for the timer to expire
nb::block!(timer.try_wait()).ok();
nb::block!(timer.wait()).ok();
}
}

@ -68,13 +68,13 @@ fn SysTick() {
// Check state variable, keep LED off most of the time and turn it on every 10th tick
if *STATE < 10 {
// Turn off the LED
led.try_set_low().ok();
led.set_low().ok();
// And now increment state variable
*STATE += 1;
} else {
// Turn on the LED
led.try_set_high().ok();
led.set_high().ok();
// And set new state variable back to 0
*STATE = 0;

@ -73,13 +73,13 @@ fn SysTick() {
// Check state variable, keep LED off most of the time and turn it on every 10th tick
if *STATE < 10 {
// Turn off the LED
led.try_set_low().ok();
led.set_low().ok();
// And now increment state variable
*STATE += 1;
} else {
// Turn on the LED
led.try_set_high().ok();
led.set_high().ok();
// And set new state variable back to 0
*STATE = 0;

@ -33,7 +33,7 @@ fn main() -> ! {
// The write method sends the specified address and checks for acknowledgement;
// if no ack is given by the slave device the result is Err(), otherwise Ok()
// Since we only care for an acknowledgement the data sent can be empty
if i2c.try_write(add, &[]).is_ok() {
if i2c.write(add, &[]).is_ok() {
_devices += 1;
}
}

@ -49,7 +49,7 @@ fn main() -> ! {
let mut led = gpioa.pa1.into_push_pull_output(cs);
// Turn off LED
led.try_set_low().ok();
led.set_low().ok();
// Initialise delay provider
let delay = Delay::new(cp.SYST, &rcc);
@ -96,13 +96,13 @@ fn EXTI0_1() {
INT.borrow(cs).borrow_mut().deref_mut(),
) {
// Turn on LED
led.try_set_high().ok();
led.set_high().ok();
// Wait a second
delay.try_delay_ms(1_000_u16).ok();
delay.delay_ms(1_000_u16);
// Turn off LED
led.try_set_low().ok();
led.set_low().ok();
// Clear event triggering the interrupt
exti.pr.write(|w| w.pif1().set_bit());

@ -28,10 +28,10 @@ fn main() -> ! {
loop {
// Wait for reception of a single byte
let received = nb::block!(serial.try_read()).unwrap();
let received = nb::block!(serial.read()).unwrap();
// Send back previously received byte and wait for completion
nb::block!(serial.try_write(received)).ok();
nb::block!(serial.write(received)).ok();
}
}

@ -57,10 +57,10 @@ fn main() -> ! {
let mut data = [0];
loop {
let serial_received = block!(rx.try_read()).unwrap();
spi.try_write(&[serial_received]).ok();
let spi_received = spi.try_transfer(&mut data).unwrap();
block!(tx.try_write(spi_received[0])).ok();
let serial_received = block!(rx.read()).unwrap();
spi.write(&[serial_received]).ok();
let spi_received = spi.transfer(&mut data).unwrap();
block!(tx.write(spi_received[0])).ok();
}
}

@ -37,30 +37,30 @@ fn main() -> ! {
});
// Configure SPI with 100kHz rate
let mut spi = Spi::spi1(p.SPI1, (sck, miso, mosi), MODE, 100_000_u32.hz(), &mut rcc);
let mut spi = Spi::spi1(p.SPI1, (sck, miso, mosi), MODE, 100_000.hz(), &mut rcc);
// Cycle through colors on 16 chained APA102C LEDs
loop {
for r in 0..255 {
let _ = spi.try_write(&[0, 0, 0, 0]);
let _ = spi.write(&[0, 0, 0, 0]);
for _i in 0..16 {
let _ = spi.try_write(&[0b1110_0001, 0, 0, r]);
let _ = spi.write(&[0b1110_0001, 0, 0, r]);
}
let _ = spi.try_write(&[0xFF, 0xFF, 0xFF, 0xFF]);
let _ = spi.write(&[0xFF, 0xFF, 0xFF, 0xFF]);
}
for b in 0..255 {
let _ = spi.try_write(&[0, 0, 0, 0]);
let _ = spi.write(&[0, 0, 0, 0]);
for _i in 0..16 {
let _ = spi.try_write(&[0b1110_0001, b, 0, 0]);
let _ = spi.write(&[0b1110_0001, b, 0, 0]);
}
let _ = spi.try_write(&[0xFF, 0xFF, 0xFF, 0xFF]);
let _ = spi.write(&[0xFF, 0xFF, 0xFF, 0xFF]);
}
for g in 0..255 {
let _ = spi.try_write(&[0, 0, 0, 0]);
let _ = spi.write(&[0, 0, 0, 0]);
for _i in 0..16 {
let _ = spi.try_write(&[0b1110_0001, 0, g, 0]);
let _ = spi.write(&[0b1110_0001, 0, g, 0]);
}
let _ = spi.try_write(&[0xFF, 0xFF, 0xFF, 0xFF]);
let _ = spi.write(&[0xFF, 0xFF, 0xFF, 0xFF]);
}
}
}

@ -15,13 +15,6 @@ use usbd_serial::{SerialPort, USB_CLASS_CDC};
fn main() -> ! {
let mut dp = pac::Peripherals::take().unwrap();
/* Uncomment the following lines if you have a chip in TSSOP20 (STM32F042F)
or UFQFPN28 (STM32F042G) package
This code enables clock for SYSCFG and remaps USB pins to PA9 and PA10.
*/
//dp.RCC.apb2enr.modify(|_, w| w.syscfgen().set_bit());
//dp.SYSCFG.cfgr1.modify(|_, w| w.pa11_pa12_rmp().remapped());
let mut rcc = dp
.RCC
.configure()
@ -43,10 +36,20 @@ fn main() -> ! {
pin_dm: gpioa.pa11,
pin_dp: gpioa.pa12,
};
let usb_bus = UsbBus::new(usb);
let mut serial = SerialPort::new(&usb_bus);
/*
* IMPORTANT: if you have a chip in TSSOP20 (STM32F042F) or UFQFPN28 (STM32F042G) package,
* and want to use USB, make sure you call `remap_pins(rcc, syscfg)`, otherwise the device will not enumerate.
*
* Uncomment the following function if the situation above applies to you.
*/
//usb_bus.remap_pins();
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
.manufacturer("Fake company")
.product("Serial port")

@ -37,17 +37,17 @@ fn main() -> ! {
serial.write_str("RESET \r\n").ok();
watchdog.try_start(Hertz(1)).ok();
delay.try_delay_ms(500_u16).ok();
watchdog.try_feed().ok();
delay.try_delay_ms(500_u16).ok();
watchdog.try_feed().ok();
delay.try_delay_ms(500_u16).ok();
watchdog.start(Hertz(1));
delay.delay_ms(500_u16);
watchdog.feed();
delay.delay_ms(500_u16);
watchdog.feed();
delay.delay_ms(500_u16);
serial.write_str("This will get printed \r\n").ok();
watchdog.try_feed().ok();
watchdog.feed();
// Now a reset happens while delaying
delay.try_delay_ms(1500_u16).ok();
delay.delay_ms(1500_u16);
serial.write_str("This won't\r\n").ok();
}

@ -191,7 +191,8 @@ macro_rules! adc_pins {
$(
impl Channel<Adc> for $pin {
type ID = u8;
const CHANNEL : u8 = $chan;
fn channel() -> u8 { $chan }
}
)+
};
@ -294,7 +295,7 @@ impl VTemp {
vtemp.enable(adc);
if let Some(dref) = delay {
dref.try_delay_us(2_u16).ok();
dref.delay_us(2_u16);
} else {
// Double read of vdda to allow sufficient startup time for the temp sensor
VRef::read_vdda(adc);
@ -304,7 +305,7 @@ impl VTemp {
let prev_cfg = adc.default_cfg();
let vtemp_val = adc.try_read(&mut vtemp).unwrap();
let vtemp_val = adc.read(&mut vtemp).unwrap();
if !vtemp_preenable {
vtemp.disable(adc);
@ -345,11 +346,11 @@ impl VRef {
let prev_cfg = adc.default_cfg();
let vref_val: u32 = if vref.is_enabled(&adc) {
adc.try_read(&mut vref).unwrap()
adc.read(&mut vref).unwrap()
} else {
vref.enable(adc);
let ret = adc.try_read(&mut vref).unwrap();
let ret = adc.read(&mut vref).unwrap();
vref.disable(adc);
ret
@ -534,7 +535,7 @@ impl Adc {
/// Read the value of a channel and converts the result to milli-volts
pub fn read_abs_mv<PIN: Channel<Adc, ID = u8>>(&mut self, pin: &mut PIN) -> u16 {
let vdda = u32::from(VRef::read_vdda(self));
let v: u32 = self.try_read(pin).unwrap();
let v: u32 = self.read(pin).unwrap();
let max_samp = u32::from(self.max_sample());
(v * vdda / max_samp) as u16
@ -611,9 +612,9 @@ where
{
type Error = ();
fn try_read(&mut self, _pin: &mut PIN) -> nb::Result<WORD, Self::Error> {
fn read(&mut self, _pin: &mut PIN) -> nb::Result<WORD, Self::Error> {
self.power_up();
let res = self.convert(PIN::CHANNEL);
let res = self.convert(PIN::channel());
self.power_down();
Ok(res.into())
}

@ -26,7 +26,6 @@
//! ```
use cast::{u16, u32};
use core::convert::Infallible;
use cortex_m::peripheral::syst::SystClkSource;
use cortex_m::peripheral::SYST;
@ -61,45 +60,35 @@ impl Delay {
}
impl DelayMs<u32> for Delay {
type Error = Infallible;
// At 48 MHz (the maximum frequency), calling delay_us with ms * 1_000 directly overflows at 0x15D86 (just over the max u16 value)
// So we implement a separate, higher level, delay loop
fn try_delay_ms(&mut self, mut ms: u32) -> Result<(), Self::Error> {
fn delay_ms(&mut self, mut ms: u32) {
const MAX_MS: u32 = 0x0000_FFFF;
while ms != 0 {
let current_ms = if ms <= MAX_MS { ms } else { MAX_MS };
self.try_delay_us(current_ms * 1_000)?;
self.delay_us(current_ms * 1_000);
ms -= current_ms;
}
Ok(())
}
}
impl DelayMs<u16> for Delay {
type Error = Infallible;
fn try_delay_ms(&mut self, ms: u16) -> Result<(), Self::Error> {
fn delay_ms(&mut self, ms: u16) {
// Call delay_us directly, so we don't have to use the additional
// delay loop the u32 variant uses
self.try_delay_us(u32(ms) * 1_000)
self.delay_us(u32(ms) * 1_000);
}
}
impl DelayMs<u8> for Delay {
type Error = Infallible;
fn try_delay_ms(&mut self, ms: u8) -> Result<(), Self::Error> {
self.try_delay_ms(u16(ms))
fn delay_ms(&mut self, ms: u8) {
self.delay_ms(u16(ms));
}
}
// At 48MHz (the maximum frequency), this overflows at approx. 2^32 / 48 = 89 seconds
impl DelayUs<u32> for Delay {
type Error = Infallible;
fn try_delay_us(&mut self, us: u32) -> Result<(), Self::Error> {
fn delay_us(&mut self, us: u32) {
// The SysTick Reload Value register supports values between 1 and 0x00FFFFFF.
// Here less than maximum is used so we have some play if there's a long running interrupt.
const MAX_TICKS: u32 = 0x007F_FFFF;
@ -120,23 +109,17 @@ impl DelayUs<u32> for Delay {
// from 0 to 0xFFFF
while (start_count.wrapping_sub(SYST::get_current()) % SYSTICK_RANGE) < current_ticks {}
}
Ok(())
}
}
impl DelayUs<u16> for Delay {
type Error = Infallible;
fn try_delay_us(&mut self, us: u16) -> Result<(), Self::Error> {
self.try_delay_us(u32(us))
fn delay_us(&mut self, us: u16) {
self.delay_us(u32(us))
}
}
impl DelayUs<u8> for Delay {
type Error = Infallible;
fn try_delay_us(&mut self, us: u8) -> Result<(), Self::Error> {
self.try_delay_us(u32(us))
fn delay_us(&mut self, us: u8) {
self.delay_us(u32(us))
}
}

@ -15,10 +15,10 @@ pub trait GpioExt {
}
trait GpioRegExt {
fn try_is_low(&self, pos: u8) -> bool;
fn try_is_set_low(&self, pos: u8) -> bool;
fn try_set_high(&self, pos: u8);
fn try_set_low(&self, pos: u8);
fn is_low(&self, pos: u8) -> bool;
fn is_set_low(&self, pos: u8) -> bool;
fn set_high(&self, pos: u8);
fn set_low(&self, pos: u8);
}
/// Alternate function 0
@ -71,7 +71,7 @@ pub struct Output<MODE> {
/// Push pull output (type state)
pub struct PushPull;
use embedded_hal::digital::{toggleable, InputPin, OutputPin, StatefulOutputPin};
use embedded_hal::digital::v2::{toggleable, InputPin, OutputPin, StatefulOutputPin};
/// Fully erased pin
pub struct Pin<MODE> {
@ -88,13 +88,13 @@ unsafe impl<MODE> Send for Pin<MODE> {}
impl<MODE> StatefulOutputPin for Pin<Output<MODE>> {
#[inline(always)]
fn try_is_set_high(&self) -> Result<bool, Self::Error> {
self.try_is_set_low().map(|v| !v)
fn is_set_high(&self) -> Result<bool, Self::Error> {
self.is_set_low().map(|v| !v)
}
#[inline(always)]
fn try_is_set_low(&self) -> Result<bool, Self::Error> {
Ok(unsafe { (*self.port).try_is_set_low(self.i) })
fn is_set_low(&self) -> Result<bool, Self::Error> {
Ok(unsafe { (*self.port).is_set_low(self.i) })
}
}
@ -102,14 +102,14 @@ impl<MODE> OutputPin for Pin<Output<MODE>> {
type Error = Infallible;
#[inline(always)]
fn try_set_high(&mut self) -> Result<(), Self::Error> {
unsafe { (*self.port).try_set_high(self.i) };
fn set_high(&mut self) -> Result<(), Self::Error> {
unsafe { (*self.port).set_high(self.i) };
Ok(())
}
#[inline(always)]
fn try_set_low(&mut self) -> Result<(), Self::Error> {
unsafe { (*self.port).try_set_low(self.i) }
fn set_low(&mut self) -> Result<(), Self::Error> {
unsafe { (*self.port).set_low(self.i) }
Ok(())
}
}
@ -120,13 +120,13 @@ impl InputPin for Pin<Output<OpenDrain>> {
type Error = Infallible;
#[inline(always)]
fn try_is_high(&self) -> Result<bool, Self::Error> {
self.try_is_low().map(|v| !v)
fn is_high(&self) -> Result<bool, Self::Error> {
self.is_low().map(|v| !v)
}
#[inline(always)]
fn try_is_low(&self) -> Result<bool, Self::Error> {
Ok(unsafe { (*self.port).try_is_low(self.i) })
fn is_low(&self) -> Result<bool, Self::Error> {
Ok(unsafe { (*self.port).is_low(self.i) })
}
}
@ -134,35 +134,35 @@ impl<MODE> InputPin for Pin<Input<MODE>> {
type Error = Infallible;
#[inline(always)]
fn try_is_high(&self) -> Result<bool, Self::Error> {
self.try_is_low().map(|v| !v)
fn is_high(&self) -> Result<bool, Self::Error> {
self.is_low().map(|v| !v)
}
#[inline(always)]
fn try_is_low(&self) -> Result<bool, Self::Error> {
Ok(unsafe { (*self.port).try_is_low(self.i) })
fn is_low(&self) -> Result<bool, Self::Error> {
Ok(unsafe { (*self.port).is_low(self.i) })
}
}
macro_rules! gpio_trait {
($gpiox:ident) => {
impl GpioRegExt for crate::pac::$gpiox::RegisterBlock {
fn try_is_low(&self, pos: u8) -> bool {
fn is_low(&self, pos: u8) -> bool {
// NOTE(unsafe) atomic read with no side effects
self.idr.read().bits() & (1 << pos) == 0
}
fn try_is_set_low(&self, pos: u8) -> bool {
fn is_set_low(&self, pos: u8) -> bool {
// NOTE(unsafe) atomic read with no side effects
self.odr.read().bits() & (1 << pos) == 0
}
fn try_set_high(&self, pos: u8) {
fn set_high(&self, pos: u8) {
// NOTE(unsafe) atomic write to a stateless register
unsafe { self.bsrr.write(|w| w.bits(1 << pos)) }
}
fn try_set_low(&self, pos: u8) {
fn set_low(&self, pos: u8) {
// NOTE(unsafe) atomic write to a stateless register
unsafe { self.bsrr.write(|w| w.bits(1 << (pos + 16))) }
}
@ -184,7 +184,7 @@ macro_rules! gpio {
use core::marker::PhantomData;
use core::convert::Infallible;
use embedded_hal::digital::{InputPin, OutputPin, StatefulOutputPin, toggleable};
use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, toggleable};
use crate::{
rcc::Rcc,
pac::$GPIOX
@ -504,24 +504,24 @@ macro_rules! gpio {
}
impl<MODE> StatefulOutputPin for $PXi<Output<MODE>> {
fn try_is_set_high(&self) -> Result<bool, Self::Error> {
self.try_is_set_low().map(|v| !v)
fn is_set_high(&self) -> Result<bool, Self::Error> {
self.is_set_low().map(|v| !v)
}
fn try_is_set_low(&self) -> Result<bool, Self::Error> {
Ok(unsafe { (*$GPIOX::ptr()).try_is_set_low($i) })
fn is_set_low(&self) -> Result<bool, Self::Error> {
Ok(unsafe { (*$GPIOX::ptr()).is_set_low($i) })
}
}
impl<MODE> OutputPin for $PXi<Output<MODE>> {
type Error = Infallible;
fn try_set_high(&mut self) -> Result<(), Self::Error> {
Ok(unsafe { (*$GPIOX::ptr()).try_set_high($i) })
fn set_high(&mut self) -> Result<(), Self::Error> {
Ok(unsafe { (*$GPIOX::ptr()).set_high($i) })
}
fn try_set_low(&mut self) -> Result<(), Self::Error> {
Ok(unsafe { (*$GPIOX::ptr()).try_set_low($i) })
fn set_low(&mut self) -> Result<(), Self::Error> {
Ok(unsafe { (*$GPIOX::ptr()).set_low($i) })
}
}
@ -530,12 +530,12 @@ macro_rules! gpio {
impl InputPin for $PXi<Output<OpenDrain>> {
type Error = Infallible;
fn try_is_high(&self) -> Result<bool, Self::Error> {
self.try_is_low().map(|v| !v)
fn is_high(&self) -> Result<bool, Self::Error> {
self.is_low().map(|v| !v)
}
fn try_is_low(&self) -> Result<bool, Self::Error> {
Ok(unsafe { (*$GPIOX::ptr()).try_is_low($i) })
fn is_low(&self) -> Result<bool, Self::Error> {
Ok(unsafe { (*$GPIOX::ptr()).is_low($i) })
}
}
@ -556,12 +556,12 @@ macro_rules! gpio {
impl<MODE> InputPin for $PXi<Input<MODE>> {
type Error = Infallible;
fn try_is_high(&self) -> Result<bool, Self::Error> {
self.try_is_low().map(|v| !v)
fn is_high(&self) -> Result<bool, Self::Error> {
self.is_low().map(|v| !v)
}
fn try_is_low(&self) -> Result<bool, Self::Error> {
Ok(unsafe { (*$GPIOX::ptr()).try_is_low($i) })
fn is_low(&self) -> Result<bool, Self::Error> {
Ok(unsafe { (*$GPIOX::ptr()).is_low($i) })
}
}
)+

@ -321,7 +321,7 @@ where
{
type Error = Error;
fn try_write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
// Set up current slave address for writing and disable autoending
self.i2c.cr2.modify(|_, w| {
w.sadd()
@ -394,7 +394,7 @@ where
{
type Error = Error;
fn try_read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> {
fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> {
// Set up current address for reading
self.i2c.cr2.modify(|_, w| {
w.sadd()
@ -429,7 +429,7 @@ where
{
type Error = Error;
fn try_write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
// Set up current slave address for writing and enable autoending
self.i2c.cr2.modify(|_, w| {
w.sadd()

@ -6,10 +6,10 @@ pub use embedded_hal::watchdog::WatchdogEnable as _stm32f0xx_hal_embedded_hal_wa
pub use embedded_hal::adc::OneShot as _embedded_hal_adc_OneShot;
pub use embedded_hal::digital::InputPin as _embedded_hal_gpio_InputPin;
pub use embedded_hal::digital::OutputPin as _embedded_hal_gpio_OutputPin;
pub use embedded_hal::digital::StatefulOutputPin as _embedded_hal_gpio_StatefulOutputPin;
pub use embedded_hal::digital::ToggleableOutputPin as _embedded_hal_gpio_ToggleableOutputPin;
pub use embedded_hal::digital::v2::InputPin as _embedded_hal_gpio_InputPin;
pub use embedded_hal::digital::v2::OutputPin as _embedded_hal_gpio_OutputPin;
pub use embedded_hal::digital::v2::StatefulOutputPin as _embedded_hal_gpio_StatefulOutputPin;
pub use embedded_hal::digital::v2::ToggleableOutputPin as _embedded_hal_gpio_ToggleableOutputPin;
pub use crate::gpio::GpioExt as _stm32f0xx_hal_gpio_GpioExt;
pub use crate::rcc::RccExt as _stm32f0xx_hal_rcc_RccExt;

@ -64,7 +64,8 @@ use core::{
ops::Deref,
};
use crate::prelude::*;
use embedded_hal::prelude::*;
use crate::{gpio::*, rcc::Rcc, time::Bps};
use core::marker::PhantomData;
@ -429,7 +430,7 @@ where
type Error = Error;
/// Tries to read a byte from the uart
fn try_read(&mut self) -> nb::Result<u8, Error> {
fn read(&mut self) -> nb::Result<u8, Error> {
read(self.usart)
}
}
@ -442,7 +443,7 @@ where
type Error = Error;
/// Tries to read a byte from the uart
fn try_read(&mut self) -> nb::Result<u8, Error> {
fn read(&mut self) -> nb::Result<u8, Error> {
read(&*self.usart)
}
}
@ -454,13 +455,13 @@ where
type Error = Infallible;
/// Ensures that none of the previously written words are still buffered
fn try_flush(&mut self) -> nb::Result<(), Self::Error> {
fn flush(&mut self) -> nb::Result<(), Self::Error> {
flush(self.usart)
}
/// Tries to write a byte to the uart
/// Fails if the transmit buffer is full
fn try_write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
write(self.usart, byte)
}
}
@ -473,13 +474,13 @@ where
type Error = Infallible;
/// Ensures that none of the previously written words are still buffered
fn try_flush(&mut self) -> nb::Result<(), Self::Error> {
fn flush(&mut self) -> nb::Result<(), Self::Error> {
flush(&*self.usart)
}
/// Tries to write a byte to the uart
/// Fails if the transmit buffer is full
fn try_write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
write(&*self.usart, byte)
}
}
@ -519,7 +520,7 @@ where
fn write_str(&mut self, s: &str) -> Result {
s.as_bytes()
.iter()
.try_for_each(|c| nb::block!(self.try_write(*c)))
.try_for_each(|c| nb::block!(self.write(*c)))
.map_err(|_| core::fmt::Error)
}
}
@ -532,7 +533,7 @@ where
fn write_str(&mut self, s: &str) -> Result {
s.as_bytes()
.iter()
.try_for_each(|c| nb::block!(self.try_write(*c)))
.try_for_each(|c| nb::block!(self.write(*c)))
.map_err(|_| core::fmt::Error)
}
}

@ -365,17 +365,27 @@ where
fn check_read(&mut self) -> nb::Result<(), Error> {
let sr = self.spi.sr.read();
Err(if sr.ovr().bit_is_set() {
nb::Error::Other(Error::Overrun)
self.check_errors()?;
if !sr.rxne().bit_is_set() {
Err(nb::Error::WouldBlock)
} else {
Ok(())
}
}
fn check_errors(&mut self) -> Result<(), Error> {
let sr = self.spi.sr.read();
if sr.ovr().bit_is_set() {
Err(Error::Overrun)
} else if sr.modf().bit_is_set() {
nb::Error::Other(Error::ModeFault)
Err(Error::ModeFault)
} else if sr.crcerr().bit_is_set() {
nb::Error::Other(Error::Crc)
} else if sr.rxne().bit_is_set() {
return Ok(());
Err(Error::Crc)
} else {
nb::Error::WouldBlock
})
Ok(())
}
}
fn send_buffer_size(&mut self) -> u8 {
@ -394,17 +404,13 @@ where
fn check_send(&mut self) -> nb::Result<(), Error> {
let sr = self.spi.sr.read();
Err(if sr.ovr().bit_is_set() {
nb::Error::Other(Error::Overrun)
} else if sr.modf().bit_is_set() {
nb::Error::Other(Error::ModeFault)
} else if sr.crcerr().bit_is_set() {
nb::Error::Other(Error::Crc)
} else if sr.txe().bit_is_set() {
return Ok(());
self.check_errors()?;
if !sr.txe().bit_is_set() {
Err(nb::Error::WouldBlock)
} else {
nb::Error::WouldBlock
})
Ok(())
}
}
fn read_u8(&mut self) -> u8 {
@ -439,7 +445,7 @@ where
{
type Error = Error;
fn try_transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
// We want to transfer bidirectionally, make sure we're in the correct mode
self.set_bidi();
@ -454,6 +460,29 @@ where
}
}
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::spi::FullDuplex<u8>
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, EightBit>
where
SPI: Deref<Target = SpiRegisterBlock>,
{
type Error = Error;
fn read(&mut self) -> nb::Result<u8, Error> {
self.check_read()?;
Ok(self.read_u8())
}
fn send(&mut self, byte: u8) -> nb::Result<(), Error> {
// We want to transfer bidirectionally, make sure we're in the correct mode
self.set_bidi();
self.check_send()?;
self.send_u8(byte);
self.check_errors().map_err(|e| nb::Error::Other(e))
}
}
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::blocking::spi::Write<u8>
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, EightBit>
where
@ -461,7 +490,7 @@ where
{
type Error = Error;
fn try_write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
let mut bufcap: u8 = 0;
// We only want to send, so we don't need to worry about the receive buffer overflowing
@ -482,8 +511,33 @@ where
}
// Do one last status register check before continuing
self.check_send().ok();
Ok(())
self.check_errors()
}
}
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::spi::FullDuplex<u16>
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, SixteenBit>
where
SPI: Deref<Target = SpiRegisterBlock>,
{
type Error = Error;
fn read(&mut self) -> nb::Result<u16, Error> {
self.check_read()?;
Ok(self.read_u16())
}
fn send(&mut self, byte: u16) -> nb::Result<(), Error> {
// We want to transfer bidirectionally, make sure we're in the correct mode
self.set_bidi();
self.check_send()?;
self.send_u16(byte);
match self.check_errors() {
Ok(_) => Ok(()),
Err(e) => Err(nb::Error::Other(e)),
}
}
}
@ -494,7 +548,7 @@ where
{
type Error = Error;
fn try_transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> {
fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> {
// We want to transfer bidirectionally, make sure we're in the correct mode
self.set_bidi();
@ -516,7 +570,7 @@ where
{
type Error = Error;
fn try_write(&mut self, words: &[u16]) -> Result<(), Self::Error> {
fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> {
// We only want to send, so we don't need to worry about the receive buffer overflowing
self.set_send_only();
@ -526,7 +580,6 @@ where
}
// Do one last status register check before continuing
self.check_send().ok();
Ok(())
self.check_errors()
}
}

@ -32,10 +32,10 @@ use cortex_m::peripheral::syst::SystClkSource;
use cortex_m::peripheral::SYST;
use crate::rcc::{Clocks, Rcc};
use core::convert::Infallible;
use crate::time::Hertz;
use embedded_hal::timer::{CountDown, Periodic};
use void::Void;
/// Hardware timers
pub struct Timer<TIM> {
@ -60,7 +60,7 @@ impl Timer<SYST> {
tim: syst,
clocks: rcc.clocks,
};
timer.try_start(timeout).ok();
timer.start(timeout);
timer
}
@ -84,10 +84,9 @@ impl Timer<SYST> {
/// Be aware that intervals less than 4 Hertz may not function properly
impl CountDown for Timer<SYST> {
type Time = Hertz;
type Error = Infallible;
/// Start the timer with a `timeout`
fn try_start<T>(&mut self, timeout: T) -> Result<(), Self::Error>
fn start<T>(&mut self, timeout: T)
where
T: Into<Hertz>,
{
@ -98,13 +97,11 @@ impl CountDown for Timer<SYST> {
self.tim.set_reload(rvr);
self.tim.clear_current();
self.tim.enable_counter();
Ok(())
}
/// Return `Ok` if the timer has wrapped
/// Automatically clears the flag and restarts the time
fn try_wait(&mut self) -> nb::Result<(), Self::Error> {
fn wait(&mut self) -> nb::Result<(), Void> {
if self.tim.has_wrapped() {
Ok(())
} else {
@ -137,7 +134,7 @@ macro_rules! timers {
clocks: rcc.clocks,
tim,
};
timer.try_start(timeout).ok();
timer.start(timeout);
timer
}
@ -175,10 +172,9 @@ macro_rules! timers {
impl CountDown for Timer<$TIM> {
type Time = Hertz;
type Error = Infallible;
/// Start the timer with a `timeout`
fn try_start<T>(&mut self, timeout: T) -> Result<(), Self::Error>
fn start<T>(&mut self, timeout: T)
where
T: Into<Hertz>,
{
@ -204,13 +200,11 @@ macro_rules! timers {
// start counter
self.tim.cr1.modify(|_, w| w.cen().set_bit());
Ok(())
}
/// Return `Ok` if the timer has wrapped
/// Automatically clears the flag and restarts the time
fn try_wait(&mut self) -> nb::Result<(), Self::Error> {
fn wait(&mut self) -> nb::Result<(), Void> {
if self.tim.sr.read().uif().bit_is_clear() {
Err(nb::Error::WouldBlock)
} else {

@ -7,7 +7,7 @@
//! usually comprised between 47nF and 100nF. These values are given as reference for an
//! electrode fitting a human finger tip size across a few millimeters dielectric panel.