|
| 1 | +//! Bit banding |
| 2 | +//! |
| 3 | +//! Support for the manipulation of peripheral registers through bit-banding. |
| 4 | +//! Not all peripherals are mapped to the bit-banding alias region, the peripheral bit-band region |
| 5 | +//! is from `0x4000_0000` to `0x400F_FFFF`. Bit-banding allows the manipulation of individual bits |
| 6 | +//! atomically. |
| 7 | +
|
| 8 | +use core::ptr; |
| 9 | + |
| 10 | +// Start address of the peripheral memory region capable of being addressed by bit-banding |
| 11 | +const PERI_ADDRESS_START: usize = 0x4000_0000; |
| 12 | +const PERI_ADDRESS_END: usize = 0x400F_FFFF; |
| 13 | + |
| 14 | +const PERI_BIT_BAND_BASE: usize = 0x4200_0000; |
| 15 | + |
| 16 | +/// Clears the bit on the provided register without modifying other bits. |
| 17 | +/// |
| 18 | +/// # Safety |
| 19 | +/// |
| 20 | +/// Some registers have reserved bits which should not be modified. |
| 21 | +pub unsafe fn clear<T>(register: *const T, bit: u8) { |
| 22 | + write(register, bit, false); |
| 23 | +} |
| 24 | + |
| 25 | +/// Sets the bit on the provided register without modifying other bits. |
| 26 | +/// |
| 27 | +/// # Safety |
| 28 | +/// |
| 29 | +/// Some registers have reserved bits which should not be modified. |
| 30 | +pub unsafe fn set<T>(register: *const T, bit: u8) { |
| 31 | + write(register, bit, true); |
| 32 | +} |
| 33 | + |
| 34 | +/// Sets or clears the bit on the provided register without modifying other bits. |
| 35 | +/// |
| 36 | +/// # Safety |
| 37 | +/// |
| 38 | +/// Some registers have reserved bits which should not be modified. |
| 39 | +pub unsafe fn write<T>(register: *const T, bit: u8, set: bool) { |
| 40 | + let addr = register as usize; |
| 41 | + |
| 42 | + assert!(addr >= PERI_ADDRESS_START && addr <= PERI_ADDRESS_END); |
| 43 | + assert!(bit < 32); |
| 44 | + |
| 45 | + let bit = bit as usize; |
| 46 | + let bb_addr = (PERI_BIT_BAND_BASE + (addr - PERI_ADDRESS_START) * 32) + 4 * bit; |
| 47 | + ptr::write_volatile(bb_addr as *mut u32, if set { 1 } else { 0 }); |
| 48 | +} |
0 commit comments