Switch to 32bit SPI.
This commit is contained in:
parent
7dfdea8797
commit
931e3d7ee0
2 changed files with 55 additions and 71 deletions
|
@ -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(())
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue