diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-07-16 18:06:57 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-07-16 18:06:57 +0200 |
| commit | 931e3d7ee0cb1ff9f320b22aab3f4ea375a1c624 (patch) | |
| tree | 63e0f277d49814a634d31a7bbfa02d0cd807871d /src | |
| parent | 7dfdea87971bf7a951b2b1d3fc2e50e245005d07 (diff) | |
Switch to 32bit SPI.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 112 |
1 files changed, 48 insertions, 64 deletions
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::*; | |||
| 28 | use crate::events::Event; | 28 | use crate::events::Event; |
| 29 | 29 | ||
| 30 | fn swap16(x: u32) -> u32 { | 30 | fn swap16(x: u32) -> u32 { |
| 31 | (x & 0xFF00FF00) >> 8 | (x & 0x00FF00FF) << 8 | 31 | x.rotate_left(16) |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | fn cmd_word(write: bool, incr: bool, func: u32, addr: u32, len: u32) -> u32 { | 34 | fn 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 | ||
| 38 | fn 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 | |||
| 38 | const FUNC_BUS: u32 = 0; | 43 | const FUNC_BUS: u32 = 0; |
| 39 | const FUNC_BACKPLANE: u32 = 1; | 44 | const FUNC_BACKPLANE: u32 = 1; |
| 40 | const FUNC_WLAN: u32 = 2; | 45 | const FUNC_WLAN: u32 = 2; |
| @@ -529,7 +534,7 @@ pub async fn new<'a, PWR, SPI>(state: &'a State, pwr: PWR, spi: SPI) -> (Control | |||
| 529 | where | 534 | where |
| 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> | |||
| 549 | where | 554 | where |
| 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 | }) |
