ruduino icon indicating copy to clipboard operation
ruduino copied to clipboard

contributing other boards

Open dsvensson opened this issue 8 years ago • 30 comments

I just tried out this framework on the leonardo/promicro/atmega32u4 and had to change some addresses around to get for example serial working, but I guess the rest need some tweaking too. Do you have any nice idea on how to have different boards in the same code base?

dsvensson avatar Jun 25 '17 21:06 dsvensson

I just tried out this framework on the leonardo/promicro/atmega32u4 and had to change some addresses around to get for example serial working

What addresses were these? Did you have to run a custom linking command?

dylanmckay avatar Jul 01 '17 01:07 dylanmckay

AVR-LLVM itself supports hundreds of different AVR microcontrollers, so the problem is likely that Rust needs to pass extra arguments to the linker.

dylanmckay avatar Jul 01 '17 01:07 dylanmckay

UDR0, UBRR0H, UBRR0L, UCSR0C, UCSR0B, UCSR0A etc

dsvensson avatar Jul 02 '17 08:07 dsvensson

I'm getting my repositories mixed up haha, cc @shepmaster

dylanmckay avatar Jul 02 '17 09:07 dylanmckay

Do you have any nice idea on how to have different boards in the same code base?

Yeah, that's a big question for this library!

My hope was that basically the giant list of registers could be specified for each chip, perhaps in a module. That should work nowadays.

The hard part comes with selecting the appropriate chipset. My first idea would be to have a feature flag that switches them around (and maybe enables certain parts like what serial features are available).

@dsvensson Could you maybe publish your fork somewhere so we could see what kind of diff you had to make? That might help guide what kind of swapability we need to enable.

shepmaster avatar Jul 05 '17 23:07 shepmaster

Going sligthly off-topic... I have very little experience in this area, but wouldn't it make sense to try to align this to the route @japaric is taking with embedded-hal etc, or is his arm efforts just too far away? Thinking otherwise it would be nice to get some cross pollination?

dsvensson avatar Jul 07 '17 22:07 dsvensson

wouldn't it make sense to try to align this to the route @japaric is taking with embedded-hal etc, or is his arm efforts just too far away? Thinking otherwise it would be nice to get some cross pollination?

I'm always of two minds on this kind of thing. Having two parallel approaches has the potential for independent discovery of useful ideas. It also has the downside of duplicated effort for the common stuff.

For example, back in ye olde days, there was zinc.rs which offered one way of this type of abstraction. I haven't even looked at the ARM HAL stuff, so I don't know if it's the same idea as zinc or if they started from the same place.

However, @japaric is a smart embedded programmer, so I'd appreciate any input from them!

shepmaster avatar Jul 08 '17 16:07 shepmaster

Found a git repo with the datasheets in XML format, so here's a generated set of registers (and the script). Up for debate what the names should be... and maybe newer versions of Atmel Studio has updated XML files that could be used instead for better naming.

http://7b014214dde8b39f.paste.se/

dsvensson avatar Jul 09 '17 19:07 dsvensson

Thanks. Would you mind running the script for the atmega328p as well? That way I can compare it to the checked-in version. Any idea about 16-bit register pairs or aliases?

Saved script for reference
import xml.etree.ElementTree as ET
import argparse
import math

def bits(n):
    while n:
        b = n & (~n+1)
        yield int(round(math.log(b, 2)))
        n ^= b

def gen_bitfields(name, mask):
    fields = [None] * 8
    for bit in bits(mask):
        fields[7 - bit] = '{}{}'.format(name, bit)
    return tuple(fields)

def get_bitfields(node):
    fields = [None] * 8
    for bitfield in node.findall('bitfield'):
        name = bitfield.attrib['name']
        mask = int(bitfield.attrib['mask'], 16)
        for i, bit in enumerate(bits(mask)):
            if bin(mask).count('1') > 1:
                fields[7 - bit] = '{}{}'.format(name, i)
            else:
                fields[7 - bit] = name
    return tuple(fields)

def get_registers(node):
    for group in node.findall('.//register-group'):
        for register in group.findall('register'):
            name = register.attrib['name']
            offset = int(register.attrib['offset'], 16)

            if 'mask' in register.attrib:
                # If mask defined, there are no named bitfields
                mask = int(register.attrib['mask'], 16)
                if mask > 0xff:
                    # Split between high and low registers
                    yield (offset + 1, name + 'H', gen_bitfields(name + 'H', mask & 0xff00))
                    yield (offset, name + 'L', gen_bitfields(name + 'L', mask & 0xff))
                else:
                    yield (offset, name, gen_bitfields(name, mask))
            else:
                yield (offset, name, get_bitfields(register))


if __name__ == '__main__':
    # Datasheets can be found at https://github.com/avrxml/AS6-Devices-XML
    parser = argparse.ArgumentParser()
    parser.add_argument('datasheet', help='Atmel XML Register Datasheet.')
    args = parser.parse_args()

    for offset, name, bitfields in get_registers(ET.parse(args.datasheet).getroot()):
        fields = ''.join('{:11}'.format((f or '-') + ',') for f in bitfields).rstrip(', ')
        print('register!(0x{:02X}, {:9} [{:87}]);'.format(offset, name + ',', fields))


