use core::{fmt, marker::PhantomData};
use embedded_hal::{blocking::spi, digital::v2::OutputPin};
pub struct DW1000<SPI, CS> {
spi: SPI,
chip_select: CS,
}
impl<SPI, CS> DW1000<SPI, CS> {
pub fn new(spi: SPI, chip_select: CS) -> Self {
DW1000 { spi, chip_select }
}
fn block_read<'a>(
&mut self,
id: u8,
start_sub_id: u16,
buffer: &'a mut [u8],
) -> Result<&'a mut [u8], Error<SPI, CS>>
where
SPI: spi::Transfer<u8> + spi::Write<u8>,
CS: OutputPin,
{
buffer[0] = (((start_sub_id as u8) << 6) & 0x40) | (id & 0x3f);
buffer[1] = 0x80 | (start_sub_id & 0x7F) as u8;
buffer[2] = ((start_sub_id & 0x7f80) >> 7) as u8;
self.assert_cs_low()?;
self.spi
.transfer(buffer)
.map_err(|err| Error::Transfer(err))?;
self.assert_cs_high()?;
Ok(&mut buffer[3..])
}
pub fn cir<'a>(
&mut self,
start_index: u16,
buffer: &'a mut [u8],
) -> Result<&'a mut [u8], Error<SPI, CS>>
where
SPI: spi::Transfer<u8> + spi::Write<u8>,
CS: OutputPin,
{
let block = self.block_read(0x25, start_index, buffer)?;
Ok(&mut block[1..])
}
pub fn access_spi<F>(&mut self, f: F)
where
F: FnOnce(SPI) -> SPI,
{
unsafe {
let spi = core::mem::zeroed();
let spi = core::mem::replace(&mut self.spi, spi);
self.spi = f(spi);
}
}
pub(crate) fn assert_cs_low(&mut self) -> Result<(), Error<SPI, CS>>
where
SPI: spi::Transfer<u8> + spi::Write<u8>,
CS: OutputPin,
{
self.chip_select
.set_low()
.map_err(|err| Error::ChipSelect(err))?;
Ok(())
}
pub(crate) fn assert_cs_high(&mut self) -> Result<(), Error<SPI, CS>>
where
SPI: spi::Transfer<u8> + spi::Write<u8>,
CS: OutputPin,
{
self.chip_select
.set_high()
.map_err(|err| Error::ChipSelect(err))?;
Ok(())
}
}
pub struct RegAccessor<'s, R, SPI, CS>(&'s mut DW1000<SPI, CS>, PhantomData<R>);
impl<'s, R, SPI, CS> RegAccessor<'s, R, SPI, CS>
where
SPI: spi::Transfer<u8> + spi::Write<u8>,
CS: OutputPin,
{
pub fn read(&mut self) -> Result<R::Read, Error<SPI, CS>>
where
R: Register + Readable,
{
let mut r = R::read();
let mut buffer = R::buffer(&mut r);
init_header::<R>(false, &mut buffer);
self.0.assert_cs_low()?;
self.0
.spi
.transfer(buffer)
.map_err(|err| Error::Transfer(err))?;
self.0.assert_cs_high()?;
Ok(r)
}
pub fn write<F>(&mut self, f: F) -> Result<(), Error<SPI, CS>>
where
R: Register + Writable,
F: FnOnce(&mut R::Write) -> &mut R::Write,
{
let mut w = R::write();
f(&mut w);
let buffer = R::buffer(&mut w);
init_header::<R>(true, buffer);
self.0.assert_cs_low()?;
<SPI as spi::Write<u8>>::write(&mut self.0.spi, buffer).map_err(|err| Error::Write(err))?;
self.0.assert_cs_high()?;
Ok(())
}
pub fn modify<F>(&mut self, f: F) -> Result<(), Error<SPI, CS>>
where
R: Register + Readable + Writable,
F: for<'r> FnOnce(&mut R::Read, &'r mut R::Write) -> &'r mut R::Write,
{
let mut r = self.read()?;
let mut w = R::write();
<R as Writable>::buffer(&mut w).copy_from_slice(<R as Readable>::buffer(&mut r));
f(&mut r, &mut w);
let buffer = <R as Writable>::buffer(&mut w);
init_header::<R>(true, buffer);
self.0.assert_cs_low()?;
<SPI as spi::Write<u8>>::write(&mut self.0.spi, buffer).map_err(|err| Error::Write(err))?;
self.0.assert_cs_high()?;
Ok(())
}
}
pub enum Error<SPI, CS>
where
SPI: spi::Transfer<u8> + spi::Write<u8>,
CS: OutputPin,
{
Transfer(<SPI as spi::Transfer<u8>>::Error),
Write(<SPI as spi::Write<u8>>::Error),
ChipSelect(<CS as OutputPin>::Error),
}
impl<SPI, CS> fmt::Debug for Error<SPI, CS>
where
SPI: spi::Transfer<u8> + spi::Write<u8>,
<SPI as spi::Transfer<u8>>::Error: fmt::Debug,
<SPI as spi::Write<u8>>::Error: fmt::Debug,
CS: OutputPin,
<CS as OutputPin>::Error: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::Transfer(error) => write!(f, "Transfer({:?})", error),
Error::Write(error) => write!(f, "Write({:?})", error),
Error::ChipSelect(error) => write!(f, "ChipSelect({:?})", error),
}
}
}
fn init_header<R: Register>(write: bool, buffer: &mut [u8]) -> usize {
let sub_id = R::SUB_ID > 0;
buffer[0] = (((write as u8) << 7) & 0x80) | (((sub_id as u8) << 6) & 0x40) | (R::ID & 0x3f);
if !sub_id {
return 1;
}
let ext_addr = R::SUB_ID > 127;
buffer[1] = (((ext_addr as u8) << 7) & 0x80) | (R::SUB_ID as u8 & 0x7f);
if !ext_addr {
return 2;
}
buffer[2] = ((R::SUB_ID & 0x7f80) >> 7) as u8;
3
}
pub trait Register {
const ID: u8;
const SUB_ID: u16;
const LEN: usize;
}
pub trait Readable {
type Read;
fn read() -> Self::Read;
fn buffer(r: &mut Self::Read) -> &mut [u8];
}
pub trait Writable {
type Write;
fn write() -> Self::Write;
fn buffer(w: &mut Self::Write) -> &mut [u8];
}
macro_rules! impl_register {
(
$(
$id:expr,
$sub_id:expr,
$len:expr,
$rw:tt,
$name:ident($name_lower:ident) {
#[$doc:meta]
$(
$field:ident,
$first_bit:expr,
$last_bit:expr,
$ty:ty;
#[$field_doc:meta]
)*
}
)*
) => {
$(
#[$doc]
#[allow(non_camel_case_types)]
pub struct $name;
impl Register for $name {
const ID: u8 = $id;
const SUB_ID: u16 = $sub_id;
const LEN: usize = $len;
}
impl $name {
const SUB_INDEX_IS_NONZERO: usize =
(Self::SUB_ID > 0) as usize;
const SUB_INDEX_NEEDS_SECOND_BYTE: usize =
(Self::SUB_ID > 127) as usize;
const HEADER_LEN: usize =
1
+ Self::SUB_INDEX_IS_NONZERO
+ Self::SUB_INDEX_NEEDS_SECOND_BYTE;
}
#[$doc]
pub mod $name_lower {
use core::fmt;
const HEADER_LEN: usize = super::$name::HEADER_LEN;
pub struct R(pub(crate) [u8; HEADER_LEN + $len]);
impl R {
$(
#[$field_doc]
pub fn $field(&self) -> $ty {
use core::mem::size_of;
use crate::ll::FromBytes;
const START: usize = $first_bit / 8;
const END: usize = $last_bit / 8 + 1;
const LEN: usize = END - START;
let mut bytes = [0; LEN];
bytes[..LEN].copy_from_slice(
&self.0[START+HEADER_LEN .. END+HEADER_LEN]
);
const OFFSET_IN_BYTE: usize = $first_bit % 8;
if OFFSET_IN_BYTE > 0 {
bytes[0] >>= OFFSET_IN_BYTE;
let mut i = 1;
#[allow(exceeding_bitshifts)]
#[allow(arithmetic_overflow)]
while i < LEN {
bytes[i - 1] |=
bytes[i] << 8 - OFFSET_IN_BYTE;
bytes[i] >>= OFFSET_IN_BYTE;
i += 1;
}
}
const SIZE_IN_BITS: usize =
$last_bit - $first_bit + 1;
const BITS_ABOVE_FIELD: usize =
8 - (SIZE_IN_BITS % 8);
const SIZE_IN_BYTES: usize =
(SIZE_IN_BITS - 1) / 8 + 1;
const LAST_INDEX: usize =
SIZE_IN_BYTES - 1;
if BITS_ABOVE_FIELD < 8 {
#[allow(exceeding_bitshifts)]
#[allow(arithmetic_overflow)]
{
bytes[LAST_INDEX] <<= BITS_ABOVE_FIELD;
bytes[LAST_INDEX] >>= BITS_ABOVE_FIELD;
}
}
let bytes = if bytes.len() > size_of::<$ty>() {
&bytes[..size_of::<$ty>()]
}
else {
&bytes
};
<$ty as FromBytes>::from_bytes(bytes)
}
)*
}
impl fmt::Debug for R {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "0x")?;
for i in (0 .. $len).rev() {
write!(f, "{:02x}", self.0[HEADER_LEN + i])?;
}
Ok(())
}
}
pub struct W(pub(crate) [u8; HEADER_LEN + $len]);
impl W {
$(
#[$field_doc]
pub fn $field(&mut self, value: $ty) -> &mut Self {
use crate::ll::ToBytes;
let source = <$ty as ToBytes>::to_bytes(value);
const START: usize = $first_bit / 8;
const END: usize = $last_bit / 8 + 1;
const OFFSET_IN_BYTE: usize = $first_bit % 8;
const LEN: usize = $last_bit - $first_bit + 1;
let mut bits_left = LEN;
let mut bits_left_in_byte = 8;
let mut bits_written_to_byte = 0;
let mut source_i = 0;
let mut target_i = START;
while target_i < END {
let mut mask = 0xff;
let mut offset_in_this_byte = 0;
if target_i == START {
mask <<= OFFSET_IN_BYTE;
offset_in_this_byte = OFFSET_IN_BYTE;
}
if target_i == END - 1 {
let shift =
8 - bits_left - offset_in_this_byte;
mask <<= shift;
mask >>= shift;
}
mask <<= bits_written_to_byte;
let value = source[source_i]
>> 8 - bits_left_in_byte
<< offset_in_this_byte
<< bits_written_to_byte;
self.0[HEADER_LEN + target_i] &= !mask;
self.0[HEADER_LEN + target_i] |= value & mask;
let bits_needed = mask.count_ones() as usize;
let bits_used = bits_needed.min(
bits_left_in_byte - offset_in_this_byte
);
bits_left -= bits_used;
bits_written_to_byte += bits_used;
if bits_left_in_byte > bits_used {
bits_left_in_byte -= bits_used;
}
else {
bits_left_in_byte =
8 - (bits_used - bits_left_in_byte);
source_i += 1;
}
if bits_used == bits_needed {
target_i += 1;
bits_written_to_byte = 0;
}
}
self
}
)*
}
}
impl_rw!($rw, $name, $name_lower, $len);
)*
impl<SPI, CS> DW1000<SPI, CS> {
$(
#[$doc]
pub fn $name_lower(&mut self) -> RegAccessor<$name, SPI, CS> {
RegAccessor(self, PhantomData)
}
)*
}
}
}
macro_rules! impl_rw {
(RO, $name:ident, $name_lower:ident, $len:expr) => {
impl_rw!(@R, $name, $name_lower, $len);
};
(RW, $name:ident, $name_lower:ident, $len:expr) => {
impl_rw!(@R, $name, $name_lower, $len);
impl_rw!(@W, $name, $name_lower, $len);
};
(@R, $name:ident, $name_lower:ident, $len:expr) => {
impl Readable for $name {
type Read = $name_lower::R;
fn read() -> Self::Read {
$name_lower::R([0; Self::HEADER_LEN + $len])
}
fn buffer(r: &mut Self::Read) -> &mut [u8] {
&mut r.0
}
}
};
(@W, $name:ident, $name_lower:ident, $len:expr) => {
impl Writable for $name {
type Write = $name_lower::W;
fn write() -> Self::Write {
$name_lower::W([0; Self::HEADER_LEN + $len])
}
fn buffer(w: &mut Self::Write) -> &mut [u8] {
&mut w.0
}
}
};
}
impl_register! {
0x00, 0x00, 4, RO, DEV_ID(dev_id) { rev, 0, 3, u8; ver, 4, 7, u8; model, 8, 15, u8; ridtag, 16, 31, u16; }
0x01, 0x00, 8, RW, EUI(eui) { value, 0, 63, u64; }
0x03, 0x00, 4, RW, PANADR(panadr) { short_addr, 0, 15, u16; pan_id, 16, 31, u16; }
0x04, 0x00, 4, RW, SYS_CFG(sys_cfg) { ffen, 0, 0, u8; ffbc, 1, 1, u8; ffab, 2, 2, u8; ffad, 3, 3, u8; ffaa, 4, 4, u8; ffam, 5, 5, u8; ffar, 6, 6, u8; ffa4, 7, 7, u8; ffa5, 8, 8, u8; hirq_pol, 9, 9, u8; spi_edge, 10, 10, u8; dis_fce, 11, 11, u8; dis_drxb, 12, 12, u8; dis_phe, 13, 13, u8; dis_rsde, 14, 14, u8; fcs_init2f, 15, 15, u8; phr_mode, 16, 17, u8; dis_stxp, 18, 18, u8; rxm110k, 22, 22, u8; rxwtoe, 28, 28, u8; rxautr, 29, 29, u8; autoack, 30, 30, u8; aackpend, 31, 31, u8; }
0x06, 0x00, 5, RO, SYS_TIME(sys_time) { value, 0, 39, u64; }
0x08, 0x00, 5, RW, TX_FCTRL(tx_fctrl) { tflen, 0, 6, u8; tfle, 7, 9, u8; txbr, 13, 14, u8; tr, 15, 15, u8; txprf, 16, 17, u8; txpsr, 18, 19, u8; pe, 20, 21, u8; txboffs, 22, 31, u16; ifsdelay, 32, 39, u8; }
0x0A, 0x00, 5, RW, DX_TIME(dx_time) { value, 0, 39, u64; }
0x0D, 0x00, 4, RW, SYS_CTRL(sys_ctrl) { sfcst, 0, 0, u8; txstrt, 1, 1, u8; txdlys, 2, 2, u8; cansfcs, 3, 3, u8; trxoff, 6, 6, u8; wait4resp, 7, 7, u8; rxenab, 8, 8, u8; rxdlye, 9, 9, u8; hrbpt, 24, 24, u8; }
0x0E, 0x00, 4, RW, SYS_MASK(sys_mask) { mcplock, 1, 1, u8; mesyncr, 2, 2, u8; maat, 3, 3, u8; mtxfrbm, 4, 4, u8; mtxprs, 5, 5, u8; mtxphs, 6, 6, u8; mtxfrs, 7, 7, u8; mrxprd, 8, 8, u8; mrxsfdd, 9, 9, u8; mldedone, 10, 10, u8; mrxphd, 11, 11, u8; mrxphe, 12, 12, u8; mrxdfr, 13, 13, u8; mrxfcg, 14, 14, u8; mrxfce, 15, 15, u8; mrxrfsl, 16, 16, u8; mrxrfto, 17, 17, u8; mldeerr, 18, 18, u8; mrxovrr, 20, 20, u8; mrxpto, 21, 21, u8; mgpioirq, 22, 22, u8; mslp2init, 23, 23, u8; mrfpllll, 24, 24, u8; mcpllll, 25, 25, u8; mrxsfdto, 26, 26, u8; mhpdwarn, 27, 27, u8; mtxberr, 28, 28, u8; maffrej, 29, 29, u8; }
0x0F, 0x00, 5, RW, SYS_STATUS(sys_status) { irqs, 0, 0, u8; cplock, 1, 1, u8; esyncr, 2, 2, u8; aat, 3, 3, u8; txfrb, 4, 4, u8; txprs, 5, 5, u8; txphs, 6, 6, u8; txfrs, 7, 7, u8; rxprd, 8, 8, u8; rxsfdd, 9, 9, u8; ldedone, 10, 10, u8; rxphd, 11, 11, u8; rxphe, 12, 12, u8; rxdfr, 13, 13, u8; rxfcg, 14, 14, u8; rxfce, 15, 15, u8; rxrfsl, 16, 16, u8; rxrfto, 17, 17, u8; ldeerr, 18, 18, u8; rxovrr, 20, 20, u8; rxpto, 21, 21, u8; gpioirq, 22, 22, u8; slp2init, 23, 23, u8; rfpll_ll, 24, 24, u8; clkpll_ll, 25, 25, u8; rxsfdto, 26, 26, u8; hpdwarn, 27, 27, u8; txberr, 28, 28, u8; affrej, 29, 29, u8; hsrbp, 30, 30, u8; icrbp, 31, 31, u8; rxrscs, 32, 32, u8; rxprej, 33, 33, u8; txpute, 34, 34, u8; }
0x10, 0x00, 4, RO, RX_FINFO(rx_finfo) { rxflen, 0, 6, u8; rxfle, 7, 9, u8; rxnspl, 11, 12, u8; rxbr, 13, 14, u8; rng, 15, 15, u8; rxprfr, 16, 17, u8; rxpsr, 18, 19, u8; rxpacc, 20, 31, u16; }
0x12, 0x00, 8, RO, RX_FQUAL(rx_fqual) { std_noise, 0, 15, u16; fp_ampl2, 16, 31, u16; fp_ampl3, 32, 47, u16; cir_pwr, 48, 63, u16; }
0x13, 0x00, 4, RO, RX_TTCKI(rx_ttcki) { value, 0, 31, u32; }
0x14, 0x00, 5, RO, RX_TTCKO(rx_ttcko) { rxtofs, 0, 18, u32; rsmpdel, 24, 31, u8; rcphase, 32, 39, u8; }
0x15, 0x00, 14, RO, RX_TIME(rx_time) { rx_stamp, 0, 39, u64; fp_index, 40, 55, u16; fp_ampl1, 56, 71, u16; rx_rawst, 72, 111, u64; }
0x17, 0x00, 10, RO, TX_TIME(tx_time) { tx_stamp, 0, 39, u64; tx_rawst, 40, 79, u64; }
0x18, 0x00, 2, RW, TX_ANTD(tx_antd) { value, 0, 15, u16; }
0x19, 0x00, 5, RO, SYS_STATE(sys_state) { tx_state, 0, 3, u8; rx_state, 8, 12, u8; pmsc_state, 16, 23, u8; }
0x1E, 0x00, 4, RW, TX_POWER(tx_power) { value, 0, 31, u32; }
0x1F, 0x00, 4, RW, CHAN_CTRL(chan_ctrl) { tx_chan, 0, 3, u8; rx_chan, 4, 7, u8; dwsfd, 17, 17, u8; rxprf, 18, 19, u8; tnssfd, 20, 20, u8; rnssfd, 21, 21, u8; tx_pcode, 22, 26, u8; rx_pcode, 27, 31, u8; }
0x21, 0x00, 1, RW, SFD_LENGTH(sfd_length) { value, 0, 7, u8; }
0x23, 0x04, 2, RW, AGC_TUNE1(agc_tune1) { value, 0, 15, u16; }
0x23, 0x0C, 4, RW, AGC_TUNE2(agc_tune2) { value, 0, 31, u32; }
0x24, 0x00, 4, RW, EC_CTRL(ec_ctrl) { ostsm, 0, 0, u8; osrsm, 1, 1, u8; pllldt, 2, 2, u8; wait, 3, 10, u8; ostrm, 11, 11, u8; }
0x24, 0x04, 4, RO, EC_RXTC(ec_rxtc) { rx_ts_est, 0, 31, u32; }
0x24, 0x08, 4, RO, EC_GOLP(ec_golp) { offset_ext, 0, 5, u8; }
0x26, 0x00, 4, RW, GPIO_MODE(gpio_mode) { msgp0, 6, 7, u8; msgp1, 8, 9, u8; msgp2, 10, 11, u8; msgp3, 12, 13, u8; msgp4, 14, 15, u8; msgp5, 16, 17, u8; msgp6, 18, 19, u8; msgp7, 20, 21, u8; msgp8, 22, 23, u8; }
0x26, 0x08, 4, RW, GPIO_DIR(gpio_dir) { gdp0, 0, 0, u8; gdp1, 1, 1, u8; gdp2, 2, 2, u8; gdp3, 3, 3, u8; gdm0, 4, 4, u8; gdm1, 5, 5, u8; gdm2, 6, 6, u8; gdm3, 7, 7, u8; gdp4, 8, 8, u8; gdp5, 9, 9, u8; gdp6, 10, 10, u8; gdp7, 11, 11, u8; gdm4, 12, 12, u8; gdm5, 13, 13, u8; gdm6, 14, 14, u8; gdm7, 15, 15, u8; gdp8, 16, 16, u8; gdm8, 20, 20, u8; }
0x26, 0x0C, 4, RW, GPIO_DOUT(gpio_dout) { gop0, 0, 0, u8; gop1, 1, 1, u8; gop2, 2, 2, u8; gop3, 3, 3, u8; gom0, 4, 4, u8; gom1, 5, 5, u8; gom2, 6, 6, u8; gom3, 7, 7, u8; gop4, 8, 8, u8; gop5, 9, 9, u8; gop6, 10, 10, u8; gop7, 11, 11, u8; gom4, 12, 12, u8; gom5, 13, 13, u8; gom6, 14, 14, u8; gom7, 15, 15, u8; gop8, 16, 16, u8; gom8, 20, 20, u8; }
0x26, 0x10, 4, RW, GPIO_IRQE(gpio_irqe) { girqe0, 0, 0, u8; girqe1, 1, 1, u8; girqe2, 2, 2, u8; girqe3, 3, 3, u8; girqe4, 4, 4, u8; girqe5, 5, 5, u8; girqe6, 6, 6, u8; girqe7, 7, 7, u8; girqe8, 8, 8, u8; }
0x26, 0x14, 4, RW, GPIO_ISEN(gpio_isen) { gisen0, 0, 0, u8; gisen1, 1, 1, u8; gisen2, 2, 2, u8; gisen3, 3, 3, u8; gisen4, 4, 4, u8; gisen5, 5, 5, u8; gisen6, 6, 6, u8; gisen7, 7, 7, u8; gisen8, 8, 8, u8; }
0x26, 0x18, 4, RW, GPIO_IMODE(gpio_imode) { gimod0, 0, 0, u8; gimod1, 1, 1, u8; gimod2, 2, 2, u8; gimod3, 3, 3, u8; gimod4, 4, 4, u8; gimod5, 5, 5, u8; gimod6, 6, 6, u8; gimod7, 7, 7, u8; gimod8, 8, 8, u8; }
0x26, 0x1C, 4, RW, GPIO_IBES(gpio_ibes) { gibes0, 0, 0, u8; gibes1, 1, 1, u8; gibes2, 2, 2, u8; gibes3, 3, 3, u8; gibes4, 4, 4, u8; gibes5, 5, 5, u8; gibes6, 6, 6, u8; gibes7, 7, 7, u8; gibes8, 8, 8, u8; }
0x26, 0x20, 4, RW, GPIO_ICLR(gpio_iclr) { giclr0, 0, 0, u8; giclr1, 1, 1, u8; giclr2, 2, 2, u8; giclr3, 3, 3, u8; giclr4, 4, 4, u8; giclr5, 5, 5, u8; giclr6, 6, 6, u8; giclr7, 7, 7, u8; giclr8, 8, 8, u8; }
0x26, 0x24, 4, RW, GPIO_IDBE(gpio_idbe) { gidbe0, 0, 0, u8; gidbe1, 1, 1, u8; gidbe2, 2, 2, u8; gidbe3, 3, 3, u8; gidbe4, 4, 4, u8; gidbe5, 5, 5, u8; gidbe6, 6, 6, u8; gidbe7, 7, 7, u8; gidbe8, 8, 8, u8; }
0x26, 0x28, 4, RW, GPIO_RAW(gpio_raw) { grawp0, 0, 0, u8; grawp1, 1, 1, u8; grawp2, 2, 2, u8; grawp3, 3, 3, u8; grawp4, 4, 4, u8; grawp5, 5, 5, u8; grawp6, 6, 6, u8; grawp7, 7, 7, u8; grawp8, 8, 8, u8; }
0x27, 0x02, 2, RW, DRX_TUNE0B(drx_tune0b) { value, 0, 15, u16; }
0x27, 0x04, 2, RW, DRX_TUNE1A(drx_tune1a) { value, 0, 15, u16; }
0x27, 0x06, 2, RW, DRX_TUNE1B(drx_tune1b) { value, 0, 15, u16; }
0x27, 0x08, 4, RW, DRX_TUNE2(drx_tune2) { value, 0, 31, u32; }
0x27, 0x20, 2, RW, DRX_SFDTOC(drx_sfdtoc) { count, 0, 15, u16; }
0x27, 0x24, 2, RW, DRX_PRETOC(drx_pretoc) { count, 0, 15, u16; }
0x27, 0x26, 2, RW, DRX_TUNE4H(drx_tune4h) { value, 0, 15, u16; }
0x27, 0x28, 2, RO, DRX_CAR_INT(dxr_car_int) { value, 0, 15, u16; }
0x27, 0x2C, 2, RO, RXPACC_NOSAT(rxpacc_nosat) { value, 0, 15, u16; }
0x28, 0x0B, 1, RW, RF_RXCTRLH(rf_rxctrlh) { value, 0, 7, u8; }
0x28, 0x0C, 3, RW, RF_TXCTRL(rf_txctrl) { txmtune, 5, 8, u8; txmq, 9, 11, u8; value, 0, 23, u32; }
0x28, 0x2C, 4, RO, RF_STATUS(rf_status) { cplllock, 0, 0, u8; cplllow, 1, 1, u8; cpllhigh, 2, 2, u8; rfplllock, 3, 3, u8; }
0x28, 0x30, 5, RW, LDOTUNE(ldotune) { value, 0, 39, u64; }
0x2A, 0x0B, 1, RW, TC_PGDELAY(tc_pgdelay) { value, 0, 7, u8; }
0x2B, 0x07, 4, RW, FS_PLLCFG(fs_pllcfg) { value, 0, 31, u32; }
0x2B, 0x0B, 1, RW, FS_PLLTUNE(fs_plltune) { value, 0, 7, u8; }
0x2C, 0x00, 2, RW, AON_WCFG(aon_wcfg) { onw_radc, 0, 0, u8; onw_rx, 1, 1, u8; onw_leui, 3, 3, u8; onw_ldc, 6, 6, u8; onw_l64p, 7, 7, u8; pres_sleep,8, 8, u8; onw_llde, 11, 11, u8; onw_lldo, 12, 12, u8; }
0x2C, 0x02, 1, RW, AON_CTRL(aon_ctrl) { restore, 0, 0, u8; save, 1, 1, u8; upl_cfg, 2, 2, u8; dca_read, 3, 3, u8; dca_enab, 7, 7, u8; }
0x2C, 0x06, 4, RW, AON_CFG0(aon_cfg0) { sleep_en, 0, 0, u8; wake_pin, 1, 1, u8; wake_spi, 2, 2, u8; wake_cnt, 3, 3, u8; lpdiv_en, 4, 4, u8; lpclkdiva, 5, 15, u16; sleep_tim, 16, 31, u16; }
0x2C, 0x0A, 2, RW, AON_CFG1(aon_cfg1) { sleep_cen, 0, 0, u8; smxx, 1, 1, u8; lposc_cal, 2, 2, u8; }
0x2D, 0x04, 2, RW, OTP_ADDR(otp_addr) { value, 0, 10, u16; }
0x2D, 0x06, 2, RW, OTP_CTRL(otp_ctrl) { otprden, 0, 0, u8; otpread, 1, 1, u8; otpmrwr, 3, 3, u8; otpprog, 6, 6, u8; otpmr, 7, 10, u8; ldeload, 15, 15, u8; }
0x2D, 0x0A, 4, RO, OTP_RDAT(otp_rdat) { value, 0, 31, u32; }
0x2E, 0x0806, 1, RW, LDE_CFG1(lde_cfg1) { ntm, 0, 4, u8; pmult, 5, 7, u8; }
0x2E, 0x1000, 2, RO, LDE_PPINDX(lde_ppindx) { value, 0, 15, u16; }
0x2E, 0x1002, 2, RO, LDE_PPAMPL(lde_ppampl) { value, 0, 15, u16; }
0x2E, 0x1804, 2, RW, LDE_RXANTD(lde_rxantd) { value, 0, 15, u16; }
0x2E, 0x1806, 2, RW, LDE_CFG2(lde_cfg2) { value, 0, 15, u16; }
0x2E, 0x2804, 2, RW, LDE_REPC(lde_repc) { value, 0, 15, u16; }
0x2F, 0x00, 4, RW, EVC_CTRL(evc_ctrl) { evc_en, 0, 0, u8; evc_clr, 1, 1, u8; }
0x2F, 0x18, 2, RO, EVC_HPW(evc_hpw) { value, 0, 11, u16; }
0x2F, 0x1A, 2, RO, EVC_TPW(evc_tpw) { value, 0, 11, u16; }
0x36, 0x00, 4, RW, PMSC_CTRL0(pmsc_ctrl0) { sysclks, 0, 1, u8; rxclks, 2, 3, u8; txclks, 4, 5, u8; face, 6, 6, u8; adcce, 10, 10, u8; amce, 15, 15, u8; gpce, 16, 16, u8; gprn, 17, 17, u8; gpdce, 18, 18, u8; gpdrn, 19, 19, u8; khzclken, 23, 23, u8; softreset, 28, 31, u8; raw_value, 0, 31,u32; }
0x36, 0x04, 4, RW, PMSC_CTRL1(pmsc_ctrl1) { arx2init, 1, 1, u8; pktseq, 3, 10, u8; atxslp, 11, 11, u8; arxslp, 12, 12, u8; snoze, 13, 13, u8; snozr, 14, 14, u8; pllsyn, 15, 15, u8; lderune, 17, 17, u8; khzclkdiv, 26, 31, u8; }
0x36, 0x28, 4, RW, PMSC_LEDC(pmsc_ledc) { blink_tim, 0, 7, u8; blnken, 8, 8, u8; blnknow, 16, 19, u8; }
}
#[allow(non_camel_case_types)]
pub struct TX_BUFFER;
impl Register for TX_BUFFER {
const ID: u8 = 0x09;
const SUB_ID: u16 = 0x00;
const LEN: usize = 127;
}
impl Writable for TX_BUFFER {
type Write = tx_buffer::W;
fn write() -> Self::Write {
tx_buffer::W([0; 127 + 1])
}
fn buffer(w: &mut Self::Write) -> &mut [u8] {
&mut w.0
}
}
impl<SPI, CS> DW1000<SPI, CS> {
pub fn tx_buffer(&mut self) -> RegAccessor<TX_BUFFER, SPI, CS> {
RegAccessor(self, PhantomData)
}
}
pub mod tx_buffer {
pub struct W(pub(crate) [u8; 127 + 1]);
impl W {
pub fn data(&mut self) -> &mut [u8] {
&mut self.0[1..]
}
}
}
#[allow(non_camel_case_types)]
pub struct RX_BUFFER;
impl Register for RX_BUFFER {
const ID: u8 = 0x11;
const SUB_ID: u16 = 0x00;
const LEN: usize = 127;
}
impl Readable for RX_BUFFER {
type Read = rx_buffer::R;
fn read() -> Self::Read {
rx_buffer::R([0; 127 + 1])
}
fn buffer(w: &mut Self::Read) -> &mut [u8] {
&mut w.0
}
}
impl<SPI, CS> DW1000<SPI, CS> {
pub fn rx_buffer(&mut self) -> RegAccessor<RX_BUFFER, SPI, CS> {
RegAccessor(self, PhantomData)
}
}
pub mod rx_buffer {
use core::fmt;
const HEADER_LEN: usize = 1;
const LEN: usize = 127;
pub struct R(pub(crate) [u8; HEADER_LEN + LEN]);
impl R {
pub fn data(&self) -> &[u8] {
&self.0[HEADER_LEN..HEADER_LEN + LEN]
}
}
impl fmt::Debug for R {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "0x")?;
for i in (0..LEN).rev() {
write!(f, "{:02x}", self.0[HEADER_LEN + i])?;
}
Ok(())
}
}
}
trait FromBytes {
fn from_bytes(bytes: &[u8]) -> Self;
}
trait ToBytes {
type Bytes;
fn to_bytes(self) -> Self::Bytes;
}
macro_rules! impl_bytes {
($($ty:ty,)*) => {
$(
impl FromBytes for $ty {
fn from_bytes(bytes: &[u8]) -> Self {
let mut val = 0;
for (i, &b) in bytes.iter().enumerate() {
val |= (b as $ty) << (i * 8);
}
val
}
}
impl ToBytes for $ty {
type Bytes = [u8; ::core::mem::size_of::<$ty>()];
fn to_bytes(self) -> Self::Bytes {
let mut bytes = [0; ::core::mem::size_of::<$ty>()];
for (i, b) in bytes.iter_mut().enumerate() {
let shift = 8 * i;
let mask = 0xff << shift;
*b = ((self & mask) >> shift) as u8;
}
bytes
}
}
)*
}
}
impl_bytes! {
u8,
u16,
u32,
u64,
}