sifli_hal/
usb.rs

1/// Universal Serial Bus (USB)
2///
3/// See more: https://github.com/decaday/musb
4use core::marker::PhantomData;
5
6use embassy_usb_driver::{self as driver, EndpointAddress, EndpointType};
7use musb::MusbInstance;
8use musb::{Bus, ControlPipe, Endpoint, In, MusbDriver, Out, UsbInstance};
9
10use crate::gpio::hpsys::HpsysPin;
11use crate::pac::HPSYS_CFG;
12use crate::interrupt::typelevel::Interrupt;
13use crate::rcc::{get_clk_usb_div, get_clk_usb_source, RccEnableReset, RccGetFreq};
14use crate::{interrupt, Peripheral};
15
16fn init<T: Instance>() {
17    let freq = T::frequency();
18    if let Some(f) = freq {
19        if f.0 != 60_000_000 {
20            panic!(
21                "USB clock must be 60MHz, clock is {:?}, clock source:{:?}, div:{}", 
22                freq, 
23                get_clk_usb_source(), 
24                get_clk_usb_div()
25            );
26        }
27    } else {
28        panic!("USB clock is not configured, clock source:{:?}", 
29            get_clk_usb_source()
30        );
31    }
32    // rcc::enable_and_reset::<T>();
33    T::rcc_enable();
34
35    // 58: TODO
36    // 52 & 56
37    HPSYS_CFG.usbcr().modify(|w| {
38        w.set_dm_pd(true);
39        w.set_dp_en(true);
40        w.set_usb_en(true);
41    });
42
43    // Enable USB PHY
44    UsbInstance::regs().usbcfg().modify(|w| {
45        w.set_avalid(true);
46        w.set_avalid_dr(true);
47        // w.set_usb_en(true);
48    });
49
50    musb::common_impl::endpoints_set_rx_dualpacket_enabled::<UsbInstance>(0x00);
51    musb::common_impl::endpoints_set_tx_dualpacket_enabled::<UsbInstance>(0x00);
52
53    T::Interrupt::unpend();
54    unsafe { T::Interrupt::enable() };
55
56    HPSYS_CFG.usbcr().modify(|w| {
57        w.set_usb_en(true);
58    });
59
60    // info!("USB power {:b}", UsbInstance::regs().power().read().0);
61
62    UsbInstance::regs().power().modify(|w| {
63        w.set_hs_enab(false);
64    });
65
66    UsbInstance::regs().power().modify(|w| {
67        w.set_soft_conn(true);
68    });
69
70    // UsbInstance::regs().devctl().modify(|w| {
71    //     w.set_session(true);
72    // });
73
74    UsbInstance::regs().index().write(|w| w.set_index(0));
75
76    // TODO: Should this?
77    // crate::blocking_delay_us(1000);
78}
79
80/// USB driver.
81pub struct Driver<'d, T: Instance> {
82    phantom: PhantomData<&'d mut T>,
83    inner: MusbDriver<'d, UsbInstance>,
84}
85
86impl<'d, T: Instance> Driver<'d, T> {
87    /// Create a new USB driver.
88    pub fn new(
89        _usb: impl Peripheral<P = T> + 'd,
90        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
91        dp: impl Peripheral<P = impl DpPin<T>> + 'd,
92        dm: impl Peripheral<P = impl DmPin<T>> + 'd,
93    ) -> Self {
94        let mut dm = HpsysPin::new(dm.into_ref().pin_bank());
95        dm.disable_interrupt();
96        dm.set_as_analog();
97
98        let mut dp = HpsysPin::new(dp.into_ref().pin_bank());
99        dp.disable_interrupt();
100        dp.set_as_analog();
101        
102        init::<T>();
103        Self {
104            inner: MusbDriver::new(),
105            phantom: PhantomData,
106        }
107    }
108}
109
110impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
111    type EndpointOut = Endpoint<'d, UsbInstance, Out>;
112    type EndpointIn = Endpoint<'d, UsbInstance, In>;
113    type ControlPipe = ControlPipe<'d, UsbInstance>;
114    type Bus = Bus<'d, UsbInstance>;
115
116    fn alloc_endpoint_in(
117        &mut self,
118        ep_type: EndpointType,
119        ep_addr: Option<EndpointAddress>,
120        max_packet_size: u16,
121        interval_ms: u8,
122    ) -> Result<Self::EndpointIn, driver::EndpointAllocError> {
123        self.inner
124            .alloc_endpoint(ep_type, ep_addr, max_packet_size, interval_ms)
125    }
126
127    fn alloc_endpoint_out(
128        &mut self,
129        ep_type: EndpointType,
130        ep_addr: Option<EndpointAddress>,
131        max_packet_size: u16,
132        interval_ms: u8,
133    ) -> Result<Self::EndpointOut, driver::EndpointAllocError> {
134        self.inner
135            .alloc_endpoint(ep_type, ep_addr, max_packet_size, interval_ms)
136    }
137
138    fn start(
139        self,
140        control_max_packet_size: u16,
141    ) -> (Bus<'d, UsbInstance>, ControlPipe<'d, UsbInstance>) {
142        self.inner.start(control_max_packet_size)
143    }
144}
145
146/// Interrupt handler.
147pub struct InterruptHandler<T: Instance> {
148    _phantom: PhantomData<T>,
149}
150
151impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
152    unsafe fn on_interrupt() {
153        musb::on_interrupt::<UsbInstance>();
154    }
155}
156
157trait SealedInstance: RccEnableReset + RccGetFreq {}
158
159/// USB instance trait.
160#[allow(private_bounds)]
161pub trait Instance: SealedInstance + 'static {
162    /// Interrupt for this USB instance.
163    type Interrupt: interrupt::typelevel::Interrupt;
164}
165
166impl SealedInstance for crate::peripherals::USBC {}
167impl Instance for crate::peripherals::USBC {
168    type Interrupt = crate::interrupt::typelevel::USBC;
169}
170
171// Internal PHY pins
172pin_trait!(DpPin, Instance);
173pin_trait!(DmPin, Instance);
174
175// SDK set them to analog.
176// Datasheet shows: PA35 AF2 #USB11_DP
177impl DpPin<crate::peripherals::USBC> for crate::peripherals::PA35 {
178    fn fsel(&self) -> u8 {
179        0x2
180    }
181}
182
183impl DmPin<crate::peripherals::USBC> for crate::peripherals::PA36 {
184    fn fsel(&self) -> u8 {
185        0x2
186    }
187}
188
189
190// impl SealedInstance for  {}