Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ATmega32U4 support: collect register definitions from multiple modules #48

Open
gergoerdi opened this issue Dec 22, 2022 · 1 comment
Open

Comments

@gergoerdi
Copy link

gergoerdi commented Dec 22, 2022

I'd like to use Rust to develop for the ArduBoy, which uses an ATmega32U4, which I believe is the same mcu as used on the Arduino Leonardo. So there should be quite a lot of boards out there using it.

Ruduino's core_generator chokes on the 16u4 and the 32u4 as-is because they have PDI and PDO pins in their SPI definition. I think these can be safely ignored as they are only used for in-circuit programming.

However, if we get over this hump, we get a more severe problem: registers that are defined "piecewise" at multiple locations in the packfile. For example, on the 32u4 ADCSRB is defined in two modules, in AC and in ADC. With core_generator's naive handling of registers, these end up as duplicate definitions in atmega32u4.rs:

#[allow(non_camel_case_types)]
pub struct ADCSRB;

impl ADCSRB {
    pub const ACME: RegisterBits<Self> = RegisterBits::new(0x40);
    pub const ACME0: RegisterBits<Self> = RegisterBits::new(1<<6);

}

impl Register for ADCSRB {
    type T = u8;
    const ADDRESS: *mut u8 = 0x7b as *mut u8;
}
#[allow(non_camel_case_types)]
pub struct ADCSRB;

impl ADCSRB {
    pub const ADHSM: RegisterBits<Self> = RegisterBits::new(0x80);
    pub const ADHSM0: RegisterBits<Self> = RegisterBits::new(1<<7);

    pub const MUX5: RegisterBits<Self> = RegisterBits::new(0x20);
    pub const MUX50: RegisterBits<Self> = RegisterBits::new(1<<5);

    pub const ADTS: RegisterBits<Self> = RegisterBits::new(0x17);
    pub const ADTS0: RegisterBits<Self> = RegisterBits::new(1<<0);
    pub const ADTS1: RegisterBits<Self> = RegisterBits::new(1<<1);
    pub const ADTS2: RegisterBits<Self> = RegisterBits::new(1<<2);
    pub const ADTS3: RegisterBits<Self> = RegisterBits::new(1<<4);

}

impl Register for ADCSRB {
    type T = u8;
    const ADDRESS: *mut u8 = 0x7b as *mut u8;
}
@gergoerdi gergoerdi changed the title ATMega32U4 support: collect register definitions from multiple modules ATmega32U4 support: collect register definitions from multiple modules Dec 22, 2022
gergoerdi added a commit to gergoerdi/ruduino that referenced this issue Dec 22, 2022
gergoerdi added a commit to gergoerdi/ruduino that referenced this issue Dec 22, 2022
gergoerdi added a commit to gergoerdi/ruduino that referenced this issue Dec 22, 2022
@gergoerdi
Copy link
Author

The next problem is the 16-bit timer module TC16, for which the following code is generated:

impl modules::Timer16 for Timer16 {
    type CompareA = OCR3A;
    type CompareB = OCR3B;
    type Counter = TCNT3;
    type ControlA = TCCR3A;
    type ControlB = TCCR3B;
    type ControlC = TCCR3C;
    type InterruptMask = TIMSK3;
    type InterruptFlag = TIFR3;
    const CS0: RegisterBits<Self::ControlB> = Self::ControlB::CS10;
    const CS1: RegisterBits<Self::ControlB> = Self::ControlB::CS11;
    const CS2: RegisterBits<Self::ControlB> = Self::ControlB::CS12;
    const WGM0: RegisterBits<Self::ControlA> = Self::ControlA::WGM10;
    const WGM1: RegisterBits<Self::ControlA> = Self::ControlA::WGM11;
    const WGM2: RegisterBits<Self::ControlB> = Self::ControlB::WGM10;
    const WGM3: RegisterBits<Self::ControlB> = Self::ControlB::WGM11;
    const OCIEA: RegisterBits<Self::InterruptMask> = Self::InterruptMask::OCIE3A;
}

The problem here is that TCCR3A and TCCR3B are missing these RegisterBits:

impl TCCR3A {
    pub const COM3A: RegisterBits<Self> = RegisterBits::new(0xc0);
    pub const COM3A0: RegisterBits<Self> = RegisterBits::new(1<<6);
    pub const COM3A1: RegisterBits<Self> = RegisterBits::new(1<<7);

    pub const COM3B: RegisterBits<Self> = RegisterBits::new(0x30);
    pub const COM3B0: RegisterBits<Self> = RegisterBits::new(1<<4);
    pub const COM3B1: RegisterBits<Self> = RegisterBits::new(1<<5);

    pub const COM3C: RegisterBits<Self> = RegisterBits::new(0xc);
    pub const COM3C0: RegisterBits<Self> = RegisterBits::new(1<<2);
    pub const COM3C1: RegisterBits<Self> = RegisterBits::new(1<<3);

    pub const WGM3: RegisterBits<Self> = RegisterBits::new(0x3);
    pub const WGM30: RegisterBits<Self> = RegisterBits::new(1<<0);
    pub const WGM31: RegisterBits<Self> = RegisterBits::new(1<<1);

}
impl TCCR3B {
    pub const ICNC3: RegisterBits<Self> = RegisterBits::new(0x80);
    pub const ICNC30: RegisterBits<Self> = RegisterBits::new(1<<7);

    pub const ICES3: RegisterBits<Self> = RegisterBits::new(0x40);
    pub const ICES30: RegisterBits<Self> = RegisterBits::new(1<<6);

    pub const WGM3: RegisterBits<Self> = RegisterBits::new(0x18);
    pub const WGM30: RegisterBits<Self> = RegisterBits::new(1<<3);
    pub const WGM31: RegisterBits<Self> = RegisterBits::new(1<<4);

    pub const CS3: RegisterBits<Self> = RegisterBits::new(0x7);
    pub const CS30: RegisterBits<Self> = RegisterBits::new(1<<0);
    pub const CS31: RegisterBits<Self> = RegisterBits::new(1<<1);
    pub const CS32: RegisterBits<Self> = RegisterBits::new(1<<2);

}

This is probably related to the fact that the 16-bit timer's register group is called TC3 in the 32u4.

gergoerdi added a commit to gergoerdi/ruduino that referenced this issue Dec 22, 2022
gergoerdi added a commit to gergoerdi/ruduino that referenced this issue Dec 22, 2022
gergoerdi added a commit to gergoerdi/ruduino that referenced this issue Dec 22, 2022
gergoerdi added a commit to gergoerdi/ruduino that referenced this issue Dec 22, 2022
gergoerdi added a commit to gergoerdi/ruduino that referenced this issue Dec 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant