From 86c7f95c0ec7aee9a633550ed5c3179f2851b9c8 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Wed, 13 Nov 2019 14:28:43 +0300 Subject: [PATCH 1/4] Add USB driver --- Cargo.toml | 1 + src/lib.rs | 10 ++++++++++ src/usb.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 src/usb.rs diff --git a/Cargo.toml b/Cargo.toml index aad94e4..5c2f5b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ embedded-hal = { version = "0.2", features = ["unproven"] } stm32f0 = "0.8" nb = "0.1" void = { version = "1.0", default-features = false } +stm32-usbd = { version = "0.5.0", features = ["ram_access_2x16"], optional = true } [dev-dependencies] panic-halt = "0.2" diff --git a/src/lib.rs b/src/lib.rs index 0abb490..bd4bf5f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,5 +69,15 @@ pub mod timers; feature = "stm32f098", ))] pub mod tsc; +#[cfg(all( + feature = "stm32-usbd", + any( + feature = "stm32f042", + feature = "stm32f048", + feature = "stm32f072", + feature = "stm32f078", + ) +))] +pub mod usb; #[cfg(feature = "device-selected")] pub mod watchdog; diff --git a/src/usb.rs b/src/usb.rs new file mode 100644 index 0000000..092537a --- /dev/null +++ b/src/usb.rs @@ -0,0 +1,44 @@ +//! USB peripheral + +use crate::stm32::{RCC, USB}; +use stm32_usbd::UsbPeripheral; + +use crate::gpio::gpioa::{PA11, PA12}; +use crate::gpio::{Floating, Input}; +pub use stm32_usbd::UsbBus; + +pub struct Peripheral { + pub usb: USB, + pub pin_dm: PA11>, + pub pin_dp: PA12>, +} + +unsafe impl Sync for Peripheral {} + +unsafe impl UsbPeripheral for Peripheral { + const REGISTERS: *const () = USB::ptr() as *const (); + const DP_PULL_UP_FEATURE: bool = true; + const EP_MEMORY: *const () = 0x4000_6000 as _; + const EP_MEMORY_SIZE: usize = 1024; + + fn enable() { + let rcc = unsafe { (&*RCC::ptr()) }; + + cortex_m::interrupt::free(|_| { + // Enable USB peripheral + rcc.apb1enr.modify(|_, w| w.usben().set_bit()); + + // Reset USB peripheral + rcc.apb1rstr.modify(|_, w| w.usbrst().set_bit()); + rcc.apb1rstr.modify(|_, w| w.usbrst().clear_bit()); + }); + } + + fn startup_delay() { + // There is a chip specific startup delay. For STM32F103xx it's 1µs and this should wait for + // at least that long. + cortex_m::asm::delay(72); + } +} + +pub type UsbBusType = UsbBus; From 83a0e618f34bf6221ff1b195521b80387aa42496 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Wed, 13 Nov 2019 14:30:41 +0300 Subject: [PATCH 2/4] Add USB example --- Cargo.toml | 6 +++ examples/usb_serial.rs | 90 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 examples/usb_serial.rs diff --git a/Cargo.toml b/Cargo.toml index 5c2f5b8..3aae6a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,8 @@ stm32-usbd = { version = "0.5.0", features = ["ram_access_2x16"], optional = tru [dev-dependencies] panic-halt = "0.2" +usb-device = "0.2.3" +usbd-serial = "0.1.0" [features] device-selected = [] @@ -81,3 +83,7 @@ required-features = ["stm32f042", "rt"] [[example]] name = "dac" required-features = ["stm32f072"] + +[[example]] +name = "usb_serial" +required-features = ["rt", "stm32f042", "stm32-usbd"] diff --git a/examples/usb_serial.rs b/examples/usb_serial.rs new file mode 100644 index 0000000..4fbeb69 --- /dev/null +++ b/examples/usb_serial.rs @@ -0,0 +1,90 @@ +//! CDC-ACM serial port example using polling in a busy loop. +//! Target board: NUCLEO-F042K6 +#![no_std] +#![no_main] + +extern crate panic_halt; + +use cortex_m_rt::entry; +use stm32f0xx_hal::usb::{Peripheral, UsbBus}; +use stm32f0xx_hal::{prelude::*, stm32}; +use usb_device::prelude::*; +use usbd_serial::{SerialPort, USB_CLASS_CDC}; + +#[entry] +fn main() -> ! { + let mut dp = stm32::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() + .hsi48() + .enable_crs(dp.CRS) + .sysclk(48.mhz()) + .pclk(24.mhz()) + .freeze(&mut dp.FLASH); + + // Configure the on-board LED (LD3, green) + let gpiob = dp.GPIOB.split(&mut rcc); + let mut led = cortex_m::interrupt::free(|cs| gpiob.pb3.into_push_pull_output(cs)); + led.set_low(); // Turn off + + let gpioa = dp.GPIOA.split(&mut rcc); + + let usb = Peripheral { + usb: dp.USB, + pin_dm: gpioa.pa11, + pin_dp: gpioa.pa12, + }; + let usb_bus = UsbBus::new(usb); + + let mut serial = SerialPort::new(&usb_bus); + + let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd)) + .manufacturer("Fake company") + .product("Serial port") + .serial_number("TEST") + .device_class(USB_CLASS_CDC) + .build(); + + loop { + if !usb_dev.poll(&mut [&mut serial]) { + continue; + } + + let mut buf = [0u8; 64]; + + match serial.read(&mut buf) { + Ok(count) if count > 0 => { + led.set_high(); // Turn on + + // Echo back in upper case + for c in buf[0..count].iter_mut() { + if 0x61 <= *c && *c <= 0x7a { + *c &= !0x20; + } + } + + let mut write_offset = 0; + while write_offset < count { + match serial.write(&buf[write_offset..count]) { + Ok(len) if len > 0 => { + write_offset += len; + } + _ => {} + } + } + } + _ => {} + } + + led.set_low(); // Turn off + } +} From f9ef8c347924b076df0100ef9b26015ce658829d Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Wed, 13 Nov 2019 14:33:26 +0300 Subject: [PATCH 3/4] Enable USB support for STM32F070x6/B --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index bd4bf5f..fed653c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,6 +76,8 @@ pub mod tsc; feature = "stm32f048", feature = "stm32f072", feature = "stm32f078", + feature = "stm32f070x6", + feature = "stm32f070xb", ) ))] pub mod usb; From 74670ac848397dec21dd88a3578e26be74d71e4b Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Wed, 13 Nov 2019 15:38:07 +0300 Subject: [PATCH 4/4] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e4c1b6..fd2ff7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Enabled commented out and now available GPIOE support for 07x and 09x families - Extract register block address only once - Add DAC driver +- Added USB driver ## [v0.15.1] - 2019-08-11