use std::fmt;
use std::marker;
#[derive(PartialEq, Eq, Copy, Clone)]
#[repr(C)]
pub struct Segment<'a, 'b> {
tx_buf: u64,
rx_buf: u64,
len: u32,
speed_hz: u32,
delay_usecs: u16,
bits_per_word: u8,
cs_change: u8,
tx_nbits: u8,
rx_nbits: u8,
pad: u16,
read_buffer_lifetime: marker::PhantomData<&'a mut [u8]>,
write_buffer_lifetime: marker::PhantomData<&'b [u8]>,
}
impl<'a, 'b> Segment<'a, 'b> {
pub fn new(read_buffer: &'a mut [u8], write_buffer: &'b [u8]) -> Segment<'a, 'b> {
Segment::with_settings(Some(read_buffer), Some(write_buffer), 0, 0, 0, false)
}
pub fn with_read(buffer: &mut [u8]) -> Segment<'_, '_> {
Segment::with_settings(Some(buffer), None, 0, 0, 0, false)
}
pub fn with_write(buffer: &[u8]) -> Segment<'_, '_> {
Segment::with_settings(None, Some(buffer), 0, 0, 0, false)
}
pub fn with_settings(
read_buffer: Option<&'a mut [u8]>,
write_buffer: Option<&'b [u8]>,
clock_speed: u32,
delay: u16,
bits_per_word: u8,
ss_change: bool,
) -> Segment<'a, 'b> {
let mut len: u32 = 0;
let tx_buf = if let Some(buffer) = write_buffer {
len = buffer.len() as u32;
buffer.as_ptr() as u64
} else {
0
};
let rx_buf = if let Some(buffer) = read_buffer {
if (len > buffer.len() as u32) || tx_buf == 0 {
len = buffer.len() as u32;
}
buffer.as_ptr() as u64
} else {
0
};
Segment {
tx_buf,
rx_buf,
len,
speed_hz: clock_speed,
delay_usecs: delay,
bits_per_word,
cs_change: ss_change as u8,
tx_nbits: 0,
rx_nbits: 0,
pad: 0,
read_buffer_lifetime: marker::PhantomData,
write_buffer_lifetime: marker::PhantomData,
}
}
pub fn len(&self) -> usize {
self.len as usize
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn clock_speed(&self) -> u32 {
self.speed_hz
}
pub fn set_clock_speed(&mut self, clock_speed: u32) {
self.speed_hz = clock_speed;
}
pub fn delay(&self) -> u16 {
self.delay_usecs
}
pub fn set_delay(&mut self, delay: u16) {
self.delay_usecs = delay;
}
pub fn bits_per_word(&self) -> u8 {
self.bits_per_word
}
pub fn set_bits_per_word(&mut self, bits_per_word: u8) {
self.bits_per_word = bits_per_word;
}
pub fn ss_change(&self) -> bool {
self.cs_change == 1
}
pub fn set_ss_change(&mut self, ss_change: bool) {
self.cs_change = ss_change as u8;
}
}
impl<'a, 'b> fmt::Debug for Segment<'a, 'b> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Segment")
.field("tx_buf", &self.tx_buf)
.field("rx_buf", &self.rx_buf)
.field("len", &self.len)
.field("speed_hz", &self.speed_hz)
.field("delay_usecs", &self.delay_usecs)
.field("bits_per_word", &self.bits_per_word)
.field("cs_change", &self.cs_change)
.field("tx_nbits", &self.tx_nbits)
.field("rx_nbits", &self.rx_nbits)
.field("pad", &self.pad)
.finish()
}
}