1pub use esp_synopsys_usb_otg::UsbBus;
40use esp_synopsys_usb_otg::UsbPeripheral;
41
42use crate::{
43 gpio::InputSignal,
44 peripherals,
45 system::{GenericPeripheralGuard, Peripheral as PeripheralEnable},
46};
47
48#[doc(hidden)]
49pub trait UsbDp: crate::private::Sealed {}
51
52#[doc(hidden)]
53pub trait UsbDm: crate::private::Sealed {}
55
56for_each_analog_function! {
57 (USB_DM, $gpio:ident) => {
58 impl UsbDm for crate::peripherals::$gpio<'_> {}
59 };
60 (USB_DP, $gpio:ident) => {
61 impl UsbDp for crate::peripherals::$gpio<'_> {}
62 };
63}
64
65pub struct Usb<'d> {
67 _usb0: peripherals::USB0<'d>,
68 _guard: GenericPeripheralGuard<{ PeripheralEnable::Usb as u8 }>,
69}
70
71impl<'d> Usb<'d> {
72 pub fn new(
74 usb0: peripherals::USB0<'d>,
75 _usb_dp: impl UsbDp + 'd,
76 _usb_dm: impl UsbDm + 'd,
77 ) -> Self {
78 let guard = GenericPeripheralGuard::new();
79
80 Self {
81 _usb0: usb0,
82 _guard: guard,
83 }
84 }
85
86 fn _enable() {
87 peripherals::USB_WRAP::regs().otg_conf().modify(|_, w| {
88 w.usb_pad_enable().set_bit();
89 w.phy_sel().clear_bit();
90 w.clk_en().set_bit();
91 w.ahb_clk_force_on().set_bit();
92 w.phy_clk_force_on().set_bit()
93 });
94
95 #[cfg(esp32s3)]
96 peripherals::LPWR::regs().usb_conf().modify(|_, w| {
97 w.sw_hw_usb_phy_sel().set_bit();
98 w.sw_usb_phy_sel().set_bit()
99 });
100
101 use crate::gpio::Level;
102
103 InputSignal::USB_OTG_IDDIG.connect_to(&Level::High); InputSignal::USB_SRP_BVALID.connect_to(&Level::High); InputSignal::USB_OTG_VBUSVALID.connect_to(&Level::High); InputSignal::USB_OTG_AVALID.connect_to(&Level::Low);
107 }
108
109 fn _disable() {
110 }
112}
113
114unsafe impl Sync for Usb<'_> {}
115
116unsafe impl UsbPeripheral for Usb<'_> {
117 const REGISTERS: *const () = peripherals::USB0::PTR.cast();
118
119 const HIGH_SPEED: bool = false;
120 const FIFO_DEPTH_WORDS: usize = 256;
121 const ENDPOINT_COUNT: usize = 5;
122
123 fn enable() {
124 Self::_enable();
125 }
126
127 fn ahb_frequency_hz(&self) -> u32 {
128 80_000_000
130 }
131}
132pub mod asynch {
134 use embassy_usb_driver::{
135 EndpointAddress,
136 EndpointAllocError,
137 EndpointType,
138 Event,
139 Unsupported,
140 };
141 pub use embassy_usb_synopsys_otg::Config;
142 use embassy_usb_synopsys_otg::{
143 Bus as OtgBus,
144 ControlPipe,
145 Driver as OtgDriver,
146 Endpoint,
147 In,
148 OtgInstance,
149 Out,
150 PhyType,
151 State,
152 on_interrupt,
153 otg_v1::Otg,
154 };
155 use procmacros::handler;
156
157 use super::*;
158 use crate::system::Cpu;
159
160 const MAX_EP_COUNT: usize = 7;
163
164 static STATE: State<MAX_EP_COUNT> = State::new();
165
166 pub struct Driver<'d> {
168 inner: OtgDriver<'d, MAX_EP_COUNT>,
169 _usb: Usb<'d>,
170 }
171
172 impl<'d> Driver<'d> {
173 const REGISTERS: Otg = unsafe { Otg::from_ptr(Usb::REGISTERS.cast_mut()) };
174
175 pub fn new(peri: Usb<'d>, ep_out_buffer: &'d mut [u8], config: Config) -> Self {
185 const RX_FIFO_EXTRA_SIZE_WORDS: u16 = 30;
190
191 let instance = OtgInstance {
192 regs: Self::REGISTERS,
193 state: &STATE,
194 fifo_depth_words: Usb::FIFO_DEPTH_WORDS as u16,
195 extra_rx_fifo_words: RX_FIFO_EXTRA_SIZE_WORDS,
196 endpoint_count: Usb::ENDPOINT_COUNT,
197 phy_type: PhyType::InternalFullSpeed,
198 calculate_trdt_fn: |_| 5,
199 };
200 Self {
201 inner: OtgDriver::new(ep_out_buffer, instance, config),
202 _usb: peri,
203 }
204 }
205 }
206
207 impl<'d> embassy_usb_driver::Driver<'d> for Driver<'d> {
208 type EndpointOut = Endpoint<'d, Out>;
209 type EndpointIn = Endpoint<'d, In>;
210 type ControlPipe = ControlPipe<'d>;
211 type Bus = Bus<'d>;
212
213 fn alloc_endpoint_in(
214 &mut self,
215 ep_type: EndpointType,
216 max_packet_size: u16,
217 interval_ms: u8,
218 ) -> Result<Self::EndpointIn, EndpointAllocError> {
219 self.inner
220 .alloc_endpoint_in(ep_type, max_packet_size, interval_ms)
221 }
222
223 fn alloc_endpoint_out(
224 &mut self,
225 ep_type: EndpointType,
226 max_packet_size: u16,
227 interval_ms: u8,
228 ) -> Result<Self::EndpointOut, EndpointAllocError> {
229 self.inner
230 .alloc_endpoint_out(ep_type, max_packet_size, interval_ms)
231 }
232
233 fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
234 let (bus, cp) = self.inner.start(control_max_packet_size);
235
236 let mut bus = Bus {
237 inner: bus,
238 _usb: self._usb,
239 };
240
241 bus.init();
242
243 (bus, cp)
244 }
245 }
246
247 pub struct Bus<'d> {
250 inner: OtgBus<'d, MAX_EP_COUNT>,
251 _usb: Usb<'d>,
252 }
253
254 impl Bus<'_> {
255 fn init(&mut self) {
256 Usb::_enable();
257
258 let r = Driver::REGISTERS;
259
260 while !r.grstctl().read().ahbidl() {}
262
263 r.gusbcfg().modify(|w| {
265 w.set_fdmod(true);
267 w.set_srpcap(false);
268 });
269
270 while !r.grstctl().read().ahbidl() {}
272 r.grstctl().modify(|w| w.set_csrst(true));
273 while r.grstctl().read().csrst() {}
274
275 self.inner.config_v1();
276
277 r.pcgcctl().write(|w| w.0 = 0);
279
280 unsafe {
281 crate::interrupt::bind_interrupt(
282 crate::peripherals::Interrupt::USB,
283 interrupt_handler.handler(),
284 );
285 }
286 unwrap!(crate::interrupt::enable(
287 crate::peripherals::Interrupt::USB,
288 interrupt_handler.priority(),
289 ));
290 }
291
292 fn disable(&mut self) {
293 crate::interrupt::disable(Cpu::ProCpu, peripherals::Interrupt::USB);
294
295 #[cfg(multi_core)]
296 crate::interrupt::disable(Cpu::AppCpu, peripherals::Interrupt::USB);
297
298 Usb::_disable();
299 }
300 }
301
302 impl embassy_usb_driver::Bus for Bus<'_> {
303 async fn poll(&mut self) -> Event {
304 self.inner.poll().await
305 }
306
307 fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) {
308 self.inner.endpoint_set_stalled(ep_addr, stalled)
309 }
310
311 fn endpoint_is_stalled(&mut self, ep_addr: EndpointAddress) -> bool {
312 self.inner.endpoint_is_stalled(ep_addr)
313 }
314
315 fn endpoint_set_enabled(&mut self, ep_addr: EndpointAddress, enabled: bool) {
316 self.inner.endpoint_set_enabled(ep_addr, enabled)
317 }
318
319 async fn enable(&mut self) {
320 self.inner.enable().await
321 }
322
323 async fn disable(&mut self) {
324 self.inner.disable().await
325 }
326
327 async fn remote_wakeup(&mut self) -> Result<(), Unsupported> {
328 self.inner.remote_wakeup().await
329 }
330 }
331
332 impl Drop for Bus<'_> {
333 fn drop(&mut self) {
334 Bus::disable(self);
335 }
336 }
337
338 #[handler(priority = crate::interrupt::Priority::max())]
339 fn interrupt_handler() {
340 unsafe { on_interrupt(Driver::REGISTERS, &STATE, Usb::ENDPOINT_COUNT) }
341 }
342}