Skip to content
This repository has been archived by the owner on Dec 27, 2023. It is now read-only.

Commit

Permalink
Use spi transactions
Browse files Browse the repository at this point in the history
Because we now use SpiDevice, each read/write/transfer also toggles the
CS pin this means we need to use a single transaction or the radio will
send back garbage. This should also make spi transfers more effiecient.
  • Loading branch information
CBJamo committed Oct 16, 2023
1 parent 4f1d55f commit ece1dd3
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 170 deletions.
129 changes: 37 additions & 92 deletions src/interface.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use defmt::trace;
use embedded_hal_async::spi::SpiDevice;
use embedded_hal_async::spi::{Operation, SpiDevice};

use crate::mod_params::RadioError;
use crate::mod_params::RadioError::*;
Expand All @@ -19,125 +19,70 @@ where
Self { spi, iv }
}

// Write one or more buffers to the radio.
pub async fn write(&mut self, write_buffers: &[&[u8]], is_sleep_command: bool) -> Result<(), RadioError> {
for buffer in write_buffers {
let write_result = self.spi.write(buffer).await.map_err(|_| SPI);
if write_result != Ok(()) {
write_result?;
}
}
// Write a buffer to the radio.
pub async fn write(&mut self, write_buffer: &[u8], is_sleep_command: bool) -> Result<(), RadioError> {
self.spi.write(&write_buffer).await.map_err(|_| SPI)?;

if !is_sleep_command {
self.iv.wait_on_busy().await?;
}

match write_buffers.len() {
1 => trace!("write: 0x{:x}", write_buffers[0]),
2 => trace!("write: 0x{:x} 0x{:x}", write_buffers[0], write_buffers[1]),
3 => trace!(
"write: 0x{:x} 0x{:x} 0x{:x}",
write_buffers[0],
write_buffers[1],
write_buffers[2]
),
_ => trace!("write: too many buffers"),
}
trace!("write: 0x{:x}", write_buffer);

Ok(())
}

// Request a read, filling the provided buffer.
pub async fn read(
// Write
pub async fn write_with_payload(
&mut self,
write_buffers: &[&[u8]],
read_buffer: &mut [u8],
read_length: Option<u8>,
write_buffer: &[u8],
payload: &[u8],
is_sleep_command: bool,
) -> Result<(), RadioError> {
let mut input = [0u8];
let mut ops = [Operation::Write(write_buffer), Operation::Write(payload)];
self.spi.transaction(&mut ops).await.map_err(|_| SPI)?;

for buffer in write_buffers {
let write_result = self.spi.write(buffer).await.map_err(|_| SPI);
if write_result != Ok(()) {
write_result?;
}
if !is_sleep_command {
self.iv.wait_on_busy().await?;
}

let number_to_read = match read_length {
Some(len) => len as usize,
None => read_buffer.len(),
};

#[allow(clippy::needless_range_loop)]
for i in 0..number_to_read {
let transfer_result = self.spi.transfer(&mut input, &[0x00]).await.map_err(|_| SPI);
if transfer_result != Ok(()) {
transfer_result?;
}
read_buffer[i] = input[0];
trace!("write: 0x{:x}", write_buffer);

Ok(())
}

// Request a read, filling the provided buffer.
pub async fn read(&mut self, write_buffer: &[u8], read_buffer: &mut [u8]) -> Result<(), RadioError> {
{
let mut ops = [Operation::Write(write_buffer), Operation::Read(read_buffer)];

self.spi.transaction(&mut ops).await.map_err(|_| SPI)?;
}

self.iv.wait_on_busy().await?;

match write_buffers.len() {
1 => trace!("write: 0x{:x}", write_buffers[0]),
2 => trace!("write: 0x{:x} 0x{:x}", write_buffers[0], write_buffers[1]),
3 => trace!(
"write: 0x{:x} 0x{:x} 0x{:x}",
write_buffers[0],
write_buffers[1],
write_buffers[2]
),
_ => trace!("write: too many buffers"),
}
trace!("read {}: 0x{:x}", number_to_read, read_buffer);
trace!("write: 0x{:x}", write_buffer);
trace!("read {}: 0x{:x}", read_buffer.len(), read_buffer);

Ok(())
}

// Request a read with status, filling the provided buffer and returning the status.
pub async fn read_with_status(
&mut self,
write_buffers: &[&[u8]],
read_buffer: &mut [u8],
) -> Result<u8, RadioError> {
pub async fn read_with_status(&mut self, write_buffer: &[u8], read_buffer: &mut [u8]) -> Result<u8, RadioError> {
let mut status = [0u8];
let mut input = [0u8];

for buffer in write_buffers {
let write_result = self.spi.write(buffer).await.map_err(|_| SPI);
if write_result != Ok(()) {
write_result?;
}
}

let transfer_result = self.spi.transfer(&mut status, &[0x00]).await.map_err(|_| SPI);
if transfer_result != Ok(()) {
transfer_result?;
}

#[allow(clippy::needless_range_loop)]
for i in 0..read_buffer.len() {
let transfer_result = self.spi.transfer(&mut input, &[0x00]).await.map_err(|_| SPI);
if transfer_result != Ok(()) {
transfer_result?;
}
read_buffer[i] = input[0];
{
let mut ops = [
Operation::Write(write_buffer),
Operation::Read(&mut status),
Operation::Read(read_buffer),
];

self.spi.transaction(&mut ops).await.map_err(|_| SPI)?;
}

self.iv.wait_on_busy().await?;

match write_buffers.len() {
1 => trace!("write: 0x{:x}", write_buffers[0]),
2 => trace!("write: 0x{:x} 0x{:x}", write_buffers[0], write_buffers[1]),
3 => trace!(
"write: 0x{:x} 0x{:x} 0x{:x}",
write_buffers[0],
write_buffers[1],
write_buffers[2]
),
_ => trace!("write: too many buffers"),
}
trace!("write: 0x{:x}", write_buffer);
trace!(
"read {} status 0x{:x}: 0x{:x}",
read_buffer.len(),
Expand Down
Loading

0 comments on commit ece1dd3

Please sign in to comment.