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-rp/src/usb.rs | |
| parent | 758f5d7ea29f1df14d5ef59c82e4b7f22545d775 (diff) | |
Switch to async-fn-in-trait
Diffstat (limited to 'embassy-rp/src/usb.rs')
| -rw-r--r-- | embassy-rp/src/usb.rs | 513 |
1 files changed, 235 insertions, 278 deletions
diff --git a/embassy-rp/src/usb.rs b/embassy-rp/src/usb.rs index 6dc90b98e..32fc2632d 100644 --- a/embassy-rp/src/usb.rs +++ b/embassy-rp/src/usb.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | use core::future::{poll_fn, Future}; | 1 | use core::future::poll_fn; |
| 2 | use core::marker::PhantomData; | 2 | use core::marker::PhantomData; |
| 3 | use core::slice; | 3 | use core::slice; |
| 4 | use core::sync::atomic::Ordering; | 4 | use core::sync::atomic::Ordering; |
| @@ -352,9 +352,7 @@ pub struct Bus<'d, T: Instance> { | |||
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | impl<'d, T: Instance> driver::Bus for Bus<'d, T> { | 354 | impl<'d, T: Instance> driver::Bus for Bus<'d, T> { |
| 355 | type PollFuture<'a> = impl Future<Output = Event> + 'a where Self: 'a; | 355 | async fn poll(&mut self) -> Event { |
| 356 | |||
| 357 | fn poll<'a>(&'a mut self) -> Self::PollFuture<'a> { | ||
| 358 | poll_fn(move |cx| unsafe { | 356 | poll_fn(move |cx| unsafe { |
| 359 | BUS_WAKER.register(cx.waker()); | 357 | BUS_WAKER.register(cx.waker()); |
| 360 | 358 | ||
| @@ -406,6 +404,7 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { | |||
| 406 | }); | 404 | }); |
| 407 | Poll::Pending | 405 | Poll::Pending |
| 408 | }) | 406 | }) |
| 407 | .await | ||
| 409 | } | 408 | } |
| 410 | 409 | ||
| 411 | #[inline] | 410 | #[inline] |
| @@ -456,22 +455,12 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> { | |||
| 456 | } | 455 | } |
| 457 | } | 456 | } |
| 458 | 457 | ||
| 459 | type EnableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | 458 | async fn enable(&mut self) {} |
| 460 | |||
| 461 | fn enable(&mut self) -> Self::EnableFuture<'_> { | ||
| 462 | async move {} | ||
| 463 | } | ||
| 464 | |||
| 465 | type DisableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | ||
| 466 | |||
| 467 | fn disable(&mut self) -> Self::DisableFuture<'_> { | ||
| 468 | async move {} | ||
| 469 | } | ||
| 470 | 459 | ||
| 471 | type RemoteWakeupFuture<'a> = impl Future<Output = Result<(), Unsupported>> + 'a where Self: 'a; | 460 | async fn disable(&mut self) {} |
| 472 | 461 | ||
| 473 | fn remote_wakeup(&mut self) -> Self::RemoteWakeupFuture<'_> { | 462 | async fn remote_wakeup(&mut self) -> Result<(), Unsupported> { |
| 474 | async move { Err(Unsupported) } | 463 | Err(Unsupported) |
| 475 | } | 464 | } |
| 476 | } | 465 | } |
| 477 | 466 | ||
| @@ -515,24 +504,20 @@ impl<'d, T: Instance> driver::Endpoint for Endpoint<'d, T, In> { | |||
| 515 | &self.info | 504 | &self.info |
| 516 | } | 505 | } |
| 517 | 506 | ||
| 518 | type WaitEnabledFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | 507 | async fn wait_enabled(&mut self) { |
| 519 | 508 | trace!("wait_enabled IN WAITING"); | |
| 520 | fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_> { | 509 | let index = self.info.addr.index(); |
| 521 | async move { | 510 | poll_fn(|cx| { |
| 522 | trace!("wait_enabled IN WAITING"); | 511 | EP_IN_WAKERS[index].register(cx.waker()); |
| 523 | let index = self.info.addr.index(); | 512 | let val = unsafe { T::dpram().ep_in_control(self.info.addr.index() - 1).read() }; |
| 524 | poll_fn(|cx| { | 513 | if val.enable() { |
| 525 | EP_IN_WAKERS[index].register(cx.waker()); | 514 | Poll::Ready(()) |
| 526 | let val = unsafe { T::dpram().ep_in_control(self.info.addr.index() - 1).read() }; | 515 | } else { |
| 527 | if val.enable() { | 516 | Poll::Pending |
| 528 | Poll::Ready(()) | 517 | } |
| 529 | } else { | 518 | }) |
| 530 | Poll::Pending | 519 | .await; |
| 531 | } | 520 | trace!("wait_enabled IN OK"); |
| 532 | }) | ||
| 533 | .await; | ||
| 534 | trace!("wait_enabled IN OK"); | ||
| 535 | } | ||
| 536 | } | 521 | } |
| 537 | } | 522 | } |
| 538 | 523 | ||
| @@ -541,117 +526,105 @@ impl<'d, T: Instance> driver::Endpoint for Endpoint<'d, T, Out> { | |||
| 541 | &self.info | 526 | &self.info |
| 542 | } | 527 | } |
| 543 | 528 | ||
| 544 | type WaitEnabledFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | 529 | async fn wait_enabled(&mut self) { |
| 545 | 530 | trace!("wait_enabled OUT WAITING"); | |
| 546 | fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_> { | 531 | let index = self.info.addr.index(); |
| 547 | async move { | 532 | poll_fn(|cx| { |
| 548 | trace!("wait_enabled OUT WAITING"); | 533 | EP_OUT_WAKERS[index].register(cx.waker()); |
| 549 | let index = self.info.addr.index(); | 534 | let val = unsafe { T::dpram().ep_out_control(self.info.addr.index() - 1).read() }; |
| 550 | poll_fn(|cx| { | 535 | if val.enable() { |
| 551 | EP_OUT_WAKERS[index].register(cx.waker()); | 536 | Poll::Ready(()) |
| 552 | let val = unsafe { T::dpram().ep_out_control(self.info.addr.index() - 1).read() }; | 537 | } else { |
| 553 | if val.enable() { | 538 | Poll::Pending |
| 554 | Poll::Ready(()) | 539 | } |
| 555 | } else { | 540 | }) |
| 556 | Poll::Pending | 541 | .await; |
| 557 | } | 542 | trace!("wait_enabled OUT OK"); |
| 558 | }) | ||
| 559 | .await; | ||
| 560 | trace!("wait_enabled OUT OK"); | ||
| 561 | } | ||
| 562 | } | 543 | } |
| 563 | } | 544 | } |
| 564 | 545 | ||
| 565 | impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> { | 546 | impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> { |
| 566 | type ReadFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a; | 547 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> { |
| 567 | 548 | trace!("READ WAITING, buf.len() = {}", buf.len()); | |
| 568 | fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { | 549 | let index = self.info.addr.index(); |
| 569 | async move { | 550 | let val = poll_fn(|cx| unsafe { |
| 570 | trace!("READ WAITING, buf.len() = {}", buf.len()); | 551 | EP_OUT_WAKERS[index].register(cx.waker()); |
| 571 | let index = self.info.addr.index(); | 552 | let val = T::dpram().ep_out_buffer_control(index).read(); |
| 572 | let val = poll_fn(|cx| unsafe { | 553 | if val.available(0) { |
| 573 | EP_OUT_WAKERS[index].register(cx.waker()); | 554 | Poll::Pending |
| 574 | let val = T::dpram().ep_out_buffer_control(index).read(); | 555 | } else { |
| 575 | if val.available(0) { | 556 | Poll::Ready(val) |
| 576 | Poll::Pending | ||
| 577 | } else { | ||
| 578 | Poll::Ready(val) | ||
| 579 | } | ||
| 580 | }) | ||
| 581 | .await; | ||
| 582 | |||
| 583 | let rx_len = val.length(0) as usize; | ||
| 584 | if rx_len > buf.len() { | ||
| 585 | return Err(EndpointError::BufferOverflow); | ||
| 586 | } | 557 | } |
| 587 | self.buf.read(&mut buf[..rx_len]); | 558 | }) |
| 559 | .await; | ||
| 588 | 560 | ||
| 589 | trace!("READ OK, rx_len = {}", rx_len); | 561 | let rx_len = val.length(0) as usize; |
| 562 | if rx_len > buf.len() { | ||
| 563 | return Err(EndpointError::BufferOverflow); | ||
| 564 | } | ||
| 565 | self.buf.read(&mut buf[..rx_len]); | ||
| 590 | 566 | ||
| 591 | unsafe { | 567 | trace!("READ OK, rx_len = {}", rx_len); |
| 592 | let pid = !val.pid(0); | ||
| 593 | T::dpram().ep_out_buffer_control(index).write(|w| { | ||
| 594 | w.set_pid(0, pid); | ||
| 595 | w.set_length(0, self.info.max_packet_size); | ||
| 596 | }); | ||
| 597 | cortex_m::asm::delay(12); | ||
| 598 | T::dpram().ep_out_buffer_control(index).write(|w| { | ||
| 599 | w.set_pid(0, pid); | ||
| 600 | w.set_length(0, self.info.max_packet_size); | ||
| 601 | w.set_available(0, true); | ||
| 602 | }); | ||
| 603 | } | ||
| 604 | 568 | ||
| 605 | Ok(rx_len) | 569 | unsafe { |
| 570 | let pid = !val.pid(0); | ||
| 571 | T::dpram().ep_out_buffer_control(index).write(|w| { | ||
| 572 | w.set_pid(0, pid); | ||
| 573 | w.set_length(0, self.info.max_packet_size); | ||
| 574 | }); | ||
| 575 | cortex_m::asm::delay(12); | ||
| 576 | T::dpram().ep_out_buffer_control(index).write(|w| { | ||
| 577 | w.set_pid(0, pid); | ||
| 578 | w.set_length(0, self.info.max_packet_size); | ||
| 579 | w.set_available(0, true); | ||
| 580 | }); | ||
| 606 | } | 581 | } |
| 582 | |||
| 583 | Ok(rx_len) | ||
| 607 | } | 584 | } |
| 608 | } | 585 | } |
| 609 | 586 | ||
| 610 | impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> { | 587 | impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> { |
| 611 | type WriteFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a; | 588 | async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> { |
| 612 | 589 | if buf.len() > self.info.max_packet_size as usize { | |
| 613 | fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { | 590 | return Err(EndpointError::BufferOverflow); |
| 614 | async move { | 591 | } |
| 615 | if buf.len() > self.info.max_packet_size as usize { | ||
| 616 | return Err(EndpointError::BufferOverflow); | ||
| 617 | } | ||
| 618 | |||
| 619 | trace!("WRITE WAITING"); | ||
| 620 | |||
| 621 | let index = self.info.addr.index(); | ||
| 622 | let val = poll_fn(|cx| unsafe { | ||
| 623 | EP_IN_WAKERS[index].register(cx.waker()); | ||
| 624 | let val = T::dpram().ep_in_buffer_control(index).read(); | ||
| 625 | if val.available(0) { | ||
| 626 | Poll::Pending | ||
| 627 | } else { | ||
| 628 | Poll::Ready(val) | ||
| 629 | } | ||
| 630 | }) | ||
| 631 | .await; | ||
| 632 | 592 | ||
| 633 | self.buf.write(buf); | 593 | trace!("WRITE WAITING"); |
| 634 | 594 | ||
| 635 | unsafe { | 595 | let index = self.info.addr.index(); |
| 636 | let pid = !val.pid(0); | 596 | let val = poll_fn(|cx| unsafe { |
| 637 | T::dpram().ep_in_buffer_control(index).write(|w| { | 597 | EP_IN_WAKERS[index].register(cx.waker()); |
| 638 | w.set_pid(0, pid); | 598 | let val = T::dpram().ep_in_buffer_control(index).read(); |
| 639 | w.set_length(0, buf.len() as _); | 599 | if val.available(0) { |
| 640 | w.set_full(0, true); | 600 | Poll::Pending |
| 641 | }); | 601 | } else { |
| 642 | cortex_m::asm::delay(12); | 602 | Poll::Ready(val) |
| 643 | T::dpram().ep_in_buffer_control(index).write(|w| { | ||
| 644 | w.set_pid(0, pid); | ||
| 645 | w.set_length(0, buf.len() as _); | ||
| 646 | w.set_full(0, true); | ||
| 647 | w.set_available(0, true); | ||
| 648 | }); | ||
| 649 | } | 603 | } |
| 604 | }) | ||
| 605 | .await; | ||
| 650 | 606 | ||
| 651 | trace!("WRITE OK"); | 607 | self.buf.write(buf); |
| 652 | 608 | ||
| 653 | Ok(()) | 609 | unsafe { |
| 610 | let pid = !val.pid(0); | ||
| 611 | T::dpram().ep_in_buffer_control(index).write(|w| { | ||
| 612 | w.set_pid(0, pid); | ||
| 613 | w.set_length(0, buf.len() as _); | ||
| 614 | w.set_full(0, true); | ||
| 615 | }); | ||
| 616 | cortex_m::asm::delay(12); | ||
| 617 | T::dpram().ep_in_buffer_control(index).write(|w| { | ||
| 618 | w.set_pid(0, pid); | ||
| 619 | w.set_length(0, buf.len() as _); | ||
| 620 | w.set_full(0, true); | ||
| 621 | w.set_available(0, true); | ||
| 622 | }); | ||
| 654 | } | 623 | } |
| 624 | |||
| 625 | trace!("WRITE OK"); | ||
| 626 | |||
| 627 | Ok(()) | ||
| 655 | } | 628 | } |
| 656 | } | 629 | } |
| 657 | 630 | ||
| @@ -661,199 +634,183 @@ pub struct ControlPipe<'d, T: Instance> { | |||
| 661 | } | 634 | } |
| 662 | 635 | ||
| 663 | impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | 636 | impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { |
| 664 | type SetupFuture<'a> = impl Future<Output = [u8;8]> + 'a where Self: 'a; | ||
| 665 | type DataOutFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a; | ||
| 666 | type DataInFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a; | ||
| 667 | type AcceptFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | ||
| 668 | type RejectFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a; | ||
| 669 | |||
| 670 | fn max_packet_size(&self) -> usize { | 637 | fn max_packet_size(&self) -> usize { |
| 671 | 64 | 638 | 64 |
| 672 | } | 639 | } |
| 673 | 640 | ||
| 674 | fn setup<'a>(&'a mut self) -> Self::SetupFuture<'a> { | 641 | async fn setup<'a>(&'a mut self) -> [u8; 8] { |
| 675 | async move { | 642 | loop { |
| 676 | loop { | 643 | trace!("SETUP read waiting"); |
| 677 | trace!("SETUP read waiting"); | 644 | let regs = T::regs(); |
| 678 | let regs = T::regs(); | 645 | unsafe { regs.inte().write_set(|w| w.set_setup_req(true)) }; |
| 679 | unsafe { regs.inte().write_set(|w| w.set_setup_req(true)) }; | ||
| 680 | |||
| 681 | poll_fn(|cx| unsafe { | ||
| 682 | EP_OUT_WAKERS[0].register(cx.waker()); | ||
| 683 | let regs = T::regs(); | ||
| 684 | if regs.sie_status().read().setup_rec() { | ||
| 685 | Poll::Ready(()) | ||
| 686 | } else { | ||
| 687 | Poll::Pending | ||
| 688 | } | ||
| 689 | }) | ||
| 690 | .await; | ||
| 691 | |||
| 692 | let mut buf = [0; 8]; | ||
| 693 | EndpointBuffer::<T>::new(0, 8).read(&mut buf); | ||
| 694 | |||
| 695 | let regs = T::regs(); | ||
| 696 | unsafe { | ||
| 697 | regs.sie_status().write(|w| w.set_setup_rec(true)); | ||
| 698 | |||
| 699 | // set PID to 0, so (after toggling) first DATA is PID 1 | ||
| 700 | T::dpram().ep_in_buffer_control(0).write(|w| w.set_pid(0, false)); | ||
| 701 | T::dpram().ep_out_buffer_control(0).write(|w| w.set_pid(0, false)); | ||
| 702 | } | ||
| 703 | |||
| 704 | trace!("SETUP read ok"); | ||
| 705 | return buf; | ||
| 706 | } | ||
| 707 | } | ||
| 708 | } | ||
| 709 | |||
| 710 | fn data_out<'a>(&'a mut self, buf: &'a mut [u8], _first: bool, _last: bool) -> Self::DataOutFuture<'a> { | ||
| 711 | async move { | ||
| 712 | unsafe { | ||
| 713 | let bufcontrol = T::dpram().ep_out_buffer_control(0); | ||
| 714 | let pid = !bufcontrol.read().pid(0); | ||
| 715 | bufcontrol.write(|w| { | ||
| 716 | w.set_length(0, self.max_packet_size); | ||
| 717 | w.set_pid(0, pid); | ||
| 718 | }); | ||
| 719 | cortex_m::asm::delay(12); | ||
| 720 | bufcontrol.write(|w| { | ||
| 721 | w.set_length(0, self.max_packet_size); | ||
| 722 | w.set_pid(0, pid); | ||
| 723 | w.set_available(0, true); | ||
| 724 | }); | ||
| 725 | } | ||
| 726 | 646 | ||
| 727 | trace!("control: data_out len={} first={} last={}", buf.len(), _first, _last); | 647 | poll_fn(|cx| unsafe { |
| 728 | let val = poll_fn(|cx| unsafe { | ||
| 729 | EP_OUT_WAKERS[0].register(cx.waker()); | 648 | EP_OUT_WAKERS[0].register(cx.waker()); |
| 730 | let val = T::dpram().ep_out_buffer_control(0).read(); | 649 | let regs = T::regs(); |
| 731 | if val.available(0) { | 650 | if regs.sie_status().read().setup_rec() { |
| 732 | Poll::Pending | 651 | Poll::Ready(()) |
| 733 | } else { | 652 | } else { |
| 734 | Poll::Ready(val) | 653 | Poll::Pending |
| 735 | } | 654 | } |
| 736 | }) | 655 | }) |
| 737 | .await; | 656 | .await; |
| 738 | 657 | ||
| 739 | let rx_len = val.length(0) as _; | 658 | let mut buf = [0; 8]; |
| 740 | trace!("control data_out DONE, rx_len = {}", rx_len); | 659 | EndpointBuffer::<T>::new(0, 8).read(&mut buf); |
| 741 | 660 | ||
| 742 | if rx_len > buf.len() { | 661 | let regs = T::regs(); |
| 743 | return Err(EndpointError::BufferOverflow); | 662 | unsafe { |
| 663 | regs.sie_status().write(|w| w.set_setup_rec(true)); | ||
| 664 | |||
| 665 | // set PID to 0, so (after toggling) first DATA is PID 1 | ||
| 666 | T::dpram().ep_in_buffer_control(0).write(|w| w.set_pid(0, false)); | ||
| 667 | T::dpram().ep_out_buffer_control(0).write(|w| w.set_pid(0, false)); | ||
| 744 | } | 668 | } |
| 745 | EndpointBuffer::<T>::new(0x100, 64).read(&mut buf[..rx_len]); | ||
| 746 | 669 | ||
| 747 | Ok(rx_len) | 670 | trace!("SETUP read ok"); |
| 671 | return buf; | ||
| 748 | } | 672 | } |
| 749 | } | 673 | } |
| 750 | 674 | ||
| 751 | fn data_in<'a>(&'a mut self, buf: &'a [u8], _first: bool, _last: bool) -> Self::DataInFuture<'a> { | 675 | async fn data_out(&mut self, buf: &mut [u8], first: bool, last: bool) -> Result<usize, EndpointError> { |
| 752 | async move { | 676 | unsafe { |
| 753 | trace!("control: data_in len={} first={} last={}", buf.len(), _first, _last); | 677 | let bufcontrol = T::dpram().ep_out_buffer_control(0); |
| 754 | 678 | let pid = !bufcontrol.read().pid(0); | |
| 755 | if buf.len() > 64 { | 679 | bufcontrol.write(|w| { |
| 756 | return Err(EndpointError::BufferOverflow); | 680 | w.set_length(0, self.max_packet_size); |
| 757 | } | 681 | w.set_pid(0, pid); |
| 758 | EndpointBuffer::<T>::new(0x100, 64).write(buf); | 682 | }); |
| 683 | cortex_m::asm::delay(12); | ||
| 684 | bufcontrol.write(|w| { | ||
| 685 | w.set_length(0, self.max_packet_size); | ||
| 686 | w.set_pid(0, pid); | ||
| 687 | w.set_available(0, true); | ||
| 688 | }); | ||
| 689 | } | ||
| 759 | 690 | ||
| 760 | unsafe { | 691 | trace!("control: data_out len={} first={} last={}", buf.len(), first, last); |
| 761 | let bufcontrol = T::dpram().ep_in_buffer_control(0); | 692 | let val = poll_fn(|cx| unsafe { |
| 762 | let pid = !bufcontrol.read().pid(0); | 693 | EP_OUT_WAKERS[0].register(cx.waker()); |
| 763 | bufcontrol.write(|w| { | 694 | let val = T::dpram().ep_out_buffer_control(0).read(); |
| 764 | w.set_length(0, buf.len() as _); | 695 | if val.available(0) { |
| 765 | w.set_pid(0, pid); | 696 | Poll::Pending |
| 766 | w.set_full(0, true); | 697 | } else { |
| 767 | }); | 698 | Poll::Ready(val) |
| 768 | cortex_m::asm::delay(12); | ||
| 769 | bufcontrol.write(|w| { | ||
| 770 | w.set_length(0, buf.len() as _); | ||
| 771 | w.set_pid(0, pid); | ||
| 772 | w.set_full(0, true); | ||
| 773 | w.set_available(0, true); | ||
| 774 | }); | ||
| 775 | } | 699 | } |
| 700 | }) | ||
| 701 | .await; | ||
| 776 | 702 | ||
| 777 | poll_fn(|cx| unsafe { | 703 | let rx_len = val.length(0) as _; |
| 778 | EP_IN_WAKERS[0].register(cx.waker()); | 704 | trace!("control data_out DONE, rx_len = {}", rx_len); |
| 779 | let bufcontrol = T::dpram().ep_in_buffer_control(0); | ||
| 780 | if bufcontrol.read().available(0) { | ||
| 781 | Poll::Pending | ||
| 782 | } else { | ||
| 783 | Poll::Ready(()) | ||
| 784 | } | ||
| 785 | }) | ||
| 786 | .await; | ||
| 787 | trace!("control: data_in DONE"); | ||
| 788 | |||
| 789 | if _last { | ||
| 790 | // prepare status phase right away. | ||
| 791 | unsafe { | ||
| 792 | let bufcontrol = T::dpram().ep_out_buffer_control(0); | ||
| 793 | bufcontrol.write(|w| { | ||
| 794 | w.set_length(0, 0); | ||
| 795 | w.set_pid(0, true); | ||
| 796 | }); | ||
| 797 | cortex_m::asm::delay(12); | ||
| 798 | bufcontrol.write(|w| { | ||
| 799 | w.set_length(0, 0); | ||
| 800 | w.set_pid(0, true); | ||
| 801 | w.set_available(0, true); | ||
| 802 | }); | ||
| 803 | } | ||
| 804 | } | ||
| 805 | 705 | ||
| 806 | Ok(()) | 706 | if rx_len > buf.len() { |
| 707 | return Err(EndpointError::BufferOverflow); | ||
| 807 | } | 708 | } |
| 709 | EndpointBuffer::<T>::new(0x100, 64).read(&mut buf[..rx_len]); | ||
| 710 | |||
| 711 | Ok(rx_len) | ||
| 808 | } | 712 | } |
| 809 | 713 | ||
| 810 | fn accept<'a>(&'a mut self) -> Self::AcceptFuture<'a> { | 714 | async fn data_in(&mut self, data: &[u8], first: bool, last: bool) -> Result<(), EndpointError> { |
| 811 | async move { | 715 | trace!("control: data_in len={} first={} last={}", data.len(), first, last); |
| 812 | trace!("control: accept"); | 716 | |
| 717 | if data.len() > 64 { | ||
| 718 | return Err(EndpointError::BufferOverflow); | ||
| 719 | } | ||
| 720 | EndpointBuffer::<T>::new(0x100, 64).write(data); | ||
| 721 | |||
| 722 | unsafe { | ||
| 723 | let bufcontrol = T::dpram().ep_in_buffer_control(0); | ||
| 724 | let pid = !bufcontrol.read().pid(0); | ||
| 725 | bufcontrol.write(|w| { | ||
| 726 | w.set_length(0, data.len() as _); | ||
| 727 | w.set_pid(0, pid); | ||
| 728 | w.set_full(0, true); | ||
| 729 | }); | ||
| 730 | cortex_m::asm::delay(12); | ||
| 731 | bufcontrol.write(|w| { | ||
| 732 | w.set_length(0, data.len() as _); | ||
| 733 | w.set_pid(0, pid); | ||
| 734 | w.set_full(0, true); | ||
| 735 | w.set_available(0, true); | ||
| 736 | }); | ||
| 737 | } | ||
| 813 | 738 | ||
| 739 | poll_fn(|cx| unsafe { | ||
| 740 | EP_IN_WAKERS[0].register(cx.waker()); | ||
| 814 | let bufcontrol = T::dpram().ep_in_buffer_control(0); | 741 | let bufcontrol = T::dpram().ep_in_buffer_control(0); |
| 742 | if bufcontrol.read().available(0) { | ||
| 743 | Poll::Pending | ||
| 744 | } else { | ||
| 745 | Poll::Ready(()) | ||
| 746 | } | ||
| 747 | }) | ||
| 748 | .await; | ||
| 749 | trace!("control: data_in DONE"); | ||
| 750 | |||
| 751 | if last { | ||
| 752 | // prepare status phase right away. | ||
| 815 | unsafe { | 753 | unsafe { |
| 754 | let bufcontrol = T::dpram().ep_out_buffer_control(0); | ||
| 816 | bufcontrol.write(|w| { | 755 | bufcontrol.write(|w| { |
| 817 | w.set_length(0, 0); | 756 | w.set_length(0, 0); |
| 818 | w.set_pid(0, true); | 757 | w.set_pid(0, true); |
| 819 | w.set_full(0, true); | ||
| 820 | }); | 758 | }); |
| 821 | cortex_m::asm::delay(12); | 759 | cortex_m::asm::delay(12); |
| 822 | bufcontrol.write(|w| { | 760 | bufcontrol.write(|w| { |
| 823 | w.set_length(0, 0); | 761 | w.set_length(0, 0); |
| 824 | w.set_pid(0, true); | 762 | w.set_pid(0, true); |
| 825 | w.set_full(0, true); | ||
| 826 | w.set_available(0, true); | 763 | w.set_available(0, true); |
| 827 | }); | 764 | }); |
| 828 | } | 765 | } |
| 829 | |||
| 830 | // wait for completion before returning, needed so | ||
| 831 | // set_address() doesn't happen early. | ||
| 832 | poll_fn(|cx| { | ||
| 833 | EP_IN_WAKERS[0].register(cx.waker()); | ||
| 834 | if unsafe { bufcontrol.read().available(0) } { | ||
| 835 | Poll::Pending | ||
| 836 | } else { | ||
| 837 | Poll::Ready(()) | ||
| 838 | } | ||
| 839 | }) | ||
| 840 | .await; | ||
| 841 | } | 766 | } |
| 767 | |||
| 768 | Ok(()) | ||
| 842 | } | 769 | } |
| 843 | 770 | ||
| 844 | fn reject<'a>(&'a mut self) -> Self::RejectFuture<'a> { | 771 | async fn accept(&mut self) { |
| 845 | async move { | 772 | trace!("control: accept"); |
| 846 | trace!("control: reject"); | ||
| 847 | 773 | ||
| 848 | let regs = T::regs(); | 774 | let bufcontrol = T::dpram().ep_in_buffer_control(0); |
| 849 | unsafe { | 775 | unsafe { |
| 850 | regs.ep_stall_arm().write_set(|w| { | 776 | bufcontrol.write(|w| { |
| 851 | w.set_ep0_in(true); | 777 | w.set_length(0, 0); |
| 852 | w.set_ep0_out(true); | 778 | w.set_pid(0, true); |
| 853 | }); | 779 | w.set_full(0, true); |
| 854 | T::dpram().ep_out_buffer_control(0).write(|w| w.set_stall(true)); | 780 | }); |
| 855 | T::dpram().ep_in_buffer_control(0).write(|w| w.set_stall(true)); | 781 | cortex_m::asm::delay(12); |
| 782 | bufcontrol.write(|w| { | ||
| 783 | w.set_length(0, 0); | ||
| 784 | w.set_pid(0, true); | ||
| 785 | w.set_full(0, true); | ||
| 786 | w.set_available(0, true); | ||
| 787 | }); | ||
| 788 | } | ||
| 789 | |||
| 790 | // wait for completion before returning, needed so | ||
| 791 | // set_address() doesn't happen early. | ||
| 792 | poll_fn(|cx| { | ||
| 793 | EP_IN_WAKERS[0].register(cx.waker()); | ||
| 794 | if unsafe { bufcontrol.read().available(0) } { | ||
| 795 | Poll::Pending | ||
| 796 | } else { | ||
| 797 | Poll::Ready(()) | ||
| 856 | } | 798 | } |
| 799 | }) | ||
| 800 | .await; | ||
| 801 | } | ||
| 802 | |||
| 803 | async fn reject(&mut self) { | ||
| 804 | trace!("control: reject"); | ||
| 805 | |||
| 806 | let regs = T::regs(); | ||
| 807 | unsafe { | ||
| 808 | regs.ep_stall_arm().write_set(|w| { | ||
| 809 | w.set_ep0_in(true); | ||
| 810 | w.set_ep0_out(true); | ||
| 811 | }); | ||
| 812 | T::dpram().ep_out_buffer_control(0).write(|w| w.set_stall(true)); | ||
| 813 | T::dpram().ep_in_buffer_control(0).write(|w| w.set_stall(true)); | ||
| 857 | } | 814 | } |
| 858 | } | 815 | } |
| 859 | } | 816 | } |
