aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-07-16 18:06:57 +0200
committerDario Nieuwenhuis <[email protected]>2022-07-16 18:06:57 +0200
commit931e3d7ee0cb1ff9f320b22aab3f4ea375a1c624 (patch)
tree63e0f277d49814a634d31a7bbfa02d0cd807871d
parent7dfdea87971bf7a951b2b1d3fc2e50e245005d07 (diff)
Switch to 32bit SPI.
-rw-r--r--examples/rpi-pico-w/src/main.rs14
-rw-r--r--src/lib.rs112
2 files changed, 55 insertions, 71 deletions
diff --git a/examples/rpi-pico-w/src/main.rs b/examples/rpi-pico-w/src/main.rs
index 655535f9d..475c69067 100644
--- a/examples/rpi-pico-w/src/main.rs
+++ b/examples/rpi-pico-w/src/main.rs
@@ -153,17 +153,17 @@ impl SpiBusFlush for MySpi {
153 } 153 }
154} 154}
155 155
156impl SpiBusRead for MySpi { 156impl SpiBusRead<u32> for MySpi {
157 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> 157 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>>
158 where 158 where
159 Self: 'a; 159 Self: 'a;
160 160
161 fn read<'a>(&'a mut self, words: &'a mut [u8]) -> Self::ReadFuture<'a> { 161 fn read<'a>(&'a mut self, words: &'a mut [u32]) -> Self::ReadFuture<'a> {
162 async move { 162 async move {
163 self.dio.set_as_input(); 163 self.dio.set_as_input();
164 for word in words { 164 for word in words {
165 let mut w = 0; 165 let mut w = 0;
166 for _ in 0..8 { 166 for _ in 0..32 {
167 w = w << 1; 167 w = w << 1;
168 168
169 // rising edge, sample data 169 // rising edge, sample data
@@ -183,20 +183,20 @@ impl SpiBusRead for MySpi {
183 } 183 }
184} 184}
185 185
186impl SpiBusWrite for MySpi { 186impl SpiBusWrite<u32> for MySpi {
187 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> 187 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>>
188 where 188 where
189 Self: 'a; 189 Self: 'a;
190 190
191 fn write<'a>(&'a mut self, words: &'a [u8]) -> Self::WriteFuture<'a> { 191 fn write<'a>(&'a mut self, words: &'a [u32]) -> Self::WriteFuture<'a> {
192 async move { 192 async move {
193 self.dio.set_as_output(); 193 self.dio.set_as_output();
194 for word in words { 194 for word in words {
195 let mut word = *word; 195 let mut word = *word;
196 for _ in 0..8 { 196 for _ in 0..32 {
197 // falling edge, setup data 197 // falling edge, setup data
198 self.clk.set_low(); 198 self.clk.set_low();
199 if word & 0x80 == 0 { 199 if word & 0x8000_0000 == 0 {
200 self.dio.set_low(); 200 self.dio.set_low();
201 } else { 201 } else {
202 self.dio.set_high(); 202 self.dio.set_high();
diff --git a/src/lib.rs b/src/lib.rs
index fb693c323..8c235b174 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -28,13 +28,18 @@ use self::structs::*;
28use crate::events::Event; 28use crate::events::Event;
29 29
30fn swap16(x: u32) -> u32 { 30fn swap16(x: u32) -> u32 {
31 (x & 0xFF00FF00) >> 8 | (x & 0x00FF00FF) << 8 31 x.rotate_left(16)
32} 32}
33 33
34fn cmd_word(write: bool, incr: bool, func: u32, addr: u32, len: u32) -> u32 { 34fn cmd_word(write: bool, incr: bool, func: u32, addr: u32, len: u32) -> u32 {
35 (write as u32) << 31 | (incr as u32) << 30 | (func & 0b11) << 28 | (addr & 0x1FFFF) << 11 | (len & 0x7FF) 35 (write as u32) << 31 | (incr as u32) << 30 | (func & 0b11) << 28 | (addr & 0x1FFFF) << 11 | (len & 0x7FF)
36} 36}
37 37
38fn slice8_mut(x: &mut [u32]) -> &mut [u8] {
39 let len = x.len() * 4;
40 unsafe { slice::from_raw_parts_mut(x.as_mut_ptr() as _, len) }
41}
42
38const FUNC_BUS: u32 = 0; 43const FUNC_BUS: u32 = 0;
39const FUNC_BACKPLANE: u32 = 1; 44const FUNC_BACKPLANE: u32 = 1;
40const FUNC_WLAN: u32 = 2; 45const FUNC_WLAN: u32 = 2;
@@ -529,7 +534,7 @@ pub async fn new<'a, PWR, SPI>(state: &'a State, pwr: PWR, spi: SPI) -> (Control
529where 534where
530 PWR: OutputPin, 535 PWR: OutputPin,
531 SPI: SpiDevice, 536 SPI: SpiDevice,
532 SPI::Bus: SpiBusRead + SpiBusWrite, 537 SPI::Bus: SpiBusRead<u32> + SpiBusWrite<u32>,
533{ 538{
534 let mut runner = Runner { 539 let mut runner = Runner {
535 state, 540 state,
@@ -549,7 +554,7 @@ impl<'a, PWR, SPI> Runner<'a, PWR, SPI>
549where 554where
550 PWR: OutputPin, 555 PWR: OutputPin,
551 SPI: SpiDevice, 556 SPI: SpiDevice,
552 SPI::Bus: SpiBusRead + SpiBusWrite, 557 SPI::Bus: SpiBusRead<u32> + SpiBusWrite<u32>,
553{ 558{
554 async fn init(&mut self) { 559 async fn init(&mut self) {
555 // Reset 560 // Reset
@@ -566,8 +571,8 @@ where
566 let val = self.read32_swapped(REG_BUS_TEST).await; 571 let val = self.read32_swapped(REG_BUS_TEST).await;
567 assert_eq!(val, TEST_PATTERN); 572 assert_eq!(val, TEST_PATTERN);
568 573
569 // 32bit, big endian. 574 // 32bit, little endian.
570 self.write32_swapped(REG_BUS_CTRL, 0x00010033).await; 575 self.write32_swapped(REG_BUS_CTRL, 0x00010031).await;
571 576
572 let val = self.read32(FUNC_BUS, REG_BUS_FEEDBEAD).await; 577 let val = self.read32(FUNC_BUS, REG_BUS_FEEDBEAD).await;
573 assert_eq!(val, FEEDBEAD); 578 assert_eq!(val, FEEDBEAD);
@@ -607,14 +612,6 @@ where
607 info!("loading fw"); 612 info!("loading fw");
608 self.bp_write(ram_addr, fw).await; 613 self.bp_write(ram_addr, fw).await;
609 614
610 info!("verifying fw");
611 let mut buf = [0; 1024];
612 for (i, chunk) in fw.chunks(1024).enumerate() {
613 let buf = &mut buf[..chunk.len()];
614 self.bp_read(ram_addr + i as u32 * 1024, buf).await;
615 assert_eq!(chunk, buf);
616 }
617
618 info!("loading nvram"); 615 info!("loading nvram");
619 // Round up to 4 bytes. 616 // Round up to 4 bytes.
620 let nvram_len = (NVRAM.len() + 3) / 4 * 4; 617 let nvram_len = (NVRAM.len() + 3) / 4 * 4;
@@ -675,7 +672,7 @@ where
675 } 672 }
676 673
677 pub async fn run(mut self) -> ! { 674 pub async fn run(mut self) -> ! {
678 let mut buf = [0; 2048]; 675 let mut buf = [0; 512];
679 loop { 676 loop {
680 // Send stuff 677 // Send stuff
681 // TODO flow control 678 // TODO flow control
@@ -707,14 +704,8 @@ where
707 .transaction(|bus| { 704 .transaction(|bus| {
708 let bus = unsafe { &mut *bus }; 705 let bus = unsafe { &mut *bus };
709 async { 706 async {
710 bus.write(&cmd.to_le_bytes()).await?; 707 bus.write(&[cmd]).await?;
711 bus.read(&mut buf[..len as usize]).await?; 708 bus.read(&mut buf[..(len as usize + 3) / 4]).await?;
712 // pad to 32bit
713 let mut junk = [0; 4];
714 if len % 4 != 0 {
715 bus.read(&mut junk[..(4 - len as usize % 4)]).await?;
716 }
717
718 Ok(()) 709 Ok(())
719 } 710 }
720 }) 711 })
@@ -723,7 +714,7 @@ where
723 714
724 trace!("rx {:02x}", &buf[..(len as usize).min(48)]); 715 trace!("rx {:02x}", &buf[..(len as usize).min(48)]);
725 716
726 self.rx(&buf[..len as usize]); 717 self.rx(&slice8_mut(&mut buf)[..len as usize]);
727 } 718 }
728 } 719 }
729 720
@@ -735,7 +726,8 @@ where
735 async fn send_packet(&mut self, packet: &[u8]) { 726 async fn send_packet(&mut self, packet: &[u8]) {
736 trace!("tx pkt {:02x}", &packet[..packet.len().min(48)]); 727 trace!("tx pkt {:02x}", &packet[..packet.len().min(48)]);
737 728
738 let mut buf = [0; 2048]; 729 let mut buf = [0; 512];
730 let buf8 = slice8_mut(&mut buf);
739 731
740 let total_len = SdpcmHeader::SIZE + BcdHeader::SIZE + packet.len(); 732 let total_len = SdpcmHeader::SIZE + BcdHeader::SIZE + packet.len();
741 733
@@ -763,21 +755,21 @@ where
763 trace!("tx {:?}", sdpcm_header); 755 trace!("tx {:?}", sdpcm_header);
764 trace!(" {:?}", bcd_header); 756 trace!(" {:?}", bcd_header);
765 757
766 buf[0..SdpcmHeader::SIZE].copy_from_slice(&sdpcm_header.to_bytes()); 758 buf8[0..SdpcmHeader::SIZE].copy_from_slice(&sdpcm_header.to_bytes());
767 buf[SdpcmHeader::SIZE..][..BcdHeader::SIZE].copy_from_slice(&bcd_header.to_bytes()); 759 buf8[SdpcmHeader::SIZE..][..BcdHeader::SIZE].copy_from_slice(&bcd_header.to_bytes());
768 buf[SdpcmHeader::SIZE + BcdHeader::SIZE..][..packet.len()].copy_from_slice(packet); 760 buf8[SdpcmHeader::SIZE + BcdHeader::SIZE..][..packet.len()].copy_from_slice(packet);
769 761
770 let total_len = (total_len + 3) & !3; // round up to 4byte 762 let total_len = (total_len + 3) & !3; // round up to 4byte
771 763
772 trace!(" {:02x}", &buf[..total_len.min(48)]); 764 trace!(" {:02x}", &buf8[..total_len.min(48)]);
773 765
774 let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _); 766 let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _);
775 self.spi 767 self.spi
776 .transaction(|bus| { 768 .transaction(|bus| {
777 let bus = unsafe { &mut *bus }; 769 let bus = unsafe { &mut *bus };
778 async { 770 async {
779 bus.write(&cmd.to_le_bytes()).await?; 771 bus.write(&[cmd]).await?;
780 bus.write(&buf[..total_len]).await?; 772 bus.write(&buf[..(total_len + 3 / 4)]).await?;
781 Ok(()) 773 Ok(())
782 } 774 }
783 }) 775 })
@@ -875,7 +867,8 @@ where
875 } 867 }
876 868
877 async fn send_ioctl(&mut self, kind: u32, cmd: u32, iface: u32, data: &[u8], id: u16) { 869 async fn send_ioctl(&mut self, kind: u32, cmd: u32, iface: u32, data: &[u8], id: u16) {
878 let mut buf = [0; 2048]; 870 let mut buf = [0; 512];
871 let buf8 = slice8_mut(&mut buf);
879 872
880 let total_len = SdpcmHeader::SIZE + CdcHeader::SIZE + data.len(); 873 let total_len = SdpcmHeader::SIZE + CdcHeader::SIZE + data.len();
881 874
@@ -904,13 +897,13 @@ where
904 trace!("tx {:?}", sdpcm_header); 897 trace!("tx {:?}", sdpcm_header);
905 trace!(" {:?}", cdc_header); 898 trace!(" {:?}", cdc_header);
906 899
907 buf[0..SdpcmHeader::SIZE].copy_from_slice(&sdpcm_header.to_bytes()); 900 buf8[0..SdpcmHeader::SIZE].copy_from_slice(&sdpcm_header.to_bytes());
908 buf[SdpcmHeader::SIZE..][..CdcHeader::SIZE].copy_from_slice(&cdc_header.to_bytes()); 901 buf8[SdpcmHeader::SIZE..][..CdcHeader::SIZE].copy_from_slice(&cdc_header.to_bytes());
909 buf[SdpcmHeader::SIZE + CdcHeader::SIZE..][..data.len()].copy_from_slice(data); 902 buf8[SdpcmHeader::SIZE + CdcHeader::SIZE..][..data.len()].copy_from_slice(data);
910 903
911 let total_len = (total_len + 3) & !3; // round up to 4byte 904 let total_len = (total_len + 3) & !3; // round up to 4byte
912 905
913 trace!(" {:02x}", &buf[..total_len.min(48)]); 906 trace!(" {:02x}", &buf8[..total_len.min(48)]);
914 907
915 let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _); 908 let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _);
916 909
@@ -918,8 +911,8 @@ where
918 .transaction(|bus| { 911 .transaction(|bus| {
919 let bus = unsafe { &mut *bus }; 912 let bus = unsafe { &mut *bus };
920 async { 913 async {
921 bus.write(&cmd.to_le_bytes()).await?; 914 bus.write(&[cmd]).await?;
922 bus.write(&buf[..total_len]).await?; 915 bus.write(&buf[..(total_len + 3) / 4]).await?;
923 Ok(()) 916 Ok(())
924 } 917 }
925 }) 918 })
@@ -984,7 +977,7 @@ where
984 true 977 true
985 } 978 }
986 979
987 async fn bp_read(&mut self, mut addr: u32, mut data: &mut [u8]) { 980 async fn bp_read(&mut self, mut addr: u32, mut data: &mut [u32]) {
988 // It seems the HW force-aligns the addr 981 // It seems the HW force-aligns the addr
989 // to 2 if data.len() >= 2 982 // to 2 if data.len() >= 2
990 // to 4 if data.len() >= 4 983 // to 4 if data.len() >= 4
@@ -1006,19 +999,14 @@ where
1006 .transaction(|bus| { 999 .transaction(|bus| {
1007 let bus = unsafe { &mut *bus }; 1000 let bus = unsafe { &mut *bus };
1008 async { 1001 async {
1009 bus.write(&cmd.to_le_bytes()).await?; 1002 bus.write(&[cmd]).await?;
1010 1003
1011 // 4-byte response delay. 1004 // 4-byte response delay.
1012 let mut junk = [0; 4]; 1005 let mut junk = [0; 1];
1013 bus.read(&mut junk).await?; 1006 bus.read(&mut junk).await?;
1014 1007
1015 // Read data 1008 // Read data
1016 bus.read(&mut data[..len]).await?; 1009 bus.read(&mut data[..len / 4]).await?;
1017
1018 // pad to 32bit
1019 if len % 4 != 0 {
1020 bus.read(&mut junk[..(4 - len % 4)]).await?;
1021 }
1022 Ok(()) 1010 Ok(())
1023 } 1011 }
1024 }) 1012 })
@@ -1027,7 +1015,7 @@ where
1027 1015
1028 // Advance ptr. 1016 // Advance ptr.
1029 addr += len as u32; 1017 addr += len as u32;
1030 data = &mut data[len..]; 1018 data = &mut data[len / 4..];
1031 } 1019 }
1032 } 1020 }
1033 1021
@@ -1038,12 +1026,15 @@ where
1038 // To simplify, enforce 4-align for now. 1026 // To simplify, enforce 4-align for now.
1039 assert!(addr % 4 == 0); 1027 assert!(addr % 4 == 0);
1040 1028
1029 let mut buf = [0u32; BACKPLANE_MAX_TRANSFER_SIZE / 4];
1030
1041 while !data.is_empty() { 1031 while !data.is_empty() {
1042 // Ensure transfer doesn't cross a window boundary. 1032 // Ensure transfer doesn't cross a window boundary.
1043 let window_offs = addr & BACKPLANE_ADDRESS_MASK; 1033 let window_offs = addr & BACKPLANE_ADDRESS_MASK;
1044 let window_remaining = BACKPLANE_WINDOW_SIZE - window_offs as usize; 1034 let window_remaining = BACKPLANE_WINDOW_SIZE - window_offs as usize;
1045 1035
1046 let len = data.len().min(BACKPLANE_MAX_TRANSFER_SIZE).min(window_remaining); 1036 let len = data.len().min(BACKPLANE_MAX_TRANSFER_SIZE).min(window_remaining);
1037 slice8_mut(&mut buf)[..len].copy_from_slice(&data[..len]);
1047 1038
1048 self.backplane_set_window(addr).await; 1039 self.backplane_set_window(addr).await;
1049 1040
@@ -1053,13 +1044,8 @@ where
1053 .transaction(|bus| { 1044 .transaction(|bus| {
1054 let bus = unsafe { &mut *bus }; 1045 let bus = unsafe { &mut *bus };
1055 async { 1046 async {
1056 bus.write(&cmd.to_le_bytes()).await?; 1047 bus.write(&[cmd]).await?;
1057 bus.write(&data[..len]).await?; 1048 bus.write(&buf[..(len + 3) / 4]).await?;
1058 // pad to 32bit
1059 if len % 4 != 0 {
1060 let zeros = [0; 4];
1061 bus.write(&zeros[..(4 - len % 4)]).await?;
1062 }
1063 Ok(()) 1049 Ok(())
1064 } 1050 }
1065 }) 1051 })
@@ -1172,13 +1158,13 @@ where
1172 1158
1173 async fn readn(&mut self, func: u32, addr: u32, len: u32) -> u32 { 1159 async fn readn(&mut self, func: u32, addr: u32, len: u32) -> u32 {
1174 let cmd = cmd_word(false, true, func, addr, len); 1160 let cmd = cmd_word(false, true, func, addr, len);
1175 let mut buf = [0; 4]; 1161 let mut buf = [0; 1];
1176 1162
1177 self.spi 1163 self.spi
1178 .transaction(|bus| { 1164 .transaction(|bus| {
1179 let bus = unsafe { &mut *bus }; 1165 let bus = unsafe { &mut *bus };
1180 async { 1166 async {
1181 bus.write(&cmd.to_le_bytes()).await?; 1167 bus.write(&[cmd]).await?;
1182 if func == FUNC_BACKPLANE { 1168 if func == FUNC_BACKPLANE {
1183 // 4-byte response delay. 1169 // 4-byte response delay.
1184 bus.read(&mut buf).await?; 1170 bus.read(&mut buf).await?;
@@ -1190,7 +1176,7 @@ where
1190 .await 1176 .await
1191 .unwrap(); 1177 .unwrap();
1192 1178
1193 u32::from_le_bytes(buf) 1179 buf[0]
1194 } 1180 }
1195 1181
1196 async fn writen(&mut self, func: u32, addr: u32, val: u32, len: u32) { 1182 async fn writen(&mut self, func: u32, addr: u32, val: u32, len: u32) {
@@ -1200,8 +1186,7 @@ where
1200 .transaction(|bus| { 1186 .transaction(|bus| {
1201 let bus = unsafe { &mut *bus }; 1187 let bus = unsafe { &mut *bus };
1202 async { 1188 async {
1203 bus.write(&cmd.to_le_bytes()).await?; 1189 bus.write(&[cmd, val]).await?;
1204 bus.write(&val.to_le_bytes()).await?;
1205 Ok(()) 1190 Ok(())
1206 } 1191 }
1207 }) 1192 })
@@ -1211,13 +1196,13 @@ where
1211 1196
1212 async fn read32_swapped(&mut self, addr: u32) -> u32 { 1197 async fn read32_swapped(&mut self, addr: u32) -> u32 {
1213 let cmd = cmd_word(false, true, FUNC_BUS, addr, 4); 1198 let cmd = cmd_word(false, true, FUNC_BUS, addr, 4);
1214 let mut buf = [0; 4]; 1199 let mut buf = [0; 1];
1215 1200
1216 self.spi 1201 self.spi
1217 .transaction(|bus| { 1202 .transaction(|bus| {
1218 let bus = unsafe { &mut *bus }; 1203 let bus = unsafe { &mut *bus };
1219 async { 1204 async {
1220 bus.write(&swap16(cmd).to_le_bytes()).await?; 1205 bus.write(&[swap16(cmd)]).await?;
1221 bus.read(&mut buf).await?; 1206 bus.read(&mut buf).await?;
1222 Ok(()) 1207 Ok(())
1223 } 1208 }
@@ -1225,7 +1210,7 @@ where
1225 .await 1210 .await
1226 .unwrap(); 1211 .unwrap();
1227 1212
1228 swap16(u32::from_le_bytes(buf)) 1213 swap16(buf[0])
1229 } 1214 }
1230 1215
1231 async fn write32_swapped(&mut self, addr: u32, val: u32) { 1216 async fn write32_swapped(&mut self, addr: u32, val: u32) {
@@ -1235,8 +1220,7 @@ where
1235 .transaction(|bus| { 1220 .transaction(|bus| {
1236 let bus = unsafe { &mut *bus }; 1221 let bus = unsafe { &mut *bus };
1237 async { 1222 async {
1238 bus.write(&swap16(cmd).to_le_bytes()).await?; 1223 bus.write(&[swap16(cmd), swap16(val)]).await?;
1239 bus.write(&swap16(val).to_le_bytes()).await?;
1240 Ok(()) 1224 Ok(())
1241 } 1225 }
1242 }) 1226 })