mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-10-02 06:40:47 +00:00
Support USB-DEVICE on ESP32-S3 and ESP32-S2
This commit is contained in:
parent
fae2f1add3
commit
a876d8d344
@ -12,18 +12,20 @@ repository = "https://github.com/esp-rs/esp-hal"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[dependencies]
|
||||
cfg-if = "1.0.0"
|
||||
critical-section = "1.1.0"
|
||||
embedded-hal = { version = "0.2.7", features = ["unproven"] }
|
||||
embedded-hal-1 = { version = "=1.0.0-alpha.9", optional = true, package = "embedded-hal" }
|
||||
embedded-hal-nb = { version = "=1.0.0-alpha.1", optional = true }
|
||||
fugit = "0.3.6"
|
||||
lock_api = { version = "0.4.8", optional = true }
|
||||
nb = "1.0.0"
|
||||
paste = "=1.0.8"
|
||||
procmacros = { version = "0.1.0", package = "esp-hal-procmacros", path = "../esp-hal-procmacros" }
|
||||
void = { version = "1.0.2", default-features = false }
|
||||
embedded-dma = "0.2.0"
|
||||
cfg-if = "1.0.0"
|
||||
critical-section = "1.1.1"
|
||||
embedded-hal = { version = "0.2.7", features = ["unproven"] }
|
||||
embedded-hal-1 = { version = "=1.0.0-alpha.9", optional = true, package = "embedded-hal" }
|
||||
embedded-hal-nb = { version = "=1.0.0-alpha.1", optional = true }
|
||||
fugit = "0.3.6"
|
||||
lock_api = { version = "0.4.8", optional = true }
|
||||
nb = "1.0.0"
|
||||
paste = "=1.0.8"
|
||||
procmacros = { version = "0.1.0", package = "esp-hal-procmacros", path = "../esp-hal-procmacros" }
|
||||
void = { version = "1.0.2", default-features = false }
|
||||
embedded-dma = "0.2.0"
|
||||
esp-synopsys-usb-otg = { version = "0.3.1", optional = true, features = ["fs", "esp32sx"] }
|
||||
usb-device = { version = "0.2.3", optional = true }
|
||||
|
||||
# RISC-V
|
||||
riscv = { version = "0.9.0", optional = true }
|
||||
@ -46,15 +48,15 @@ ufmt-write = { version = "0.1.0", optional = true }
|
||||
esp32 = { version = "0.14.0", features = ["critical-section"], optional = true }
|
||||
esp32c2 = { version = "0.3.0", features = ["critical-section"], optional = true }
|
||||
esp32c3 = { version = "0.6.0", features = ["critical-section"], optional = true }
|
||||
esp32s2 = { version = "0.4.0", features = ["critical-section"], optional = true }
|
||||
esp32s3 = { version = "0.4.0", features = ["critical-section"], optional = true }
|
||||
esp32s2 = { version = "0.5.0", features = ["critical-section"], optional = true }
|
||||
esp32s3 = { version = "0.5.0", features = ["critical-section"], optional = true }
|
||||
|
||||
[features]
|
||||
esp32 = ["esp32/rt" , "procmacros/xtensa", "xtensa-lx-rt/esp32", "xtensa-lx/esp32", "critical-section/restore-state-u32", "lock_api"]
|
||||
esp32c2 = ["esp32c2/rt", "procmacros/riscv" , "riscv", "riscv-atomic-emulation-trap", "critical-section/restore-state-u8"]
|
||||
esp32c3 = ["esp32c3/rt", "procmacros/riscv" , "riscv", "riscv-atomic-emulation-trap", "critical-section/restore-state-u8"]
|
||||
esp32s2 = ["esp32s2/rt", "procmacros/xtensa", "xtensa-lx-rt/esp32s2", "xtensa-lx/esp32s2", "critical-section/restore-state-u32"]
|
||||
esp32s3 = ["esp32s3/rt", "procmacros/xtensa", "xtensa-lx-rt/esp32s3", "xtensa-lx/esp32s3", "critical-section/restore-state-u32", "lock_api"]
|
||||
esp32s2 = ["esp32s2/rt", "procmacros/xtensa", "xtensa-lx-rt/esp32s2", "xtensa-lx/esp32s2", "critical-section/restore-state-u32", "esp-synopsys-usb-otg", "usb-device"]
|
||||
esp32s3 = ["esp32s3/rt", "procmacros/xtensa", "xtensa-lx-rt/esp32s3", "xtensa-lx/esp32s3", "critical-section/restore-state-u32", "lock_api", "esp-synopsys-usb-otg", "usb-device"]
|
||||
|
||||
# Implement the `embedded-hal==1.0.0-alpha.x` traits
|
||||
eh1 = ["embedded-hal-1", "embedded-hal-nb"]
|
||||
|
@ -418,7 +418,7 @@ pub fn connect_low_to_peripheral(signal: InputSignal) {
|
||||
.in_inv_sel()
|
||||
.bit(false)
|
||||
.in_sel()
|
||||
.bits(0x1f)
|
||||
.bits(ZERO_INPUT)
|
||||
});
|
||||
}
|
||||
|
||||
@ -430,7 +430,7 @@ pub fn connect_high_to_peripheral(signal: InputSignal) {
|
||||
.in_inv_sel()
|
||||
.bit(false)
|
||||
.in_sel()
|
||||
.bits(0x1e)
|
||||
.bits(ONE_INPUT)
|
||||
});
|
||||
}
|
||||
|
||||
@ -1311,4 +1311,4 @@ pub use impl_interrupt_status_register_access;
|
||||
pub use impl_output;
|
||||
pub use impl_output_wrap;
|
||||
|
||||
use self::types::{InputSignal, OutputSignal};
|
||||
use self::types::{InputSignal, OutputSignal, ONE_INPUT, ZERO_INPUT};
|
||||
|
@ -2,6 +2,9 @@ pub type OutputSignalType = u16;
|
||||
pub const OUTPUT_SIGNAL_MAX: u16 = 548;
|
||||
pub const INPUT_SIGNAL_MAX: u16 = 539;
|
||||
|
||||
pub const ONE_INPUT: u8 = 0x38;
|
||||
pub const ZERO_INPUT: u8 = 0x30;
|
||||
|
||||
/// Peripheral input signals for the GPIO mux
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(PartialEq, Copy, Clone)]
|
||||
|
@ -2,6 +2,9 @@ pub type OutputSignalType = u8;
|
||||
pub const OUTPUT_SIGNAL_MAX: u8 = 128;
|
||||
pub const INPUT_SIGNAL_MAX: u8 = 100;
|
||||
|
||||
pub const ONE_INPUT: u8 = 0x1e;
|
||||
pub const ZERO_INPUT: u8 = 0x1f;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum InputSignal {
|
||||
|
@ -2,6 +2,9 @@ pub type OutputSignalType = u8;
|
||||
pub const OUTPUT_SIGNAL_MAX: u8 = 128;
|
||||
pub const INPUT_SIGNAL_MAX: u8 = 100;
|
||||
|
||||
pub const ONE_INPUT: u8 = 0x1e;
|
||||
pub const ZERO_INPUT: u8 = 0x1f;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum InputSignal {
|
||||
|
@ -2,6 +2,9 @@ pub type OutputSignalType = u16;
|
||||
pub const OUTPUT_SIGNAL_MAX: u16 = 256;
|
||||
pub const INPUT_SIGNAL_MAX: u16 = 204;
|
||||
|
||||
pub const ONE_INPUT: u8 = 0x38;
|
||||
pub const ZERO_INPUT: u8 = 0x3c;
|
||||
|
||||
/// Peripheral input signals for the GPIO mux
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(PartialEq, Copy, Clone)]
|
||||
|
@ -2,6 +2,9 @@ pub type OutputSignalType = u16;
|
||||
pub const OUTPUT_SIGNAL_MAX: u16 = 256;
|
||||
pub const INPUT_SIGNAL_MAX: u16 = 189;
|
||||
|
||||
pub const ONE_INPUT: u8 = 0x38;
|
||||
pub const ZERO_INPUT: u8 = 0x3c;
|
||||
|
||||
/// Peripheral input signals for the GPIO mux
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(PartialEq, Copy, Clone)]
|
||||
|
@ -91,6 +91,9 @@ pub mod efuse;
|
||||
#[cfg_attr(xtensa, path = "interrupt/xtensa.rs")]
|
||||
pub mod interrupt;
|
||||
|
||||
#[cfg(any(esp32s3, esp32s2))]
|
||||
pub mod otg_fs;
|
||||
|
||||
/// Enumeration of CPU cores
|
||||
/// The actual number of available cores depends on the target.
|
||||
pub enum Cpu {
|
||||
|
123
esp-hal-common/src/otg_fs.rs
Normal file
123
esp-hal-common/src/otg_fs.rs
Normal file
@ -0,0 +1,123 @@
|
||||
//! USB OTG full-speed peripheral
|
||||
|
||||
pub use esp_synopsys_usb_otg::UsbBus;
|
||||
use esp_synopsys_usb_otg::UsbPeripheral;
|
||||
|
||||
use crate::{
|
||||
pac,
|
||||
system::{Peripheral, PeripheralClockControl},
|
||||
types::InputSignal,
|
||||
};
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait UsbSel {}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait UsbDp {}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait UsbDm {}
|
||||
|
||||
pub struct USB<S, P, M>
|
||||
where
|
||||
S: UsbSel + Send + Sync,
|
||||
P: UsbDp + Send + Sync,
|
||||
M: UsbDm + Send + Sync,
|
||||
{
|
||||
_usb0: pac::USB0,
|
||||
_usb_sel: S,
|
||||
_usb_dp: P,
|
||||
_usb_dm: M,
|
||||
}
|
||||
|
||||
impl<S, P, M> USB<S, P, M>
|
||||
where
|
||||
S: UsbSel + Send + Sync,
|
||||
P: UsbDp + Send + Sync,
|
||||
M: UsbDm + Send + Sync,
|
||||
{
|
||||
pub fn new(
|
||||
usb0: pac::USB0,
|
||||
usb_sel: S,
|
||||
usb_dp: P,
|
||||
usb_dm: M,
|
||||
peripheral_clock_control: &mut PeripheralClockControl,
|
||||
) -> Self {
|
||||
peripheral_clock_control.enable(Peripheral::Usb);
|
||||
Self {
|
||||
_usb0: usb0,
|
||||
_usb_sel: usb_sel,
|
||||
_usb_dp: usb_dp,
|
||||
_usb_dm: usb_dm,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<S, P, M> Sync for USB<S, P, M>
|
||||
where
|
||||
S: UsbSel + Send + Sync,
|
||||
P: UsbDp + Send + Sync,
|
||||
M: UsbDm + Send + Sync,
|
||||
{
|
||||
}
|
||||
|
||||
unsafe impl<S, P, M> UsbPeripheral for USB<S, P, M>
|
||||
where
|
||||
S: UsbSel + Send + Sync,
|
||||
P: UsbDp + Send + Sync,
|
||||
M: UsbDm + Send + Sync,
|
||||
{
|
||||
const REGISTERS: *const () = pac::USB0::ptr() as *const ();
|
||||
|
||||
const HIGH_SPEED: bool = false;
|
||||
const FIFO_DEPTH_WORDS: usize = 256;
|
||||
const ENDPOINT_COUNT: usize = 5;
|
||||
|
||||
fn enable() {
|
||||
unsafe {
|
||||
let usb_wrap = &*pac::USB_WRAP::PTR;
|
||||
usb_wrap.otg_conf.modify(|_, w| {
|
||||
w.usb_pad_enable()
|
||||
.set_bit()
|
||||
.phy_sel()
|
||||
.clear_bit()
|
||||
.clk_en()
|
||||
.set_bit()
|
||||
.ahb_clk_force_on()
|
||||
.set_bit()
|
||||
.phy_clk_force_on()
|
||||
.set_bit()
|
||||
});
|
||||
|
||||
#[cfg(esp32s3)]
|
||||
{
|
||||
let rtc = &*pac::RTC_CNTL::PTR;
|
||||
rtc.usb_conf
|
||||
.modify(|_, w| w.sw_hw_usb_phy_sel().set_bit().sw_usb_phy_sel().set_bit());
|
||||
}
|
||||
|
||||
crate::gpio::connect_high_to_peripheral(InputSignal::USB_OTG_IDDIG); // connected connector is mini-B side
|
||||
crate::gpio::connect_high_to_peripheral(InputSignal::USB_SRP_BVALID); // HIGH to force USB device mode
|
||||
crate::gpio::connect_high_to_peripheral(InputSignal::USB_OTG_VBUSVALID); // receiving a valid Vbus from device
|
||||
crate::gpio::connect_low_to_peripheral(InputSignal::USB_OTG_AVALID);
|
||||
|
||||
usb_wrap.otg_conf.modify(|_, w| {
|
||||
w.pad_pull_override()
|
||||
.set_bit()
|
||||
.dp_pullup()
|
||||
.set_bit()
|
||||
.dp_pulldown()
|
||||
.clear_bit()
|
||||
.dm_pullup()
|
||||
.clear_bit()
|
||||
.dm_pulldown()
|
||||
.clear_bit()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn ahb_frequency_hz(&self) -> u32 {
|
||||
// unused
|
||||
80_000_000
|
||||
}
|
||||
}
|
@ -30,6 +30,8 @@ pub enum Peripheral {
|
||||
Gdma,
|
||||
#[cfg(any(esp32, esp32s2))]
|
||||
Dma,
|
||||
#[cfg(any(esp32s2, esp32s3))]
|
||||
Usb,
|
||||
}
|
||||
|
||||
/// Controls the enablement of peripheral clocks.
|
||||
@ -106,6 +108,11 @@ impl PeripheralClockControl {
|
||||
perip_clk_en0.modify(|_, w| w.spi3_dma_clk_en().set_bit());
|
||||
perip_rst_en0.modify(|_, w| w.spi3_dma_rst().clear_bit());
|
||||
}
|
||||
#[cfg(any(esp32s2, esp32s3))]
|
||||
Peripheral::Usb => {
|
||||
perip_clk_en0.modify(|_, w| w.usb_clk_en().set_bit());
|
||||
perip_rst_en0.modify(|_, w| w.usb_rst().clear_bit());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,8 @@ esp-backtrace = { version = "0.2.0", features = ["esp32s2", "panic-handler",
|
||||
esp-println = { version = "0.3.0", features = ["esp32s2"] }
|
||||
smart-leds = "0.3.0"
|
||||
ssd1306 = "0.7.1"
|
||||
usb-device = { version = "0.2.3" }
|
||||
usbd-serial = "0.1.1"
|
||||
|
||||
[features]
|
||||
default = ["rt", "vectored"]
|
||||
|
87
esp32s2-hal/examples/usb_serial.rs
Normal file
87
esp32s2-hal/examples/usb_serial.rs
Normal file
@ -0,0 +1,87 @@
|
||||
//! CDC-ACM serial port example using polling in a busy loop.
|
||||
//!
|
||||
//! This example should be built in release mode.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use esp32s2_hal::{
|
||||
clock::{ClockControl, CpuClock},
|
||||
otg_fs::{UsbBus, USB},
|
||||
pac::Peripherals,
|
||||
prelude::*,
|
||||
timer::TimerGroup,
|
||||
Rtc,
|
||||
IO,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use usb_device::prelude::{UsbDeviceBuilder, UsbVidPid};
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut EP_MEMORY: [u32; 1024] = [0; 1024];
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let peripherals = Peripherals::take().unwrap();
|
||||
let mut system = peripherals.SYSTEM.split();
|
||||
let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock240MHz).freeze();
|
||||
|
||||
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
|
||||
let mut wdt = timer_group0.wdt;
|
||||
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
|
||||
// Disable MWDT and RWDT (Watchdog) flash boot protection
|
||||
wdt.disable();
|
||||
rtc.rwdt.disable();
|
||||
|
||||
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
let usb = USB::new(
|
||||
peripherals.USB0,
|
||||
io.pins.gpio18,
|
||||
io.pins.gpio19,
|
||||
io.pins.gpio20,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
|
||||
let usb_bus = UsbBus::new(usb, unsafe { &mut EP_MEMORY });
|
||||
|
||||
let mut serial = usbd_serial::SerialPort::new(&usb_bus);
|
||||
|
||||
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
|
||||
.manufacturer("esp-hal")
|
||||
.product("esp-hal")
|
||||
.serial_number("12345678")
|
||||
.device_class(usbd_serial::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 => {
|
||||
// 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;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
@ -83,3 +83,8 @@ analog! {
|
||||
Gpio20: (20, rtc_pad20, rtc_pad20_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio21: (21, rtc_pad21, rtc_pad21_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
}
|
||||
|
||||
// implement marker traits on USB pins
|
||||
impl<T> esp_hal_common::otg_fs::UsbSel for Gpio18<T> {}
|
||||
impl<T> esp_hal_common::otg_fs::UsbDp for Gpio19<T> {}
|
||||
impl<T> esp_hal_common::otg_fs::UsbDm for Gpio20<T> {}
|
||||
|
@ -11,6 +11,7 @@ pub use esp_hal_common::{
|
||||
interrupt,
|
||||
ledc,
|
||||
macros,
|
||||
otg_fs,
|
||||
pac,
|
||||
prelude,
|
||||
pulse_control,
|
||||
|
@ -41,6 +41,8 @@ esp-backtrace = { version = "0.2.0", features = ["esp32s3", "panic-handler",
|
||||
esp-println = { version = "0.3.0", features = ["esp32s3"] }
|
||||
smart-leds = "0.3.0"
|
||||
ssd1306 = "0.7.1"
|
||||
usb-device = { version = "0.2.3" }
|
||||
usbd-serial = "0.1.1"
|
||||
|
||||
[features]
|
||||
default = ["rt", "vectored"]
|
||||
|
87
esp32s3-hal/examples/usb_serial.rs
Normal file
87
esp32s3-hal/examples/usb_serial.rs
Normal file
@ -0,0 +1,87 @@
|
||||
//! CDC-ACM serial port example using polling in a busy loop.
|
||||
//!
|
||||
//! This example should be built in release mode.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use esp32s3_hal::{
|
||||
clock::{ClockControl, CpuClock},
|
||||
otg_fs::{UsbBus, USB},
|
||||
pac::Peripherals,
|
||||
prelude::*,
|
||||
timer::TimerGroup,
|
||||
Rtc,
|
||||
IO,
|
||||
};
|
||||
use esp_backtrace as _;
|
||||
use usb_device::prelude::{UsbDeviceBuilder, UsbVidPid};
|
||||
use xtensa_lx_rt::entry;
|
||||
|
||||
static mut EP_MEMORY: [u32; 1024] = [0; 1024];
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let peripherals = Peripherals::take().unwrap();
|
||||
let mut system = peripherals.SYSTEM.split();
|
||||
let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock240MHz).freeze();
|
||||
|
||||
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
|
||||
let mut wdt = timer_group0.wdt;
|
||||
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
|
||||
// Disable MWDT and RWDT (Watchdog) flash boot protection
|
||||
wdt.disable();
|
||||
rtc.rwdt.disable();
|
||||
|
||||
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
let usb = USB::new(
|
||||
peripherals.USB0,
|
||||
io.pins.gpio18,
|
||||
io.pins.gpio19,
|
||||
io.pins.gpio20,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
|
||||
let usb_bus = UsbBus::new(usb, unsafe { &mut EP_MEMORY });
|
||||
|
||||
let mut serial = usbd_serial::SerialPort::new(&usb_bus);
|
||||
|
||||
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
|
||||
.manufacturer("esp-hal")
|
||||
.product("esp-hal")
|
||||
.serial_number("12345678")
|
||||
.device_class(usbd_serial::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 => {
|
||||
// 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;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
@ -88,3 +88,8 @@ analog! {
|
||||
Gpio20: (20, rtc_pad20, rtc_pad20_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
Gpio21: (21, rtc_pad21, rtc_pad21_hold, mux_sel, fun_sel, fun_ie, slp_ie, slp_sel, rue, rde, drv, slp_oe),
|
||||
}
|
||||
|
||||
// implement marker traits on USB pins
|
||||
impl<T> esp_hal_common::otg_fs::UsbSel for Gpio18<T> {}
|
||||
impl<T> esp_hal_common::otg_fs::UsbDp for Gpio19<T> {}
|
||||
impl<T> esp_hal_common::otg_fs::UsbDm for Gpio20<T> {}
|
||||
|
@ -13,6 +13,7 @@ pub use esp_hal_common::{
|
||||
interrupt,
|
||||
ledc,
|
||||
macros,
|
||||
otg_fs,
|
||||
pac,
|
||||
prelude,
|
||||
pulse_control,
|
||||
|
Loading…
x
Reference in New Issue
Block a user