drone-core 0.10.0

The core crate for Drone, an Embedded Operating System.
#![feature(proc_macro_hygiene)]

use drone_core::{
    periph,
    reg::{marker::*, prelude::*},
    token::Token,
};

use drone_core::reg;

reg! {
    pub mod RCC AHB2ENR;
    0 0x20 0 RReg WReg;
    GPIOAEN { 0 1 RRRegField WWRegField }
    GPIOBEN { 1 1 RRRegField WWRegField }
    GPIOCEN { 2 1 RRRegField WWRegField }
    GPIOARST { 3 1 RRRegField WWRegField }
    GPIOBRST { 4 1 RRRegField WWRegField }
}

reg! {
    pub mod GPIOA ODR;
    0 0x20 0 RReg WReg;
    ODR0 { 0 1 RRRegField WWRegField }
    ODR1 { 1 1 RRRegField WWRegField }
}

reg! {
    pub mod GPIOA IDR;
    0 0x20 0 RReg WReg;
    IDR0 { 0 1 RRRegField WWRegField }
    IDR1 { 1 1 RRRegField WWRegField }
}

reg! {
    pub mod GPIOB ODR;
    0 0x20 0 RReg WReg;
    ODR0 { 0 1 RRRegField WWRegField }
    ODR1 { 1 1 RRRegField WWRegField }
}

reg! {
    pub mod GPIOB IDR;
    0 0x20 0 RReg WReg;
    IDR0 { 0 1 RRRegField WWRegField }
}

reg! {
    pub mod GPIOC ODR;
    0 0x20 0 RReg WReg;
    ODR0 { 0 1 RRRegField WWRegField }
}

reg::tokens! {
    pub macro reg_tokens;
    crate;
    crate;

    pub mod RCC { AHB2ENR; }
    pub mod GPIOA { ODR; IDR; }
    pub mod GPIOB { ODR; IDR; }
    pub mod GPIOC { ODR; }
}

reg_tokens! {
    pub struct Regs;
}

periph! {
    pub trait GpioMap {}
    pub struct GpioPeriph;

    RCC {
        AHB2ENR {
            0x20 RwReg Shared;
            GPIOEN { RwRwRegFieldBit }
            GPIORST { RwRwRegFieldBit Option }
        }
    }

    GPIO {
        ODR {
            0x20 RwReg;
            ODR0 { RwRwRegFieldBit }
            ODR1 { RwRwRegFieldBit Option }
        }
        IDR {
            0x20 RwReg Option;
            IDR0 { RwRwRegFieldBit }
            IDR1 { RwRwRegFieldBit Option }
        }
    }
}

periph::map! {
    pub macro periph_gpio_a;
    pub struct GpioA;
    impl GpioMap for GpioA {}
    self;
    crate;

    RCC {
        AHB2ENR {
            AHB2ENR Shared;
            GPIOEN { GPIOAEN }
            GPIORST { GPIOARST Option }
        }
    }

    GPIO {
        GPIOA;
        ODR {
            ODR;
            ODR0 { ODR0 }
            ODR1 { ODR1 Option }
        }
        IDR {
            IDR Option;
            IDR0 { IDR0 }
            IDR1 { IDR1 Option }
        }
    }
}

periph::map! {
    pub macro periph_gpio_b;
    pub struct GpioB;
    impl GpioMap for GpioB {}
    self;
    crate;

    RCC {
        AHB2ENR {
            AHB2ENR Shared;
            GPIOEN { GPIOBEN }
            GPIORST { GPIOBRST Option }
        }
    }

    GPIO {
        GPIOB;
        ODR {
            ODR;
            ODR0 { ODR0 }
            ODR1 { ODR1 Option }
        }
        IDR {
            IDR Option;
            IDR0 { IDR0 }
            IDR1 {}
        }
    }
}

periph::map! {
    pub macro periph_gpio_c;
    pub struct GpioC;
    impl GpioMap for GpioC {}
    self;
    crate;

    RCC {
        AHB2ENR {
            AHB2ENR Shared;
            GPIOEN { GPIOCEN }
            GPIORST {}
        }
    }

    GPIO {
        GPIOC;
        ODR {
            ODR;
            ODR0 { ODR0 }
            ODR1 {}
        }
        IDR {}
    }
}