"""
atmega32u4:
register!(0xF4, UEINT,    [-,         UEINT6,    UEINT5,    UEINT4,    UEINT3,    UEINT2,    UEINT1,    UEINT0    ]);
register!(0xF3, UEBCHX,   [-,         -,         -,         -,         -,         UEBCHX2,   UEBCHX1,   UEBCHX0   ]);
register!(0xF2, UEBCLX,   [UEBCLX7,   UEBCLX6,   UEBCLX5,   UEBCLX4,   UEBCLX3,   UEBCLX2,   UEBCLX1,   UEBCLX0   ]);
register!(0xF1, UEDATX,   [DAT7,      DAT6,      DAT5,      DAT4,      DAT3,      DAT2,      DAT1,      DAT0      ]);
register!(0xF0, UEIENX,   [FLERRE,    NAKINE,    -,         NAKOUTE,   RXSTPE,    RXOUTE,    STALLEDE,  TXINE     ]);
register!(0xEF, UESTA1X,  [-,         -,         -,         -,         -,         CTRLDIR,   CURRBK1,   CURRBK0   ]);
register!(0xEE, UESTA0X,  [CFGOK,     OVERFI,    UNDERFI,   -,         DTSEQ1,    DTSEQ0,    NBUSYBK1,  NBUSYBK0  ]);
register!(0xED, UECFG1X,  [-,         EPSIZE2,   EPSIZE1,   EPSIZE0,   EPBK1,     EPBK0,     ALLOC,     -         ]);
register!(0xEC, UECFG0X,  [EPTYPE1,   EPTYPE0,   -,         -,         -,         -,         -,         EPDIR     ]);
register!(0xEB, UECONX,   [-,         -,         STALLRQ,   STALLRQC,  RSTDT,     -,         -,         EPEN      ]);
register!(0xEA, UERST,    [-,         EPRST6,    EPRST5,    EPRST4,    EPRST3,    EPRST2,    EPRST1,    EPRST0    ]);
register!(0xE9, UENUM,    [-,         -,         -,         -,         -,         UENUM2,    UENUM1,    UENUM0    ]);
register!(0xE8, UEINTX,   [FIFOCON,   NAKINI,    RWAL,      NAKOUTI,   RXSTPI,    RXOUTI,    STALLEDI,  TXINI     ]);
register!(0xE6, UDMFN,    [-,         -,         -,         FNCERR,    -,         -,         -,         -         ]);
register!(0xE5, UDFNUMH,  [-,         -,         -,         -,         -,         UDFNUMH10, UDFNUMH9,  UDFNUMH8  ]);
register!(0xE4, UDFNUML,  [UDFNUML7,  UDFNUML6,  UDFNUML5,  UDFNUML4,  UDFNUML3,  UDFNUML2,  UDFNUML1,  UDFNUML0  ]);
register!(0xE3, UDADDR,   [ADDEN,     UADD6,     UADD5,     UADD4,     UADD3,     UADD2,     UADD1,     UADD0     ]);
register!(0xE2, UDIEN,    [-,         UPRSME,    EORSME,    WAKEUPE,   EORSTE,    SOFE,      -,         SUSPE     ]);
register!(0xE1, UDINT,    [-,         UPRSMI,    EORSMI,    WAKEUPI,   EORSTI,    SOFI,      -,         SUSPI     ]);
register!(0xE0, UDCON,    [-,         -,         -,         -,         RSTCPU,    LSM,       RMWKUP,    DETACH    ]);
register!(0xDA, USBINT,   [-,         -,         -,         -,         -,         -,         -,         VBUSTI    ]);
register!(0xD9, USBSTA,   [-,         -,         -,         -,         SPEED,     -,         -,         VBUS      ]);
register!(0xD8, USBCON,   [USBE,      -,         FRZCLK,    OTGPADE,   -,         -,         -,         VBUSTE    ]);
register!(0xD7, UHWCON,   [-,         -,         -,         -,         -,         -,         -,         UVREGE    ]);
register!(0xD4, DT4,      [DT4L7,     DT4L6,     DT4L5,     DT4L4,     DT4L3,     DT4L2,     DT4L1,     DT4L0     ]);
register!(0xD2, OCR4D,    [OCR4D7,    OCR4D6,    OCR4D5,    OCR4D4,    OCR4D3,    OCR4D2,    OCR4D1,    OCR4D0    ]);
register!(0xD1, OCR4C,    [OCR4C7,    OCR4C6,    OCR4C5,    OCR4C4,    OCR4C3,    OCR4C2,    OCR4C1,    OCR4C0    ]);
register!(0xD0, OCR4B,    [OCR4B7,    OCR4B6,    OCR4B5,    OCR4B4,    OCR4B3,    OCR4B2,    OCR4B1,    OCR4B0    ]);
register!(0xCF, OCR4A,    [OCR4A7,    OCR4A6,    OCR4A5,    OCR4A4,    OCR4A3,    OCR4A2,    OCR4A1,    OCR4A0    ]);
register!(0xCE, UDR1,     [UDR17,     UDR16,     UDR15,     UDR14,     UDR13,     UDR12,     UDR11,     UDR10     ]);
register!(0xCD, UBRR1H,   [-,         -,         -,         -,         UBRR1H11,  UBRR1H10,  UBRR1H9,   UBRR1H8   ]);
register!(0xCC, UBRR1L,   [UBRR1L7,   UBRR1L6,   UBRR1L5,   UBRR1L4,   UBRR1L3,   UBRR1L2,   UBRR1L1,   UBRR1L0   ]);
register!(0xCA, UCSR1C,   [UMSEL11,   UMSEL10,   UPM11,     UPM10,     USBS1,     UCSZ11,    UCSZ10,    UCPOL1    ]);
register!(0xC9, UCSR1B,   [RXCIE1,    TXCIE1,    UDRIE1,    RXEN1,     TXEN1,     UCSZ12,    RXB81,     TXB81     ]);
register!(0xC8, UCSR1A,   [RXC1,      TXC1,      UDRE1,     FE1,       DOR1,      UPE1,      U2X1,      MPCM1     ]);
register!(0xC7, CLKSTA,   [-,         -,         -,         -,         -,         -,         RCON,      EXTON     ]);
register!(0xC6, CLKSEL1,  [RCCKSEL3,  RCCKSEL2,  RCCKSEL1,  RCCKSEL0,  EXCKSEL3,  EXCKSEL2,  EXCKSEL1,  EXCKSEL0  ]);
register!(0xC5, CLKSEL0,  [RCSUT1,    RCSUT0,    EXSUT1,    EXSUT0,    RCE,       EXTE,      -,         CLKS      ]);
register!(0xC4, TCCR4E,   [TLOCK4,    ENHC4,     OC4OE5,    OC4OE4,    OC4OE3,    OC4OE2,    OC4OE1,    OC4OE0    ]);
register!(0xC3, TCCR4D,   [FPIE4,     FPEN4,     FPNC4,     FPES4,     FPAC4,     FPF4,      WGM41,     WGM40     ]);
register!(0xC2, TCCR4C,   [COM4A1S,   COM4A0S,   COM4B1S,   COM4B0S,   COM4D1,    COM4D0,    FOC4D,     PWM4D     ]);
register!(0xC1, TCCR4B,   [PWM4X,     PSR4,      DTPS41,    DTPS40,    CS43,      CS42,      CS41,      CS40      ]);
register!(0xC0, TCCR4A,   [COM4A1,    COM4A0,    COM4B1,    COM4B0,    FOC4A,     FOC4B,     PWM4A,     PWM4B     ]);
register!(0xBF, TC4H,     [-,         -,         -,         -,         -,         TC4H2,     TC4H1,     TC4H0     ]);
register!(0xBE, TCNT4,    [TCNT47,    TCNT46,    TCNT45,    TCNT44,    TCNT43,    TCNT42,    TCNT41,    TCNT40    ]);
register!(0xBD, TWAMR,    [TWAM6,     TWAM5,     TWAM4,     TWAM3,     TWAM2,     TWAM1,     TWAM0,     -         ]);
register!(0xBC, TWCR,     [TWINT,     TWEA,      TWSTA,     TWSTO,     TWWC,      TWEN,      -,         TWIE      ]);
register!(0xBB, TWDR,     [TWDR7,     TWDR6,     TWDR5,     TWDR4,     TWDR3,     TWDR2,     TWDR1,     TWDR0     ]);
register!(0xBA, TWAR,     [TWA6,      TWA5,      TWA4,      TWA3,      TWA2,      TWA1,      TWA0,      TWGCE     ]);
register!(0xB9, TWSR,     [TWS4,      TWS3,      TWS2,      TWS1,      TWS0,      -,         TWPS1,     TWPS0     ]);
register!(0xB8, TWBR,     [TWBR7,     TWBR6,     TWBR5,     TWBR4,     TWBR3,     TWBR2,     TWBR1,     TWBR0     ]);
register!(0x9D, OCR3CH,   [OCR3CH15,  OCR3CH14,  OCR3CH13,  OCR3CH12,  OCR3CH11,  OCR3CH10,  OCR3CH9,   OCR3CH8   ]);
register!(0x9C, OCR3CL,   [OCR3CL7,   OCR3CL6,   OCR3CL5,   OCR3CL4,   OCR3CL3,   OCR3CL2,   OCR3CL1,   OCR3CL0   ]);
register!(0x9B, OCR3BH,   [OCR3BH15,  OCR3BH14,  OCR3BH13,  OCR3BH12,  OCR3BH11,  OCR3BH10,  OCR3BH9,   OCR3BH8   ]);
register!(0x9A, OCR3BL,   [OCR3BL7,   OCR3BL6,   OCR3BL5,   OCR3BL4,   OCR3BL3,   OCR3BL2,   OCR3BL1,   OCR3BL0   ]);
register!(0x99, OCR3AH,   [OCR3AH15,  OCR3AH14,  OCR3AH13,  OCR3AH12,  OCR3AH11,  OCR3AH10,  OCR3AH9,   OCR3AH8   ]);
register!(0x98, OCR3AL,   [OCR3AL7,   OCR3AL6,   OCR3AL5,   OCR3AL4,   OCR3AL3,   OCR3AL2,   OCR3AL1,   OCR3AL0   ]);
register!(0x97, ICR3H,    [ICR3H15,   ICR3H14,   ICR3H13,   ICR3H12,   ICR3H11,   ICR3H10,   ICR3H9,    ICR3H8    ]);
register!(0x96, ICR3L,    [ICR3L7,    ICR3L6,    ICR3L5,    ICR3L4,    ICR3L3,    ICR3L2,    ICR3L1,    ICR3L0    ]);
register!(0x95, TCNT3H,   [TCNT3H15,  TCNT3H14,  TCNT3H13,  TCNT3H12,  TCNT3H11,  TCNT3H10,  TCNT3H9,   TCNT3H8   ]);
register!(0x94, TCNT3L,   [TCNT3L7,   TCNT3L6,   TCNT3L5,   TCNT3L4,   TCNT3L3,   TCNT3L2,   TCNT3L1,   TCNT3L0   ]);
register!(0x92, TCCR3C,   [FOC3A,     FOC3B,     FOC3C,     -,         -,         -,         -,         -         ]);
register!(0x91, TCCR3B,   [ICNC3,     ICES3,     -,         WGM31,     WGM30,     CS32,      CS31,      CS30      ]);
register!(0x90, TCCR3A,   [COM3A1,    COM3A0,    COM3B1,    COM3B0,    COM3C1,    COM3C0,    WGM31,     WGM30     ]);
register!(0x8D, OCR1CH,   [OCR1CH15,  OCR1CH14,  OCR1CH13,  OCR1CH12,  OCR1CH11,  OCR1CH10,  OCR1CH9,   OCR1CH8   ]);
register!(0x8C, OCR1CL,   [OCR1CL7,   OCR1CL6,   OCR1CL5,   OCR1CL4,   OCR1CL3,   OCR1CL2,   OCR1CL1,   OCR1CL0   ]);
register!(0x8B, OCR1BH,   [OCR1BH15,  OCR1BH14,  OCR1BH13,  OCR1BH12,  OCR1BH11,  OCR1BH10,  OCR1BH9,   OCR1BH8   ]);
register!(0x8A, OCR1BL,   [OCR1BL7,   OCR1BL6,   OCR1BL5,   OCR1BL4,   OCR1BL3,   OCR1BL2,   OCR1BL1,   OCR1BL0   ]);
register!(0x89, OCR1AH,   [OCR1AH15,  OCR1AH14,  OCR1AH13,  OCR1AH12,  OCR1AH11,  OCR1AH10,  OCR1AH9,   OCR1AH8   ]);
register!(0x88, OCR1AL,   [OCR1AL7,   OCR1AL6,   OCR1AL5,   OCR1AL4,   OCR1AL3,   OCR1AL2,   OCR1AL1,   OCR1AL0   ]);
register!(0x87, ICR1H,    [ICR1H15,   ICR1H14,   ICR1H13,   ICR1H12,   ICR1H11,   ICR1H10,   ICR1H9,    ICR1H8    ]);
register!(0x86, ICR1L,    [ICR1L7,    ICR1L6,    ICR1L5,    ICR1L4,    ICR1L3,    ICR1L2,    ICR1L1,    ICR1L0    ]);
register!(0x85, TCNT1H,   [TCNT1H15,  TCNT1H14,  TCNT1H13,  TCNT1H12,  TCNT1H11,  TCNT1H10,  TCNT1H9,   TCNT1H8   ]);
register!(0x84, TCNT1L,   [TCNT1L7,   TCNT1L6,   TCNT1L5,   TCNT1L4,   TCNT1L3,   TCNT1L2,   TCNT1L1,   TCNT1L0   ]);
register!(0x82, TCCR1C,   [FOC1A,     FOC1B,     FOC1C,     -,         -,         -,         -,         -         ]);
register!(0x81, TCCR1B,   [ICNC1,     ICES1,     -,         WGM11,     WGM10,     CS12,      CS11,      CS10      ]);
register!(0x80, TCCR1A,   [COM1A1,    COM1A0,    COM1B1,    COM1B0,    COM1C1,    COM1C0,    WGM11,     WGM10     ]);
register!(0x7F, DIDR1,    [-,         -,         -,         -,         -,         -,         AIN1D,     AIN0D     ]);
register!(0x7E, DIDR0,    [ADC7D,     ADC6D,     ADC5D,     ADC4D,     ADC3D,     ADC2D,     ADC1D,     ADC0D     ]);
register!(0x7D, DIDR2,    [-,         -,         ADC13D,    ADC12D,    ADC11D,    ADC10D,    ADC9D,     ADC8D     ]);
register!(0x7C, ADMUX,    [REFS1,     REFS0,     ADLAR,     MUX4,      MUX3,      MUX2,      MUX1,      MUX0      ]);
register!(0x7B, ADCSRB,   [ADHSM,     -,         MUX5,      ADTS3,     -,         ADTS2,     ADTS1,     ADTS0     ]);
register!(0x7B, ADCSRB,   [-,         ACME,      -,         -,         -,         -,         -,         -         ]);
register!(0x7A, ADCSRA,   [ADEN,      ADSC,      ADATE,     ADIF,      ADIE,      ADPS2,     ADPS1,     ADPS0     ]);
register!(0x79, ADCH,     [ADCH15,    ADCH14,    ADCH13,    ADCH12,    ADCH11,    ADCH10,    ADCH9,     ADCH8     ]);
register!(0x78, ADCL,     [ADCL7,     ADCL6,     ADCL5,     ADCL4,     ADCL3,     ADCL2,     ADCL1,     ADCL0     ]);
register!(0x72, TIMSK4,   [OCIE4D,    OCIE4A,    OCIE4B,    -,         -,         TOIE4,     -,         -         ]);
register!(0x71, TIMSK3,   [-,         -,         ICIE3,     -,         OCIE3C,    OCIE3B,    OCIE3A,    TOIE3     ]);
register!(0x6F, TIMSK1,   [-,         -,         ICIE1,     -,         OCIE1C,    OCIE1B,    OCIE1A,    TOIE1     ]);
register!(0x6E, TIMSK0,   [-,         -,         -,         -,         -,         OCIE0B,    OCIE0A,    TOIE0     ]);
register!(0x6B, PCMSK0,   [PCMSK07,   PCMSK06,   PCMSK05,   PCMSK04,   PCMSK03,   PCMSK02,   PCMSK01,   PCMSK00   ]);
register!(0x6A, EICRB,    [ISC71,     ISC70,     ISC61,     ISC60,     ISC51,     ISC50,     ISC41,     ISC40     ]);
register!(0x69, EICRA,    [ISC31,     ISC30,     ISC21,     ISC20,     ISC11,     ISC10,     ISC01,     ISC00     ]);
register!(0x68, PCICR,    [-,         -,         -,         -,         -,         -,         -,         PCIE0     ]);
register!(0x67, RCCTRL,   [-,         -,         -,         -,         -,         -,         -,         RCFREQ    ]);
register!(0x66, OSCCAL,   [OSCCAL7,   OSCCAL6,   OSCCAL5,   OSCCAL4,   OSCCAL3,   OSCCAL2,   OSCCAL1,   OSCCAL0   ]);
register!(0x65, PRR1,     [PRUSB,     -,         -,         -,         PRTIM3,    -,         -,         PRUSART1  ]);
register!(0x64, PRR0,     [PRTWI,     PRTIM2,    PRTIM0,    -,         PRTIM1,    PRSPI,     PRUSART0,  PRADC     ]);
register!(0x61, CLKPR,    [CLKPCE,    -,         -,         -,         CLKPS3,    CLKPS2,    CLKPS1,    CLKPS0    ]);
register!(0x60, WDTCSR,   [WDIF,      WDIE,      WDP3,      WDCE,      WDE,       WDP2,      WDP1,      WDP0      ]);
register!(0x5F, SREG,     [I,         T,         H,         S,         V,         N,         Z,         C         ]);
register!(0x5E, SPH,      [SPH15,     SPH14,     SPH13,     SPH12,     SPH11,     SPH10,     SPH9,      SPH8      ]);
register!(0x5D, SPL,      [SPL7,      SPL6,      SPL5,      SPL4,      SPL3,      SPL2,      SPL1,      SPL0      ]);
register!(0x5C, EIND,     [-,         -,         -,         -,         -,         -,         -,         EIND0     ]);
register!(0x57, SPMCSR,   [SPMIE,     RWWSB,     SIGRD,     RWWSRE,    BLBSET,    PGWRT,     PGERS,     SPMEN     ]);
register!(0x55, MCUCR,    [JTD,       -,         -,         PUD,       -,         -,         IVSEL,     IVCE      ]);
register!(0x55, MCUCR,    [JTD,       -,         -,         -,         -,         -,         -,         -         ]);
register!(0x54, MCUSR,    [-,         -,         -,         JTRF,      WDRF,      BORF,      EXTRF,     PORF      ]);
register!(0x54, MCUSR,    [-,         -,         -,         JTRF,      -,         -,         -,         -         ]);
register!(0x53, SMCR,     [-,         -,         -,         -,         SM2,       SM1,       SM0,       SE        ]);
register!(0x52, PLLFRQ,   [PINMUX,    PLLUSB,    PLLTM1,    PLLTM0,    PDIV3,     PDIV2,     PDIV1,     PDIV0     ]);
register!(0x51, OCDR,     [OCDR7,     OCDR6,     OCDR5,     OCDR4,     OCDR3,     OCDR2,     OCDR1,     OCDR0     ]);
register!(0x50, ACSR,     [ACD,       ACBG,      ACO,       ACI,       ACIE,      ACIC,      ACIS1,     ACIS0     ]);
register!(0x4E, SPDR,     [SPDR7,     SPDR6,     SPDR5,     SPDR4,     SPDR3,     SPDR2,     SPDR1,     SPDR0     ]);
register!(0x4D, SPSR,     [SPIF,      WCOL,      -,         -,         -,         -,         -,         SPI2X     ]);
register!(0x4C, SPCR,     [SPIE,      SPE,       DORD,      MSTR,      CPOL,      CPHA,      SPR1,      SPR0      ]);
register!(0x4B, GPIOR2,   [GPIOR7,    GPIOR6,    GPIOR5,    GPIOR4,    GPIOR3,    GPIOR2,    GPIOR1,    GPIOR0    ]);
register!(0x4A, GPIOR1,   [GPIOR7,    GPIOR6,    GPIOR5,    GPIOR4,    GPIOR3,    GPIOR2,    GPIOR1,    GPIOR0    ]);
register!(0x49, PLLCSR,   [-,         -,         -,         PINDIV,    -,         -,         PLLE,      PLOCK     ]);
register!(0x48, OCR0B,    [OCR0B7,    OCR0B6,    OCR0B5,    OCR0B4,    OCR0B3,    OCR0B2,    OCR0B1,    OCR0B0    ]);
register!(0x47, OCR0A,    [OCR0A7,    OCR0A6,    OCR0A5,    OCR0A4,    OCR0A3,    OCR0A2,    OCR0A1,    OCR0A0    ]);
register!(0x46, TCNT0,    [TCNT07,    TCNT06,    TCNT05,    TCNT04,    TCNT03,    TCNT02,    TCNT01,    TCNT00    ]);
register!(0x45, TCCR0B,   [FOC0A,     FOC0B,     -,         -,         WGM02,     CS02,      CS01,      CS00      ]);
register!(0x44, TCCR0A,   [COM0A1,    COM0A0,    COM0B1,    COM0B0,    -,         -,         WGM01,     WGM00     ]);
register!(0x43, GTCCR,    [TSM,       -,         -,         -,         -,         -,         -,         PSRSYNC   ]);
register!(0x42, EEARH,    [-,         -,         -,         -,         EEARH11,   EEARH10,   EEARH9,    EEARH8    ]);
register!(0x41, EEARL,    [EEARL7,    EEARL6,    EEARL5,    EEARL4,    EEARL3,    EEARL2,    EEARL1,    EEARL0    ]);
register!(0x40, EEDR,     [EEDR7,     EEDR6,     EEDR5,     EEDR4,     EEDR3,     EEDR2,     EEDR1,     EEDR0     ]);
register!(0x3F, EECR,     [-,         -,         EEPM1,     EEPM0,     EERIE,     EEMPE,     EEPE,      EERE      ]);
register!(0x3E, GPIOR0,   [GPIOR07,   GPIOR06,   GPIOR05,   GPIOR04,   GPIOR03,   GPIOR02,   GPIOR01,   GPIOR00   ]);
register!(0x3D, EIMSK,    [INT7,      INT6,      INT5,      INT4,      INT3,      INT2,      INT1,      INT0      ]);
register!(0x3C, EIFR,     [INTF7,     INTF6,     INTF5,     INTF4,     INTF3,     INTF2,     INTF1,     INTF0     ]);
register!(0x3B, PCIFR,    [-,         -,         -,         -,         -,         -,         -,         PCIF0     ]);
register!(0x39, TIFR4,    [OCF4D,     OCF4A,     OCF4B,     -,         -,         TOV4,      -,         -         ]);
register!(0x38, TIFR3,    [-,         -,         ICF3,      -,         OCF3C,     OCF3B,     OCF3A,     TOV3      ]);
register!(0x36, TIFR1,    [-,         -,         ICF1,      -,         OCF1C,     OCF1B,     OCF1A,     TOV1      ]);
register!(0x35, TIFR0,    [-,         -,         -,         -,         -,         OCF0B,     OCF0A,     TOV0      ]);
register!(0x31, PORTF,    [PORTF7,    PORTF6,    PORTF5,    PORTF4,    -,         -,         PORTF1,    PORTF0    ]);
register!(0x30, DDRF,     [DDRF7,     DDRF6,     DDRF5,     DDRF4,     -,         -,         DDRF1,     DDRF0     ]);
register!(0x2F, PINF,     [PINF7,     PINF6,     PINF5,     PINF4,     -,         -,         PINF1,     PINF0     ]);
register!(0x2E, PORTE,    [-,         PORTE6,    -,         -,         -,         PORTE2,    -,         -         ]);
register!(0x2D, DDRE,     [-,         DDRE6,     -,         -,         -,         DDRE2,     -,         -         ]);
register!(0x2C, PINE,     [-,         PINE6,     -,         -,         -,         PINE2,     -,         -         ]);
register!(0x2B, PORTD,    [PORTD7,    PORTD6,    PORTD5,    PORTD4,    PORTD3,    PORTD2,    PORTD1,    PORTD0    ]);
register!(0x2A, DDRD,     [DDRD7,     DDRD6,     DDRD5,     DDRD4,     DDRD3,     DDRD2,     DDRD1,     DDRD0     ]);
register!(0x29, PIND,     [PIND7,     PIND6,     PIND5,     PIND4,     PIND3,     PIND2,     PIND1,     PIND0     ]);
register!(0x28, PORTC,    [PORTC7,    PORTC6,    -,         -,         -,         -,         -,         -         ]);
register!(0x27, DDRC,     [DDRC7,     DDRC6,     -,         -,         -,         -,         -,         -         ]);
register!(0x26, PINC,     [PINC7,     PINC6,     -,         -,         -,         -,         -,         -         ]);
register!(0x25, PORTB,    [PORTB7,    PORTB6,    PORTB5,    PORTB4,    PORTB3,    PORTB2,    PORTB1,    PORTB0    ]);
register!(0x24, DDRB,     [DDRB7,     DDRB6,     DDRB5,     DDRB4,     DDRB3,     DDRB2,     DDRB1,     DDRB0     ]);
register!(0x23, PINB,     [PINB7,     PINB6,     PINB5,     PINB4,     PINB3,     PINB2,     PINB1,     PINB0     ]);
register!(0x02, EXTENDED, [-,         -,         -,         -,         HWBE,      BODLEVEL2, BODLEVEL1, BODLEVEL0 ]);
register!(0x01, HIGH,     [OCDEN,     JTAGEN,    SPIEN,     WDTON,     EESAVE,    BOOTSZ1,   BOOTSZ0,   BOOTRST   ]);
register!(0x00, LOW,      [CKDIV8,    CKOUT,     SUT_CKSEL5,SUT_CKSEL4,SUT_CKSEL3,SUT_CKSEL2,SUT_CKSEL1,SUT_CKSEL0]);
register!(0x00, LOCKBIT,  [-,         -,         BLB11,     BLB10,     BLB01,     BLB00,     LB1,       LB0       ]);
"""

