Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

USB: Add support for external ULPI PHYs #184

Merged
merged 3 commits into from
Feb 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ authors = ["Andrew Straw <strawman@astraw.com>",
"Robert Jördens <rj@quartiq.de>",
"Ryan Summers <ryan.summers@vertigo-designs.com>",
"Matthew Meyer <mtthw.meyer@gmail.com>",
"Florian Jung <flo@windfisch.org>"]
"Florian Jung <flo@windfisch.org>",
"Matt Ickstadt <mattico8@gmail.com>"]
edition = "2018"
categories = ["embedded", "hardware-support", "no-std"]
description = "Hardware Abstraction Layer implementation for STM32H7 series microcontrollers"
Expand Down Expand Up @@ -36,7 +37,7 @@ paste = "1.0.1"
bare-metal = "1.0.0"
sdio-host = { version = "0.4", optional = true }
stm32-fmc = { version = "0.2", optional = true }
synopsys-usb-otg = { version = "^0.2.2", features = ["cortex-m"], optional = true }
synopsys-usb-otg = { version = "^0.2.4", features = ["cortex-m"], optional = true }

[dependencies.smoltcp]
version = "0.7.0"
Expand Down
4 changes: 3 additions & 1 deletion examples/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,7 @@ fn main() -> ! {

info!("Memory to Memory DMA completed successfully");

loop {}
loop {
cortex_m::asm::nop()
}
}
4 changes: 3 additions & 1 deletion examples/fmc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ const APP: () = {

assert_eq!(ram_slice[0], 1);

loop {}
loop {
cortex_m::asm::nop()
}
}
};
4 changes: 3 additions & 1 deletion examples/fractional-pll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,7 @@ fn main() -> ! {

let _mco2_ck = ccdr.clocks.mco2_ck().unwrap().0;

loop {}
loop {
cortex_m::asm::nop()
}
}
4 changes: 3 additions & 1 deletion examples/i2c4_bdma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,7 @@ fn I2C4_EV() {

assert_eq!(buffer[0], 0xBE);

loop {}
loop {
cortex_m::asm::nop()
}
}
4 changes: 3 additions & 1 deletion examples/mco.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,7 @@ fn main() -> ! {

info!("MCO outputs running!");

loop {}
loop {
cortex_m::asm::nop()
}
}
4 changes: 3 additions & 1 deletion examples/prec_kernel_clocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,7 @@ fn main() -> ! {
// Can't change group clocks - ccdr.peripheral has been partially used
//ccdr.peripheral.kernel_i2c123_clk_mux(I2c123ClkSel::HSI_KER);

loop {}
loop {
cortex_m::asm::nop()
}
}
4 changes: 3 additions & 1 deletion examples/pwm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,7 @@ fn main() -> ! {
pwm.set_duty(max / 2);
pwm.enable();

loop {}
loop {
cortex_m::asm::nop()
}
}
4 changes: 3 additions & 1 deletion examples/rcc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,7 @@ fn main() -> ! {
info!("sys_ck = {} MHz", ccdr.clocks.sys_ck().0 as f32 / 1e6);
assert_eq!(ccdr.clocks.sys_ck().0, 100_000_000);

loop {}
loop {
cortex_m::asm::nop()
}
}
4 changes: 3 additions & 1 deletion examples/sdmmc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,5 +166,7 @@ fn main() -> ! {

info!("Done!");

loop {}
loop {
cortex_m::asm::nop()
}
}
4 changes: 3 additions & 1 deletion examples/spi-dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,5 +176,7 @@ fn main() -> ! {

// We could re-use the stream or spi here

loop {}
loop {
cortex_m::asm::nop()
}
}
4 changes: 3 additions & 1 deletion examples/vos0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,7 @@ fn main() -> ! {
info!("sys_ck = {} MHz", ccdr.clocks.sys_ck().0 as f32 / 1e6);
assert_eq!(ccdr.clocks.sys_ck().0, 480_000_000);

loop {}
loop {
cortex_m::asm::nop()
}
}
4 changes: 3 additions & 1 deletion examples/watchdog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,7 @@ fn main() -> ! {
// -> restart the chip
watchdog.start(100.ms());

loop {}
loop {
cortex_m::asm::nop()
}
}
101 changes: 96 additions & 5 deletions src/usb_hs.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
//! USB OTG peripherals
//!
//! Requires the `usb_hs` feature.
//!
//! Note that only full-speed mode is supported,
//! external high-speed PHY is not supported.

use crate::rcc;
use crate::stm32;