#[test]
fn periph_macros() {
    #![allow(unused_variables)]
    let reg = unsafe { Regs::take() };
    let gpioa = periph_gpio_a!(reg);
    let gpiob = periph_gpio_b!(reg);
    let gpioc = periph_gpio_c!(reg);
}

#[test]
fn concrete() {
    let reg = unsafe { Regs::take() };
    let gpio_c = periph_gpio_c!(reg);
    let GpioPeriph {
        rcc_ahb2enr_gpioen,
        rcc_ahb2enr_gpiorst: (),
        gpio_odr,
        gpio_idr: (),
    } = gpio_c;
    let gpio_odr = gpio_odr.into_unsync();
    let gpio_odr = gpio_odr.into_sync();
    let SGpioOdrFields { odr0, odr1: () } = gpio_odr.into_fields();
    let odr0 = odr0.into_copy();
    let gpio_odr = CGpioOdr::from_fields(CGpioOdrFields::<GpioC> { odr0, odr1: () });
    let gpioc::Odr { odr0 } = gpio_odr;
    let gpio_odr = gpioc::Odr { odr0 };
    let rcc_ahb2enr_gpioen = rcc_ahb2enr_gpioen.into_copy();
    if false {
        gpio_odr.store(|r| r.set_odr0());
        gpio_odr.odr0.read_bit();
        rcc_ahb2enr_gpioen.read_bit();
    }
}

#[test]
fn generic_without_holes() {
    fn f<T: GpioMap + GpioOdrOdr1 + GpioIdr + GpioIdrIdr1>(gpio: GpioPeriph<T>) {
        let GpioPeriph {
            rcc_ahb2enr_gpioen,
            rcc_ahb2enr_gpiorst: _,
            gpio_odr,
            gpio_idr: _,
        } = gpio;
        let gpio_odr = gpio_odr.into_unsync();
        let gpio_odr = gpio_odr.into_sync();
        let SGpioOdrFields { odr0, odr1 } = gpio_odr.into_fields();
        let odr0 = odr0.into_copy();
        let odr1 = odr1.into_copy();
        let gpio_odr = T::CGpioOdr::from_fields(CGpioOdrFields { odr0, odr1 });
        let rcc_ahb2enr_gpioen = rcc_ahb2enr_gpioen.into_copy();
        if false {
            let mut val = gpio_odr.load().val();
            gpio_odr.odr0().set(&mut val);
            gpio_odr.odr1().set(&mut val);
            gpio_odr.store_val(val);
            rcc_ahb2enr_gpioen.read_bit();
        }
    }
    let reg = unsafe { Regs::take() };
    let gpio_a = periph_gpio_a!(reg);
    f(gpio_a);
}

#[test]
fn generic_with_holes() {
    fn f<T: GpioMap>(gpio: GpioPeriph<T>) {
        let GpioPeriph {
            rcc_ahb2enr_gpioen,
            rcc_ahb2enr_gpiorst: _,
            gpio_odr,
            gpio_idr: _,
        } = gpio;
        let gpio_odr = gpio_odr.into_unsync();
        let gpio_odr = gpio_odr.into_sync();
        let SGpioOdrFields { odr0, odr1 } = gpio_odr.into_fields();
        let odr0 = odr0.into_sync();
        let gpio_odr = T::SGpioOdr::from_fields(SGpioOdrFields { odr0, odr1 });
        let rcc_ahb2enr_gpioen = rcc_ahb2enr_gpioen.into_copy();
        if false {
            let mut val = gpio_odr.load().val();
            gpio_odr.odr0().set(&mut val);
            gpio_odr.store_val(val);
            rcc_ahb2enr_gpioen.read_bit();
        }
    }
    let reg = unsafe { Regs::take() };
    let gpio_c = periph_gpio_c!(reg);
    f(gpio_c);
}