shepmaster avatar Jul 09 '17 19:07 shepmaster

Heh, didn't know about collapsable parts in comments before! Here you go:

ATmega328p
// python pyavr.py AS6-Devices-XML/ATmega328P.xml|sort -r
register!(0xC6, UDR0,     [UDR07,     UDR06,     UDR05,     UDR04,     UDR03,     UDR02,     UDR01,     UDR00     ]);
register!(0xC5, UBRR0H,   [-,         -,         -,         -,         UBRR0H11,  UBRR0H10,  UBRR0H9,   UBRR0H8   ]);
register!(0xC4, UBRR0L,   [UBRR0L7,   UBRR0L6,   UBRR0L5,   UBRR0L4,   UBRR0L3,   UBRR0L2,   UBRR0L1,   UBRR0L0   ]);
register!(0xC2, UCSR0C,   [UMSEL01,   UMSEL00,   UPM01,     UPM00,     USBS0,     UCSZ01,    UCSZ00,    UCPOL0    ]);
register!(0xC1, UCSR0B,   [RXCIE0,    TXCIE0,    UDRIE0,    RXEN0,     TXEN0,     UCSZ02,    RXB80,     TXB80     ]);
register!(0xC0, UCSR0A,   [RXC0,      TXC0,      UDRE0,     FE0,       DOR0,      UPE0,      U2X0,      MPCM0     ]);
register!(0xBD, TWAMR,    [TWAM6,     TWAM5,     TWAM4,     TWAM3,     TWAM2,     TWAM1,     TWAM0,     -         ]);
register!(0xBC, TWCR,     [TWINT,     TWEA,      TWSTA,     TWSTO,     TWWC,      TWEN,      -,         TWIE      ]);
register!(0xBB, TWDR,     [TWDR7,     TWDR6,     TWDR5,     TWDR4,     TWDR3,     TWDR2,     TWDR1,     TWDR0     ]);
register!(0xBA, TWAR,     [TWA6,      TWA5,      TWA4,      TWA3,      TWA2,      TWA1,      TWA0,      TWGCE     ]);
register!(0xB9, TWSR,     [TWS4,      TWS3,      TWS2,      TWS1,      TWS0,      -,         TWPS1,     TWPS0     ]);
register!(0xB8, TWBR,     [TWBR7,     TWBR6,     TWBR5,     TWBR4,     TWBR3,     TWBR2,     TWBR1,     TWBR0     ]);
register!(0xB6, ASSR,     [-,         EXCLK,     AS2,       TCN2UB,    OCR2AUB,   OCR2BUB,   TCR2AUB,   TCR2BUB   ]);
register!(0xB4, OCR2B,    [OCR2B7,    OCR2B6,    OCR2B5,    OCR2B4,    OCR2B3,    OCR2B2,    OCR2B1,    OCR2B0    ]);
register!(0xB3, OCR2A,    [OCR2A7,    OCR2A6,    OCR2A5,    OCR2A4,    OCR2A3,    OCR2A2,    OCR2A1,    OCR2A0    ]);
register!(0xB2, TCNT2,    [TCNT27,    TCNT26,    TCNT25,    TCNT24,    TCNT23,    TCNT22,    TCNT21,    TCNT20    ]);
register!(0xB1, TCCR2B,   [FOC2A,     FOC2B,     -,         -,         WGM22,     CS22,      CS21,      CS20      ]);
register!(0xB0, TCCR2A,   [COM2A1,    COM2A0,    COM2B1,    COM2B0,    -,         -,         WGM21,     WGM20     ]);
register!(0x8B, OCR1BH,   [OCR1BH15,  OCR1BH14,  OCR1BH13,  OCR1BH12,  OCR1BH11,  OCR1BH10,  OCR1BH9,   OCR1BH8   ]);
register!(0x8A, OCR1BL,   [OCR1BL7,   OCR1BL6,   OCR1BL5,   OCR1BL4,   OCR1BL3,   OCR1BL2,   OCR1BL1,   OCR1BL0   ]);
register!(0x89, OCR1AH,   [OCR1AH15,  OCR1AH14,  OCR1AH13,  OCR1AH12,  OCR1AH11,  OCR1AH10,  OCR1AH9,   OCR1AH8   ]);
register!(0x88, OCR1AL,   [OCR1AL7,   OCR1AL6,   OCR1AL5,   OCR1AL4,   OCR1AL3,   OCR1AL2,   OCR1AL1,   OCR1AL0   ]);
register!(0x87, ICR1H,    [ICR1H15,   ICR1H14,   ICR1H13,   ICR1H12,   ICR1H11,   ICR1H10,   ICR1H9,    ICR1H8    ]);
register!(0x86, ICR1L,    [ICR1L7,    ICR1L6,    ICR1L5,    ICR1L4,    ICR1L3,    ICR1L2,    ICR1L1,    ICR1L0    ]);
register!(0x85, TCNT1H,   [TCNT1H15,  TCNT1H14,  TCNT1H13,  TCNT1H12,  TCNT1H11,  TCNT1H10,  TCNT1H9,   TCNT1H8   ]);
register!(0x84, TCNT1L,   [TCNT1L7,   TCNT1L6,   TCNT1L5,   TCNT1L4,   TCNT1L3,   TCNT1L2,   TCNT1L1,   TCNT1L0   ]);
register!(0x82, TCCR1C,   [FOC1A,     FOC1B,     -,         -,         -,         -,         -,         -         ]);
register!(0x81, TCCR1B,   [ICNC1,     ICES1,     -,         WGM11,     WGM10,     CS12,      CS11,      CS10      ]);
register!(0x80, TCCR1A,   [COM1A1,    COM1A0,    COM1B1,    COM1B0,    -,         -,         WGM11,     WGM10     ]);
register!(0x7F, DIDR1,    [-,         -,         -,         -,         -,         -,         AIN1D,     AIN0D     ]);
register!(0x7E, DIDR0,    [-,         -,         ADC5D,     ADC4D,     ADC3D,     ADC2D,     ADC1D,     ADC0D     ]);
register!(0x7C, ADMUX,    [REFS1,     REFS0,     ADLAR,     -,         MUX3,      MUX2,      MUX1,      MUX0      ]);
register!(0x7B, ADCSRB,   [-,         ACME,      -,         -,         -,         ADTS2,     ADTS1,     ADTS0     ]);
register!(0x7A, ADCSRA,   [ADEN,      ADSC,      ADATE,     ADIF,      ADIE,      ADPS2,     ADPS1,     ADPS0     ]);
register!(0x79, ADCH,     [ADCH15,    ADCH14,    ADCH13,    ADCH12,    ADCH11,    ADCH10,    ADCH9,     ADCH8     ]);
register!(0x78, ADCL,     [ADCL7,     ADCL6,     ADCL5,     ADCL4,     ADCL3,     ADCL2,     ADCL1,     ADCL0     ]);
register!(0x70, TIMSK2,   [-,         -,         -,         -,         -,         OCIE2B,    OCIE2A,    TOIE2     ]);
register!(0x6F, TIMSK1,   [-,         -,         ICIE1,     -,         -,         OCIE1B,    OCIE1A,    TOIE1     ]);
register!(0x6E, TIMSK0,   [-,         -,         -,         -,         -,         OCIE0B,    OCIE0A,    TOIE0     ]);
register!(0x6D, PCMSK2,   [PCINT7,    PCINT6,    PCINT5,    PCINT4,    PCINT3,    PCINT2,    PCINT1,    PCINT0    ]);
register!(0x6C, PCMSK1,   [-,         PCINT6,    PCINT5,    PCINT4,    PCINT3,    PCINT2,    PCINT1,    PCINT0    ]);
register!(0x6B, PCMSK0,   [PCINT7,    PCINT6,    PCINT5,    PCINT4,    PCINT3,    PCINT2,    PCINT1,    PCINT0    ]);
register!(0x69, EICRA,    [-,         -,         -,         -,         ISC11,     ISC10,     ISC01,     ISC00     ]);
register!(0x68, PCICR,    [-,         -,         -,         -,         -,         PCIE2,     PCIE1,     PCIE0     ]);
register!(0x66, OSCCAL,   [OSCCAL7,   OSCCAL6,   OSCCAL5,   OSCCAL4,   OSCCAL3,   OSCCAL2,   OSCCAL1,   OSCCAL0   ]);
register!(0x64, PRR,      [PRTWI,     PRTIM2,    PRTIM0,    -,         PRTIM1,    PRSPI,     PRUSART0,  PRADC     ]);
register!(0x61, CLKPR,    [CLKPCE,    -,         -,         -,         CLKPS3,    CLKPS2,    CLKPS1,    CLKPS0    ]);
register!(0x60, WDTCSR,   [WDIF,      WDIE,      WDP3,      WDCE,      WDE,       WDP2,      WDP1,      WDP0      ]);
register!(0x5F, SREG,     [I,         T,         H,         S,         V,         N,         Z,         C         ]);
register!(0x5E, SPH,      [-,         -,         -,         -,         SPH11,     SPH10,     SPH9,      SPH8      ]);
register!(0x5D, SPL,      [SPL7,      SPL6,      SPL5,      SPL4,      SPL3,      SPL2,      SPL1,      SPL0      ]);
register!(0x57, SPMCSR,   [SPMIE,     RWWSB,     -,         RWWSRE,    BLBSET,    PGWRT,     PGERS,     SELFPRGEN ]);
register!(0x55, MCUCR,    [-,         BODS,      BODSE,     PUD,       -,         -,         IVSEL,     IVCE      ]);
register!(0x54, MCUSR,    [-,         -,         -,         -,         WDRF,      BORF,      EXTRF,     PORF      ]);
register!(0x53, SMCR,     [-,         -,         -,         -,         SM2,       SM1,       SM0,       SE        ]);
register!(0x50, ACSR,     [ACD,       ACBG,      ACO,       ACI,       ACIE,      ACIC,      ACIS1,     ACIS0     ]);
register!(0x4E, SPDR,     [SPDR7,     SPDR6,     SPDR5,     SPDR4,     SPDR3,     SPDR2,     SPDR1,     SPDR0     ]);
register!(0x4D, SPSR,     [SPIF,      WCOL,      -,         -,         -,         -,         -,         SPI2X     ]);
register!(0x4C, SPCR,     [SPIE,      SPE,       DORD,      MSTR,      CPOL,      CPHA,      SPR1,      SPR0      ]);
register!(0x4B, GPIOR2,   [GPIOR27,   GPIOR26,   GPIOR25,   GPIOR24,   GPIOR23,   GPIOR22,   GPIOR21,   GPIOR20   ]);
register!(0x4A, GPIOR1,   [GPIOR17,   GPIOR16,   GPIOR15,   GPIOR14,   GPIOR13,   GPIOR12,   GPIOR11,   GPIOR10   ]);
register!(0x48, OCR0B,    [OCR0B7,    OCR0B6,    OCR0B5,    OCR0B4,    OCR0B3,    OCR0B2,    OCR0B1,    OCR0B0    ]);
register!(0x47, OCR0A,    [OCR0A7,    OCR0A6,    OCR0A5,    OCR0A4,    OCR0A3,    OCR0A2,    OCR0A1,    OCR0A0    ]);
register!(0x46, TCNT0,    [TCNT07,    TCNT06,    TCNT05,    TCNT04,    TCNT03,    TCNT02,    TCNT01,    TCNT00    ]);
register!(0x45, TCCR0B,   [FOC0A,     FOC0B,     -,         -,         WGM02,     CS02,      CS01,      CS00      ]);
register!(0x44, TCCR0A,   [COM0A1,    COM0A0,    COM0B1,    COM0B0,    -,         -,         WGM01,     WGM00     ]);
register!(0x43, GTCCR,    [TSM,       -,         -,         -,         -,         -,         PSRASY,    -         ]);
register!(0x43, GTCCR,    [TSM,       -,         -,         -,         -,         -,         -,         PSRSYNC   ]);
register!(0x43, GTCCR,    [TSM,       -,         -,         -,         -,         -,         -,         PSRSYNC   ]);
register!(0x42, EEARH,    [-,         -,         -,         -,         -,         -,         EEARH9,    EEARH8    ]);
register!(0x41, EEARL,    [EEARL7,    EEARL6,    EEARL5,    EEARL4,    EEARL3,    EEARL2,    EEARL1,    EEARL0    ]);
register!(0x40, EEDR,     [EEDR7,     EEDR6,     EEDR5,     EEDR4,     EEDR3,     EEDR2,     EEDR1,     EEDR0     ]);
register!(0x3F, EECR,     [-,         -,         EEPM1,     EEPM0,     EERIE,     EEMPE,     EEPE,      EERE      ]);
register!(0x3E, GPIOR0,   [GPIOR07,   GPIOR06,   GPIOR05,   GPIOR04,   GPIOR03,   GPIOR02,   GPIOR01,   GPIOR00   ]);
register!(0x3D, EIMSK,    [-,         -,         -,         -,         -,         -,         INT1,      INT0      ]);
register!(0x3C, EIFR,     [-,         -,         -,         -,         -,         -,         INTF1,     INTF0     ]);
register!(0x3B, PCIFR,    [-,         -,         -,         -,         -,         PCIF2,     PCIF1,     PCIF0     ]);
register!(0x37, TIFR2,    [-,         -,         -,         -,         -,         OCF2B,     OCF2A,     TOV2      ]);
register!(0x36, TIFR1,    [-,         -,         ICF1,      -,         -,         OCF1B,     OCF1A,     TOV1      ]);
register!(0x35, TIFR0,    [-,         -,         -,         -,         -,         OCF0B,     OCF0A,     TOV0      ]);
register!(0x2B, PORTD,    [PORTD7,    PORTD6,    PORTD5,    PORTD4,    PORTD3,    PORTD2,    PORTD1,    PORTD0    ]);
register!(0x2A, DDRD,     [DDRD7,     DDRD6,     DDRD5,     DDRD4,     DDRD3,     DDRD2,     DDRD1,     DDRD0     ]);
register!(0x29, PIND,     [PIND7,     PIND6,     PIND5,     PIND4,     PIND3,     PIND2,     PIND1,     PIND0     ]);
register!(0x28, PORTC,    [-,         PORTC6,    PORTC5,    PORTC4,    PORTC3,    PORTC2,    PORTC1,    PORTC0    ]);
register!(0x27, DDRC,     [-,         DDRC6,     DDRC5,     DDRC4,     DDRC3,     DDRC2,     DDRC1,     DDRC0     ]);
register!(0x26, PINC,     [-,         PINC6,     PINC5,     PINC4,     PINC3,     PINC2,     PINC1,     PINC0     ]);
register!(0x25, PORTB,    [PORTB7,    PORTB6,    PORTB5,    PORTB4,    PORTB3,    PORTB2,    PORTB1,    PORTB0    ]);
register!(0x24, DDRB,     [DDRB7,     DDRB6,     DDRB5,     DDRB4,     DDRB3,     DDRB2,     DDRB1,     DDRB0     ]);
register!(0x23, PINB,     [PINB7,     PINB6,     PINB5,     PINB4,     PINB3,     PINB2,     PINB1,     PINB0     ]);
register!(0x02, EXTENDED, [-,         -,         -,         -,         -,         BODLEVEL2, BODLEVEL1, BODLEVEL0 ]);
register!(0x01, HIGH,     [RSTDISBL,  DWEN,      SPIEN,     WDTON,     EESAVE,    BOOTSZ1,   BOOTSZ0,   BOOTRST   ]);
register!(0x00, LOW,      [CKDIV8,    CKOUT,     SUT_CKSEL5,SUT_CKSEL4,SUT_CKSEL3,SUT_CKSEL2,SUT_CKSEL1,SUT_CKSEL0]);
register!(0x00, LOCKBIT,  [-,         -,         BLB11,     BLB10,     BLB01,     BLB00,     LB1,       LB0       ]);

