1use crate::endpoint_memory::{EndpointBuffer, EndpointBufferState};
2use crate::ral::{endpoint0_out, endpoint_in, endpoint_out, modify_reg, read_reg, write_reg};
3use crate::target::{fifo_write, UsbRegisters};
4use crate::transition::EndpointDescriptor;
5use crate::UsbPeripheral;
6use core::cell::RefCell;
7use core::ops::{Deref, DerefMut};
8use critical_section::{CriticalSection, Mutex};
9use usb_device::endpoint::EndpointAddress;
10use usb_device::{Result, UsbDirection, UsbError};
11
12pub fn set_stalled(usb: UsbRegisters, address: EndpointAddress, stalled: bool) {
13 critical_section::with(|_| match address.direction() {
14 UsbDirection::Out => {
15 let ep = usb.endpoint_out(address.index() as usize);
16 modify_reg!(endpoint_out, ep, DOEPCTL, STALL: stalled as u32);
17 }
18 UsbDirection::In => {
19 let ep = usb.endpoint_in(address.index() as usize);
20 modify_reg!(endpoint_in, ep, DIEPCTL, STALL: stalled as u32);
21 }
22 })
23}
24
25pub fn is_stalled(usb: UsbRegisters, address: EndpointAddress) -> bool {
26 let stall = match address.direction() {
27 UsbDirection::Out => {
28 let ep = usb.endpoint_out(address.index());
29 read_reg!(endpoint_out, ep, DOEPCTL, STALL)
30 }
31 UsbDirection::In => {
32 let ep = usb.endpoint_in(address.index());
33 read_reg!(endpoint_in, ep, DIEPCTL, STALL)
34 }
35 };
36 stall != 0
37}
38
39pub struct Endpoint {
41 descriptor: EndpointDescriptor,
42 usb: UsbRegisters,
43}
44
45impl Endpoint {
46 pub fn new<USB: UsbPeripheral>(descriptor: EndpointDescriptor) -> Endpoint {
47 Endpoint {
48 descriptor,
49 usb: UsbRegisters::new::<USB>(),
50 }
51 }
52
53 pub fn address(&self) -> EndpointAddress {
54 self.descriptor.address
55 }
56
57 #[inline(always)]
58 fn index(&self) -> u8 {
59 self.descriptor.address.index() as u8
60 }
61}
62
63pub struct EndpointIn {
64 common: Endpoint,
65}
66
67impl EndpointIn {
68 pub fn new<USB: UsbPeripheral>(descriptor: EndpointDescriptor) -> EndpointIn {
69 EndpointIn {
70 common: Endpoint::new::<USB>(descriptor),
71 }
72 }
73
74 pub fn configure(&self, _cs: CriticalSection<'_>) {
75 if self.index() == 0 {
76 let mpsiz = match self.descriptor.max_packet_size {
77 8 => 0b11,
78 16 => 0b10,
79 32 => 0b01,
80 64 => 0b00,
81 other => panic!("Unsupported EP0 size: {}", other),
82 };
83
84 let regs = self.usb.endpoint_in(self.index() as usize);
85 write_reg!(endpoint_in, regs, DIEPCTL, MPSIZ: mpsiz as u32, SNAK: 1);
86 write_reg!(endpoint_in, regs, DIEPTSIZ, PKTCNT: 0, XFRSIZ: self.descriptor.max_packet_size as u32);
87 } else {
88 let regs = self.usb.endpoint_in(self.index() as usize);
89 write_reg!(endpoint_in, regs, DIEPCTL,
90 SNAK: 1,
91 USBAEP: 1,
92 EPTYP: self.descriptor.ep_type.to_bm_attributes() as u32,
93 SD0PID_SEVNFRM: 1,
94 TXFNUM: self.index() as u32,
95 MPSIZ: self.descriptor.max_packet_size as u32
96 );
97 }
98 }
99
100 pub fn deconfigure(&self, _cs: CriticalSection<'_>) {
101 let regs = self.usb.endpoint_in(self.index() as usize);
102
103 modify_reg!(endpoint_in, regs, DIEPCTL, USBAEP: 0);
105
106 if read_reg!(endpoint_in, regs, DIEPCTL, EPENA) != 0 && self.index() != 0 {
110 modify_reg!(endpoint_in, regs, DIEPCTL, EPDIS: 1)
111 }
112
113 write_reg!(endpoint_in, regs, DIEPINT, 0xff);
115
116 }
118
119 pub fn write(&self, buf: &[u8]) -> Result<()> {
120 let ep = self.usb.endpoint_in(self.index() as usize);
121 if self.index() != 0 && read_reg!(endpoint_in, ep, DIEPCTL, EPENA) != 0 {
122 return Err(UsbError::WouldBlock);
123 }
124
125 if buf.len() > self.descriptor.max_packet_size as usize {
126 return Err(UsbError::BufferOverflow);
127 }
128
129 if !buf.is_empty() {
130 let size_words = (buf.len() + 3) / 4;
132 if size_words > read_reg!(endpoint_in, ep, DTXFSTS, INEPTFSAV) as usize {
133 return Err(UsbError::WouldBlock);
134 }
135 }
136
137 #[cfg(feature = "fs")]
138 write_reg!(endpoint_in, ep, DIEPTSIZ, PKTCNT: 1, XFRSIZ: buf.len() as u32);
139 #[cfg(feature = "hs")]
140 write_reg!(endpoint_in, ep, DIEPTSIZ, MCNT: 1, PKTCNT: 1, XFRSIZ: buf.len() as u32);
141
142 modify_reg!(endpoint_in, ep, DIEPCTL, CNAK: 1, EPENA: 1);
143
144 fifo_write(self.usb, self.index(), buf);
145
146 Ok(())
147 }
148}
149
150pub struct EndpointOut {
151 common: Endpoint,
152 pub(crate) buffer: Mutex<RefCell<EndpointBuffer>>,
153}
154
155impl EndpointOut {
156 pub fn new<USB: UsbPeripheral>(
157 descriptor: EndpointDescriptor,
158 buffer: EndpointBuffer,
159 ) -> EndpointOut {
160 EndpointOut {
161 common: Endpoint::new::<USB>(descriptor),
162 buffer: Mutex::new(RefCell::new(buffer)),
163 }
164 }
165
166 pub fn configure(&self, _cs: CriticalSection<'_>) {
167 if self.index() == 0 {
168 let mpsiz = match self.descriptor.max_packet_size {
169 8 => 0b11,
170 16 => 0b10,
171 32 => 0b01,
172 64 => 0b00,
173 other => panic!("Unsupported EP0 size: {}", other),
174 };
175
176 let regs = self.usb.endpoint0_out();
177 write_reg!(endpoint0_out, regs, DOEPTSIZ0, STUPCNT: 1, PKTCNT: 1, XFRSIZ: self.descriptor.max_packet_size as u32);
178 modify_reg!(endpoint0_out, regs, DOEPCTL0, MPSIZ: mpsiz as u32, EPENA: 1, CNAK: 1);
179 } else {
180 let regs = self.usb.endpoint_out(self.index() as usize);
181 write_reg!(endpoint_out, regs, DOEPCTL,
182 SD0PID_SEVNFRM: 1,
183 CNAK: 1,
184 EPENA: 1,
185 USBAEP: 1,
186 EPTYP: self.descriptor.ep_type.to_bm_attributes() as u32,
187 MPSIZ: self.descriptor.max_packet_size as u32
188 );
189 }
190 }
191
192 pub fn deconfigure(&self, _cs: CriticalSection<'_>, core_id: u32) {
193 let regs = self.usb.endpoint_out(self.index() as usize);
194
195 if core_id > 0x0000_1000 {
197 modify_reg!(endpoint_out, regs, DOEPCTL, USBAEP: 0);
199
200 if read_reg!(endpoint_out, regs, DOEPCTL, EPENA) != 0 && self.index() != 0 {
202 modify_reg!(endpoint_out, regs, DOEPCTL, EPDIS: 1)
203 }
204 }
205
206 write_reg!(endpoint_out, regs, DOEPINT, 0xff);
208 }
209
210 pub fn read(&self, buf: &mut [u8]) -> Result<usize> {
211 critical_section::with(|cs| self.buffer.borrow_ref_mut(cs).read_packet(buf))
212 }
213
214 pub fn buffer_state(&self) -> EndpointBufferState {
215 critical_section::with(|cs| self.buffer.borrow_ref(cs).state())
216 }
217}
218
219impl Deref for EndpointIn {
220 type Target = Endpoint;
221
222 fn deref(&self) -> &Self::Target {
223 &self.common
224 }
225}
226
227impl DerefMut for EndpointIn {
228 fn deref_mut(&mut self) -> &mut Self::Target {
229 &mut self.common
230 }
231}
232
233impl Deref for EndpointOut {
234 type Target = Endpoint;
235
236 fn deref(&self) -> &Self::Target {
237 &self.common
238 }
239}
240
241impl DerefMut for EndpointOut {
242 fn deref_mut(&mut self) -> &mut Self::Target {
243 &mut self.common
244 }
245}