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