dsvensson avatar Jul 09 '17 19:07 dsvensson

Any idea about 16-bit register pairs or aliases?

I'm generating them as H/L, with bits from 0...15, here they are:

// atmega32u4
pub const ADC:    *mut u16 = ADCL    as *mut u16;
pub const EEAR:   *mut u16 = EEARL   as *mut u16;
pub const ICR1:   *mut u16 = ICR1L   as *mut u16;
pub const ICR3:   *mut u16 = ICR3L   as *mut u16;
pub const OCR1A:  *mut u16 = OCR1AL  as *mut u16;
pub const OCR1B:  *mut u16 = OCR1BL  as *mut u16;
pub const OCR1C:  *mut u16 = OCR1CL  as *mut u16;
pub const OCR3A:  *mut u16 = OCR3AL  as *mut u16;
pub const OCR3B:  *mut u16 = OCR3BL  as *mut u16;
pub const OCR3C:  *mut u16 = OCR3CL  as *mut u16;
pub const SP:     *mut u16 = SPL     as *mut u16;
pub const TCNT1:  *mut u16 = TCNT1L  as *mut u16;
pub const TCNT3:  *mut u16 = TCNT3L  as *mut u16;
pub const UBRR1:  *mut u16 = UBRR1L  as *mut u16;
pub const UDFNUM: *mut u16 = UDFNUML as *mut u16;

