humpback-dds/src/config_register.rs

126 lines
2.7 KiB
Rust
Raw Normal View History

2020-08-11 16:51:17 +08:00
use embedded_hal::blocking::spi::Transfer;
use crate::Error;
2020-08-26 11:04:08 +08:00
use core::mem::size_of;
2020-08-11 11:29:47 +08:00
// Bitmasks for CFG
2020-08-13 16:31:27 +08:00
construct_bitmask!(CFGMask; u32;
RF_SW, 0, 4,
2020-08-11 16:51:17 +08:00
LED, 4, 4,
PROFILE, 8, 3,
IO_UPDATE, 12, 1,
MASK_NU, 13, 4,
CLK_SEL0, 17, 1,
SYNC_SEL, 18, 1,
RST, 19, 1,
IO_RST, 20, 1,
CLK_SEL1, 21, 1,
DIV, 22, 2
);
// BitMasks for CFG read
2020-08-13 16:31:27 +08:00
construct_bitmask!(StatusMask; u32;
RF_SW, 0, 4,
2020-08-11 16:55:31 +08:00
SMP_ERR, 4, 4,
PLL_LOCK, 8, 4,
IFC_MODE, 12, 4,
PROTO_KEY, 16, 7
2020-08-11 16:51:17 +08:00
);
2020-08-11 11:29:47 +08:00
pub struct ConfigRegister<SPI> {
spi: SPI,
data: u32,
}
2020-08-11 16:51:17 +08:00
impl<SPI, E> ConfigRegister<SPI>
where
SPI: Transfer<u8, Error = E>
{
pub fn new(spi: SPI) -> Self {
ConfigRegister {
spi,
data: 0,
}
}
2020-08-12 12:26:15 +08:00
/*
* Set configuration bits according to data field
* Return status
*/
2020-08-12 11:50:24 +08:00
fn set_all_configurations(&mut self) -> Result<u32, Error<E>> {
2020-08-11 16:51:17 +08:00
match self.spi.transfer(&mut [
2020-08-12 11:50:24 +08:00
((self.data & 0x00FF0000) >> 16) as u8,
((self.data & 0x0000FF00) >> 8) as u8,
((self.data & 0x000000FF) >> 0) as u8,
2020-08-11 16:51:17 +08:00
]).map_err(Error::SPI) {
2020-08-12 12:26:15 +08:00
Ok(arr) => Ok(
((arr[0] as u32) << 16) |
((arr[1] as u32) << 8) |
arr[2] as u32
),
2020-08-11 16:51:17 +08:00
Err(e) => Err(e),
}
}
2020-08-12 11:50:24 +08:00
2020-08-12 12:26:15 +08:00
/*
* Set configuration bits according to supplied configs
* Return status
*/
2020-08-12 11:50:24 +08:00
pub fn set_configurations(&mut self, configs: &mut[(CFGMask, u32)]) -> Result<u32, Error<E>> {
for config in configs.into_iter() {
2020-08-13 16:31:27 +08:00
config.0.set_data_by_arg(&mut self.data, config.1)
2020-08-12 11:50:24 +08:00
}
// Write all configurations at the same time
self.set_all_configurations()
}
2020-08-12 12:00:11 +08:00
2020-08-12 12:26:15 +08:00
/*
* Return selected configuration field
2020-09-15 14:03:59 +08:00
* TODO: Return result type instead for error checking
2020-08-12 12:26:15 +08:00
*/
2020-08-12 12:00:11 +08:00
pub fn get_configuration(&mut self, config_type: CFGMask) -> u8 {
2020-08-26 16:49:37 +08:00
config_type.get_filtered_content(self.data) as u8
2020-08-12 12:00:11 +08:00
}
2020-08-12 12:26:15 +08:00
/*
2020-08-26 11:04:08 +08:00
* Return status using mask
2020-08-12 12:26:15 +08:00
*/
pub fn get_status(&mut self, status_type: StatusMask) -> Result<u8, Error<E>> {
2020-08-12 12:26:15 +08:00
match self.set_all_configurations() {
2020-08-13 17:17:21 +08:00
Ok(val) => Ok(status_type.get_filtered_content(val) as u8),
2020-08-12 12:26:15 +08:00
Err(e) => Err(e),
}
}
2020-08-26 11:04:08 +08:00
/*
* Return entire status register
*/
pub fn get_all_status(&mut self) -> Result<u32, Error<E>> {
return self.set_all_configurations();
}
2020-08-31 17:43:15 +08:00
/*
* Test method for Configuration Register.
* Return the number of test failed.
*/
pub fn test(&mut self) -> Result<u32, Error<E>> {
// Test configuration register by getting PROTO_KEY.
match self.get_status(StatusMask::PROTO_KEY) {
Ok(8) => Ok(0),
Ok(_) => Ok(1),
Err(_) => Err(Error::ConfigRegisterError),
}
}
2020-08-11 16:51:17 +08:00
}
impl<SPI, E> Transfer<u8> for ConfigRegister<SPI>
where
SPI: Transfer<u8, Error = E>
{
type Error = Error<E>;
fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
self.spi.transfer(words).map_err(Error::SPI)
}
}