Switch to 32bit SPI.
This commit is contained in:
		| @@ -153,17 +153,17 @@ impl SpiBusFlush for MySpi { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl SpiBusRead for MySpi { | ||||
| impl SpiBusRead<u32> for MySpi { | ||||
|     type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> | ||||
|     where | ||||
|         Self: 'a; | ||||
|  | ||||
|     fn read<'a>(&'a mut self, words: &'a mut [u8]) -> Self::ReadFuture<'a> { | ||||
|     fn read<'a>(&'a mut self, words: &'a mut [u32]) -> Self::ReadFuture<'a> { | ||||
|         async move { | ||||
|             self.dio.set_as_input(); | ||||
|             for word in words { | ||||
|                 let mut w = 0; | ||||
|                 for _ in 0..8 { | ||||
|                 for _ in 0..32 { | ||||
|                     w = w << 1; | ||||
|  | ||||
|                     // rising edge, sample data | ||||
| @@ -183,20 +183,20 @@ impl SpiBusRead for MySpi { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl SpiBusWrite for MySpi { | ||||
| impl SpiBusWrite<u32> for MySpi { | ||||
|     type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> | ||||
|     where | ||||
|         Self: 'a; | ||||
|  | ||||
|     fn write<'a>(&'a mut self, words: &'a [u8]) -> Self::WriteFuture<'a> { | ||||
|     fn write<'a>(&'a mut self, words: &'a [u32]) -> Self::WriteFuture<'a> { | ||||
|         async move { | ||||
|             self.dio.set_as_output(); | ||||
|             for word in words { | ||||
|                 let mut word = *word; | ||||
|                 for _ in 0..8 { | ||||
|                 for _ in 0..32 { | ||||
|                     // falling edge, setup data | ||||
|                     self.clk.set_low(); | ||||
|                     if word & 0x80 == 0 { | ||||
|                     if word & 0x8000_0000 == 0 { | ||||
|                         self.dio.set_low(); | ||||
|                     } else { | ||||
|                         self.dio.set_high(); | ||||
|   | ||||
							
								
								
									
										112
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										112
									
								
								src/lib.rs
									
									
									
									
									
								
							| @@ -28,13 +28,18 @@ use self::structs::*; | ||||
| use crate::events::Event; | ||||
|  | ||||
| fn swap16(x: u32) -> u32 { | ||||
|     (x & 0xFF00FF00) >> 8 | (x & 0x00FF00FF) << 8 | ||||
|     x.rotate_left(16) | ||||
| } | ||||
|  | ||||
| fn cmd_word(write: bool, incr: bool, func: u32, addr: u32, len: u32) -> u32 { | ||||
|     (write as u32) << 31 | (incr as u32) << 30 | (func & 0b11) << 28 | (addr & 0x1FFFF) << 11 | (len & 0x7FF) | ||||
| } | ||||
|  | ||||
| fn slice8_mut(x: &mut [u32]) -> &mut [u8] { | ||||
|     let len = x.len() * 4; | ||||
|     unsafe { slice::from_raw_parts_mut(x.as_mut_ptr() as _, len) } | ||||
| } | ||||
|  | ||||
| const FUNC_BUS: u32 = 0; | ||||
| const FUNC_BACKPLANE: u32 = 1; | ||||
| const FUNC_WLAN: u32 = 2; | ||||
| @@ -529,7 +534,7 @@ pub async fn new<'a, PWR, SPI>(state: &'a State, pwr: PWR, spi: SPI) -> (Control | ||||
| where | ||||
|     PWR: OutputPin, | ||||
|     SPI: SpiDevice, | ||||
|     SPI::Bus: SpiBusRead + SpiBusWrite, | ||||
|     SPI::Bus: SpiBusRead<u32> + SpiBusWrite<u32>, | ||||
| { | ||||
|     let mut runner = Runner { | ||||
|         state, | ||||
| @@ -549,7 +554,7 @@ impl<'a, PWR, SPI> Runner<'a, PWR, SPI> | ||||
| where | ||||
|     PWR: OutputPin, | ||||
|     SPI: SpiDevice, | ||||
|     SPI::Bus: SpiBusRead + SpiBusWrite, | ||||
|     SPI::Bus: SpiBusRead<u32> + SpiBusWrite<u32>, | ||||
| { | ||||
|     async fn init(&mut self) { | ||||
|         // Reset | ||||
| @@ -566,8 +571,8 @@ where | ||||
|         let val = self.read32_swapped(REG_BUS_TEST).await; | ||||
|         assert_eq!(val, TEST_PATTERN); | ||||
|  | ||||
|         // 32bit, big endian. | ||||
|         self.write32_swapped(REG_BUS_CTRL, 0x00010033).await; | ||||
|         // 32bit, little endian. | ||||
|         self.write32_swapped(REG_BUS_CTRL, 0x00010031).await; | ||||
|  | ||||
|         let val = self.read32(FUNC_BUS, REG_BUS_FEEDBEAD).await; | ||||
|         assert_eq!(val, FEEDBEAD); | ||||
| @@ -607,14 +612,6 @@ where | ||||
|         info!("loading fw"); | ||||
|         self.bp_write(ram_addr, fw).await; | ||||
|  | ||||
|         info!("verifying fw"); | ||||
|         let mut buf = [0; 1024]; | ||||
|         for (i, chunk) in fw.chunks(1024).enumerate() { | ||||
|             let buf = &mut buf[..chunk.len()]; | ||||
|             self.bp_read(ram_addr + i as u32 * 1024, buf).await; | ||||
|             assert_eq!(chunk, buf); | ||||
|         } | ||||
|  | ||||
|         info!("loading nvram"); | ||||
|         // Round up to 4 bytes. | ||||
|         let nvram_len = (NVRAM.len() + 3) / 4 * 4; | ||||
| @@ -675,7 +672,7 @@ where | ||||
|     } | ||||
|  | ||||
|     pub async fn run(mut self) -> ! { | ||||
|         let mut buf = [0; 2048]; | ||||
|         let mut buf = [0; 512]; | ||||
|         loop { | ||||
|             // Send stuff | ||||
|             // TODO flow control | ||||
| @@ -707,14 +704,8 @@ where | ||||
|                         .transaction(|bus| { | ||||
|                             let bus = unsafe { &mut *bus }; | ||||
|                             async { | ||||
|                                 bus.write(&cmd.to_le_bytes()).await?; | ||||
|                                 bus.read(&mut buf[..len as usize]).await?; | ||||
|                                 // pad to 32bit | ||||
|                                 let mut junk = [0; 4]; | ||||
|                                 if len % 4 != 0 { | ||||
|                                     bus.read(&mut junk[..(4 - len as usize % 4)]).await?; | ||||
|                                 } | ||||
|  | ||||
|                                 bus.write(&[cmd]).await?; | ||||
|                                 bus.read(&mut buf[..(len as usize + 3) / 4]).await?; | ||||
|                                 Ok(()) | ||||
|                             } | ||||
|                         }) | ||||
| @@ -723,7 +714,7 @@ where | ||||
|  | ||||
|                     trace!("rx {:02x}", &buf[..(len as usize).min(48)]); | ||||
|  | ||||
|                     self.rx(&buf[..len as usize]); | ||||
|                     self.rx(&slice8_mut(&mut buf)[..len as usize]); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @@ -735,7 +726,8 @@ where | ||||
|     async fn send_packet(&mut self, packet: &[u8]) { | ||||
|         trace!("tx pkt {:02x}", &packet[..packet.len().min(48)]); | ||||
|  | ||||
|         let mut buf = [0; 2048]; | ||||
|         let mut buf = [0; 512]; | ||||
|         let buf8 = slice8_mut(&mut buf); | ||||
|  | ||||
|         let total_len = SdpcmHeader::SIZE + BcdHeader::SIZE + packet.len(); | ||||
|  | ||||
| @@ -763,21 +755,21 @@ where | ||||
|         trace!("tx {:?}", sdpcm_header); | ||||
|         trace!("    {:?}", bcd_header); | ||||
|  | ||||
|         buf[0..SdpcmHeader::SIZE].copy_from_slice(&sdpcm_header.to_bytes()); | ||||
|         buf[SdpcmHeader::SIZE..][..BcdHeader::SIZE].copy_from_slice(&bcd_header.to_bytes()); | ||||
|         buf[SdpcmHeader::SIZE + BcdHeader::SIZE..][..packet.len()].copy_from_slice(packet); | ||||
|         buf8[0..SdpcmHeader::SIZE].copy_from_slice(&sdpcm_header.to_bytes()); | ||||
|         buf8[SdpcmHeader::SIZE..][..BcdHeader::SIZE].copy_from_slice(&bcd_header.to_bytes()); | ||||
|         buf8[SdpcmHeader::SIZE + BcdHeader::SIZE..][..packet.len()].copy_from_slice(packet); | ||||
|  | ||||
|         let total_len = (total_len + 3) & !3; // round up to 4byte | ||||
|  | ||||
|         trace!("    {:02x}", &buf[..total_len.min(48)]); | ||||
|         trace!("    {:02x}", &buf8[..total_len.min(48)]); | ||||
|  | ||||
|         let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _); | ||||
|         self.spi | ||||
|             .transaction(|bus| { | ||||
|                 let bus = unsafe { &mut *bus }; | ||||
|                 async { | ||||
|                     bus.write(&cmd.to_le_bytes()).await?; | ||||
|                     bus.write(&buf[..total_len]).await?; | ||||
|                     bus.write(&[cmd]).await?; | ||||
|                     bus.write(&buf[..(total_len + 3 / 4)]).await?; | ||||
|                     Ok(()) | ||||
|                 } | ||||
|             }) | ||||
| @@ -875,7 +867,8 @@ where | ||||
|     } | ||||
|  | ||||
|     async fn send_ioctl(&mut self, kind: u32, cmd: u32, iface: u32, data: &[u8], id: u16) { | ||||
|         let mut buf = [0; 2048]; | ||||
|         let mut buf = [0; 512]; | ||||
|         let buf8 = slice8_mut(&mut buf); | ||||
|  | ||||
|         let total_len = SdpcmHeader::SIZE + CdcHeader::SIZE + data.len(); | ||||
|  | ||||
| @@ -904,13 +897,13 @@ where | ||||
|         trace!("tx {:?}", sdpcm_header); | ||||
|         trace!("    {:?}", cdc_header); | ||||
|  | ||||
|         buf[0..SdpcmHeader::SIZE].copy_from_slice(&sdpcm_header.to_bytes()); | ||||
|         buf[SdpcmHeader::SIZE..][..CdcHeader::SIZE].copy_from_slice(&cdc_header.to_bytes()); | ||||
|         buf[SdpcmHeader::SIZE + CdcHeader::SIZE..][..data.len()].copy_from_slice(data); | ||||
|         buf8[0..SdpcmHeader::SIZE].copy_from_slice(&sdpcm_header.to_bytes()); | ||||
|         buf8[SdpcmHeader::SIZE..][..CdcHeader::SIZE].copy_from_slice(&cdc_header.to_bytes()); | ||||
|         buf8[SdpcmHeader::SIZE + CdcHeader::SIZE..][..data.len()].copy_from_slice(data); | ||||
|  | ||||
|         let total_len = (total_len + 3) & !3; // round up to 4byte | ||||
|  | ||||
|         trace!("    {:02x}", &buf[..total_len.min(48)]); | ||||
|         trace!("    {:02x}", &buf8[..total_len.min(48)]); | ||||
|  | ||||
|         let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _); | ||||
|  | ||||
| @@ -918,8 +911,8 @@ where | ||||
|             .transaction(|bus| { | ||||
|                 let bus = unsafe { &mut *bus }; | ||||
|                 async { | ||||
|                     bus.write(&cmd.to_le_bytes()).await?; | ||||
|                     bus.write(&buf[..total_len]).await?; | ||||
|                     bus.write(&[cmd]).await?; | ||||
|                     bus.write(&buf[..(total_len + 3) / 4]).await?; | ||||
|                     Ok(()) | ||||
|                 } | ||||
|             }) | ||||
| @@ -984,7 +977,7 @@ where | ||||
|         true | ||||
|     } | ||||
|  | ||||
|     async fn bp_read(&mut self, mut addr: u32, mut data: &mut [u8]) { | ||||
|     async fn bp_read(&mut self, mut addr: u32, mut data: &mut [u32]) { | ||||
|         // It seems the HW force-aligns the addr | ||||
|         // to 2 if data.len() >= 2 | ||||
|         // to 4 if data.len() >= 4 | ||||
| @@ -1006,19 +999,14 @@ where | ||||
|                 .transaction(|bus| { | ||||
|                     let bus = unsafe { &mut *bus }; | ||||
|                     async { | ||||
|                         bus.write(&cmd.to_le_bytes()).await?; | ||||
|                         bus.write(&[cmd]).await?; | ||||
|  | ||||
|                         // 4-byte response delay. | ||||
|                         let mut junk = [0; 4]; | ||||
|                         let mut junk = [0; 1]; | ||||
|                         bus.read(&mut junk).await?; | ||||
|  | ||||
|                         // Read data | ||||
|                         bus.read(&mut data[..len]).await?; | ||||
|  | ||||
|                         // pad to 32bit | ||||
|                         if len % 4 != 0 { | ||||
|                             bus.read(&mut junk[..(4 - len % 4)]).await?; | ||||
|                         } | ||||
|                         bus.read(&mut data[..len / 4]).await?; | ||||
|                         Ok(()) | ||||
|                     } | ||||
|                 }) | ||||
| @@ -1027,7 +1015,7 @@ where | ||||
|  | ||||
|             // Advance ptr. | ||||
|             addr += len as u32; | ||||
|             data = &mut data[len..]; | ||||
|             data = &mut data[len / 4..]; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -1038,12 +1026,15 @@ where | ||||
|         // To simplify, enforce 4-align for now. | ||||
|         assert!(addr % 4 == 0); | ||||
|  | ||||
|         let mut buf = [0u32; BACKPLANE_MAX_TRANSFER_SIZE / 4]; | ||||
|  | ||||
|         while !data.is_empty() { | ||||
|             // Ensure transfer doesn't cross a window boundary. | ||||
|             let window_offs = addr & BACKPLANE_ADDRESS_MASK; | ||||
|             let window_remaining = BACKPLANE_WINDOW_SIZE - window_offs as usize; | ||||
|  | ||||
|             let len = data.len().min(BACKPLANE_MAX_TRANSFER_SIZE).min(window_remaining); | ||||
|             slice8_mut(&mut buf)[..len].copy_from_slice(&data[..len]); | ||||
|  | ||||
|             self.backplane_set_window(addr).await; | ||||
|  | ||||
| @@ -1053,13 +1044,8 @@ where | ||||
|                 .transaction(|bus| { | ||||
|                     let bus = unsafe { &mut *bus }; | ||||
|                     async { | ||||
|                         bus.write(&cmd.to_le_bytes()).await?; | ||||
|                         bus.write(&data[..len]).await?; | ||||
|                         // pad to 32bit | ||||
|                         if len % 4 != 0 { | ||||
|                             let zeros = [0; 4]; | ||||
|                             bus.write(&zeros[..(4 - len % 4)]).await?; | ||||
|                         } | ||||
|                         bus.write(&[cmd]).await?; | ||||
|                         bus.write(&buf[..(len + 3) / 4]).await?; | ||||
|                         Ok(()) | ||||
|                     } | ||||
|                 }) | ||||
| @@ -1172,13 +1158,13 @@ where | ||||
|  | ||||
|     async fn readn(&mut self, func: u32, addr: u32, len: u32) -> u32 { | ||||
|         let cmd = cmd_word(false, true, func, addr, len); | ||||
|         let mut buf = [0; 4]; | ||||
|         let mut buf = [0; 1]; | ||||
|  | ||||
|         self.spi | ||||
|             .transaction(|bus| { | ||||
|                 let bus = unsafe { &mut *bus }; | ||||
|                 async { | ||||
|                     bus.write(&cmd.to_le_bytes()).await?; | ||||
|                     bus.write(&[cmd]).await?; | ||||
|                     if func == FUNC_BACKPLANE { | ||||
|                         // 4-byte response delay. | ||||
|                         bus.read(&mut buf).await?; | ||||
| @@ -1190,7 +1176,7 @@ where | ||||
|             .await | ||||
|             .unwrap(); | ||||
|  | ||||
|         u32::from_le_bytes(buf) | ||||
|         buf[0] | ||||
|     } | ||||
|  | ||||
|     async fn writen(&mut self, func: u32, addr: u32, val: u32, len: u32) { | ||||
| @@ -1200,8 +1186,7 @@ where | ||||
|             .transaction(|bus| { | ||||
|                 let bus = unsafe { &mut *bus }; | ||||
|                 async { | ||||
|                     bus.write(&cmd.to_le_bytes()).await?; | ||||
|                     bus.write(&val.to_le_bytes()).await?; | ||||
|                     bus.write(&[cmd, val]).await?; | ||||
|                     Ok(()) | ||||
|                 } | ||||
|             }) | ||||
| @@ -1211,13 +1196,13 @@ where | ||||
|  | ||||
|     async fn read32_swapped(&mut self, addr: u32) -> u32 { | ||||
|         let cmd = cmd_word(false, true, FUNC_BUS, addr, 4); | ||||
|         let mut buf = [0; 4]; | ||||
|         let mut buf = [0; 1]; | ||||
|  | ||||
|         self.spi | ||||
|             .transaction(|bus| { | ||||
|                 let bus = unsafe { &mut *bus }; | ||||
|                 async { | ||||
|                     bus.write(&swap16(cmd).to_le_bytes()).await?; | ||||
|                     bus.write(&[swap16(cmd)]).await?; | ||||
|                     bus.read(&mut buf).await?; | ||||
|                     Ok(()) | ||||
|                 } | ||||
| @@ -1225,7 +1210,7 @@ where | ||||
|             .await | ||||
|             .unwrap(); | ||||
|  | ||||
|         swap16(u32::from_le_bytes(buf)) | ||||
|         swap16(buf[0]) | ||||
|     } | ||||
|  | ||||
|     async fn write32_swapped(&mut self, addr: u32, val: u32) { | ||||
| @@ -1235,8 +1220,7 @@ where | ||||
|             .transaction(|bus| { | ||||
|                 let bus = unsafe { &mut *bus }; | ||||
|                 async { | ||||
|                     bus.write(&swap16(cmd).to_le_bytes()).await?; | ||||
|                     bus.write(&swap16(val).to_le_bytes()).await?; | ||||
|                     bus.write(&[swap16(cmd), swap16(val)]).await?; | ||||
|                     Ok(()) | ||||
|                 } | ||||
|             }) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user