// atmega328p
pub const ADC:    *mut u16 = ADCL    as *mut u16;
pub const EEAR:   *mut u16 = EEARL   as *mut u16;
pub const ICR1:   *mut u16 = ICR1L   as *mut u16;
pub const OCR1A:  *mut u16 = OCR1AL  as *mut u16;
pub const OCR1B:  *mut u16 = OCR1BL  as *mut u16;
pub const SP:     *mut u16 = SPL     as *mut u16;
pub const TCNT1:  *mut u16 = TCNT1L  as *mut u16;
pub const UBRR0:  *mut u16 = UBRR0L  as *mut u16;

And here is the updated script.

dsvensson avatar Jul 10 '17 13:07 dsvensson

Side note, does this library have support for the Mega? It does have an increased number of pins compared to the Uno and other similar boards, as well as having (2 iirc) more serial ports, which run on certain pins.

Restioson avatar Aug 10 '17 12:08 Restioson

@dylanmckay any idea if avrd can be of use here? Specifically, I don't see any of the bits available there.

shepmaster avatar Aug 25 '17 16:08 shepmaster

AVRd does have the pins afaik. It could solve the problem.

Restioson avatar Aug 25 '17 17:08 Restioson

AVRd does have the pins afaik

It appears it has access to the pins (bitfield), but isn't currently making use of them.

