diff options
Diffstat (limited to 'tests/macros.rs')
| -rw-r--r-- | tests/macros.rs | 719 |
1 files changed, 408 insertions, 311 deletions
diff --git a/tests/macros.rs b/tests/macros.rs index 7f84221..211c7bc 100644 --- a/tests/macros.rs +++ b/tests/macros.rs @@ -1,414 +1,511 @@ -//! Tests that read, write, modify, and reset macros -//! work with -//! -//! - scalar register syntax -//! - array register syntax -//! -//! when supplied with -//! -//! - a reference to a register block. -//! - an "instance" type that derefs to a register block. -//! - a pointer to a register block. - #![allow(non_upper_case_globals, non_snake_case)] // Macro conventions. -use ral_registers as ral; +use ral_registers::{self as ral, Instance}; /// A peripheral module. mod periph { #[repr(C)] pub struct RegisterBlock { - pub MY_SCALAR: ral_registers::RWRegister<u32>, - pub MY_ARRAY: [ral_registers::RWRegister<u32>; 3], + pub MY_SCALAR: u32, + pub MY_ARRAY: [u32; 3], + pub MY_2D_ARRAY: [[u32; 3]; 3], + pub MY_BLOCK: MY_BLOCK::RegisterBlock, + pub MY_BLOCKS: [MY_BLOCK::RegisterBlock; 4], } - pub mod MY_SCALAR { - pub mod FIELD_A { - pub const offset: u32 = 0; - pub const mask: u32 = 0x7F << offset; - pub mod R {} - pub mod W {} - pub mod RW {} - } - pub mod FIELD_B { - pub const offset: u32 = 27; - pub const mask: u32 = 0b11 << offset; - pub mod R {} - pub mod W {} - pub mod RW {} + ral_registers::register!(pub MY_SCALAR<u32> RW [ + FIELD_A start(0) width(7) RW {} + /// Field B documentation. + /// + /// It's a field. + FIELD_B start(27) width(2) RW { + /// This is some magic number. + /// + /// It's three. + MAGIC = 0b11, } - } + ]); - /// The register array module resembles the register module for - /// a scalar register. The macros distinguish the index - /// operator from the register name to look up items in - /// this module. pub mod MY_ARRAY { - // For testing convenience, we're pretending that MY_ARRAY - // has the same fields as MY_SCALAR. pub use super::MY_SCALAR::*; } - /// Reset values are always expressed as a scalar, no matter - /// the register plurality. - pub struct ResetValues { - pub MY_SCALAR: u32, - pub MY_ARRAY: u32, + pub mod MY_2D_ARRAY { + pub use super::MY_SCALAR::*; } - pub mod INST { - pub const reset: super::ResetValues = super::ResetValues { - MY_SCALAR: 42, - MY_ARRAY: 42, - }; - } -} + pub mod MY_BLOCK { + #[repr(C)] + pub struct RegisterBlock { + pub BLOCK_SCALAR: u32, + pub BLOCK_ARRAY: [u32; 4], + pub BLOCK_SUBBLOCKS: [[BLOCK_SUBBLOCKS::RegisterBlock; 2]; 2], + } -fn register_block() -> periph::RegisterBlock { - // Safety: bitpattern of zero is fine. - use std::mem::MaybeUninit; - unsafe { MaybeUninit::zeroed().assume_init() } -} + ral_registers::register!(pub BLOCK_SCALAR<u32> RW [ + BLOCK_FIELD_A start(0) width(7) RW {} + BLOCK_FIELD_B start(27) width(2) RW { MAGIC = 0b11 } + ]); -struct Instance<'a> { - rb: &'a periph::RegisterBlock, -} + pub mod BLOCK_ARRAY { + pub use super::BLOCK_SCALAR::*; + } -impl<'a> Instance<'a> { - fn new(rb: &'a periph::RegisterBlock) -> Self { - Self { rb } + pub mod BLOCK_SUBBLOCKS { + #[repr(C)] + pub struct RegisterBlock { + pub SUBBLOCK_SCALAR: u32, + pub SUBBLOCK_ARRAY: [u32; 3], + } + + ral_registers::register!(pub SUBBLOCK_SCALAR<u32> RW [ + SUBBLOCK_FIELD_A start(0) width(7) RW {} + SUBBLOCK_FIELD_B start(27) width(2) RW { MAGIC = 0b11 } + + ]); + pub mod SUBBLOCK_ARRAY { + pub use super::SUBBLOCK_SCALAR::*; + } + } } -} -impl std::ops::Deref for Instance<'_> { - type Target = periph::RegisterBlock; - fn deref(&self) -> &Self::Target { - self.rb + pub mod MY_BLOCKS { + pub use super::MY_BLOCK::*; } } -/// Defines the base cases for read_reg. -/// -/// The goal is to have one macro path that supports both scalar -/// and array tests cases. To achieve that, there's always a register -/// identifier. There's optionally a bracket that has an offset. -macro_rules! read_reg_test_cases { - ($instance:expr, $register:ident $([$offset:expr])*) => { - // Setup: - (*$instance).$register $([$offset])*.write(u32::MAX); - - assert_eq!(ral::read_reg!(periph, $instance, $register $([$offset])*), u32::MAX, "Direct read"); - - assert_eq!(ral::read_reg!(periph, $instance, $register $([$offset])*, FIELD_A), 0x7F, "Individual field read (A)"); - assert_eq!(ral::read_reg!(periph, $instance, $register $([$offset])*, FIELD_B), 0b11, "Individual field read (B)"); - assert_eq!(ral::read_reg!(periph, $instance, $register $([$offset])*, FIELD_A,), 0x7F, "Individual field read with trailing comma"); - - assert_eq!( - ral::read_reg!(periph, $instance, $register $([$offset])*, FIELD_A, FIELD_B), - (0x7F, 0b11), - "Tuple field reads" - ); - - assert!(ral::read_reg!( - periph, - $instance, - $register $([$offset])*, - FIELD_A == 0x7F - ), "Boolean expressions"); - }; +fn zeroed() -> periph::RegisterBlock { + unsafe { std::mem::MaybeUninit::zeroed().assume_init() } } #[test] -fn read_scalar_ref() { - let rb = register_block(); - read_reg_test_cases!(&rb, MY_SCALAR); -} +fn read_scalar() { + let mut block = zeroed(); + block.MY_SCALAR = 4; -#[test] -fn read_scalar_deref() { - let rb = register_block(); - let inst = Instance::new(&rb); - read_reg_test_cases!(inst, MY_SCALAR); + let inst = unsafe { Instance::new_unchecked(&mut block) }; + assert_eq!(ral::read_reg!(periph, inst, MY_SCALAR), 4); } #[test] -fn read_scalar_ptr() { - let ptr: *const _ = ®ister_block(); - unsafe { - read_reg_test_cases!(ptr, MY_SCALAR); - } -} +fn read_array() { + let mut block = zeroed(); + block.MY_ARRAY[1] = 4; -#[test] -fn read_array_ref() { - let rb = register_block(); - read_reg_test_cases!(&rb, MY_ARRAY[1]); + let inst = unsafe { Instance::new_unchecked(&mut block) }; + assert_eq!(ral::read_reg!(periph, inst, MY_ARRAY[1]), 4); } #[test] -fn read_array_deref() { - let rb = register_block(); - let inst = Instance::new(&rb); - read_reg_test_cases!(inst, MY_ARRAY[1]); -} +fn read_2d_array() { + let mut block = zeroed(); + block.MY_2D_ARRAY[1][1] = 4; -#[test] -fn read_array_ptr() { - let ptr: *const _ = ®ister_block(); - unsafe { - read_reg_test_cases!(ptr, MY_ARRAY[1]); - } + let inst = unsafe { Instance::new_unchecked(&mut block) }; + assert_eq!(ral::read_reg!(periph, inst, MY_2D_ARRAY[1][1]), 4); } -#[should_panic] #[test] -fn read_array_out_of_bounds() { - let rb = register_block(); - ral::read_reg!(periph, &rb, MY_ARRAY[42]); -} +fn read_block_scalar() { + let mut block = zeroed(); + block.MY_BLOCK.BLOCK_SCALAR = 4; -/// Base test cases for write_reg. -/// -/// See [read_reg_test_cases] for more information. -macro_rules! write_reg_test_cases { - ($instance:expr, $register:ident $([$offset:expr])*) => { - ral::write_reg!(periph, $instance, $register $([$offset])*, FIELD_A: u32::MAX); - assert_eq!((*$instance).$register $([$offset])*.read(), 0x7F, "1:1 write:field (A)"); - ral::write_reg!(periph, $instance, $register $([$offset])*, FIELD_B: u32::MAX); - assert_eq!((*$instance).$register $([$offset])*.read(), 0b11 << 27, "1:1 write:field (B)"); - ral::write_reg!(periph, $instance, $register $([$offset])*, FIELD_A: u32::MAX,); - assert_eq!((*$instance).$register $([$offset])*.read(), 0x7F, "write with trailing comma"); - - ral::write_reg!( - periph, - $instance, - $register $([$offset])*, - FIELD_A: u32::MAX, - FIELD_B: u32::MAX - ); - assert_eq!((*$instance).$register $([$offset])*.read(), (0b11 << 27) | 0x7F, "1:N write:field"); - - ral::write_reg!(periph, $instance, $register $([$offset])*, 0xAAAAAAAA); - assert_eq!((*$instance).$register $([$offset])*.read(), 0xAAAAAAAA, "Direct write"); - - // Make sure that local variables mask, offset don't shadow macro details. - #[deny(warnings)] - { - let mask = 7; - let offset = 8; - ral::write_reg!(periph, $instance, $register $([$offset])*, FIELD_A: mask, FIELD_B: offset); - } - }; + let inst = unsafe { Instance::new_unchecked(&mut block) }; + assert_eq!(ral::read_reg!(periph, inst, MY_BLOCK.BLOCK_SCALAR), 4); } #[test] -fn write_scalar_ref() { - let rb = register_block(); - write_reg_test_cases!(&rb, MY_SCALAR); +fn read_block_array() { + let mut block = zeroed(); + block.MY_BLOCK.BLOCK_ARRAY[1] = 4; + + let inst = unsafe { Instance::new_unchecked(&mut block) }; + assert_eq!(ral::read_reg!(periph, inst, MY_BLOCK.BLOCK_ARRAY[1]), 4); } #[test] -fn write_scalar_deref() { - let rb = register_block(); - let inst = Instance::new(&rb); - write_reg_test_cases!(inst, MY_SCALAR); +fn read_block_subblock_array() { + let mut block = zeroed(); + block.MY_BLOCK.BLOCK_SUBBLOCKS[1][1].SUBBLOCK_SCALAR = 4; + + let inst = unsafe { Instance::new_unchecked(&mut block) }; + assert_eq!( + ral::read_reg!(periph, inst, MY_BLOCK.BLOCK_SUBBLOCKS[1][1].SUBBLOCK_SCALAR), + 4 + ); } #[test] -fn write_scalar_ptr() { - let ptr: *const _ = ®ister_block(); - unsafe { - write_reg_test_cases!(ptr, MY_SCALAR); - } +fn read_scalar_fields() { + let mut block = zeroed(); + block.MY_SCALAR = u32::MAX; + + let inst = unsafe { Instance::new_unchecked(&mut block) }; + + let a = ral::read_reg!(periph, &&&&&&&&&&inst, MY_SCALAR, FIELD_A); + assert_eq!(a, 0x7F); + + let b = ral::read_reg!(periph, inst, MY_SCALAR, FIELD_B); + assert_eq!(b, 0b11); + + let (a, b) = ral::read_reg!(periph, inst, MY_SCALAR, FIELD_A, FIELD_B); + assert_eq!(a, 0x7F); + assert_eq!(b, 0b11); } #[test] -fn write_array_ref() { - let rb = register_block(); - write_reg_test_cases!(&rb, MY_ARRAY[1]); +fn read_array_fields() { + let mut block = zeroed(); + block.MY_ARRAY[1] = u32::MAX; + + let inst = unsafe { Instance::new_unchecked(&mut block) }; + + let a = ral::read_reg!(periph, inst, MY_ARRAY[1], FIELD_A); + assert_eq!(a, 0x7F); + + let b = ral::read_reg!(periph, inst, MY_ARRAY[1], FIELD_B); + assert_eq!(b, 0b11); + + let (a, b) = ral::read_reg!(periph, inst, MY_ARRAY[1], FIELD_A, FIELD_B); + assert_eq!(a, 0x7F); + assert_eq!(b, 0b11); } #[test] -fn write_array_deref() { - let rb = register_block(); - let inst = Instance::new(&rb); - write_reg_test_cases!(inst, MY_ARRAY[1]); +fn read_2d_array_fields() { + let mut block = zeroed(); + block.MY_2D_ARRAY[1][1] = u32::MAX; + + let inst = unsafe { Instance::new_unchecked(&mut block) }; + + let a = ral::read_reg!(::self::periph, inst, MY_2D_ARRAY[1][1], FIELD_A); + assert_eq!(a, 0x7F); + + let b = ral::read_reg!(periph, inst, MY_2D_ARRAY[1][1], FIELD_B); + assert_eq!(b, 0b11); + + let (a, b) = ral::read_reg!(periph, inst, MY_2D_ARRAY[1][1], FIELD_A, FIELD_B); + assert_eq!(a, 0x7F); + assert_eq!(b, 0b11); } #[test] -fn write_array_ptr() { - let ptr: *const _ = ®ister_block(); - unsafe { - write_reg_test_cases!(ptr, MY_ARRAY[1]); - } +fn read_block_scalar_fields() { + let mut block = zeroed(); + block.MY_BLOCK.BLOCK_SCALAR = u32::MAX; + + let inst = unsafe { Instance::new_unchecked(&mut block) }; + + let a = ral::read_reg!(periph, inst, MY_BLOCK.BLOCK_SCALAR, BLOCK_FIELD_A); + assert_eq!(a, 0x7F); + + let b = ral::read_reg!(periph, inst, MY_BLOCK.BLOCK_SCALAR, BLOCK_FIELD_B); + assert_eq!(b, 0b11); + + let (a, b) = ral::read_reg!( + periph, + inst, + MY_BLOCK.BLOCK_SCALAR, + BLOCK_FIELD_A, + BLOCK_FIELD_B + ); + assert_eq!(a, 0x7F); + assert_eq!(b, 0b11); } -#[should_panic] #[test] -fn write_array_out_of_bounds() { - let rb = register_block(); - ral::write_reg!(periph, &rb, MY_ARRAY[42], 7); -} +fn read_block_array_fields() { + let mut block = zeroed(); + block.MY_BLOCK.BLOCK_ARRAY[1] = u32::MAX; -/// Base test cases for modify_reg. -/// -/// See [read_reg_test_cases] for more information. -macro_rules! modify_reg_test_cases { - ($instance:expr, $register:ident $([$offset:expr])*) => { - ral::modify_reg!(periph, $instance, $register $([$offset])*, FIELD_A: u32::MAX); - assert_eq!((*$instance).$register $([$offset])*.read(), 0x7F, "RMW individual fields (A)"); - ral::modify_reg!(periph, $instance, $register $([$offset])*, FIELD_B: u32::MAX); - assert_eq!((*$instance).$register $([$offset])*.read(), 0x7F | (0b11 << 27), "RMW individual fields (B)"); - ral::modify_reg!(periph, $instance, $register $([$offset])*, FIELD_A: u32::MIN,); - assert_eq!((*$instance).$register $([$offset])*.read(), (0b11 << 27), "RMW with trailing comma"); - - ral::modify_reg!(periph, $instance, $register $([$offset])*, FIELD_A: 2, FIELD_B: 2); - assert_eq!((*$instance).$register $([$offset])*.read(), 2 | (2 << 27), "RMW multiple fields"); - - ral::modify_reg!(periph, $instance, $register $([$offset])*, |reg| { - assert_eq!(reg, 2 | (2 << 27)); - reg | u32::MAX - }); - assert_eq!((*$instance).$register $([$offset])*.read(), u32::MAX, "RMW whole register"); - - // Make sure that local variables mask, offset don't shadow macro details. - #[deny(warnings)] - { - let mask = 7; - let offset = 8; - ral::modify_reg!(periph, $instance, $register $([$offset])*, FIELD_A: mask, FIELD_B: offset); - } - }; + let inst = unsafe { Instance::new_unchecked(&mut block) }; + + let a = ral::read_reg!(periph, inst, MY_BLOCK.BLOCK_ARRAY[1], BLOCK_FIELD_A); + assert_eq!(a, 0x7F); + + let b = ral::read_reg!(periph, inst, MY_BLOCK.BLOCK_ARRAY[1], BLOCK_FIELD_B); + assert_eq!(b, 0b11); + + let (a, b) = ral::read_reg!( + periph, + inst, + MY_BLOCK.BLOCK_ARRAY[1], + BLOCK_FIELD_A, + BLOCK_FIELD_B + ); + assert_eq!(a, 0x7F); + assert_eq!(b, 0b11); } #[test] -fn modify_scalar_ref() { - let rb = register_block(); - modify_reg_test_cases!(&rb, MY_SCALAR); +fn read_block_subblock_scalar_fields() { + let mut block = zeroed(); + block.MY_BLOCK.BLOCK_SUBBLOCKS[1][1].SUBBLOCK_SCALAR = u32::MAX; + + let inst = unsafe { Instance::new_unchecked(&mut block) }; + + let a = ral::read_reg!( + periph, + inst, + MY_BLOCK.BLOCK_SUBBLOCKS[1][1].SUBBLOCK_SCALAR, + SUBBLOCK_FIELD_A + ); + assert_eq!(a, 0x7F); + + let b = ral::read_reg!( + periph, + inst, + MY_BLOCK.BLOCK_SUBBLOCKS[1][1].SUBBLOCK_SCALAR, + SUBBLOCK_FIELD_B + ); + assert_eq!(b, 0b11); + + let (a, b) = ral::read_reg!( + periph, + inst, + MY_BLOCK.BLOCK_SUBBLOCKS[1][1].SUBBLOCK_SCALAR, + SUBBLOCK_FIELD_A, + SUBBLOCK_FIELD_B + ); + assert_eq!(a, 0x7F); + assert_eq!(b, 0b11); } #[test] -fn modify_scalar_deref() { - let rb = register_block(); - let inst = Instance::new(&rb); - modify_reg_test_cases!(inst, MY_SCALAR); +fn read_blocks_subblock_array_fields() { + let mut block = zeroed(); + block.MY_BLOCKS[0].BLOCK_SUBBLOCKS[1][1].SUBBLOCK_ARRAY[0] = u32::MAX; + + let inst = unsafe { Instance::new_unchecked(&mut block) }; + + let a = ral::read_reg!( + periph, + inst, + MY_BLOCKS[0].BLOCK_SUBBLOCKS[1][1].SUBBLOCK_ARRAY[0], + SUBBLOCK_FIELD_A + ); + assert_eq!(a, 0x7F); + + let b = ral::read_reg!( + periph, + inst, + MY_BLOCKS[0].BLOCK_SUBBLOCKS[1][1].SUBBLOCK_ARRAY[0], + SUBBLOCK_FIELD_B + ); + assert_eq!(b, 0b11); + + let (a, b) = ral::read_reg!( + periph, + inst, + MY_BLOCKS[0].BLOCK_SUBBLOCKS[1][1].SUBBLOCK_ARRAY[0], + SUBBLOCK_FIELD_A, + SUBBLOCK_FIELD_B + ); + assert_eq!(a, 0x7F); + assert_eq!(b, 0b11); } #[test] -fn modify_scalar_ptr() { - let ptr: *const _ = ®ister_block(); - unsafe { - modify_reg_test_cases!(ptr, MY_SCALAR); - } +fn read_scalar_field_cmp() { + let mut block = zeroed(); + block.MY_SCALAR = u32::MAX; + + let inst = unsafe { Instance::new_unchecked(&mut block) }; + assert!(ral::read_reg!(periph, inst, MY_SCALAR, FIELD_A == 0x7f)); + assert!(ral::read_reg!(periph, inst, MY_SCALAR, FIELD_B == MAGIC)); } #[test] -fn modify_array_ref() { - let rb = register_block(); - modify_reg_test_cases!(&rb, MY_ARRAY[1]); +fn read_array_field_cmp() { + let mut block = zeroed(); + block.MY_ARRAY[1] = u32::MAX; + + let inst = unsafe { Instance::new_unchecked(&mut block) }; + assert!(ral::read_reg!(periph, inst, MY_ARRAY[1], FIELD_A == 0x7f)); + assert!(ral::read_reg!(periph, inst, MY_ARRAY[1], FIELD_B == MAGIC)); } #[test] -fn modify_array_deref() { - let rb = register_block(); - let inst = Instance::new(&rb); - modify_reg_test_cases!(inst, MY_ARRAY[1]); +fn read_2d_array_field_cmp() { + let mut block = zeroed(); + block.MY_2D_ARRAY[0][1] = u32::MAX; + + let inst = unsafe { Instance::new_unchecked(&mut block) }; + assert!(ral::read_reg!( + periph, + inst, + MY_2D_ARRAY[0][1], + FIELD_A == 0x7f + )); + assert!(ral::read_reg!( + periph, + inst, + MY_2D_ARRAY[0][1], + FIELD_B == MAGIC + )); } #[test] -fn modify_array_ptr() { - let ptr: *const _ = ®ister_block(); - unsafe { - modify_reg_test_cases!(ptr, MY_ARRAY[1]); - } +fn read_blocks_subblock_array_fields_cmp() { + let mut block = zeroed(); + block.MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0] = u32::MAX; + + let inst = unsafe { Instance::new_unchecked(&mut block) }; + assert!(ral::read_reg!( + periph, + inst, + MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], + SUBBLOCK_FIELD_A == 0x7f + )); + assert!(ral::read_reg!( + periph, + inst, + MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], + SUBBLOCK_FIELD_B == MAGIC + )); } -#[should_panic] #[test] -fn modify_array_out_of_bounds() { - let rb = register_block(); - ral::modify_reg!(periph, &rb, MY_ARRAY[42], |_| 7); -} +fn write_blocks_subblock_array() { + let mut block = zeroed(); -/// Base test cases for reset_reg. -/// -/// See [read_reg_test_cases] for more information. -macro_rules! reset_reg_test_cases { - ($instance:expr, $register:ident $([$offset:expr])*) => { - (*$instance).$register $([$offset])*.write(u32::MAX); - ral::reset_reg!(periph, $instance, INST, $register $([$offset])*); - assert_eq!((*$instance).$register $([$offset])*.read(), 42, "Entire register"); - - (*$instance).$register $([$offset])*.write(u32::MAX); - ral::reset_reg!(periph, $instance, INST, $register $([$offset])*, FIELD_B); - assert_eq!((*$instance).$register $([$offset])*.read(), u32::MAX & !(0b11 << 27), "Field in register (B)"); - ral::reset_reg!(periph, $instance, INST, $register $([$offset])*, FIELD_A); - assert_eq!( - (*$instance).$register $([$offset])*.read(), - u32::MAX & !(0b11 << 27) & !0x7F | 42, - "Field in register (A)" - ); - - (*$instance).$register $([$offset])*.write(u32::MAX); - ral::reset_reg!(periph, $instance, INST, $register $([$offset])*, FIELD_B,); - assert_eq!((*$instance).$register $([$offset])*.read(), u32::MAX & !(0b11 << 27), "With trailing comma"); - - - (*$instance).$register $([$offset])*.write(u32::MAX); - ral::reset_reg!(periph, $instance, INST, $register $([$offset])*, FIELD_B, FIELD_A); - assert_eq!( - (*$instance).$register $([$offset])*.read(), - u32::MAX & !(0b11 << 27) & !0x7F | 42, - "Fields in register" - ); - }; -} + let inst = unsafe { Instance::new_unchecked(&mut block) }; + ral::write_reg!( + periph, + inst, + MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], + 42 + ); -#[test] -fn reset_scalar_ref() { - let rb = register_block(); - reset_reg_test_cases!(&rb, MY_SCALAR); + assert_eq!( + block.MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], + 42 + ); } #[test] -fn reset_scalar_deref() { - let rb = register_block(); - let inst = Instance::new(&rb); - reset_reg_test_cases!(inst, MY_SCALAR); +fn write_blocks_subblock_array_fields() { + let mut block = zeroed(); + let inst = unsafe { Instance::new_unchecked(&mut block) }; + + ral::write_reg!( + periph, + &&&&&&inst, + MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], + SUBBLOCK_FIELD_A: u32::MAX, + SUBBLOCK_FIELD_B: u32::MAX, + ); + + assert_eq!( + block.MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], + (0b11 << 27) | 0x7f + ); + + let get_inst = || inst; + + ral::write_reg!( + periph, + get_inst(), + MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], + SUBBLOCK_FIELD_A: u32::MAX, + ); + + assert_eq!( + block.MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], + 0x7f + ); + + ral::write_reg!( + crate::periph, + &&&inst, + MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], + SUBBLOCK_FIELD_B: MAGIC, + ); + + assert_eq!( + block.MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], + 0b11 << 27 + ); } #[test] -fn reset_scalar_ptr() { - let ptr: *const _ = ®ister_block(); - unsafe { - reset_reg_test_cases!(ptr, MY_SCALAR); - } -} +fn modify_blocks_subblock_array() { + let mut block = zeroed(); + block.MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0] = u32::MAX; + + let inst = unsafe { Instance::new_unchecked(&mut block) }; + ral::modify_reg!( + periph, + &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&inst, + MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], + |v| { + let x = !0xAAAA_AAAA; + v & x + } + ); -#[test] -fn reset_array_ref() { - let rb = register_block(); - reset_reg_test_cases!(&rb, MY_ARRAY[1]); + assert_eq!( + block.MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], + 0x5555_5555 + ); } #[test] -fn reset_array_deref() { - let rb = register_block(); - let inst = Instance::new(&rb); - reset_reg_test_cases!(inst, MY_ARRAY[1]); +fn modify_blocks_subblock_array_fields() { + let mut block = zeroed(); + + let inst = unsafe { Instance::new_unchecked(&mut block) }; + ral::modify_reg!( + ::periph, + inst, + MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], + SUBBLOCK_FIELD_A: u32::MAX, + SUBBLOCK_FIELD_B: MAGIC, + ); + + assert_eq!( + block.MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], + (0b11 << 27) | 0x7F, + ); } #[test] -fn reset_array_ptr() { - let ptr: *const _ = ®ister_block(); - unsafe { - reset_reg_test_cases!(ptr, MY_ARRAY[1]); - } +#[deny(warnings)] +fn mask_offset_access_shadowing() { + let mut block = zeroed(); + let inst = unsafe { Instance::new_unchecked(&mut block) }; + + let mask = 1; + let offset = 2; + let access = 3; + + ral::write_reg!(::periph, inst, MY_SCALAR, FIELD_A: (mask | offset | access)); + ral::modify_reg!(::periph, inst, MY_ARRAY[0], FIELD_A: mask, FIELD_B: offset); + ral::modify_reg!(::periph, inst, MY_SCALAR, FIELD_A: access); } -#[should_panic] #[test] -fn reset_array_out_of_bounds() { - let rb = register_block(); - ral::reset_reg!(periph, &rb, INST, MY_ARRAY[42]); +#[deny(warnings)] +fn macro_unsafe_inline() { + let mut block = zeroed(); + ral::read_reg!( + periph, + unsafe { Instance::new_unchecked(&mut block) }, + MY_SCALAR + ); + ral::write_reg!( + periph, + unsafe { Instance::new_unchecked(&mut block) }, + MY_SCALAR, + 5 + ); + ral::modify_reg!( + periph, unsafe { Instance::new_unchecked(&mut block) }, MY_SCALAR, FIELD_A: 5 + ); + ral::modify_reg!( + periph, + unsafe { Instance::new_unchecked(&mut block) }, + MY_SCALAR, + |_| 5 + ); } |