use crate::gpio::{
gpioa::{PA11, PA12},
gpioa::{PA11, PA12, PA3, PA5},
gpiob::{PB0, PB1, PB10, PB11, PB12, PB13, PB5},
gpioc::{PC0, PC2, PC3},
gpioh::PH4,
gpioi::PI11,
Alternate, AF10,
};

#[cfg(not(feature = "rm0455"))]
use crate::gpio::{
gpiob::{PB14, PB15},
Expand All @@ -33,6 +35,7 @@ pub struct USB1 {
pub prec: rcc::rec::Usb1Otg,
pub hclk: Hertz,
}

#[cfg(not(feature = "rm0455"))]
pub struct USB2 {
pub usb_global: stm32::OTG2_HS_GLOBAL,
Expand Down Expand Up @@ -64,7 +67,6 @@ macro_rules! usb_peripheral {

const HIGH_SPEED: bool = true;
const FIFO_DEPTH_WORDS: usize = 1024;

const ENDPOINT_COUNT: usize = 9;

fn enable() {
Expand Down Expand Up @@ -106,3 +108,92 @@ usb_peripheral! {
}
#[cfg(not(feature = "rm0455"))]
pub type Usb2BusType = UsbBus<USB2>;

pub struct USB1_ULPI {
pub usb_global: stm32::OTG1_HS_GLOBAL,
pub usb_device: stm32::OTG1_HS_DEVICE,
pub usb_pwrclk: stm32::OTG1_HS_PWRCLK,
pub prec: rcc::rec::Usb1Otg,
pub hclk: Hertz,
pub ulpi_clk: PA5<Alternate<AF10>>,
pub ulpi_dir: Usb1UlpiDirPin,
pub ulpi_nxt: Usb1UlpiNxtPin,
pub ulpi_stp: PC0<Alternate<AF10>>,
pub ulpi_d0: PA3<Alternate<AF10>>,
pub ulpi_d1: PB0<Alternate<AF10>>,
pub ulpi_d2: PB1<Alternate<AF10>>,
pub ulpi_d3: PB10<Alternate<AF10>>,
pub ulpi_d4: PB11<Alternate<AF10>>,
pub ulpi_d5: PB12<Alternate<AF10>>,
pub ulpi_d6: PB13<Alternate<AF10>>,
pub ulpi_d7: PB5<Alternate<AF10>>,
}

pub enum Usb1UlpiDirPin {
PC2(PC2<Alternate<AF10>>),
PI11(PI11<Alternate<AF10>>),
}

impl From<PI11<Alternate<AF10>>> for Usb1UlpiDirPin {
fn from(v: PI11<Alternate<AF10>>) -> Self {
Usb1UlpiDirPin::PI11(v)
}
}

impl From<PC2<Alternate<AF10>>> for Usb1UlpiDirPin {
fn from(v: PC2<Alternate<AF10>>) -> Self {
Usb1UlpiDirPin::PC2(v)
}
}

pub enum Usb1UlpiNxtPin {
PC3(PC3<Alternate<AF10>>),
PH4(PH4<Alternate<AF10>>),
}

impl From<PH4<Alternate<AF10>>> for Usb1UlpiNxtPin {
fn from(v: PH4<Alternate<AF10>>) -> Self {
Usb1UlpiNxtPin::PH4(v)
}
}

impl From<PC3<Alternate<AF10>>> for Usb1UlpiNxtPin {
fn from(v: PC3<Alternate<AF10>>) -> Self {
Usb1UlpiNxtPin::PC3(v)
}
}

unsafe impl Sync for USB1_ULPI {}

unsafe impl UsbPeripheral for USB1_ULPI {
const REGISTERS: *const () = stm32::OTG1_HS_GLOBAL::ptr() as *const ();

const HIGH_SPEED: bool = true;
const FIFO_DEPTH_WORDS: usize = 1024;
const ENDPOINT_COUNT: usize = 9;

fn enable() {
let rcc = unsafe { &*stm32::RCC::ptr() };

cortex_m::interrupt::free(|_| {
// Enable USB peripheral
rcc.ahb1enr.modify(|_, w| w.usb1otgen().enabled());

// Enable ULPI Clock
rcc.ahb1enr.modify(|_, w| w.usb1ulpien().enabled());

// Reset USB peripheral
rcc.ahb1rstr.modify(|_, w| w.usb1otgrst().set_bit());
rcc.ahb1rstr.modify(|_, w| w.usb1otgrst().clear_bit());
});
}

fn ahb_frequency_hz(&self) -> u32 {
self.hclk.0
}

fn phy_type(&self) -> synopsys_usb_otg::PhyType {
synopsys_usb_otg::PhyType::ExternalHighSpeed
}
}
pub type Usb1UlpiBusType = UsbBus<USB1_ULPI>;