-
Notifications
You must be signed in to change notification settings - Fork 50
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
contributing other boards #2
Comments
What addresses were these? Did you have to run a custom linking command? |
AVR-LLVM itself supports hundreds of different AVR microcontrollers, so the problem is likely that Rust needs to pass extra arguments to the linker. |
UDR0, UBRR0H, UBRR0L, UCSR0C, UCSR0B, UCSR0A etc |
I'm getting my repositories mixed up haha, cc @shepmaster |
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. |
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? |
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! |
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. |
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 referenceimport 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 ]);
""" |
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 ]); |
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. |
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. |
@dylanmckay any idea if avrd can be of use here? Specifically, I don't see any of the bits available there. |
AVRd does have the pins afaik. It could solve the problem. |
It appears it has access to the pins ( |
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 |
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 |
Can confirm that AVRd has definitions for every register across every device. |
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;
} |
I was thinking if we want the 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 |
That seems like it might be the appropriate path. A rough idea would be that the pub trait Information {
const DDR: *mut u8;
const IO: *mut u8;
const PIN: *mut u8;
} The user uses 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 This could also allow for the user to choose a serial implementation for macros like 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? |
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;
} |
I remember there also being some sort of special IO register that Because the XOR is done in hardware, it's faster than using If we abstract this on the pin level, we can write a |
Yep, that was one of the things that tripped me up earlier this year, and why I asked you about coalescing 8 consecutive You can see my current set of changes in the |
I've got my own local branch as well, exposing a I'm also creating a |
Here's my WIP PR #4 |
Related: could this be done for serial ports? Example gist: https://gist.github.com/Restioson/47976cc261a1a9b788114283e98f2308 (Apologies for any mistakes) |
Yeah, I've done it for SPI so far. |
Great 😄 |
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?
The text was updated successfully, but these errors were encountered: