Compare commits

...

7 Commits

Author SHA1 Message Date
Marc Poulhiès 34d2ee36e2 Implement FullDuplex for SPI and add check_errors method 2 years ago
Daniel Egger 2bb8bb9637
Merge pull request #126 from matoushybl/update-dependencies 2 years ago
Matous Hybl 5f656df6dc Update dependency versions. 2 years ago
Daniel Egger e679ab190f Bump version to 0.17.1 and release it 2 years ago
Daniel Egger 48d1b9a161
Merge pull request #120 from evils/complete_TscPin 2 years ago
Evils 0246e90e57 implement TscPin for remaining touch pins 2 years ago
Roman Valls Guimera 0bbb50f5fa
Move usb-remap internals for certain ICs to USB enable() (#119) 2 years ago
  1. 13
      CHANGELOG.md
  2. 14
      Cargo.toml
  3. 17
      examples/usb_serial.rs
  4. 97
      src/spi.rs
  5. 73
      src/tsc.rs
  6. 13
      src/usb.rs

13
CHANGELOG.md

@ -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

14
Cargo.toml

@ -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", features = ["const-fn"] }
bare-metal = { version = "1.0.0" }
cast = { version = "0.2", default-features = false }
cortex-m = "0.6"
embedded-hal = { version = "0.2", features = ["unproven"] }
stm32f0 = "0.11"
nb = "0.1"
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 = []

17
examples/usb_serial.rs

@ -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")

97
src/spi.rs

@ -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 {
@ -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
@ -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)),
}
}
}
@ -526,7 +580,6 @@ where
}
// Do one last status register check before continuing
self.check_send().ok();
Ok(())
self.check_errors()
}
}

73
src/tsc.rs

@ -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.
use crate::gpio::{gpioa, gpiob, Alternate, AF3};
use crate::gpio::*;
use crate::pac::TSC;
use crate::rcc::Rcc;
@ -66,12 +66,34 @@ tsc_pins!(
gpioa::PA7<Alternate<AF3>> => (2_u8, 4_u8),
);
// all with a TSC minus 42 and 48
#[cfg(any(
feature = "stm32f051",
feature = "stm32f058",
feature = "stm32f071",
feature = "stm32f072",
feature = "stm32f078",
feature = "stm32f091",
feature = "stm32f098"
))]
tsc_pins!( gpioc::PC5<Alternate<AF0>> => (3_u8, 1_u8) );
tsc_pins!(
gpiob::PB0<Alternate<AF3>> => (3_u8, 2_u8),
gpiob::PB1<Alternate<AF3>> => (3_u8, 3_u8),
gpiob::PB2<Alternate<AF3>> => (3_u8, 4_u8),
);
// all with a TCS minus 58, 78 and 98
#[cfg(any(
feature = "stm32f042",
feature = "stm32f048",
feature = "stm32f051",
feature = "stm32f071",
feature = "stm32f072",
feature = "stm32f091"
))]
tsc_pins!( gpiob::PB2<Alternate<AF3>> => (3_u8, 4_u8) );
tsc_pins!(
gpioa::PA9<Alternate<AF3>> => (4_u8, 1_u8),
gpioa::PA10<Alternate<AF3>> => (4_u8, 2_u8),
@ -86,6 +108,53 @@ tsc_pins!(
gpiob::PB7<Alternate<AF3>> => (5_u8, 4_u8),
);
// all with a TSC minus 42 and 48
#[cfg(any(
feature = "stm32f051",
feature = "stm32f058",
feature = "stm32f071",
feature = "stm32f072",
feature = "stm32f078",
feature = "stm32f091",
feature = "stm32f098"
))]
tsc_pins!(
gpiob::PB11<Alternate<AF3>> => (6_u8, 1_u8),
gpiob::PB12<Alternate<AF3>> => (6_u8, 2_u8),
gpiob::PB13<Alternate<AF3>> => (6_u8, 3_u8),
gpiob::PB14<Alternate<AF3>> => (6_u8, 4_u8),
);
// all with a TSC and gpioe
#[cfg(any(
feature = "stm32f071",
feature = "stm32f072",
feature = "stm32f078",
feature = "stm32f091",
feature = "stm32f098"
))]
tsc_pins!(
gpioe::PE2<Alternate<AF3>> => (7_u8, 1_u8),
gpioe::PE3<Alternate<AF3>> => (7_u8, 2_u8),
gpioe::PE4<Alternate<AF3>> => (7_u8, 3_u8),
gpioe::PE5<Alternate<AF3>> => (7_u8, 4_u8),
);
// all with a TSC and gpiod
#[cfg(any(
feature = "stm32f071",
feature = "stm32f072",
feature = "stm32f078",
feature = "stm32f091",
feature = "stm32f098"
))]
tsc_pins!(
gpiod::PD12<Alternate<AF3>> => (8_u8, 1_u8),
gpiod::PD13<Alternate<AF3>> => (8_u8, 2_u8),
gpiod::PD14<Alternate<AF3>> => (8_u8, 3_u8),
gpiod::PD15<Alternate<AF3>> => (8_u8, 4_u8),
);
pub struct Tsc {
tsc: TSC,
}

13
src/usb.rs

@ -5,7 +5,7 @@
//! See <https://github.com/stm32-rs/stm32f0xx-hal/tree/master/examples>
//! for usage examples.
use crate::pac::{RCC, USB};
use crate::pac::{RCC, SYSCFG, USB};
use stm32_usbd::UsbPeripheral;
use crate::gpio::gpioa::{PA11, PA12};
@ -27,7 +27,7 @@ unsafe impl UsbPeripheral for Peripheral {
const EP_MEMORY_SIZE: usize = 1024;
fn enable() {
let rcc = unsafe { (&*RCC::ptr()) };
let rcc = unsafe { &*RCC::ptr() };
cortex_m::interrupt::free(|_| {
// Enable USB peripheral
@ -46,4 +46,13 @@ unsafe impl UsbPeripheral for Peripheral {
}
}
pub fn remap_pins(rcc: &mut RCC, syscfg: &mut SYSCFG) {
cortex_m::interrupt::free(|_| {
// Remap PA11/PA12 pins to PA09/PA10 for USB on
// TSSOP20 (STM32F042F) or UFQFPN28 (STM32F042G) packages
rcc.apb2enr.modify(|_, w| w.syscfgen().set_bit());
syscfg.cfgr1.modify(|_, w| w.pa11_pa12_rmp().remapped());
});
}
pub type UsbBusType = UsbBus<Peripheral>;

Loading…
Cancel
Save