aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-09-06 22:56:24 +0200
committerGitHub <[email protected]>2022-09-06 22:56:24 +0200
commit29145e5f92918f5f6e575e5ccee159c0160c6694 (patch)
treef1eb992b2e021dc78e32ebbdc544965773481fe7 /src
parent2bd7205c79968ba2121ece47a025ac1a90b30893 (diff)
parent5c4d6232ae5822d70cba4dbd60cfe348a7f0d687 (diff)
Merge pull request #11 from jannic-dev-forks/minimal_flow_control
Implement minimal tx flow control
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs43
1 files changed, 35 insertions, 8 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 34170a266..5e79e6e40 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -525,6 +525,8 @@ pub struct Runner<'a, PWR, SPI> {
525 ioctl_id: u16, 525 ioctl_id: u16,
526 sdpcm_seq: u8, 526 sdpcm_seq: u8,
527 backplane_window: u32, 527 backplane_window: u32,
528
529 sdpcm_seq_max: u8,
528} 530}
529 531
530pub async fn new<'a, PWR, SPI>( 532pub async fn new<'a, PWR, SPI>(
@@ -546,6 +548,8 @@ where
546 ioctl_id: 0, 548 ioctl_id: 0,
547 sdpcm_seq: 0, 549 sdpcm_seq: 0,
548 backplane_window: 0xAAAA_AAAA, 550 backplane_window: 0xAAAA_AAAA,
551
552 sdpcm_seq_max: 1,
549 }; 553 };
550 554
551 runner.init(firmware).await; 555 runner.init(firmware).await;
@@ -669,14 +673,21 @@ where
669 let mut buf = [0; 512]; 673 let mut buf = [0; 512];
670 loop { 674 loop {
671 // Send stuff 675 // Send stuff
672 // TODO flow control 676 // TODO flow control not yet complete
673 if let IoctlState::Pending { kind, cmd, iface, buf } = self.state.ioctl_state.get() { 677 if !self.has_credit() {
674 self.send_ioctl(kind, cmd, iface, unsafe { &*buf }).await; 678 warn!("TX stalled");
675 self.state.ioctl_state.set(IoctlState::Sent { buf }); 679 } else {
676 } 680 if let IoctlState::Pending { kind, cmd, iface, buf } = self.state.ioctl_state.get() {
677 681 self.send_ioctl(kind, cmd, iface, unsafe { &*buf }).await;
678 if let Ok(p) = self.state.tx_channel.try_recv() { 682 self.state.ioctl_state.set(IoctlState::Sent { buf });
679 self.send_packet(&p).await; 683 }
684 if !self.has_credit() {
685 warn!("TX stalled");
686 } else {
687 if let Ok(p) = self.state.tx_channel.try_recv() {
688 self.send_packet(&p).await;
689 }
690 }
680 } 691 }
681 692
682 // Receive stuff 693 // Receive stuff
@@ -788,6 +799,8 @@ where
788 return; 799 return;
789 } 800 }
790 801
802 self.update_credit(&sdpcm_header);
803
791 let channel = sdpcm_header.channel_and_flags & 0x0f; 804 let channel = sdpcm_header.channel_and_flags & 0x0f;
792 805
793 let payload = &packet[sdpcm_header.header_length as _..]; 806 let payload = &packet[sdpcm_header.header_length as _..];
@@ -894,6 +907,20 @@ where
894 } 907 }
895 } 908 }
896 909
910 fn update_credit(&mut self, sdpcm_header: &SdpcmHeader) {
911 if sdpcm_header.channel_and_flags & 0xf < 3 {
912 let mut sdpcm_seq_max = sdpcm_header.bus_data_credit;
913 if sdpcm_seq_max - self.sdpcm_seq > 0x40 {
914 sdpcm_seq_max = self.sdpcm_seq + 2;
915 }
916 self.sdpcm_seq_max = sdpcm_seq_max;
917 }
918 }
919
920 fn has_credit(&mut self) -> bool {
921 self.sdpcm_seq != self.sdpcm_seq_max && self.sdpcm_seq_max.wrapping_sub(self.sdpcm_seq) & 0x80 == 0
922 }
923
897 async fn send_ioctl(&mut self, kind: u32, cmd: u32, iface: u32, data: &[u8]) { 924 async fn send_ioctl(&mut self, kind: u32, cmd: u32, iface: u32, data: &[u8]) {
898 let mut buf = [0; 512]; 925 let mut buf = [0; 512];
899 let buf8 = slice8_mut(&mut buf); 926 let buf8 = slice8_mut(&mut buf);