shepmaster avatar Aug 25 '17 17:08 shepmaster

What do you mean? The README indicates that you can use them like you would using the arduino library: README example

Restioson avatar Aug 25 '17 18:08 Restioson

What do you mean? The README indicates that you can use them like you would using the arduino library:

Yes, but this library currently also relies on the pins associated

register!(0x25, PORTB,  [PORTB7,  PORTB6,  PORTB5,  PORTB4,  PORTB3,  PORTB2,  PORTB1,  PORTB0 ]);

I don't see PORTB7 in those docs.

shepmaster avatar Aug 25 '17 18:08 shepmaster

Yeah, we definitely have access to the bitfields from the pack files.

At the moment, the library only uses them in generated documentation.

We can definitely use them to generate PORT[A-Z][0-9] constants.

dylanmckay avatar Aug 26 '17 00:08 dylanmckay

Can confirm that AVRd has definitions for every register across every device.

dylanmckay avatar Aug 26 '17 00:08 dylanmckay

Just because it was in my head, I wonder what kinds of type safety and structuring we could employ. For example:

struct PORTB;

impl PORTB {
    const PORTB7: u8 = 1 << 0;
}

struct Register(*const u8);

impl From<PORTB> for Register {
    fn from(_: PORTB) -> Self { Register(0x20 as _) }
}

