1use 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 T::rcc_enable();
34
35 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 UsbInstance::regs().usbcfg().modify(|w| {
45 w.set_avalid(true);
46 w.set_avalid_dr(true);
47 });
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 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().index().write(|w| w.set_index(0));
75
76 }
79
80pub 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 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
146pub 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#[allow(private_bounds)]
161pub trait Instance: SealedInstance + 'static {
162 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
171pin_trait!(DpPin, Instance);
173pin_trait!(DmPin, Instance);
174
175impl 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