Merge pull request #74 from Disasm/usb

Add USB driver
This commit is contained in:
Daniel Egger 2019-11-13 14:24:01 +01:00 committed by GitHub
commit 0872ca4f14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 154 additions and 0 deletions

View File

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

View File

@ -37,9 +37,12 @@ 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"
usb-device = "0.2.3"
usbd-serial = "0.1.0"
[features]
device-selected = []
@ -80,3 +83,7 @@ required-features = ["stm32f042", "rt"]
[[example]]
name = "dac"
required-features = ["stm32f072"]
[[example]]
name = "usb_serial"
required-features = ["rt", "stm32f042", "stm32-usbd"]

90
examples/usb_serial.rs Normal file
View File

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

View File

@ -69,5 +69,17 @@ pub mod timers;
feature = "stm32f098",
))]
pub mod tsc;
#[cfg(all(
feature = "stm32-usbd",
any(
feature = "stm32f042",
feature = "stm32f048",
feature = "stm32f072",
feature = "stm32f078",
feature = "stm32f070x6",
feature = "stm32f070xb",
)
))]
pub mod usb;
#[cfg(feature = "device-selected")]
pub mod watchdog;

44
src/usb.rs Normal file
View File

@ -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<Input<Floating>>,
pub pin_dp: PA12<Input<Floating>>,
}
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<Peripheral>;