#![allow(non_upper_case_globals, non_snake_case)] // Macro conventions. use ral_registers::{self as ral, Instance}; /// A peripheral module. mod periph { #[repr(C)] pub struct RegisterBlock { 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], } ral_registers::register!(pub MY_SCALAR 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, } ]); pub mod MY_ARRAY { pub use super::MY_SCALAR::*; } pub mod MY_2D_ARRAY { pub use super::MY_SCALAR::*; } 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], } ral_registers::register!(pub BLOCK_SCALAR RW [ BLOCK_FIELD_A start(0) width(7) RW {} BLOCK_FIELD_B start(27) width(2) RW { MAGIC = 0b11 } ]); pub mod BLOCK_ARRAY { pub use super::BLOCK_SCALAR::*; } pub mod BLOCK_SUBBLOCKS { #[repr(C)] pub struct RegisterBlock { pub SUBBLOCK_SCALAR: u32, pub SUBBLOCK_ARRAY: [u32; 3], } ral_registers::register!(pub SUBBLOCK_SCALAR 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::*; } } } pub mod MY_BLOCKS { pub use super::MY_BLOCK::*; } } fn zeroed() -> periph::RegisterBlock { unsafe { std::mem::MaybeUninit::zeroed().assume_init() } } #[test] fn read_scalar() { let mut block = zeroed(); block.MY_SCALAR = 4; let inst = unsafe { Instance::new_unchecked(&mut block) }; assert_eq!(ral::read_reg!(periph, inst, MY_SCALAR), 4); } #[test] fn read_array() { let mut block = zeroed(); block.MY_ARRAY[1] = 4; let inst = unsafe { Instance::new_unchecked(&mut block) }; assert_eq!(ral::read_reg!(periph, inst, MY_ARRAY[1]), 4); } #[test] fn read_2d_array() { let mut block = zeroed(); block.MY_2D_ARRAY[1][1] = 4; let inst = unsafe { Instance::new_unchecked(&mut block) }; assert_eq!(ral::read_reg!(periph, inst, MY_2D_ARRAY[1][1]), 4); } #[test] fn read_block_scalar() { let mut block = zeroed(); block.MY_BLOCK.BLOCK_SCALAR = 4; let inst = unsafe { Instance::new_unchecked(&mut block) }; assert_eq!(ral::read_reg!(periph, inst, MY_BLOCK.BLOCK_SCALAR), 4); } #[test] 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 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 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 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 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 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); } #[test] fn read_block_array_fields() { let mut block = zeroed(); block.MY_BLOCK.BLOCK_ARRAY[1] = u32::MAX; 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 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 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 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 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 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 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 )); } #[test] fn write_blocks_subblock_array() { 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], 42 ); assert_eq!( block.MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], 42 ); } #[test] 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 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 } ); assert_eq!( block.MY_BLOCKS[0].BLOCK_SUBBLOCKS[0][0].SUBBLOCK_ARRAY[0], 0x5555_5555 ); } #[test] 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] #[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); } #[test] #[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 ); }