This would make each register its own type, and then we could choose to implement traits across them.

I did something similar locally:

pub trait Information {
    const DDR: *mut u8;
    const IO: *mut u8;
    const PIN: *mut u8;
}

pub struct B;

impl Information for B {
    const DDR: *mut u8 = ::DDRB;
    const IO: *mut u8 = ::PORTB;
    const PIN: *mut u8 = ::PINB;
}

shepmaster avatar Aug 26 '17 15:08 shepmaster

I was thinking if we want the avrd library to do something like this.

I'd really like the library to be quite low level that other devices built atop of, but if we create a trait like this then we can auto generate it for all devices, rather than having to rebuild all of it for the Arduino library.

Another option might be to extract most of avrd to a library. With that, we could add it as a build dependency for Arduino and then use it to generate structures ourselves.

dylanmckay avatar Aug 26 '17 23:08 dylanmckay

Another option might be to extract most of avrd to a library.

That seems like it might be the appropriate path. A rough idea would be that the arduino library would have only generic things like

pub trait Information {
    const DDR: *mut u8;
    const IO: *mut u8;
    const PIN: *mut u8;
}

The user uses avrd (or something built on top of it) in their own build script (insert hand-waving here), generating code like

pub struct B;

impl Information for B {
    const DDR: *mut u8 = ::DDRB;
    const IO: *mut u8 = ::PORTB;
    const PIN: *mut u8 = ::PINB;
}

