forked from M-Labs/humpback-dds
cfg_reg: mv bitmask operation to macro
This commit is contained in:
parent
cbe36e336d
commit
31b84bc12d
|
@ -4,9 +4,11 @@ use crate::Error;
|
|||
|
||||
/*
|
||||
* Macro builder for bit masks
|
||||
* Assumption: Contiguous bit field
|
||||
* Break the bit field up when invoking macro rule if needed
|
||||
*/
|
||||
macro_rules! construct_bitmask {
|
||||
($collection: ident; $($name: ident, $shift: expr, $width: expr),+) => {
|
||||
($collection: ident; $unsigned_type: ty; $($name: ident, $shift: expr, $width: expr),+) => {
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum $collection {
|
||||
$(
|
||||
|
@ -29,25 +31,32 @@ macro_rules! construct_bitmask {
|
|||
)*
|
||||
}
|
||||
}
|
||||
pub(crate) fn get_bitmask(self) -> u32 {
|
||||
match self {
|
||||
$(
|
||||
$collection::$name => {
|
||||
let mut mask: u32 = 0;
|
||||
for bit in 0..$width {
|
||||
mask |= (1 << ($shift + bit));
|
||||
pub(crate) fn get_bitmask(self) -> $unsigned_type {
|
||||
let mut mask: $unsigned_type = 0;
|
||||
for bit in 0..self.get_width() {
|
||||
mask |= (1 << (self.get_shift() + bit));
|
||||
}
|
||||
mask
|
||||
},
|
||||
)*
|
||||
}
|
||||
pub(crate) fn get_shifted_bits(self, arg: $unsigned_type) -> $unsigned_type {
|
||||
assert!(arg < (2 << self.get_width()));
|
||||
(arg << self.get_shift())
|
||||
}
|
||||
pub(crate) fn set_data_by_arg(self, data: &mut $unsigned_type, arg: $unsigned_type) {
|
||||
// Clear bits in field, then insert shifted argument
|
||||
*data &= (!self.get_bitmask());
|
||||
*data |= self.get_shifted_bits(arg);
|
||||
}
|
||||
pub(crate) fn get_filtered_content(self, data: $unsigned_type) -> $unsigned_type {
|
||||
// Filter everything
|
||||
((data & self.get_bitmask()) >> self.get_shift())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bitmasks for CFG
|
||||
construct_bitmask!(CFGMask;
|
||||
construct_bitmask!(CFGMask; u32;
|
||||
RF_SW, 0, 4,
|
||||
LED, 4, 4,
|
||||
PROFILE, 8, 3,
|
||||
|
@ -62,7 +71,7 @@ construct_bitmask!(CFGMask;
|
|||
);
|
||||
|
||||
// BitMasks for CFG read
|
||||
construct_bitmask!(StatusMask;
|
||||
construct_bitmask!(StatusMask; u32;
|
||||
RF_SW, 0, 4,
|
||||
SMP_ERR, 4, 4,
|
||||
PLL_LOCK, 8, 4,
|
||||
|
@ -111,13 +120,7 @@ where
|
|||
*/
|
||||
pub fn set_configurations(&mut self, configs: &mut[(CFGMask, u32)]) -> Result<u32, Error<E>> {
|
||||
for config in configs.into_iter() {
|
||||
// Erase the bits in the configuration region
|
||||
self.data &= (!config.0.get_bitmask());
|
||||
// Check validity of config data
|
||||
let shifted_config: u32 = config.1 << config.0.get_shift();
|
||||
assert_eq!(shifted_config | config.0.get_bitmask(), config.0.get_bitmask());
|
||||
// Write the configuration onto local data
|
||||
self.data |= shifted_config;
|
||||
config.0.set_data_by_arg(&mut self.data, config.1)
|
||||
}
|
||||
// Write all configurations at the same time
|
||||
self.set_all_configurations()
|
||||
|
@ -127,7 +130,7 @@ where
|
|||
* Return selected configuration field
|
||||
*/
|
||||
pub fn get_configuration(&mut self, config_type: CFGMask) -> u8 {
|
||||
((self.data & config_type.get_bitmask()) >> config_type.get_shift()) as u8
|
||||
(config_type.get_filtered_content(self.data) as u8)
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue