have you ever wanted to use a 8051-based MCU with rust (neither rust nor LLVM support 8051) and were annoyed about having to use pointers to access special function registers? and were too lazy to just write a regex that does this? then i got the macro for you. just load in a SDCC board SFR definition file and invoke the macro with it! why do i even do this shit
macro_rules! reg_block {
($cont:item) => {
pub mod ptr {
#[allow(non_snake_case)]
macro_rules! SFR {
($name:ident, $offset:expr) => {
#[allow(non_camel_case_types, dead_code)]
pub const $name: *const volatile_register::RW<u8> = (0xC0000000u32+$offset) as *const volatile_register::RW<u8>;
};
}
#[allow(non_snake_case)]
macro_rules! SBIT {
($name:ident, $offset:expr, $bit:expr) => {
};
}
#[allow(non_snake_case)]
macro_rules! SFR16E {
($name:ident, $offset:expr) => {
#[allow(non_camel_case_types, dead_code)]
pub const $name: *const volatile_register::RW<u16> = (0xC0000000u32+$offset) as *const volatile_register::RW<u16>;
};
}
$cont
}
pub mod bit_ptr {
#[allow(non_snake_case)]
macro_rules! SFR {
($name:ident, $offset:expr) => {
};
}
#[allow(non_snake_case)]
macro_rules! SBIT {
($name:ident, $offset:expr, $bit:expr) => {
#[allow(non_camel_case_types, dead_code)]
pub const $name: *const volatile_register::RW<u8> = (0xC0000000u32+$offset) as *const volatile_register::RW<u8>;
};
}
#[allow(non_snake_case)]
macro_rules! SFR16E {
($name:ident, $offset:expr) => {
};
}
$cont
}
pub mod bit_num {
#[allow(non_snake_case)]
macro_rules! SFR {
($name:ident, $offset:expr) => {
};
}
#[allow(non_snake_case)]
macro_rules! SBIT {
($name:ident, $offset:expr, $bit:expr) => {
#[allow(non_camel_case_types, dead_code)]
pub const $name: u8 = $bit;
};
}
#[allow(non_snake_case)]
macro_rules! SFR16E {
($name:ident, $offset:expr) => {
};
}
$cont
}
}
}
reg_block! {pub mod inner {
SFR!(P0, 0x80); // Port 0
SBIT!(P0_0, 0x80, 0); // Port 0 bit 0
SBIT!(P0_1, 0x80, 1); // Port 0 bit 1
SBIT!(P0_2, 0x80, 2); // Port 0 bit 2
SBIT!(P0_3, 0x80, 3); // Port 0 bit 3
SBIT!(P0_4, 0x80, 4); // Port 0 bit 4
SBIT!(P0_5, 0x80, 5); // Port 0 bit 5
SBIT!(P0_6, 0x80, 6); // Port 0 bit 6
SBIT!(P0_7, 0x80, 7); // Port 0 bit 7
SFR!(SP, 0x81); // Stack Pointer ; LSB of SPX
SFR!(DPL, 0x82); // Data Pointer Low Byte
SFR!(DPH, 0x83); // Data Pointer High Byte
SFR!(PCON, 0x87); // Power Mode Control
SFR!(TCON, 0x88); // Timer Control
SBIT!(IT0, 0x88, 0); // Ext. Interrupt 0 Type Select
SBIT!(IE0, 0x88, 1); // Ext. Interrupt 0 Flag
[...]
its the recursive macro_rules! that does it for me
and if you're wondering how the FUCK i am running rust on the 8051: its possible with this masterpiece