From 31b84bc12dba41ee48331bc8a776da2a662b4f33 Mon Sep 17 00:00:00 2001 From: occheung Date: Thu, 13 Aug 2020 16:31:27 +0800 Subject: [PATCH] cfg_reg: mv bitmask operation to macro --- src/config_register.rs | 47 ++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/config_register.rs b/src/config_register.rs index c2f72da..5e41884 100644 --- a/src/config_register.rs +++ b/src/config_register.rs @@ -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)); - } - mask - }, - )* + 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> { 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) } /*