Compare commits

...

15 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
Daniel Egger 86ecf612f5 Enable USB features in CI 2 years ago
Daniel Egger 87a9955ce4
Merge pull request #117 from stm32-rs/release-0.17.0 2 years ago
Daniel Egger 77f4eedcd8 Bump version to 0.17.0 and prepare release 2 years ago
Daniel Egger ed4067b076 Fix inconsistent comment 2 years ago
Dimitri Polonski 16272ef716 fix typo 2 years ago
Torkel Danielsson bd8c2758ee fix warning 2 years ago
Torkel Danielsson 26d2148ee9 fix check errors 2 years ago
Torkel Danielsson db7428d398 Reduce the scope of some critical sections in the examples 2 years ago
  1. 16
      CHANGELOG.md
  2. 14
      Cargo.toml
  3. 10
      examples/blinky.rs
  4. 49
      examples/blinky_adc.rs
  5. 22
      examples/blinky_delay.rs
  6. 51
      examples/blinky_multiple.rs
  7. 24
      examples/blinky_timer.rs
  8. 46
      examples/dac.rs
  9. 30
      examples/serial_echo.rs
  10. 48
      examples/serial_spi_bridge.rs
  11. 64
      examples/spi_hal_apa102c.rs
  12. 17
      examples/usb_serial.rs
  13. 52
      examples/watchdog.rs
  14. 2
      src/dac.rs
  15. 2
      src/i2c.rs
  16. 2
      src/serial.rs
  17. 97
      src/spi.rs
  18. 73
      src/tsc.rs
  19. 13
      src/usb.rs
  20. 2
      tools/check.py

16
CHANGELOG.md

@ -7,6 +7,18 @@ 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
- Remove duplicate error bits clearing in serial `read()` implementation
@ -202,7 +214,9 @@ 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.16.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
[v0.15.1]: https://github.com/stm32-rs/stm32f0xx-hal/compare/v0.15.0...v0.15.1

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.16.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 = []

10
examples/blinky.rs

@ -12,14 +12,12 @@ use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
if let Some(mut p) = pac::Peripherals::take() {
let mut led = cortex_m::interrupt::free(|cs| {
let mut rcc = p.RCC.configure().sysclk(8.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 gpioa = p.GPIOA.split(&mut rcc);
// (Re-)configure PA1 as output
gpioa.pa1.into_push_pull_output(cs)
});
// (Re-)configure PA1 as output
let mut led = cortex_m::interrupt::free(|cs| gpioa.pa1.into_push_pull_output(cs));
loop {
// Turn PA1 on a million times in a row

49
examples/blinky_adc.rs

@ -13,37 +13,38 @@ use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
if let (Some(mut p), Some(cp)) = (pac::Peripherals::take(), Peripherals::take()) {
cortex_m::interrupt::free(move |cs| {
let mut rcc = p.RCC.configure().sysclk(8.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 gpioa = p.GPIOA.split(&mut rcc);
// (Re-)configure PA1 as output
let mut led = gpioa.pa1.into_push_pull_output(cs);
// (Re-)configure PA0 as analog input
let mut an_in = gpioa.pa0.into_analog(cs);
let (mut led, mut an_in) = cortex_m::interrupt::free(move |cs| {
(
// (Re-)configure PA1 as output
gpioa.pa1.into_push_pull_output(cs),
// (Re-)configure PA0 as analog input
gpioa.pa0.into_analog(cs),
)
});
// Get delay provider
let mut delay = Delay::new(cp.SYST, &rcc);
// Get delay provider
let mut delay = Delay::new(cp.SYST, &rcc);
// Get access to the ADC
let mut adc = Adc::new(p.ADC, &mut rcc);
// Get access to the ADC
let mut adc = Adc::new(p.ADC, &mut rcc);
loop {
led.toggle().ok();
loop {
led.toggle().ok();
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
} else {
1000
};
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
} else {
1000
};
delay.delay_ms(time);
}
});
delay.delay_ms(time);
}
}
loop {

22
examples/blinky_delay.rs

@ -13,22 +13,20 @@ use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
if let (Some(mut p), Some(cp)) = (pac::Peripherals::take(), Peripherals::take()) {
cortex_m::interrupt::free(move |cs| {
let mut rcc = p.RCC.configure().sysclk(8.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 gpioa = p.GPIOA.split(&mut rcc);
// (Re-)configure PA1 as output
let mut led = gpioa.pa1.into_push_pull_output(cs);
// (Re-)configure PA1 as output
let mut led = cortex_m::interrupt::free(move |cs| gpioa.pa1.into_push_pull_output(cs));
// Get delay provider
let mut delay = Delay::new(cp.SYST, &rcc);
// Get delay provider
let mut delay = Delay::new(cp.SYST, &rcc);
loop {
led.toggle().ok();
delay.delay_ms(1_000_u16);
}
});
loop {
led.toggle().ok();
delay.delay_ms(1_000_u16);
}
}
loop {

51
examples/blinky_multiple.rs

@ -13,35 +13,36 @@ use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
if let (Some(mut p), Some(cp)) = (pac::Peripherals::take(), Peripherals::take()) {
cortex_m::interrupt::free(move |cs| {
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);
// (Re-)configure PA1 as output
let led1 = gpioa.pa1.into_push_pull_output(cs);
// (Re-)configure PB1 as output
let led2 = gpiob.pb1.into_push_pull_output(cs);
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);
let (led1, led2) = cortex_m::interrupt::free(move |cs| {
(
// (Re-)configure PA1 as output
gpioa.pa1.into_push_pull_output(cs),
// (Re-)configure PB1 as output
gpiob.pb1.into_push_pull_output(cs),
)
});
// Get delay provider
let mut delay = Delay::new(cp.SYST, &rcc);
// Get delay provider
let mut delay = Delay::new(cp.SYST, &rcc);
// Store them together after erasing the type
let mut leds = [led1.downgrade(), led2.downgrade()];
loop {
for l in &mut leds {
l.set_high().ok();
}
delay.delay_ms(1_000_u16);
// Store them together after erasing the type
let mut leds = [led1.downgrade(), led2.downgrade()];
loop {
for l in &mut leds {
l.set_high().ok();
}
delay.delay_ms(1_000_u16);
for l in &mut leds {
l.set_low().ok();
}
delay.delay_ms(1_000_u16);
for l in &mut leds {
l.set_low().ok();
}
});
delay.delay_ms(1_000_u16);
}
}
loop {

24
examples/blinky_timer.rs

@ -12,24 +12,22 @@ use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
if let Some(mut p) = pac::Peripherals::take() {
cortex_m::interrupt::free(move |cs| {
let mut rcc = p.RCC.configure().sysclk(8.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 gpioa = p.GPIOA.split(&mut rcc);
// (Re-)configure PA1 as output
let mut led = gpioa.pa1.into_push_pull_output(cs);
// (Re-)configure PA1 as output
let mut led = cortex_m::interrupt::free(move |cs| gpioa.pa1.into_push_pull_output(cs));
// Set up a timer expiring after 1s
let mut timer = Timer::tim1(p.TIM1, Hertz(1), &mut rcc);
// Set up a timer expiring after 1s
let mut timer = Timer::tim1(p.TIM1, Hertz(1), &mut rcc);
loop {
led.toggle().ok();
loop {
led.toggle().ok();
// Wait for the timer to expire
nb::block!(timer.wait()).ok();
}
});
// Wait for the timer to expire
nb::block!(timer.wait()).ok();
}
}
loop {

46
examples/dac.rs

@ -22,37 +22,37 @@ enum Direction {
#[entry]
fn main() -> ! {
if let (Some(mut dp), Some(_cp)) = (pac::Peripherals::take(), cortex_m::Peripherals::take()) {
cortex_m::interrupt::free(move |cs| {
let mut rcc = dp.RCC.configure().sysclk(8.mhz()).freeze(&mut dp.FLASH);
let mut rcc = dp.RCC.configure().sysclk(8.mhz()).freeze(&mut dp.FLASH);
let gpioa = dp.GPIOA.split(&mut rcc);
let gpioa = dp.GPIOA.split(&mut rcc);
let mut dac = dac(dp.DAC, gpioa.pa4.into_analog(cs), &mut rcc);
let pa4 = cortex_m::interrupt::free(move |cs| gpioa.pa4.into_analog(cs));
dac.enable();
let mut dac = dac(dp.DAC, pa4, &mut rcc);
let mut dir = Direction::Upcounting;
let mut val = 0;
dac.enable();
dac.set_value(2058);
cortex_m::asm::bkpt();
let mut dir = Direction::Upcounting;
let mut val = 0;
dac.set_value(4095);
cortex_m::asm::bkpt();
dac.set_value(2058);
cortex_m::asm::bkpt();
loop {
dac.set_value(val);
match val {
0 => dir = Direction::Upcounting,
4095 => dir = Direction::Downcounting,
_ => (),
};
dac.set_value(4095);
cortex_m::asm::bkpt();
match dir {
Direction::Upcounting => val += 1,
Direction::Downcounting => val -= 1,
}
loop {
dac.set_value(val);
match val {
0 => dir = Direction::Upcounting,
4095 => dir = Direction::Downcounting,
_ => (),
};
match dir {
Direction::Upcounting => val += 1,
Direction::Downcounting => val -= 1,
}
});
}
}
loop {

30
examples/serial_echo.rs

@ -12,25 +12,27 @@ use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
if let Some(p) = pac::Peripherals::take() {
cortex_m::interrupt::free(move |cs| {
let mut flash = p.FLASH;
let mut rcc = p.RCC.configure().sysclk(48.mhz()).freeze(&mut flash);
let mut flash = p.FLASH;
let mut rcc = p.RCC.configure().sysclk(48.mhz()).freeze(&mut flash);
let gpioa = p.GPIOA.split(&mut rcc);
let gpioa = p.GPIOA.split(&mut rcc);
let tx = gpioa.pa9.into_alternate_af1(cs);
let rx = gpioa.pa10.into_alternate_af1(cs);
let (tx, rx) = cortex_m::interrupt::free(move |cs| {
(
gpioa.pa9.into_alternate_af1(cs),
gpioa.pa10.into_alternate_af1(cs),
)
});
let mut serial = Serial::usart1(p.USART1, (tx, rx), 115_200.bps(), &mut rcc);
let mut serial = Serial::usart1(p.USART1, (tx, rx), 115_200.bps(), &mut rcc);
loop {
// Wait for reception of a single byte
let received = nb::block!(serial.read()).unwrap();
loop {
// Wait for reception of a single byte
let received = nb::block!(serial.read()).unwrap();
// Send back previously received byte and wait for completion
nb::block!(serial.write(received)).ok();
}
});
// Send back previously received byte and wait for completion
nb::block!(serial.write(received)).ok();
}
}
loop {

48
examples/serial_spi_bridge.rs

@ -31,35 +31,37 @@ fn main() -> ! {
};
if let Some(p) = pac::Peripherals::take() {
cortex_m::interrupt::free(move |cs| {
let mut flash = p.FLASH;
let mut rcc = p.RCC.configure().freeze(&mut flash);
let mut flash = p.FLASH;
let mut rcc = p.RCC.configure().freeze(&mut flash);
let gpioa = p.GPIOA.split(&mut rcc);
let gpioa = p.GPIOA.split(&mut rcc);
// Configure pins for SPI
let sck = gpioa.pa5.into_alternate_af0(cs);
let miso = gpioa.pa6.into_alternate_af0(cs);
let mosi = gpioa.pa7.into_alternate_af0(cs);
// Configure SPI with 1MHz rate
let mut spi = Spi::spi1(p.SPI1, (sck, miso, mosi), MODE, 1.mhz(), &mut rcc);
let (sck, miso, mosi, tx, rx) = cortex_m::interrupt::free(move |cs| {
(
// SPI pins
gpioa.pa5.into_alternate_af0(cs),
gpioa.pa6.into_alternate_af0(cs),
gpioa.pa7.into_alternate_af0(cs),
// USART pins
gpioa.pa9.into_alternate_af1(cs),
gpioa.pa10.into_alternate_af1(cs),
)
});
let tx = gpioa.pa9.into_alternate_af1(cs);
let rx = gpioa.pa10.into_alternate_af1(cs);
// Configure SPI with 1MHz rate
let mut spi = Spi::spi1(p.SPI1, (sck, miso, mosi), MODE, 1.mhz(), &mut rcc);
let serial = Serial::usart1(p.USART1, (tx, rx), 115_200.bps(), &mut rcc);
let serial = Serial::usart1(p.USART1, (tx, rx), 115_200.bps(), &mut rcc);
let (mut tx, mut rx) = serial.split();
let (mut tx, mut rx) = serial.split();
let mut data = [0];
loop {
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();
}
});
let mut data = [0];
loop {
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();
}
}
loop {

64
examples/spi_hal_apa102c.rs

@ -22,45 +22,47 @@ fn main() -> ! {
};
if let Some(p) = pac::Peripherals::take() {
cortex_m::interrupt::free(move |cs| {
let mut flash = p.FLASH;
let mut rcc = p.RCC.configure().freeze(&mut flash);
let mut flash = p.FLASH;
let mut rcc = p.RCC.configure().freeze(&mut flash);
let gpioa = p.GPIOA.split(&mut rcc);
let gpioa = p.GPIOA.split(&mut rcc);
// Configure pins for SPI
let sck = gpioa.pa5.into_alternate_af0(cs);
let miso = gpioa.pa6.into_alternate_af0(cs);
let mosi = gpioa.pa7.into_alternate_af0(cs);
// Configure pins for SPI
let (sck, miso, mosi) = cortex_m::interrupt::free(move |cs| {
(
gpioa.pa5.into_alternate_af0(cs),
gpioa.pa6.into_alternate_af0(cs),
gpioa.pa7.into_alternate_af0(cs),
)
});
// Configure SPI with 100kHz rate
let mut spi = Spi::spi1(p.SPI1, (sck, miso, mosi), MODE, 100_000.hz(), &mut rcc);
// Configure SPI with 100kHz rate
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.write(&[0, 0, 0, 0]);
for _i in 0..16 {
let _ = spi.write(&[0b1110_0001, 0, 0, r]);
}
let _ = spi.write(&[0xFF, 0xFF, 0xFF, 0xFF]);
// Cycle through colors on 16 chained APA102C LEDs
loop {
for r in 0..255 {
let _ = spi.write(&[0, 0, 0, 0]);
for _i in 0..16 {
let _ = spi.write(&[0b1110_0001, 0, 0, r]);
}
for b in 0..255 {
let _ = spi.write(&[0, 0, 0, 0]);
for _i in 0..16 {
let _ = spi.write(&[0b1110_0001, b, 0, 0]);
}
let _ = spi.write(&[0xFF, 0xFF, 0xFF, 0xFF]);
let _ = spi.write(&[0xFF, 0xFF, 0xFF, 0xFF]);
}
for b in 0..255 {
let _ = spi.write(&[0, 0, 0, 0]);
for _i in 0..16 {
let _ = spi.write(&[0b1110_0001, b, 0, 0]);
}
for g in 0..255 {
let _ = spi.write(&[0, 0, 0, 0]);
for _i in 0..16 {
let _ = spi.write(&[0b1110_0001, 0, g, 0]);
}
let _ = spi.write(&[0xFF, 0xFF, 0xFF, 0xFF]);
let _ = spi.write(&[0xFF, 0xFF, 0xFF, 0xFF]);
}
for g in 0..255 {
let _ = spi.write(&[0, 0, 0, 0]);
for _i in 0..16 {
let _ = spi.write(&[0b1110_0001, 0, g, 0]);
}
let _ = spi.write(&[0xFF, 0xFF, 0xFF, 0xFF]);
}
});
}
}
loop {

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

52
examples/watchdog.rs

@ -15,42 +15,40 @@ use core::fmt::Write;
#[entry]
fn main() -> ! {
if let (Some(p), Some(cp)) = (pac::Peripherals::take(), Peripherals::take()) {
cortex_m::interrupt::free(move |cs| {
let mut flash = p.FLASH;
let mut rcc = p.RCC.configure().sysclk(8.mhz()).freeze(&mut flash);
let mut flash = p.FLASH;
let mut rcc = p.RCC.configure().sysclk(8.mhz()).freeze(&mut flash);
let gpioa = p.GPIOA.split(&mut rcc);
let dbgmcu = p.DBGMCU;
let gpioa = p.GPIOA.split(&mut rcc);
let dbgmcu = p.DBGMCU;
// Disable the watchdog when the cpu is stopped under debug
dbgmcu.apb1_fz.modify(|_, w| w.dbg_iwdg_stop().set_bit());
// Disable the watchdog when the cpu is stopped under debug
dbgmcu.apb1_fz.modify(|_, w| w.dbg_iwdg_stop().set_bit());
let mut watchdog = Watchdog::new(p.IWDG);
let mut watchdog = Watchdog::new(p.IWDG);
// Get delay provider
let mut delay = Delay::new(cp.SYST, &rcc);
// Get delay provider
let mut delay = Delay::new(cp.SYST, &rcc);
// Configure serial TX pin
let tx = gpioa.pa9.into_alternate_af1(cs);
// Configure serial TX pin
let tx = cortex_m::interrupt::free(move |cs| gpioa.pa9.into_alternate_af1(cs));
// Obtain a serial peripheral with for unidirectional communication
let mut serial = Serial::usart1tx(p.USART1, tx, 115_200.bps(), &mut rcc);
// Obtain a serial peripheral with for unidirectional communication
let mut serial = Serial::usart1tx(p.USART1, tx, 115_200.bps(), &mut rcc);
serial.write_str("RESET \r\n").ok();
serial.write_str("RESET \r\n").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.feed();
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.feed();
// Now a reset happens while delaying
delay.delay_ms(1500_u16);
serial.write_str("This won't\r\n").ok();
});
// Now a reset happens while delaying
delay.delay_ms(1500_u16);
serial.write_str("This won't\r\n").ok();
}
loop {

2
src/dac.rs

@ -114,7 +114,7 @@ where
rcc.regs.apb1rstr.modify(|_, w| w.dacrst().set_bit());
rcc.regs.apb1rstr.modify(|_, w| w.dacrst().clear_bit());
unsafe { mem::uninitialized() }
unsafe { mem::MaybeUninit::uninit().assume_init() }
}
macro_rules! dac {

2
src/i2c.rs

@ -234,7 +234,7 @@ where
scldel = 3;
}
// Enable I2C signal generator, and configure I2C for 400KHz full speed
// Enable I2C signal generator, and configure I2C for configured speed
self.i2c.timingr.write(|w| {
w.presc()
.bits(presc)

2
src/serial.rs

@ -324,7 +324,7 @@ macro_rules! usart {
where
RXPIN: RxPin<$USART>,
{
/// Creates a new tx-only serial instance
/// Creates a new rx-only serial instance
pub fn $usartrx(usart: $USART, rxpin: RXPIN, baud_rate: Bps, rcc: &mut Rcc) -> Self
{
let txpin = ();

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

2
tools/check.py

@ -28,7 +28,7 @@ def main():
crate_info = cargo_meta["packages"][0]
features = [""] + ["{} rt".format(x)
features = [""] + ["{},rt,stm32-usbd".format(x)
for x in crate_info["features"].keys()
if x != "device-selected" and x != "rt" and x != "stm32f030"]

Loading…
Cancel
Save