aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorkorbin <[email protected]>2025-07-13 22:44:48 -0600
committerkorbin <[email protected]>2025-07-13 22:44:48 -0600
commit93e2fdf51267f112adf0c14ccb7b46eb51edd48c (patch)
tree44468210395e05189dee35f54e142aee7d2fcc51 /embassy-stm32
parentb666a88ab175043d711c97b67b5b4d3bf409f102 (diff)
consolidate endpoint validation logic in stm32
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/src/usb/usb.rs78
1 files changed, 32 insertions, 46 deletions
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs
index 05c28aceb..92c1601cc 100644
--- a/embassy-stm32/src/usb/usb.rs
+++ b/embassy-stm32/src/usb/usb.rs
@@ -359,6 +359,34 @@ impl<'d, T: Instance> Driver<'d, T> {
359 addr 359 addr
360 } 360 }
361 361
362 fn is_endpoint_available<D: Dir>(&self, index: usize, ep_type: EndpointType) -> bool {
363 if index == 0 && ep_type != EndpointType::Control {
364 return false; // EP0 is reserved for control
365 }
366
367 let ep = match self.alloc.get(index) {
368 Some(ep) => ep,
369 None => return false,
370 };
371
372 let used = ep.used_out || ep.used_in;
373
374 if used && ep.ep_type == EndpointType::Isochronous {
375 // Isochronous endpoints are always double-buffered.
376 // Their corresponding endpoint/channel registers are forced to be unidirectional.
377 // Do not reuse this index.
378 // FIXME: Bulk endpoints can be double buffered, but are not in the current implementation.
379 return false;
380 }
381
382 let used_dir = match D::dir() {
383 Direction::Out => ep.used_out,
384 Direction::In => ep.used_in,
385 };
386
387 !used || (ep.ep_type == ep_type && !used_dir)
388 }
389
362 fn alloc_endpoint<D: Dir>( 390 fn alloc_endpoint<D: Dir>(
363 &mut self, 391 &mut self,
364 ep_type: EndpointType, 392 ep_type: EndpointType,
@@ -376,57 +404,15 @@ impl<'d, T: Instance> Driver<'d, T> {
376 404
377 let index = if let Some(addr) = ep_addr { 405 let index = if let Some(addr) = ep_addr {
378 // Use the specified endpoint address 406 // Use the specified endpoint address
379 let requested_index = addr.index(); 407 self.is_endpoint_available::<D>(addr.index(), ep_type)
380 if requested_index >= EP_COUNT { 408 .then_some(addr.index())
381 return Err(EndpointAllocError);
382 }
383 if requested_index == 0 && ep_type != EndpointType::Control {
384 return Err(EndpointAllocError); // EP0 is reserved for control
385 }
386
387 let ep = &self.alloc[requested_index];
388 let used = ep.used_out || ep.used_in;
389 if used && (ep.ep_type == EndpointType::Isochronous) {
390 // Isochronous endpoints are always double-buffered.
391 // Their corresponding endpoint/channel registers are forced to be unidirectional.
392 // Do not reuse this index.
393 return Err(EndpointAllocError);
394 }
395
396 let used_dir = match D::dir() {
397 Direction::Out => ep.used_out,
398 Direction::In => ep.used_in,
399 };
400 if used && (ep.ep_type != ep_type || used_dir) {
401 return Err(EndpointAllocError);
402 }
403
404 Some((requested_index, &mut self.alloc[requested_index]))
405 } else { 409 } else {
406 // Find any available endpoint 410 // Find any available endpoint
407 self.alloc.iter_mut().enumerate().find(|(i, ep)| { 411 (0..self.alloc.len()).find(|&i| self.is_endpoint_available::<D>(i, ep_type))
408 if *i == 0 && ep_type != EndpointType::Control {
409 return false; // reserved for control pipe
410 }
411 let used = ep.used_out || ep.used_in;
412 if used && (ep.ep_type == EndpointType::Isochronous) {
413 // Isochronous endpoints are always double-buffered.
414 // Their corresponding endpoint/channel registers are forced to be unidirectional.
415 // Do not reuse this index.
416 // FIXME: Bulk endpoints can be double buffered, but are not in the current implementation.
417 return false;
418 }
419
420 let used_dir = match D::dir() {
421 Direction::Out => ep.used_out,
422 Direction::In => ep.used_in,
423 };
424 !used || (ep.ep_type == ep_type && !used_dir)
425 })
426 }; 412 };
427 413
428 let (index, ep) = match index { 414 let (index, ep) = match index {
429 Some(x) => x, 415 Some(i) => (i, &mut self.alloc[i]),
430 None => return Err(EndpointAllocError), 416 None => return Err(EndpointAllocError),
431 }; 417 };
432 418