esp_hal/usb/otg/
embassy_usb_device.rs1use embassy_usb_driver::{EndpointAddress, EndpointAllocError, EndpointType, Event, Unsupported};
4pub use embassy_usb_synopsys_otg::Config;
5use embassy_usb_synopsys_otg::{
6 Bus as OtgBus,
7 ControlPipe,
8 Driver as OtgDriver,
9 Endpoint,
10 In,
11 OtgInstance,
12 Out,
13 otg_v1::Otg,
14};
15
16use crate::usb::otg::Usb;
17
18pub struct Driver<'d> {
20 inner: OtgDriver<'d>,
21 _usb: Usb<'d>,
22}
23
24impl<'d> Driver<'d> {
25 pub fn new(peri: Usb<'d>, ep_out_buffer: &'d mut [u8], config: Config) -> Self {
32 let info = peri.info();
33 let instance = OtgInstance {
34 regs: unsafe { Otg::from_ptr(info.register_ptr.cast_mut()) },
35 state: peri.embassy_device_state(),
36 fifo_depth_words: info.fifo_depth_words as u16,
37 extra_rx_fifo_words: info.rx_fifo_extra_words,
38 phy_type: info.phy_type,
39 calculate_trdt_fn: |_| 5,
40 };
41 Self {
42 inner: OtgDriver::new(ep_out_buffer, instance, config),
43 _usb: peri,
44 }
45 }
46}
47
48impl<'d> embassy_usb_driver::Driver<'d> for Driver<'d> {
49 type EndpointOut = Endpoint<'d, Out>;
50 type EndpointIn = Endpoint<'d, In>;
51 type ControlPipe = ControlPipe<'d>;
52 type Bus = Bus<'d>;
53
54 fn alloc_endpoint_in(
55 &mut self,
56 ep_type: EndpointType,
57 ep_addr: Option<EndpointAddress>,
58 max_packet_size: u16,
59 interval_ms: u8,
60 ) -> Result<Self::EndpointIn, EndpointAllocError> {
61 self.inner
62 .alloc_endpoint_in(ep_type, ep_addr, max_packet_size, interval_ms)
63 }
64
65 fn alloc_endpoint_out(
66 &mut self,
67 ep_type: EndpointType,
68 ep_addr: Option<EndpointAddress>,
69 max_packet_size: u16,
70 interval_ms: u8,
71 ) -> Result<Self::EndpointOut, EndpointAllocError> {
72 self.inner
73 .alloc_endpoint_out(ep_type, ep_addr, max_packet_size, interval_ms)
74 }
75
76 fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
77 let (bus, cp) = self.inner.start(control_max_packet_size);
78
79 (
80 Bus {
81 inner: bus,
82 inited: false,
83 _usb: self._usb,
84 },
85 cp,
86 )
87 }
88}
89
90pub struct Bus<'d> {
92 inner: OtgBus<'d>,
93 inited: bool,
94 _usb: Usb<'d>,
95}
96
97impl<'d> Bus<'d> {
98 fn init(&mut self) {
99 let i = self._usb.info();
100 (i.enable_device_mode)();
101
102 let r = unsafe { Otg::from_ptr(i.register_ptr.cast_mut()) };
103
104 self.inner.core_soft_reset();
105
106 self.inner.configure_as_device();
107 self.inner.config_v5();
108
109 r.pcgcctl().write(|w| w.0 = 0);
110
111 self._usb.bind_device_interrupt();
112 }
113
114 fn disable(&mut self) {
115 self._usb.disable_device_interrupt();
116 (self._usb.info().platform_bus_disable_on_drop)();
117 self.inited = false;
118 }
119}
120
121impl<'d> embassy_usb_driver::Bus for Bus<'d> {
122 async fn poll(&mut self) -> Event {
123 if !self.inited {
124 self.init();
125 self.inited = true;
126 }
127
128 self.inner.poll().await
129 }
130
131 fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) {
132 self.inner.endpoint_set_stalled(ep_addr, stalled)
133 }
134
135 fn endpoint_is_stalled(&mut self, ep_addr: EndpointAddress) -> bool {
136 self.inner.endpoint_is_stalled(ep_addr)
137 }
138
139 fn endpoint_set_enabled(&mut self, ep_addr: EndpointAddress, enabled: bool) {
140 self.inner.endpoint_set_enabled(ep_addr, enabled)
141 }
142
143 async fn enable(&mut self) {
144 self.inner.enable().await
145 }
146
147 async fn disable(&mut self) {
148 self.inner.disable().await
149 }
150
151 async fn remote_wakeup(&mut self) -> Result<(), Unsupported> {
152 self.inner.remote_wakeup().await
153 }
154}
155
156impl<'d> Drop for Bus<'d> {
157 fn drop(&mut self) {
158 Bus::disable(self);
159 }
160}