|
1 |
| -//! Support code for working with the USB peripheral |
2 |
| -//! |
3 |
| -//! This module is different from the other peripheral APIs, in the sense that |
4 |
| -//! it isn't really a peripheral API, just some support code to make working |
5 |
| -//! with the USB peripheral possible. This is due to the existing STM32 |
6 |
| -//! ecosystem support for USB. |
| 1 | +//! Interface to the USB peripheral |
7 | 2 | //!
|
8 | 3 | //! As USB seems to work mostly the same across all STM32 MCUs, there is a
|
9 |
| -//! single crates that supports USB for these MCUs: |
| 4 | +//! single crate that supports USB for these MCUs: |
10 | 5 | //! [`stm32-usbd`](https://crates.io/crates/stm32-usbd)
|
11 | 6 | //!
|
12 |
| -//! Since `stm32-usbd` depends on the HAL libraries for each STM32 family it |
13 |
| -//! supports, we can't exactly depend on it to provide everything you need here. |
14 |
| -//! Instead, we just provide some code that takes care of the platform-specific |
15 |
| -//! bits, which you can call before using `stm32-usbd` for the rest. |
| 7 | +//! This module implements some bits needed for `stm32-usbd` to work and exports |
| 8 | +//! `UsbBus` from `stm32-usbd`. |
16 | 9 | //!
|
17 | 10 | //! Please check out the USB examples in the `examples/` directory to see how it
|
18 | 11 | //! fits together.
|
19 | 12 |
|
| 13 | +use crate::stm32::{RCC, USB}; |
| 14 | +use stm32_usbd::UsbPeripheral; |
| 15 | + |
| 16 | +use crate::gpio::gpioa::{PA11, PA12}; |
| 17 | +use crate::gpio::{Floating, Input}; |
| 18 | +pub use stm32_usbd::UsbBus; |
| 19 | + |
| 20 | +pub struct Peripheral { |
| 21 | + pub usb: USB, |
| 22 | + pub pin_dm: PA11<Input<Floating>>, |
| 23 | + pub pin_dp: PA12<Input<Floating>>, |
| 24 | +} |
20 | 25 |
|
21 |
| -use crate::rcc::{ |
22 |
| - HSI48, |
23 |
| - Rcc, |
24 |
| -}; |
| 26 | +unsafe impl Sync for Peripheral {} |
25 | 27 |
|
| 28 | +unsafe impl UsbPeripheral for Peripheral { |
| 29 | + const REGISTERS: *const () = USB::ptr() as *const (); |
| 30 | + const DP_PULL_UP_FEATURE: bool = true; |
| 31 | + const EP_MEMORY: *const () = 0x4000_6000 as _; |
| 32 | + const EP_MEMORY_SIZE: usize = 1024; |
26 | 33 |
|
27 |
| -/// Initializes the USB peripheral |
28 |
| -/// |
29 |
| -/// This method takes care of the platform-specific bits of the USB |
30 |
| -/// initialization. After calling this method, you need `stm32-usbd` to actually |
31 |
| -/// do anything useful with the USB peripheral. |
32 |
| -pub fn init(rcc: &mut Rcc, _: HSI48) { |
33 |
| - // Reset USB peripheral |
34 |
| - rcc.rb.apb1rstr.modify(|_, w| w.usbrst().set_bit()); |
35 |
| - rcc.rb.apb1rstr.modify(|_, w| w.usbrst().clear_bit()); |
| 34 | + fn enable() { |
| 35 | + let rcc = unsafe { (&*RCC::ptr()) }; |
36 | 36 |
|
37 |
| - // We don't need to enable the USB peripheral, as stm32-usbd takes care of |
38 |
| - // that. |
| 37 | + cortex_m::interrupt::free(|_| { |
| 38 | + // Enable USB peripheral |
| 39 | + rcc.apb1enr.modify(|_, w| w.usben().set_bit()); |
| 40 | + |
| 41 | + // Reset USB peripheral |
| 42 | + rcc.apb1rstr.modify(|_, w| w.usbrst().set_bit()); |
| 43 | + rcc.apb1rstr.modify(|_, w| w.usbrst().clear_bit()); |
| 44 | + }); |
| 45 | + } |
| 46 | + |
| 47 | + fn startup_delay() { |
| 48 | + // There is a chip specific startup delay. For STM32F103xx it's 1µs and this should wait for |
| 49 | + // at least that long. |
| 50 | + cortex_m::asm::delay(72); |
| 51 | + } |
39 | 52 | }
|
| 53 | + |
| 54 | +pub type UsbBusType = UsbBus<Peripheral>; |
0 commit comments