diff options
| author | elagil <[email protected]> | 2024-09-05 21:29:11 +0200 |
|---|---|---|
| committer | elagil <[email protected]> | 2024-09-05 21:29:11 +0200 |
| commit | d37c482e2179c95740bb4284f4df30637551199b (patch) | |
| tree | 30f3b18427b9adb16d16c1eb2524145e66e1b447 /embassy-usb-synopsys-otg | |
| parent | ccf68d73910a68dc9e33beb666b20aba7430e015 (diff) | |
feat(usb-otg): add support for ISO endpoints
Diffstat (limited to 'embassy-usb-synopsys-otg')
| -rw-r--r-- | embassy-usb-synopsys-otg/src/lib.rs | 30 | ||||
| -rw-r--r-- | embassy-usb-synopsys-otg/src/otg_v1.rs | 16 |
2 files changed, 38 insertions, 8 deletions
diff --git a/embassy-usb-synopsys-otg/src/lib.rs b/embassy-usb-synopsys-otg/src/lib.rs index 5fb82db42..b145f4aa8 100644 --- a/embassy-usb-synopsys-otg/src/lib.rs +++ b/embassy-usb-synopsys-otg/src/lib.rs | |||
| @@ -1071,6 +1071,21 @@ impl<'d> embassy_usb_driver::EndpointOut for Endpoint<'d, Out> { | |||
| 1071 | w.set_pktcnt(1); | 1071 | w.set_pktcnt(1); |
| 1072 | }); | 1072 | }); |
| 1073 | 1073 | ||
| 1074 | if self.info.ep_type == EndpointType::Isochronous { | ||
| 1075 | // Isochronous endpoints must set the correct even/odd frame bit to | ||
| 1076 | // correspond with the next frame's number. | ||
| 1077 | let frame_number = self.regs.dsts().read().fnsof(); | ||
| 1078 | let frame_is_odd = frame_number & 0x01 == 1; | ||
| 1079 | |||
| 1080 | self.regs.doepctl(index).modify(|r| { | ||
| 1081 | if frame_is_odd { | ||
| 1082 | r.set_sd0pid_sevnfrm(true); | ||
| 1083 | } else { | ||
| 1084 | r.set_sd1pid_soddfrm(true); | ||
| 1085 | } | ||
| 1086 | }); | ||
| 1087 | } | ||
| 1088 | |||
| 1074 | // Clear NAK to indicate we are ready to receive more data | 1089 | // Clear NAK to indicate we are ready to receive more data |
| 1075 | self.regs.doepctl(index).modify(|w| { | 1090 | self.regs.doepctl(index).modify(|w| { |
| 1076 | w.set_cnak(true); | 1091 | w.set_cnak(true); |
| @@ -1158,6 +1173,21 @@ impl<'d> embassy_usb_driver::EndpointIn for Endpoint<'d, In> { | |||
| 1158 | w.set_xfrsiz(buf.len() as _); | 1173 | w.set_xfrsiz(buf.len() as _); |
| 1159 | }); | 1174 | }); |
| 1160 | 1175 | ||
| 1176 | if self.info.ep_type == EndpointType::Isochronous { | ||
| 1177 | // Isochronous endpoints must set the correct even/odd frame bit to | ||
| 1178 | // correspond with the next frame's number. | ||
| 1179 | let frame_number = self.regs.dsts().read().fnsof(); | ||
| 1180 | let frame_is_odd = frame_number & 0x01 == 1; | ||
| 1181 | |||
| 1182 | self.regs.diepctl(index).modify(|r| { | ||
| 1183 | if frame_is_odd { | ||
| 1184 | r.set_sd0pid_sevnfrm(true); | ||
| 1185 | } else { | ||
| 1186 | r.set_sd1pid_soddfrm(true); | ||
| 1187 | } | ||
| 1188 | }); | ||
| 1189 | } | ||
| 1190 | |||
| 1161 | // Enable endpoint | 1191 | // Enable endpoint |
| 1162 | self.regs.diepctl(index).modify(|w| { | 1192 | self.regs.diepctl(index).modify(|w| { |
| 1163 | w.set_cnak(true); | 1193 | w.set_cnak(true); |
diff --git a/embassy-usb-synopsys-otg/src/otg_v1.rs b/embassy-usb-synopsys-otg/src/otg_v1.rs index a8530980c..d3abc328d 100644 --- a/embassy-usb-synopsys-otg/src/otg_v1.rs +++ b/embassy-usb-synopsys-otg/src/otg_v1.rs | |||
| @@ -795,15 +795,15 @@ pub mod regs { | |||
| 795 | pub fn set_sd0pid_sevnfrm(&mut self, val: bool) { | 795 | pub fn set_sd0pid_sevnfrm(&mut self, val: bool) { |
| 796 | self.0 = (self.0 & !(0x01 << 28usize)) | (((val as u32) & 0x01) << 28usize); | 796 | self.0 = (self.0 & !(0x01 << 28usize)) | (((val as u32) & 0x01) << 28usize); |
| 797 | } | 797 | } |
| 798 | #[doc = "SODDFRM/SD1PID"] | 798 | #[doc = "SD1PID/SODDFRM"] |
| 799 | #[inline(always)] | 799 | #[inline(always)] |
| 800 | pub const fn soddfrm_sd1pid(&self) -> bool { | 800 | pub const fn sd1pid_soddfrm(&self) -> bool { |
| 801 | let val = (self.0 >> 29usize) & 0x01; | 801 | let val = (self.0 >> 29usize) & 0x01; |
| 802 | val != 0 | 802 | val != 0 |
| 803 | } | 803 | } |
| 804 | #[doc = "SODDFRM/SD1PID"] | 804 | #[doc = "SD1PID/SODDFRM"] |
| 805 | #[inline(always)] | 805 | #[inline(always)] |
| 806 | pub fn set_soddfrm_sd1pid(&mut self, val: bool) { | 806 | pub fn set_sd1pid_soddfrm(&mut self, val: bool) { |
| 807 | self.0 = (self.0 & !(0x01 << 29usize)) | (((val as u32) & 0x01) << 29usize); | 807 | self.0 = (self.0 & !(0x01 << 29usize)) | (((val as u32) & 0x01) << 29usize); |
| 808 | } | 808 | } |
| 809 | #[doc = "EPDIS"] | 809 | #[doc = "EPDIS"] |
| @@ -1174,15 +1174,15 @@ pub mod regs { | |||
| 1174 | pub fn set_sd0pid_sevnfrm(&mut self, val: bool) { | 1174 | pub fn set_sd0pid_sevnfrm(&mut self, val: bool) { |
| 1175 | self.0 = (self.0 & !(0x01 << 28usize)) | (((val as u32) & 0x01) << 28usize); | 1175 | self.0 = (self.0 & !(0x01 << 28usize)) | (((val as u32) & 0x01) << 28usize); |
| 1176 | } | 1176 | } |
| 1177 | #[doc = "SODDFRM"] | 1177 | #[doc = "SD1PID/SODDFRM"] |
| 1178 | #[inline(always)] | 1178 | #[inline(always)] |
| 1179 | pub const fn soddfrm(&self) -> bool { | 1179 | pub const fn sd1pid_soddfrm(&self) -> bool { |
| 1180 | let val = (self.0 >> 29usize) & 0x01; | 1180 | let val = (self.0 >> 29usize) & 0x01; |
| 1181 | val != 0 | 1181 | val != 0 |
| 1182 | } | 1182 | } |
| 1183 | #[doc = "SODDFRM"] | 1183 | #[doc = "SD1PID/SODDFRM"] |
| 1184 | #[inline(always)] | 1184 | #[inline(always)] |
| 1185 | pub fn set_soddfrm(&mut self, val: bool) { | 1185 | pub fn set_sd1pid_soddfrm(&mut self, val: bool) { |
| 1186 | self.0 = (self.0 & !(0x01 << 29usize)) | (((val as u32) & 0x01) << 29usize); | 1186 | self.0 = (self.0 & !(0x01 << 29usize)) | (((val as u32) & 0x01) << 29usize); |
| 1187 | } | 1187 | } |
| 1188 | #[doc = "EPDIS"] | 1188 | #[doc = "EPDIS"] |