Which accounts for their specific board (e.g. which PORTx are available). They can then use the combination of the two libraries, effectively dependency-injecting the concrete board information.

This could also allow for the user to choose a serial implementation for macros like println! to use.

A big question in my mind is exactly how abstract we can be. Aren't there some boards that have like... "half" of a PORT defined? Will things like that cause massive pain?

shepmaster avatar Aug 27 '17 16:08 shepmaster

We could abstract it on the GPIO level rather than the port level.

The pack files do say the number of pins supported on each port.

Something like

trait Pin {
    const DDR: *mut u8;
    const PORT: *mut u8;
    const PIN: *mut u8;
    const MASK: u8;
}

struct PB5;

impl Pin for PB5 {
    const DDR: *mut u8 = ::DDRB;
    const PORT: *mut u8 = ::PORTB;
    const PIN: *mut u8 = ::PINB;
    const MASK: u8 = 1<<5;
}

dylanmckay avatar Aug 29 '17 03:08 dylanmckay

I remember there also being some sort of special IO register that 1 can be written to which will toggle the pin, regardless of its current state.

Because the XOR is done in hardware, it's faster than using PORTB to toggle.

If we abstract this on the pin level, we can write a toggle method to do this optimisation transparently.

dylanmckay avatar Aug 29 '17 03:08 dylanmckay

I remember there also being some sort of special IO register that 1 can be written to which will toggle the pin, regardless of its current state.

Yep, that was one of the things that tripped me up earlier this year, and why I asked you about coalescing 8 consecutive sbi instructions for the same register.

You can see my current set of changes in the ports branch. TL;DR yeah, there's a toggle function.

shepmaster avatar Aug 29 '17 12:08 shepmaster

I've got my own local branch as well, exposing a Pin trait that gets implementations generated per mcu.

I'm also creating a HardwareSerial trait, and if I can understand enough about timers, will hopefully do that too.

dylanmckay avatar Aug 29 '17 23:08 dylanmckay

Here's my WIP PR avr-rust/arduino#4

dylanmckay avatar Aug 30 '17 03:08 dylanmckay

Related: could this be done for serial ports?

Example gist: https://gist.github.com/Restioson/47976cc261a1a9b788114283e98f2308 (Apologies for any mistakes)

Restioson avatar Aug 30 '17 12:08 Restioson

Yeah, I've done it for SPI so far.

dylanmckay avatar Aug 30 '17 13:08 dylanmckay

Great :smile:

Restioson avatar Aug 30 '17 13:08 Restioson