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 ep_addr: Option<EndpointAddress>,
217 max_packet_size: u16,
218 interval_ms: u8,
219 ) -> Result<Self::EndpointIn, EndpointAllocError> {
220 self.inner
221 .alloc_endpoint_in(ep_type, ep_addr, max_packet_size, interval_ms)
222 }
223
224 fn alloc_endpoint_out(
225 &mut self,
226 ep_type: EndpointType,
227 ep_addr: Option<EndpointAddress>,
228 max_packet_size: u16,
229 interval_ms: u8,
230 ) -> Result<Self::EndpointOut, EndpointAllocError> {
231 self.inner
232 .alloc_endpoint_out(ep_type, ep_addr, max_packet_size, interval_ms)
233 }
234
235 fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
236 let (bus, cp) = self.inner.start(control_max_packet_size);
237
238 let mut bus = Bus {
239 inner: bus,
240 _usb: self._usb,
241 };
242
243 bus.init();
244
245 (bus, cp)
246 }
247 }
248
249 pub struct Bus<'d> {
252 inner: OtgBus<'d, MAX_EP_COUNT>,
253 _usb: Usb<'d>,
254 }
255
256 impl Bus<'_> {
257 fn init(&mut self) {
258 Usb::_enable();
259
260 let r = Driver::REGISTERS;
261
262 while !r.grstctl().read().ahbidl() {}
264
265 r.gusbcfg().modify(|w| {
267 w.set_fdmod(true);
269 w.set_srpcap(false);
270 });
271
272 while !r.grstctl().read().ahbidl() {}
274 r.grstctl().modify(|w| w.set_csrst(true));
275 while r.grstctl().read().csrst() {}
276
277 self.inner.config_v1();
278
279 r.pcgcctl().write(|w| w.0 = 0);
281
282 unsafe {
283 crate::interrupt::bind_interrupt(
284 crate::peripherals::Interrupt::USB,
285 interrupt_handler.handler(),
286 );
287 }
288 unwrap!(crate::interrupt::enable(
289 crate::peripherals::Interrupt::USB,
290 interrupt_handler.priority(),
291 ));
292 }
293
294 fn disable(&mut self) {
295 crate::interrupt::disable(Cpu::ProCpu, peripherals::Interrupt::USB);
296
297 #[cfg(multi_core)]
298 crate::interrupt::disable(Cpu::AppCpu, peripherals::Interrupt::USB);
299
300 Usb::_disable();
301 }
302 }
303
304 impl embassy_usb_driver::Bus for Bus<'_> {
305 async fn poll(&mut self) -> Event {
306 self.inner.poll().await
307 }
308
309 fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) {
310 self.inner.endpoint_set_stalled(ep_addr, stalled)
311 }
312
313 fn endpoint_is_stalled(&mut self, ep_addr: EndpointAddress) -> bool {
314 self.inner.endpoint_is_stalled(ep_addr)
315 }
316
317 fn endpoint_set_enabled(&mut self, ep_addr: EndpointAddress, enabled: bool) {
318 self.inner.endpoint_set_enabled(ep_addr, enabled)
319 }
320
321 async fn enable(&mut self) {
322 self.inner.enable().await
323 }
324
325 async fn disable(&mut self) {
326 self.inner.disable().await
327 }
328
329 async fn remote_wakeup(&mut self) -> Result<(), Unsupported> {
330 self.inner.remote_wakeup().await
331 }
332 }
333
334 impl Drop for Bus<'_> {
335 fn drop(&mut self) {
336 Bus::disable(self);
337 }
338 }
339
340 #[handler(priority = crate::interrupt::Priority::max())]
341 fn interrupt_handler() {
342 unsafe { on_interrupt(Driver::REGISTERS, &STATE, Usb::ENDPOINT_COUNT) }
343 }
344}