diff --git a/src/config.rs b/src/config.rs index ca6ced37..10555e20 100644 --- a/src/config.rs +++ b/src/config.rs @@ -17,6 +17,7 @@ pub struct Config { pub target: Target, pub atomics: bool, pub atomics_feature: Option, + pub bit_banding: bool, pub generic_mod: bool, pub make_mod: bool, pub skip_crate_attributes: bool, diff --git a/src/generate/device.rs b/src/generate/device.rs index d2b3ee9c..c5ea0f07 100644 --- a/src/generate/device.rs +++ b/src/generate/device.rs @@ -143,6 +143,7 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result Result Result Reg { + /// Writes bit with "bit-banding". + #[inline(always)] + pub fn bb_write(&self, f: F, set: bool) + where + F: FnOnce(&mut W) -> BitWriter, + bool: From, + { + self.bbwrite(f, set) + } + #[inline(always)] + fn bbwrite(&self, f: F, set: bool) + where + F: FnOnce(&mut W) -> raw::BitWriter, + bool: From, + { + // Start address of the peripheral memory region capable of being addressed by bit-banding + const PERI_ADDRESS_START: usize = 0x4000_0000; + const PERI_BIT_BAND_BASE: usize = 0x4200_0000; + + let addr = self.as_ptr() as usize; + let bit = f(&mut W { + bits: REG::Ux::default(), + _reg: marker::PhantomData, + }) + .o as usize; + let bit = bit as usize; + let bb_addr = (PERI_BIT_BAND_BASE + (addr - PERI_ADDRESS_START) * 32) + 4 * bit; + unsafe { core::ptr::write_volatile(bb_addr as *mut u32, u32::from(set)) }; + } + + /// Sets bit with "bit-banding". + #[inline(always)] + pub fn bb_set(&self, f: F) + where + F: FnOnce(&mut W) -> raw::BitWriter, + bool: From, + B: BBSet, + { + self.bbwrite(f, true); + } + + /// Clears bit with "bit-banding". + #[inline(always)] + pub fn bb_clear(&self, f: F) + where + F: FnOnce(&mut W) -> raw::BitWriter, + bool: From, + B: BBClear, + { + self.bbwrite(f, false); + } +} + +pub trait BBSet {} +pub trait BBClear {} +impl BBSet for BitM {} +impl BBSet for Bit1S {} +impl BBSet for Bit1C {} +impl BBSet for Bit1T {} +impl BBClear for BitM {} +impl BBClear for Bit0S {} +impl BBClear for Bit0C {} +impl BBClear for Bit0T {} diff --git a/src/main.rs b/src/main.rs index 27607bfc..5b08729e 100755 --- a/src/main.rs +++ b/src/main.rs @@ -128,6 +128,13 @@ fn run() -> Result<()> { .action(ArgAction::Set) .value_name("FEATURE"), ) + .arg( + Arg::new("bit_banding") + .long("bit-banding") + .alias("bit_banding") + .action(ArgAction::SetTrue) + .help("Generate bit-banding register modification API"), + ) .arg( Arg::new("ignore_groups") .long("ignore-groups")