diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-07-15 22:08:08 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-07-15 22:08:08 +0000 |
| commit | f525386fca8299791fa81539130576059654d778 (patch) | |
| tree | 6c995bb777b140ce6c6a6b175d9ca659bb5430ab /embassy-nrf/src | |
| parent | 281a05a99de4df6088ff3333f04428b6198caf4b (diff) | |
| parent | 93e2fdf51267f112adf0c14ccb7b46eb51edd48c (diff) | |
Merge pull request #4397 from korbin/allocate-numbered-endpoints
Make USB endpoint allocator methods accept an optional `EndpointAddress`
Diffstat (limited to 'embassy-nrf/src')
| -rw-r--r-- | embassy-nrf/src/usb/mod.rs | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/embassy-nrf/src/usb/mod.rs b/embassy-nrf/src/usb/mod.rs index 6cc1b0111..c6970fc0f 100644 --- a/embassy-nrf/src/usb/mod.rs +++ b/embassy-nrf/src/usb/mod.rs | |||
| @@ -121,10 +121,11 @@ impl<'d, T: Instance, V: VbusDetect + 'd> driver::Driver<'d> for Driver<'d, T, V | |||
| 121 | fn alloc_endpoint_in( | 121 | fn alloc_endpoint_in( |
| 122 | &mut self, | 122 | &mut self, |
| 123 | ep_type: EndpointType, | 123 | ep_type: EndpointType, |
| 124 | ep_addr: Option<EndpointAddress>, | ||
| 124 | packet_size: u16, | 125 | packet_size: u16, |
| 125 | interval_ms: u8, | 126 | interval_ms: u8, |
| 126 | ) -> Result<Self::EndpointIn, driver::EndpointAllocError> { | 127 | ) -> Result<Self::EndpointIn, driver::EndpointAllocError> { |
| 127 | let index = self.alloc_in.allocate(ep_type)?; | 128 | let index = self.alloc_in.allocate(ep_type, ep_addr)?; |
| 128 | let ep_addr = EndpointAddress::from_parts(index, Direction::In); | 129 | let ep_addr = EndpointAddress::from_parts(index, Direction::In); |
| 129 | Ok(Endpoint::new(EndpointInfo { | 130 | Ok(Endpoint::new(EndpointInfo { |
| 130 | addr: ep_addr, | 131 | addr: ep_addr, |
| @@ -137,10 +138,11 @@ impl<'d, T: Instance, V: VbusDetect + 'd> driver::Driver<'d> for Driver<'d, T, V | |||
| 137 | fn alloc_endpoint_out( | 138 | fn alloc_endpoint_out( |
| 138 | &mut self, | 139 | &mut self, |
| 139 | ep_type: EndpointType, | 140 | ep_type: EndpointType, |
| 141 | ep_addr: Option<EndpointAddress>, | ||
| 140 | packet_size: u16, | 142 | packet_size: u16, |
| 141 | interval_ms: u8, | 143 | interval_ms: u8, |
| 142 | ) -> Result<Self::EndpointOut, driver::EndpointAllocError> { | 144 | ) -> Result<Self::EndpointOut, driver::EndpointAllocError> { |
| 143 | let index = self.alloc_out.allocate(ep_type)?; | 145 | let index = self.alloc_out.allocate(ep_type, ep_addr)?; |
| 144 | let ep_addr = EndpointAddress::from_parts(index, Direction::Out); | 146 | let ep_addr = EndpointAddress::from_parts(index, Direction::Out); |
| 145 | Ok(Endpoint::new(EndpointInfo { | 147 | Ok(Endpoint::new(EndpointInfo { |
| 146 | addr: ep_addr, | 148 | addr: ep_addr, |
| @@ -734,7 +736,11 @@ impl Allocator { | |||
| 734 | Self { used: 0 } | 736 | Self { used: 0 } |
| 735 | } | 737 | } |
| 736 | 738 | ||
| 737 | fn allocate(&mut self, ep_type: EndpointType) -> Result<usize, driver::EndpointAllocError> { | 739 | fn allocate( |
| 740 | &mut self, | ||
| 741 | ep_type: EndpointType, | ||
| 742 | ep_addr: Option<EndpointAddress>, | ||
| 743 | ) -> Result<usize, driver::EndpointAllocError> { | ||
| 738 | // Endpoint addresses are fixed in hardware: | 744 | // Endpoint addresses are fixed in hardware: |
| 739 | // - 0x80 / 0x00 - Control EP0 | 745 | // - 0x80 / 0x00 - Control EP0 |
| 740 | // - 0x81 / 0x01 - Bulk/Interrupt EP1 | 746 | // - 0x81 / 0x01 - Bulk/Interrupt EP1 |
| @@ -748,16 +754,37 @@ impl Allocator { | |||
| 748 | 754 | ||
| 749 | // Endpoint directions are allocated individually. | 755 | // Endpoint directions are allocated individually. |
| 750 | 756 | ||
| 751 | let alloc_index = match ep_type { | 757 | let alloc_index = if let Some(addr) = ep_addr { |
| 752 | EndpointType::Isochronous => 8, | 758 | // Use the specified endpoint address |
| 753 | EndpointType::Control => return Err(driver::EndpointAllocError), | 759 | let requested_index = addr.index(); |
| 754 | EndpointType::Interrupt | EndpointType::Bulk => { | 760 | // Validate the requested index based on endpoint type |
| 755 | // Find rightmost zero bit in 1..=7 | 761 | match ep_type { |
| 756 | let ones = (self.used >> 1).trailing_ones() as usize; | 762 | EndpointType::Isochronous => { |
| 757 | if ones >= 7 { | 763 | if requested_index != 8 { |
| 758 | return Err(driver::EndpointAllocError); | 764 | return Err(driver::EndpointAllocError); |
| 765 | } | ||
| 766 | } | ||
| 767 | EndpointType::Control => return Err(driver::EndpointAllocError), | ||
| 768 | EndpointType::Interrupt | EndpointType::Bulk => { | ||
| 769 | if requested_index < 1 || requested_index > 7 { | ||
| 770 | return Err(driver::EndpointAllocError); | ||
| 771 | } | ||
| 772 | } | ||
| 773 | } | ||
| 774 | requested_index | ||
| 775 | } else { | ||
| 776 | // Allocate any available endpoint | ||
| 777 | match ep_type { | ||
| 778 | EndpointType::Isochronous => 8, | ||
| 779 | EndpointType::Control => return Err(driver::EndpointAllocError), | ||
| 780 | EndpointType::Interrupt | EndpointType::Bulk => { | ||
| 781 | // Find rightmost zero bit in 1..=7 | ||
| 782 | let ones = (self.used >> 1).trailing_ones() as usize; | ||
| 783 | if ones >= 7 { | ||
| 784 | return Err(driver::EndpointAllocError); | ||
| 785 | } | ||
| 786 | ones + 1 | ||
| 759 | } | 787 | } |
| 760 | ones + 1 | ||
| 761 | } | 788 | } |
| 762 | }; | 789 | }; |
| 763 | 790 | ||
