diff options
| author | korbin <[email protected]> | 2025-07-13 20:30:26 -0600 |
|---|---|---|
| committer | korbin <[email protected]> | 2025-07-13 20:40:54 -0600 |
| commit | b666a88ab175043d711c97b67b5b4d3bf409f102 (patch) | |
| tree | 02436ff11d08664b4a12aa9b5f2c915f012ba13d /embassy-stm32/src/usb | |
| parent | 9651cfca51a273ba46d34ce8197fc0e63389b09e (diff) | |
make usb endpoint allocator methods accept an optional EndpointAddress
Diffstat (limited to 'embassy-stm32/src/usb')
| -rw-r--r-- | embassy-stm32/src/usb/otg.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/usb/usb.rs | 56 |
2 files changed, 51 insertions, 13 deletions
diff --git a/embassy-stm32/src/usb/otg.rs b/embassy-stm32/src/usb/otg.rs index 590d1a427..3547ded00 100644 --- a/embassy-stm32/src/usb/otg.rs +++ b/embassy-stm32/src/usb/otg.rs | |||
| @@ -231,19 +231,23 @@ impl<'d, T: Instance> embassy_usb_driver::Driver<'d> for Driver<'d, T> { | |||
| 231 | fn alloc_endpoint_in( | 231 | fn alloc_endpoint_in( |
| 232 | &mut self, | 232 | &mut self, |
| 233 | ep_type: EndpointType, | 233 | ep_type: EndpointType, |
| 234 | ep_addr: Option<EndpointAddress>, | ||
| 234 | max_packet_size: u16, | 235 | max_packet_size: u16, |
| 235 | interval_ms: u8, | 236 | interval_ms: u8, |
| 236 | ) -> Result<Self::EndpointIn, EndpointAllocError> { | 237 | ) -> Result<Self::EndpointIn, EndpointAllocError> { |
| 237 | self.inner.alloc_endpoint_in(ep_type, max_packet_size, interval_ms) | 238 | self.inner |
| 239 | .alloc_endpoint_in(ep_type, ep_addr, max_packet_size, interval_ms) | ||
| 238 | } | 240 | } |
| 239 | 241 | ||
| 240 | fn alloc_endpoint_out( | 242 | fn alloc_endpoint_out( |
| 241 | &mut self, | 243 | &mut self, |
| 242 | ep_type: EndpointType, | 244 | ep_type: EndpointType, |
| 245 | ep_addr: Option<EndpointAddress>, | ||
| 243 | max_packet_size: u16, | 246 | max_packet_size: u16, |
| 244 | interval_ms: u8, | 247 | interval_ms: u8, |
| 245 | ) -> Result<Self::EndpointOut, EndpointAllocError> { | 248 | ) -> Result<Self::EndpointOut, EndpointAllocError> { |
| 246 | self.inner.alloc_endpoint_out(ep_type, max_packet_size, interval_ms) | 249 | self.inner |
| 250 | .alloc_endpoint_out(ep_type, ep_addr, max_packet_size, interval_ms) | ||
| 247 | } | 251 | } |
| 248 | 252 | ||
| 249 | fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) { | 253 | fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) { |
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index 3e8e74a1f..05c28aceb 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs | |||
| @@ -362,6 +362,7 @@ impl<'d, T: Instance> Driver<'d, T> { | |||
| 362 | fn alloc_endpoint<D: Dir>( | 362 | fn alloc_endpoint<D: Dir>( |
| 363 | &mut self, | 363 | &mut self, |
| 364 | ep_type: EndpointType, | 364 | ep_type: EndpointType, |
| 365 | ep_addr: Option<EndpointAddress>, | ||
| 365 | max_packet_size: u16, | 366 | max_packet_size: u16, |
| 366 | interval_ms: u8, | 367 | interval_ms: u8, |
| 367 | ) -> Result<Endpoint<'d, T, D>, driver::EndpointAllocError> { | 368 | ) -> Result<Endpoint<'d, T, D>, driver::EndpointAllocError> { |
| @@ -373,25 +374,56 @@ impl<'d, T: Instance> Driver<'d, T> { | |||
| 373 | D::dir() | 374 | D::dir() |
| 374 | ); | 375 | ); |
| 375 | 376 | ||
| 376 | let index = self.alloc.iter_mut().enumerate().find(|(i, ep)| { | 377 | let index = if let Some(addr) = ep_addr { |
| 377 | if *i == 0 && ep_type != EndpointType::Control { | 378 | // Use the specified endpoint address |
| 378 | return false; // reserved for control pipe | 379 | let requested_index = addr.index(); |
| 380 | if requested_index >= EP_COUNT { | ||
| 381 | return Err(EndpointAllocError); | ||
| 379 | } | 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]; | ||
| 380 | let used = ep.used_out || ep.used_in; | 388 | let used = ep.used_out || ep.used_in; |
| 381 | if used && (ep.ep_type == EndpointType::Isochronous) { | 389 | if used && (ep.ep_type == EndpointType::Isochronous) { |
| 382 | // Isochronous endpoints are always double-buffered. | 390 | // Isochronous endpoints are always double-buffered. |
| 383 | // Their corresponding endpoint/channel registers are forced to be unidirectional. | 391 | // Their corresponding endpoint/channel registers are forced to be unidirectional. |
| 384 | // Do not reuse this index. | 392 | // Do not reuse this index. |
| 385 | // FIXME: Bulk endpoints can be double buffered, but are not in the current implementation. | 393 | return Err(EndpointAllocError); |
| 386 | return false; | ||
| 387 | } | 394 | } |
| 388 | 395 | ||
| 389 | let used_dir = match D::dir() { | 396 | let used_dir = match D::dir() { |
| 390 | Direction::Out => ep.used_out, | 397 | Direction::Out => ep.used_out, |
| 391 | Direction::In => ep.used_in, | 398 | Direction::In => ep.used_in, |
| 392 | }; | 399 | }; |
| 393 | !used || (ep.ep_type == ep_type && !used_dir) | 400 | if used && (ep.ep_type != ep_type || used_dir) { |
| 394 | }); | 401 | return Err(EndpointAllocError); |
| 402 | } | ||
| 403 | |||
| 404 | Some((requested_index, &mut self.alloc[requested_index])) | ||
| 405 | } else { | ||
| 406 | // Find any available endpoint | ||
| 407 | self.alloc.iter_mut().enumerate().find(|(i, ep)| { | ||
| 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 | }; | ||
| 395 | 427 | ||
| 396 | let (index, ep) = match index { | 428 | let (index, ep) = match index { |
| 397 | Some(x) => x, | 429 | Some(x) => x, |
| @@ -479,27 +511,29 @@ impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> { | |||
| 479 | fn alloc_endpoint_in( | 511 | fn alloc_endpoint_in( |
| 480 | &mut self, | 512 | &mut self, |
| 481 | ep_type: EndpointType, | 513 | ep_type: EndpointType, |
| 514 | ep_addr: Option<EndpointAddress>, | ||
| 482 | max_packet_size: u16, | 515 | max_packet_size: u16, |
| 483 | interval_ms: u8, | 516 | interval_ms: u8, |
| 484 | ) -> Result<Self::EndpointIn, driver::EndpointAllocError> { | 517 | ) -> Result<Self::EndpointIn, driver::EndpointAllocError> { |
| 485 | self.alloc_endpoint(ep_type, max_packet_size, interval_ms) | 518 | self.alloc_endpoint(ep_type, ep_addr, max_packet_size, interval_ms) |
| 486 | } | 519 | } |
| 487 | 520 | ||
| 488 | fn alloc_endpoint_out( | 521 | fn alloc_endpoint_out( |
| 489 | &mut self, | 522 | &mut self, |
| 490 | ep_type: EndpointType, | 523 | ep_type: EndpointType, |
| 524 | ep_addr: Option<EndpointAddress>, | ||
| 491 | max_packet_size: u16, | 525 | max_packet_size: u16, |
| 492 | interval_ms: u8, | 526 | interval_ms: u8, |
| 493 | ) -> Result<Self::EndpointOut, driver::EndpointAllocError> { | 527 | ) -> Result<Self::EndpointOut, driver::EndpointAllocError> { |
| 494 | self.alloc_endpoint(ep_type, max_packet_size, interval_ms) | 528 | self.alloc_endpoint(ep_type, ep_addr, max_packet_size, interval_ms) |
| 495 | } | 529 | } |
| 496 | 530 | ||
| 497 | fn start(mut self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) { | 531 | fn start(mut self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) { |
| 498 | let ep_out = self | 532 | let ep_out = self |
| 499 | .alloc_endpoint(EndpointType::Control, control_max_packet_size, 0) | 533 | .alloc_endpoint(EndpointType::Control, None, control_max_packet_size, 0) |
| 500 | .unwrap(); | 534 | .unwrap(); |
| 501 | let ep_in = self | 535 | let ep_in = self |
| 502 | .alloc_endpoint(EndpointType::Control, control_max_packet_size, 0) | 536 | .alloc_endpoint(EndpointType::Control, None, control_max_packet_size, 0) |
| 503 | .unwrap(); | 537 | .unwrap(); |
| 504 | assert_eq!(ep_out.info.addr.index(), 0); | 538 | assert_eq!(ep_out.info.addr.index(), 0); |
| 505 | assert_eq!(ep_in.info.addr.index(), 0); | 539 | assert_eq!(ep_in.info.addr.index(), 0); |
