py32csdk-hal-sys 0.4.0

PY32 HAL bindings
Documentation
import re
import os

def extract_vectors(startup_file):
    with open(startup_file, 'r') as file:
        content = file.read()

    # Extract the vector table
    vectors = re.findall(r'; External Interrupts\s+(.+?)__Vectors_End', content, re.DOTALL)
    if not vectors:
        raise ValueError("No vector table found between __Vectors and __Vectors_End")
    # print(vectors[0])
    vectors_list = []
    for line in vectors[0].strip().split('\n'):
        match = re.match(r'\s*DCD\s+(\w+)', line)
        if match:
            vector = match.group(1).replace("_Handler", "").replace("_IRQHandler", "").upper()
            vectors_list.append(vector)
    return vectors_list

def generate_interrupt_rs(vectors, output_dir):
    handlers = []
    for handler in vectors:
        if handler == '0':
            handlers.append('Vector { reserved: 0 }')
        else:
            handlers.append(f'Vector {{ handler: {handler} }}')

    interrupt_rs_content = '''
#[cfg(feature = "rt")]
pub use cortex_m_rt::interrupt;
#[cfg(feature = "rt")]
pub use self::Interrupt as interrupt;

pub union Vector {{
    handler: unsafe extern "C" fn(),
    reserved: usize,
}}

extern "C" {{
    {}
}}

#[link_section = ".vector_table.interrupts"]
#[no_mangle]
pub static __INTERRUPTS: [Vector; {}] = [
    {},
];
'''.format("".join([f"fn {handler}();\n    " for handler in set(re.findall(r'handler: (\w+)', "\n".join(handlers))) if handler != '0']),\

    len(handlers),\

    ",\n    ".join(handlers))


    rust_enum = """
#[doc = r"Enumeration of all the interrupts."]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u16)]
pub enum Interrupt {
"""

    for index, interrupt in enumerate(vectors):
        if interrupt == '0':
            continue
        rust_enum += f"    #[doc = \"{index} - {interrupt} interrupt\"]\n"
        rust_enum += f"    {interrupt} = {index},\n"

    rust_enum += """}

unsafe impl cortex_m::interrupt::InterruptNumber for Interrupt {
    #[inline(always)]
    fn number(self) -> u16 {
        self as u16
    }
}"""

    interrupt_rs_content += rust_enum

    with open(os.path.join(output_dir, 'interrupt.rs'), 'w') as file:
        file.write(interrupt_rs_content)

def generate_device_x(vectors, output_dir):
    handlers = [item for item in vectors if item != "0"]

    device_x_content = '/* device.x */\n' + '\n'.join([f'PROVIDE({handler} = DefaultHandler);' for handler in handlers])

    with open(os.path.join(output_dir, 'device.x'), 'w') as file:
        file.write(device_x_content)

def main():
    startup_file = '../PY32F0_Drivers/CMSIS/Device/PY32F0xx/Source/arm/startup_py32f030x8.s'
    output_dir = '../output'

    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    vectors = extract_vectors(startup_file)
    print(vectors)
    generate_interrupt_rs(vectors, output_dir)
    generate_device_x(vectors, output_dir)

if __name__ == '__main__':
    main()