diff --git a/src/lib.rs b/src/lib.rs index 0e96fb8..d61482b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,4 +40,39 @@ impl ADIS16475 { self.write_u8(addr+1, data[1]).await?; // higher byte Ok(()) } + + /// efficiently reads multiple u32s by pipelining the spi bus + async fn read_u32_multi(&mut self, addr: [u8;N]) -> Result<[u32;N], T::Error> { + let read = |addr :u8| [(addr & 0x7F), 0]; + + // first address + self.bus.write(&read(addr[0])).await?; + + let mut responses = [0; N]; + + let mut partial: [u16;2] = [0;2]; + let mut partial_idx = 0; + + let mut buf: [u8;2] = [0;2]; + + for i in 1..(addr.len()*2) { + let addr = addr[i/2] + (i as u8 % 2) * 2; + self.bus.transfer(&mut buf, &read(addr)).await?; + + partial[partial_idx] = u16::from_be_bytes(buf); + partial_idx += 1; + + if partial_idx == 2 { + partial_idx = 0; + + responses[i/2 -1] = (partial[1] as u32) << 16 + partial[0] as u32; + } + } + + // last address + self.bus.read(&mut buf).await.unwrap(); + responses[addr.len() - 1] = partial[0] as u32 + (u16::from_be_bytes(buf) as u32) << 16; + + Ok(responses) + } }