diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-11-21 23:31:31 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-11-25 21:02:06 +0100 |
| commit | 1e2fb0459d8546ba658bb9fe150be5f1f537b48e (patch) | |
| tree | eb40a5027581896c7b78db58f509431ed6b11892 /embassy-stm32/src/usb | |
| parent | 758f5d7ea29f1df14d5ef59c82e4b7f22545d775 (diff) | |
Switch to async-fn-in-trait
Diffstat (limited to 'embassy-stm32/src/usb')
| -rw-r--r-- | embassy-stm32/src/usb/usb.rs | 582 |
1 files changed, 269 insertions, 313 deletions
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs index 2654f156a..0ba06cce2 100644 --- a/embassy-stm32/src/usb/usb.rs +++ b/embassy-stm32/src/usb/usb.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | use core::future::{poll_fn, Future}; | 3 | use core::future::poll_fn; |
| 4 | use core::marker::PhantomData; | 4 | use core::marker::PhantomData; |
| 5 | use core::sync::atomic::Ordering; | 5 | use core::sync::atomic::Ordering; |
| 6 | use core::task::Poll; | 6 | use core::task::Poll; |
| @@ -429,9 +429,7 @@ pub struct Bus<'d, T: Instance> { | |||
| 429 | } | 429 | } |
| 430 | 430 | ||
| 431 | impl<'d, T: Instance> driver::Bus for Bus<'d, T> { | 431 | impl<'d, T: Instance> driver::Bus for Bus<'d, T> { |
| 432 | type PollFuture<'a> = impl Future<Output = Event> + 'a where Self: 'a; | 432 | async fn poll(&mut self) -> Event { |
| 433 | |||
| 434 | fn poll<'a>(&'a mut self) -> Self::PollFuture<'a> { | ||
| 435 | poll_fn(move |cx| unsafe { | 433 | poll_fn(move |cx| unsafe { |
| 436 | BUS_WAKER.register(cx.waker()); | 434 | BUS_WAKER.register(cx.waker()); |
| 437 | 435 | ||
| @@ -488,6 +486,7 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { | |||
| 488 | return Poll::Ready(Event::PowerDetected); | 486 | return Poll::Ready(Event::PowerDetected); |
| 489 | } | 487 | } |
| 490 | }) | 488 | }) |
| 489 | .await | ||
| 491 | } | 490 | } |
| 492 | 491 | ||
| 493 | #[inline] | 492 | #[inline] |
| @@ -598,22 +597,11 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { | |||
| 598 | trace!("EPR after: {:04x}", unsafe { reg.read() }.0); | 597 | trace!("EPR after: {:04x}", unsafe { reg.read() }.0); |
| 599 | } | 598 | } |
| 600 | 599 | ||
| 601 | type EnableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | 600 | async fn enable(&mut self) {} |
| 602 | 601 | async fn disable(&mut self) {} | |
| 603 | fn enable(&mut self) -> Self::EnableFuture<'_> { | ||
| 604 | async move {} | ||
| 605 | } | ||
| 606 | |||
| 607 | type DisableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | ||
| 608 | |||
| 609 | fn disable(&mut self) -> Self::DisableFuture<'_> { | ||
| 610 | async move {} | ||
| 611 | } | ||
| 612 | |||
| 613 | type RemoteWakeupFuture<'a> = impl Future<Output = Result<(), Unsupported>> + 'a where Self: 'a; | ||
| 614 | 602 | ||
| 615 | fn remote_wakeup(&mut self) -> Self::RemoteWakeupFuture<'_> { | 603 | async fn remote_wakeup(&mut self) -> Result<(), Unsupported> { |
| 616 | async move { Err(Unsupported) } | 604 | Err(Unsupported) |
| 617 | } | 605 | } |
| 618 | } | 606 | } |
| 619 | 607 | ||
| @@ -676,24 +664,20 @@ impl<'d, T: Instance> driver::Endpoint for Endpoint<'d, T, In> { | |||
| 676 | &self.info | 664 | &self.info |
| 677 | } | 665 | } |
| 678 | 666 | ||
| 679 | type WaitEnabledFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | 667 | async fn wait_enabled(&mut self) { |
| 680 | 668 | trace!("wait_enabled OUT WAITING"); | |
| 681 | fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_> { | 669 | let index = self.info.addr.index(); |
| 682 | async move { | 670 | poll_fn(|cx| { |
| 683 | trace!("wait_enabled OUT WAITING"); | 671 | EP_OUT_WAKERS[index].register(cx.waker()); |
| 684 | let index = self.info.addr.index(); | 672 | let regs = T::regs(); |
| 685 | poll_fn(|cx| { | 673 | if unsafe { regs.epr(index).read() }.stat_tx() == Stat::DISABLED { |
| 686 | EP_OUT_WAKERS[index].register(cx.waker()); | 674 | Poll::Pending |
| 687 | let regs = T::regs(); | 675 | } else { |
| 688 | if unsafe { regs.epr(index).read() }.stat_tx() == Stat::DISABLED { | 676 | Poll::Ready(()) |
| 689 | Poll::Pending | 677 | } |
| 690 | } else { | 678 | }) |
| 691 | Poll::Ready(()) | 679 | .await; |
| 692 | } | 680 | trace!("wait_enabled OUT OK"); |
| 693 | }) | ||
| 694 | .await; | ||
| 695 | trace!("wait_enabled OUT OK"); | ||
| 696 | } | ||
| 697 | } | 681 | } |
| 698 | } | 682 | } |
| 699 | 683 | ||
| @@ -702,116 +686,104 @@ impl<'d, T: Instance> driver::Endpoint for Endpoint<'d, T, Out> { | |||
| 702 | &self.info | 686 | &self.info |
| 703 | } | 687 | } |
| 704 | 688 | ||
| 705 | type WaitEnabledFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | 689 | async fn wait_enabled(&mut self) { |
| 706 | 690 | trace!("wait_enabled OUT WAITING"); | |
| 707 | fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_> { | 691 | let index = self.info.addr.index(); |
| 708 | async move { | 692 | poll_fn(|cx| { |
| 709 | trace!("wait_enabled OUT WAITING"); | 693 | EP_OUT_WAKERS[index].register(cx.waker()); |
| 710 | let index = self.info.addr.index(); | 694 | let regs = T::regs(); |
| 711 | poll_fn(|cx| { | 695 | if unsafe { regs.epr(index).read() }.stat_rx() == Stat::DISABLED { |
| 712 | EP_OUT_WAKERS[index].register(cx.waker()); | 696 | Poll::Pending |
| 713 | let regs = T::regs(); | 697 | } else { |
| 714 | if unsafe { regs.epr(index).read() }.stat_rx() == Stat::DISABLED { | 698 | Poll::Ready(()) |
| 715 | Poll::Pending | 699 | } |
| 716 | } else { | 700 | }) |
| 717 | Poll::Ready(()) | 701 | .await; |
| 718 | } | 702 | trace!("wait_enabled OUT OK"); |
| 719 | }) | ||
| 720 | .await; | ||
| 721 | trace!("wait_enabled OUT OK"); | ||
| 722 | } | ||
| 723 | } | 703 | } |
| 724 | } | 704 | } |
| 725 | 705 | ||
| 726 | impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> { | 706 | impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> { |
| 727 | type ReadFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a; | 707 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> { |
| 728 | 708 | trace!("READ WAITING, buf.len() = {}", buf.len()); | |
| 729 | fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { | 709 | let index = self.info.addr.index(); |
| 730 | async move { | 710 | let stat = poll_fn(|cx| { |
| 731 | trace!("READ WAITING, buf.len() = {}", buf.len()); | 711 | EP_OUT_WAKERS[index].register(cx.waker()); |
| 732 | let index = self.info.addr.index(); | 712 | let regs = T::regs(); |
| 733 | let stat = poll_fn(|cx| { | 713 | let stat = unsafe { regs.epr(index).read() }.stat_rx(); |
| 734 | EP_OUT_WAKERS[index].register(cx.waker()); | 714 | if matches!(stat, Stat::NAK | Stat::DISABLED) { |
| 735 | let regs = T::regs(); | 715 | Poll::Ready(stat) |
| 736 | let stat = unsafe { regs.epr(index).read() }.stat_rx(); | 716 | } else { |
| 737 | if matches!(stat, Stat::NAK | Stat::DISABLED) { | 717 | Poll::Pending |
| 738 | Poll::Ready(stat) | ||
| 739 | } else { | ||
| 740 | Poll::Pending | ||
| 741 | } | ||
| 742 | }) | ||
| 743 | .await; | ||
| 744 | |||
| 745 | if stat == Stat::DISABLED { | ||
| 746 | return Err(EndpointError::Disabled); | ||
| 747 | } | 718 | } |
| 719 | }) | ||
| 720 | .await; | ||
| 748 | 721 | ||
| 749 | let rx_len = self.read_data(buf)?; | 722 | if stat == Stat::DISABLED { |
| 723 | return Err(EndpointError::Disabled); | ||
| 724 | } | ||
| 750 | 725 | ||
| 751 | let regs = T::regs(); | 726 | let rx_len = self.read_data(buf)?; |
| 752 | unsafe { | ||
| 753 | regs.epr(index).write(|w| { | ||
| 754 | w.set_ep_type(convert_type(self.info.ep_type)); | ||
| 755 | w.set_ea(self.info.addr.index() as _); | ||
| 756 | w.set_stat_rx(Stat(Stat::NAK.0 ^ Stat::VALID.0)); | ||
| 757 | w.set_stat_tx(Stat(0)); | ||
| 758 | w.set_ctr_rx(true); // don't clear | ||
| 759 | w.set_ctr_tx(true); // don't clear | ||
| 760 | }) | ||
| 761 | }; | ||
| 762 | trace!("READ OK, rx_len = {}", rx_len); | ||
| 763 | 727 | ||
| 764 | Ok(rx_len) | 728 | let regs = T::regs(); |
| 765 | } | 729 | unsafe { |
| 730 | regs.epr(index).write(|w| { | ||
| 731 | w.set_ep_type(convert_type(self.info.ep_type)); | ||
| 732 | w.set_ea(self.info.addr.index() as _); | ||
| 733 | w.set_stat_rx(Stat(Stat::NAK.0 ^ Stat::VALID.0)); | ||
| 734 | w.set_stat_tx(Stat(0)); | ||
| 735 | w.set_ctr_rx(true); // don't clear | ||
| 736 | w.set_ctr_tx(true); // don't clear | ||
| 737 | }) | ||
| 738 | }; | ||
| 739 | trace!("READ OK, rx_len = {}", rx_len); | ||
| 740 | |||
| 741 | Ok(rx_len) | ||
| 766 | } | 742 | } |
| 767 | } | 743 | } |
| 768 | 744 | ||
| 769 | impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> { | 745 | impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> { |
| 770 | type WriteFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a; | 746 | async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> { |
| 771 | 747 | if buf.len() > self.info.max_packet_size as usize { | |
| 772 | fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { | 748 | return Err(EndpointError::BufferOverflow); |
| 773 | async move { | 749 | } |
| 774 | if buf.len() > self.info.max_packet_size as usize { | ||
| 775 | return Err(EndpointError::BufferOverflow); | ||
| 776 | } | ||
| 777 | |||
| 778 | let index = self.info.addr.index(); | ||
| 779 | 750 | ||
| 780 | trace!("WRITE WAITING"); | 751 | let index = self.info.addr.index(); |
| 781 | let stat = poll_fn(|cx| { | ||
| 782 | EP_IN_WAKERS[index].register(cx.waker()); | ||
| 783 | let regs = T::regs(); | ||
| 784 | let stat = unsafe { regs.epr(index).read() }.stat_tx(); | ||
| 785 | if matches!(stat, Stat::NAK | Stat::DISABLED) { | ||
| 786 | Poll::Ready(stat) | ||
| 787 | } else { | ||
| 788 | Poll::Pending | ||
| 789 | } | ||
| 790 | }) | ||
| 791 | .await; | ||
| 792 | 752 | ||
| 793 | if stat == Stat::DISABLED { | 753 | trace!("WRITE WAITING"); |
| 794 | return Err(EndpointError::Disabled); | 754 | let stat = poll_fn(|cx| { |
| 755 | EP_IN_WAKERS[index].register(cx.waker()); | ||
| 756 | let regs = T::regs(); | ||
| 757 | let stat = unsafe { regs.epr(index).read() }.stat_tx(); | ||
| 758 | if matches!(stat, Stat::NAK | Stat::DISABLED) { | ||
| 759 | Poll::Ready(stat) | ||
| 760 | } else { | ||
| 761 | Poll::Pending | ||
| 795 | } | 762 | } |
| 763 | }) | ||
| 764 | .await; | ||
| 796 | 765 | ||
| 797 | self.write_data(buf); | 766 | if stat == Stat::DISABLED { |
| 767 | return Err(EndpointError::Disabled); | ||
| 768 | } | ||
| 798 | 769 | ||
| 799 | let regs = T::regs(); | 770 | self.write_data(buf); |
| 800 | unsafe { | ||
| 801 | regs.epr(index).write(|w| { | ||
| 802 | w.set_ep_type(convert_type(self.info.ep_type)); | ||
| 803 | w.set_ea(self.info.addr.index() as _); | ||
| 804 | w.set_stat_tx(Stat(Stat::NAK.0 ^ Stat::VALID.0)); | ||
| 805 | w.set_stat_rx(Stat(0)); | ||
| 806 | w.set_ctr_rx(true); // don't clear | ||
| 807 | w.set_ctr_tx(true); // don't clear | ||
| 808 | }) | ||
| 809 | }; | ||
| 810 | 771 | ||
| 811 | trace!("WRITE OK"); | 772 | let regs = T::regs(); |
| 773 | unsafe { | ||
| 774 | regs.epr(index).write(|w| { | ||
| 775 | w.set_ep_type(convert_type(self.info.ep_type)); | ||
| 776 | w.set_ea(self.info.addr.index() as _); | ||
| 777 | w.set_stat_tx(Stat(Stat::NAK.0 ^ Stat::VALID.0)); | ||
| 778 | w.set_stat_rx(Stat(0)); | ||
| 779 | w.set_ctr_rx(true); // don't clear | ||
| 780 | w.set_ctr_tx(true); // don't clear | ||
| 781 | }) | ||
| 782 | }; | ||
| 812 | 783 | ||
| 813 | Ok(()) | 784 | trace!("WRITE OK"); |
| 814 | } | 785 | |
| 786 | Ok(()) | ||
| 815 | } | 787 | } |
| 816 | } | 788 | } |
| 817 | 789 | ||
| @@ -823,84 +795,16 @@ pub struct ControlPipe<'d, T: Instance> { | |||
| 823 | } | 795 | } |
| 824 | 796 | ||
| 825 | impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | 797 | impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { |
| 826 | type SetupFuture<'a> = impl Future<Output = [u8;8]> + 'a where Self: 'a; | ||
| 827 | type DataOutFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a; | ||
| 828 | type DataInFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a; | ||
| 829 | type AcceptFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | ||
| 830 | type RejectFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | ||
| 831 | |||
| 832 | fn max_packet_size(&self) -> usize { | 798 | fn max_packet_size(&self) -> usize { |
| 833 | usize::from(self.max_packet_size) | 799 | usize::from(self.max_packet_size) |
| 834 | } | 800 | } |
| 835 | 801 | ||
| 836 | fn setup<'a>(&'a mut self) -> Self::SetupFuture<'a> { | 802 | async fn setup<'a>(&'a mut self) -> [u8; 8] { |
| 837 | async move { | 803 | loop { |
| 838 | loop { | 804 | trace!("SETUP read waiting"); |
| 839 | trace!("SETUP read waiting"); | ||
| 840 | poll_fn(|cx| { | ||
| 841 | EP_OUT_WAKERS[0].register(cx.waker()); | ||
| 842 | if EP0_SETUP.load(Ordering::Relaxed) { | ||
| 843 | Poll::Ready(()) | ||
| 844 | } else { | ||
| 845 | Poll::Pending | ||
| 846 | } | ||
| 847 | }) | ||
| 848 | .await; | ||
| 849 | |||
| 850 | let mut buf = [0; 8]; | ||
| 851 | let rx_len = self.ep_out.read_data(&mut buf); | ||
| 852 | if rx_len != Ok(8) { | ||
| 853 | trace!("SETUP read failed: {:?}", rx_len); | ||
| 854 | continue; | ||
| 855 | } | ||
| 856 | |||
| 857 | EP0_SETUP.store(false, Ordering::Relaxed); | ||
| 858 | |||
| 859 | trace!("SETUP read ok"); | ||
| 860 | return buf; | ||
| 861 | } | ||
| 862 | } | ||
| 863 | } | ||
| 864 | |||
| 865 | fn data_out<'a>(&'a mut self, buf: &'a mut [u8], first: bool, last: bool) -> Self::DataOutFuture<'a> { | ||
| 866 | async move { | ||
| 867 | let regs = T::regs(); | ||
| 868 | |||
| 869 | // When a SETUP is received, Stat/Stat is set to NAK. | ||
| 870 | // On first transfer, we must set Stat=VALID, to get the OUT data stage. | ||
| 871 | // We want Stat=STALL so that the host gets a STALL if it switches to the status | ||
| 872 | // stage too soon, except in the last transfer we set Stat=NAK so that it waits | ||
| 873 | // for the status stage, which we will ACK or STALL later. | ||
| 874 | if first || last { | ||
| 875 | let mut stat_rx = 0; | ||
| 876 | let mut stat_tx = 0; | ||
| 877 | if first { | ||
| 878 | // change NAK -> VALID | ||
| 879 | stat_rx ^= Stat::NAK.0 ^ Stat::VALID.0; | ||
| 880 | stat_tx ^= Stat::NAK.0 ^ Stat::STALL.0; | ||
| 881 | } | ||
| 882 | if last { | ||
| 883 | // change STALL -> VALID | ||
| 884 | stat_tx ^= Stat::STALL.0 ^ Stat::NAK.0; | ||
| 885 | } | ||
| 886 | // Note: if this is the first AND last transfer, the above effectively | ||
| 887 | // changes stat_tx like NAK -> NAK, so noop. | ||
| 888 | unsafe { | ||
| 889 | regs.epr(0).write(|w| { | ||
| 890 | w.set_ep_type(EpType::CONTROL); | ||
| 891 | w.set_stat_rx(Stat(stat_rx)); | ||
| 892 | w.set_stat_tx(Stat(stat_tx)); | ||
| 893 | w.set_ctr_rx(true); // don't clear | ||
| 894 | w.set_ctr_tx(true); // don't clear | ||
| 895 | }) | ||
| 896 | } | ||
| 897 | } | ||
| 898 | |||
| 899 | trace!("data_out WAITING, buf.len() = {}", buf.len()); | ||
| 900 | poll_fn(|cx| { | 805 | poll_fn(|cx| { |
| 901 | EP_OUT_WAKERS[0].register(cx.waker()); | 806 | EP_OUT_WAKERS[0].register(cx.waker()); |
| 902 | let regs = T::regs(); | 807 | if EP0_SETUP.load(Ordering::Relaxed) { |
| 903 | if unsafe { regs.epr(0).read() }.stat_rx() == Stat::NAK { | ||
| 904 | Poll::Ready(()) | 808 | Poll::Ready(()) |
| 905 | } else { | 809 | } else { |
| 906 | Poll::Pending | 810 | Poll::Pending |
| @@ -908,157 +812,209 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 908 | }) | 812 | }) |
| 909 | .await; | 813 | .await; |
| 910 | 814 | ||
| 911 | if EP0_SETUP.load(Ordering::Relaxed) { | 815 | let mut buf = [0; 8]; |
| 912 | trace!("received another SETUP, aborting data_out."); | 816 | let rx_len = self.ep_out.read_data(&mut buf); |
| 913 | return Err(EndpointError::Disabled); | 817 | if rx_len != Ok(8) { |
| 818 | trace!("SETUP read failed: {:?}", rx_len); | ||
| 819 | continue; | ||
| 914 | } | 820 | } |
| 915 | 821 | ||
| 916 | let rx_len = self.ep_out.read_data(buf)?; | 822 | EP0_SETUP.store(false, Ordering::Relaxed); |
| 823 | |||
| 824 | trace!("SETUP read ok"); | ||
| 825 | return buf; | ||
| 826 | } | ||
| 827 | } | ||
| 828 | |||
| 829 | async fn data_out(&mut self, buf: &mut [u8], first: bool, last: bool) -> Result<usize, EndpointError> { | ||
| 830 | let regs = T::regs(); | ||
| 917 | 831 | ||
| 832 | // When a SETUP is received, Stat/Stat is set to NAK. | ||
| 833 | // On first transfer, we must set Stat=VALID, to get the OUT data stage. | ||
| 834 | // We want Stat=STALL so that the host gets a STALL if it switches to the status | ||
| 835 | // stage too soon, except in the last transfer we set Stat=NAK so that it waits | ||
| 836 | // for the status stage, which we will ACK or STALL later. | ||
| 837 | if first || last { | ||
| 838 | let mut stat_rx = 0; | ||
| 839 | let mut stat_tx = 0; | ||
| 840 | if first { | ||
| 841 | // change NAK -> VALID | ||
| 842 | stat_rx ^= Stat::NAK.0 ^ Stat::VALID.0; | ||
| 843 | stat_tx ^= Stat::NAK.0 ^ Stat::STALL.0; | ||
| 844 | } | ||
| 845 | if last { | ||
| 846 | // change STALL -> VALID | ||
| 847 | stat_tx ^= Stat::STALL.0 ^ Stat::NAK.0; | ||
| 848 | } | ||
| 849 | // Note: if this is the first AND last transfer, the above effectively | ||
| 850 | // changes stat_tx like NAK -> NAK, so noop. | ||
| 918 | unsafe { | 851 | unsafe { |
| 919 | regs.epr(0).write(|w| { | 852 | regs.epr(0).write(|w| { |
| 920 | w.set_ep_type(EpType::CONTROL); | 853 | w.set_ep_type(EpType::CONTROL); |
| 921 | w.set_stat_rx(Stat(match last { | 854 | w.set_stat_rx(Stat(stat_rx)); |
| 922 | // If last, set STAT_RX=STALL. | 855 | w.set_stat_tx(Stat(stat_tx)); |
| 923 | true => Stat::NAK.0 ^ Stat::STALL.0, | ||
| 924 | // Otherwise, set STAT_RX=VALID, to allow the host to send the next packet. | ||
| 925 | false => Stat::NAK.0 ^ Stat::VALID.0, | ||
| 926 | })); | ||
| 927 | w.set_ctr_rx(true); // don't clear | 856 | w.set_ctr_rx(true); // don't clear |
| 928 | w.set_ctr_tx(true); // don't clear | 857 | w.set_ctr_tx(true); // don't clear |
| 929 | }) | 858 | }) |
| 930 | }; | 859 | } |
| 931 | |||
| 932 | Ok(rx_len) | ||
| 933 | } | 860 | } |
| 934 | } | ||
| 935 | |||
| 936 | fn data_in<'a>(&'a mut self, buf: &'a [u8], first: bool, last: bool) -> Self::DataInFuture<'a> { | ||
| 937 | async move { | ||
| 938 | trace!("control: data_in"); | ||
| 939 | 861 | ||
| 940 | if buf.len() > self.ep_in.info.max_packet_size as usize { | 862 | trace!("data_out WAITING, buf.len() = {}", buf.len()); |
| 941 | return Err(EndpointError::BufferOverflow); | 863 | poll_fn(|cx| { |
| 864 | EP_OUT_WAKERS[0].register(cx.waker()); | ||
| 865 | let regs = T::regs(); | ||
| 866 | if unsafe { regs.epr(0).read() }.stat_rx() == Stat::NAK { | ||
| 867 | Poll::Ready(()) | ||
| 868 | } else { | ||
| 869 | Poll::Pending | ||
| 942 | } | 870 | } |
| 871 | }) | ||
| 872 | .await; | ||
| 943 | 873 | ||
| 944 | let regs = T::regs(); | 874 | if EP0_SETUP.load(Ordering::Relaxed) { |
| 875 | trace!("received another SETUP, aborting data_out."); | ||
| 876 | return Err(EndpointError::Disabled); | ||
| 877 | } | ||
| 945 | 878 | ||
| 946 | // When a SETUP is received, Stat is set to NAK. | 879 | let rx_len = self.ep_out.read_data(buf)?; |
| 947 | // We want it to be STALL in non-last transfers. | ||
| 948 | // We want it to be VALID in last transfer, so the HW does the status stage. | ||
| 949 | if first || last { | ||
| 950 | let mut stat_rx = 0; | ||
| 951 | if first { | ||
| 952 | // change NAK -> STALL | ||
| 953 | stat_rx ^= Stat::NAK.0 ^ Stat::STALL.0; | ||
| 954 | } | ||
| 955 | if last { | ||
| 956 | // change STALL -> VALID | ||
| 957 | stat_rx ^= Stat::STALL.0 ^ Stat::VALID.0; | ||
| 958 | } | ||
| 959 | // Note: if this is the first AND last transfer, the above effectively | ||
| 960 | // does a change of NAK -> VALID. | ||
| 961 | unsafe { | ||
| 962 | regs.epr(0).write(|w| { | ||
| 963 | w.set_ep_type(EpType::CONTROL); | ||
| 964 | w.set_stat_rx(Stat(stat_rx)); | ||
| 965 | w.set_ep_kind(last); // set OUT_STATUS if last. | ||
| 966 | w.set_ctr_rx(true); // don't clear | ||
| 967 | w.set_ctr_tx(true); // don't clear | ||
| 968 | }) | ||
| 969 | } | ||
| 970 | } | ||
| 971 | 880 | ||
| 972 | trace!("WRITE WAITING"); | 881 | unsafe { |
| 973 | poll_fn(|cx| { | 882 | regs.epr(0).write(|w| { |
| 974 | EP_IN_WAKERS[0].register(cx.waker()); | 883 | w.set_ep_type(EpType::CONTROL); |
| 975 | EP_OUT_WAKERS[0].register(cx.waker()); | 884 | w.set_stat_rx(Stat(match last { |
| 976 | let regs = T::regs(); | 885 | // If last, set STAT_RX=STALL. |
| 977 | if unsafe { regs.epr(0).read() }.stat_tx() == Stat::NAK { | 886 | true => Stat::NAK.0 ^ Stat::STALL.0, |
| 978 | Poll::Ready(()) | 887 | // Otherwise, set STAT_RX=VALID, to allow the host to send the next packet. |
| 979 | } else { | 888 | false => Stat::NAK.0 ^ Stat::VALID.0, |
| 980 | Poll::Pending | 889 | })); |
| 981 | } | 890 | w.set_ctr_rx(true); // don't clear |
| 891 | w.set_ctr_tx(true); // don't clear | ||
| 982 | }) | 892 | }) |
| 983 | .await; | 893 | }; |
| 984 | 894 | ||
| 985 | if EP0_SETUP.load(Ordering::Relaxed) { | 895 | Ok(rx_len) |
| 986 | trace!("received another SETUP, aborting data_in."); | 896 | } |
| 987 | return Err(EndpointError::Disabled); | ||
| 988 | } | ||
| 989 | 897 | ||
| 990 | self.ep_in.write_data(buf); | 898 | async fn data_in(&mut self, data: &[u8], first: bool, last: bool) -> Result<(), EndpointError> { |
| 899 | trace!("control: data_in"); | ||
| 991 | 900 | ||
| 992 | let regs = T::regs(); | 901 | if data.len() > self.ep_in.info.max_packet_size as usize { |
| 902 | return Err(EndpointError::BufferOverflow); | ||
| 903 | } | ||
| 904 | |||
| 905 | let regs = T::regs(); | ||
| 906 | |||
| 907 | // When a SETUP is received, Stat is set to NAK. | ||
| 908 | // We want it to be STALL in non-last transfers. | ||
| 909 | // We want it to be VALID in last transfer, so the HW does the status stage. | ||
| 910 | if first || last { | ||
| 911 | let mut stat_rx = 0; | ||
| 912 | if first { | ||
| 913 | // change NAK -> STALL | ||
| 914 | stat_rx ^= Stat::NAK.0 ^ Stat::STALL.0; | ||
| 915 | } | ||
| 916 | if last { | ||
| 917 | // change STALL -> VALID | ||
| 918 | stat_rx ^= Stat::STALL.0 ^ Stat::VALID.0; | ||
| 919 | } | ||
| 920 | // Note: if this is the first AND last transfer, the above effectively | ||
| 921 | // does a change of NAK -> VALID. | ||
| 993 | unsafe { | 922 | unsafe { |
| 994 | regs.epr(0).write(|w| { | 923 | regs.epr(0).write(|w| { |
| 995 | w.set_ep_type(EpType::CONTROL); | 924 | w.set_ep_type(EpType::CONTROL); |
| 996 | w.set_stat_tx(Stat(Stat::NAK.0 ^ Stat::VALID.0)); | 925 | w.set_stat_rx(Stat(stat_rx)); |
| 997 | w.set_ep_kind(last); // set OUT_STATUS if last. | 926 | w.set_ep_kind(last); // set OUT_STATUS if last. |
| 998 | w.set_ctr_rx(true); // don't clear | 927 | w.set_ctr_rx(true); // don't clear |
| 999 | w.set_ctr_tx(true); // don't clear | 928 | w.set_ctr_tx(true); // don't clear |
| 1000 | }) | 929 | }) |
| 1001 | }; | 930 | } |
| 1002 | |||
| 1003 | trace!("WRITE OK"); | ||
| 1004 | |||
| 1005 | Ok(()) | ||
| 1006 | } | 931 | } |
| 1007 | } | ||
| 1008 | 932 | ||
| 1009 | fn accept<'a>(&'a mut self) -> Self::AcceptFuture<'a> { | 933 | trace!("WRITE WAITING"); |
| 1010 | async move { | 934 | poll_fn(|cx| { |
| 935 | EP_IN_WAKERS[0].register(cx.waker()); | ||
| 936 | EP_OUT_WAKERS[0].register(cx.waker()); | ||
| 1011 | let regs = T::regs(); | 937 | let regs = T::regs(); |
| 1012 | trace!("control: accept"); | 938 | if unsafe { regs.epr(0).read() }.stat_tx() == Stat::NAK { |
| 939 | Poll::Ready(()) | ||
| 940 | } else { | ||
| 941 | Poll::Pending | ||
| 942 | } | ||
| 943 | }) | ||
| 944 | .await; | ||
| 1013 | 945 | ||
| 1014 | self.ep_in.write_data(&[]); | 946 | if EP0_SETUP.load(Ordering::Relaxed) { |
| 947 | trace!("received another SETUP, aborting data_in."); | ||
| 948 | return Err(EndpointError::Disabled); | ||
| 949 | } | ||
| 1015 | 950 | ||
| 1016 | // Set OUT=stall, IN=accept | 951 | self.ep_in.write_data(data); |
| 1017 | unsafe { | ||
| 1018 | let epr = regs.epr(0).read(); | ||
| 1019 | regs.epr(0).write(|w| { | ||
| 1020 | w.set_ep_type(EpType::CONTROL); | ||
| 1021 | w.set_stat_rx(Stat(epr.stat_rx().0 ^ Stat::STALL.0)); | ||
| 1022 | w.set_stat_tx(Stat(epr.stat_tx().0 ^ Stat::VALID.0)); | ||
| 1023 | w.set_ctr_rx(true); // don't clear | ||
| 1024 | w.set_ctr_tx(true); // don't clear | ||
| 1025 | }); | ||
| 1026 | } | ||
| 1027 | trace!("control: accept WAITING"); | ||
| 1028 | 952 | ||
| 1029 | // Wait is needed, so that we don't set the address too soon, breaking the status stage. | 953 | let regs = T::regs(); |
| 1030 | // (embassy-usb sets the address after accept() returns) | 954 | unsafe { |
| 1031 | poll_fn(|cx| { | 955 | regs.epr(0).write(|w| { |
| 1032 | EP_IN_WAKERS[0].register(cx.waker()); | 956 | w.set_ep_type(EpType::CONTROL); |
| 1033 | let regs = T::regs(); | 957 | w.set_stat_tx(Stat(Stat::NAK.0 ^ Stat::VALID.0)); |
| 1034 | if unsafe { regs.epr(0).read() }.stat_tx() == Stat::NAK { | 958 | w.set_ep_kind(last); // set OUT_STATUS if last. |
| 1035 | Poll::Ready(()) | 959 | w.set_ctr_rx(true); // don't clear |
| 1036 | } else { | 960 | w.set_ctr_tx(true); // don't clear |
| 1037 | Poll::Pending | ||
| 1038 | } | ||
| 1039 | }) | 961 | }) |
| 1040 | .await; | 962 | }; |
| 1041 | 963 | ||
| 1042 | trace!("control: accept OK"); | 964 | trace!("WRITE OK"); |
| 1043 | } | 965 | |
| 966 | Ok(()) | ||
| 1044 | } | 967 | } |
| 1045 | 968 | ||
| 1046 | fn reject<'a>(&'a mut self) -> Self::RejectFuture<'a> { | 969 | async fn accept(&mut self) { |
| 1047 | async move { | 970 | let regs = T::regs(); |
| 1048 | let regs = T::regs(); | 971 | trace!("control: accept"); |
| 1049 | trace!("control: reject"); | ||
| 1050 | 972 | ||
| 1051 | // Set IN+OUT to stall | 973 | self.ep_in.write_data(&[]); |
| 1052 | unsafe { | 974 | |
| 1053 | let epr = regs.epr(0).read(); | 975 | // Set OUT=stall, IN=accept |
| 1054 | regs.epr(0).write(|w| { | 976 | unsafe { |
| 1055 | w.set_ep_type(EpType::CONTROL); | 977 | let epr = regs.epr(0).read(); |
| 1056 | w.set_stat_rx(Stat(epr.stat_rx().0 ^ Stat::STALL.0)); | 978 | regs.epr(0).write(|w| { |
| 1057 | w.set_stat_tx(Stat(epr.stat_tx().0 ^ Stat::STALL.0)); | 979 | w.set_ep_type(EpType::CONTROL); |
| 1058 | w.set_ctr_rx(true); // don't clear | 980 | w.set_stat_rx(Stat(epr.stat_rx().0 ^ Stat::STALL.0)); |
| 1059 | w.set_ctr_tx(true); // don't clear | 981 | w.set_stat_tx(Stat(epr.stat_tx().0 ^ Stat::VALID.0)); |
| 1060 | }); | 982 | w.set_ctr_rx(true); // don't clear |
| 983 | w.set_ctr_tx(true); // don't clear | ||
| 984 | }); | ||
| 985 | } | ||
| 986 | trace!("control: accept WAITING"); | ||
| 987 | |||
| 988 | // Wait is needed, so that we don't set the address too soon, breaking the status stage. | ||
| 989 | // (embassy-usb sets the address after accept() returns) | ||
| 990 | poll_fn(|cx| { | ||
| 991 | EP_IN_WAKERS[0].register(cx.waker()); | ||
| 992 | let regs = T::regs(); | ||
| 993 | if unsafe { regs.epr(0).read() }.stat_tx() == Stat::NAK { | ||
| 994 | Poll::Ready(()) | ||
| 995 | } else { | ||
| 996 | Poll::Pending | ||
| 1061 | } | 997 | } |
| 998 | }) | ||
| 999 | .await; | ||
| 1000 | |||
| 1001 | trace!("control: accept OK"); | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | async fn reject(&mut self) { | ||
| 1005 | let regs = T::regs(); | ||
| 1006 | trace!("control: reject"); | ||
| 1007 | |||
| 1008 | // Set IN+OUT to stall | ||
| 1009 | unsafe { | ||
| 1010 | let epr = regs.epr(0).read(); | ||
| 1011 | regs.epr(0).write(|w| { | ||
| 1012 | w.set_ep_type(EpType::CONTROL); | ||
| 1013 | w.set_stat_rx(Stat(epr.stat_rx().0 ^ Stat::STALL.0)); | ||
| 1014 | w.set_stat_tx(Stat(epr.stat_tx().0 ^ Stat::STALL.0)); | ||
| 1015 | w.set_ctr_rx(true); // don't clear | ||
| 1016 | w.set_ctr_tx(true); // don't clear | ||
| 1017 | }); | ||
| 1062 | } | 1018 | } |
| 1063 | } | 1019 | } |
| 1064 | } | 1020 | } |
