avrdudes / avr-libc

The AVR-LibC package provides a subset of the standard C library for AVR 8-bit RISC microcontrollers.
https://avrdudes.github.io/avr-libc/
Other
240 stars 52 forks source link

Inconsistent DDR bit position definitions #913

Open stefanrueger opened 1 year ago

stefanrueger commented 1 year ago

A lot of registers give their bits names such as

#define PORTB0 0

That is mildly useful in such as the absence of that definition tells me that this bit isn't used or might be reserved.

However the DDR regs get the Cinderella treatment. :open_mouth:

Only 31 parts that have PINB0 defined go on to define DDRB0. The other 173 don't. Affected parts are at43usb320 at43usb355 at76c711 at90can128 at90can32 at90can64 at90pwm1 at90pwm216 at90pwm2b at90pwm2 at90pwm316 at90pwm3b at90pwm3 at90pwm81 at90s1200 at90s2313 at90s2323 at90s2333 at90s2343 at90s4414 at90s4433 at90s4434 at90s8515 at90s8535 at90scr100 at90usb1286 at90usb1287 at90usb162 at90usb646 at90usb647 at90usb82 ata6289 ata6612c ata6613c ata6614q ata6616c ata6617c ata664251 atmega103 atmega1280 atmega1281 atmega1284p atmega1284rfr2 atmega128 atmega128rfa1 atmega128rfr2 atmega161 atmega162 atmega163 atmega164a atmega164p atmega165 atmega165p atmega168a atmega168 atmega168p atmega169a atmega169 atmega169pa atmega169p atmega16a atmega16hva2 atmega16hva atmega16hvb atmega16hvbrevb atmega16 atmega16m1 atmega16u2 atmega16u4 atmega2560 atmega2561 atmega2564rfr2 atmega256rfr2 atmega323 atmega324a atmega324pa atmega324p atmega3250a atmega3250 atmega3250p atmega325a atmega325 atmega325p atmega328 atmega328p atmega3290a atmega3290 atmega3290p atmega329a atmega329 atmega329pa atmega329p atmega32c1 atmega32hvb atmega32hvbrevb atmega32 atmega32m1 atmega32u2 atmega32u4 atmega32u6 atmega406 atmega48a atmega48 atmega48p atmega640 atmega644a atmega644 atmega644pa atmega644p atmega644rfr2 atmega6450a atmega6450 atmega6450p atmega645a atmega645 atmega645p atmega6490a atmega6490 atmega6490p atmega649a atmega649 atmega649p atmega64c1 atmega64hve atmega64 atmega64m1 atmega64rfr2 atmega8515 atmega8535 atmega88a atmega88 atmega88pa atmega88p atmega8hva atmega8 atmega8u2 attiny10 attiny11 attiny12 attiny13a attiny13 attiny15 attiny167 attiny20 attiny22 attiny2313a attiny2313 attiny24a attiny24 attiny25 attiny261a attiny261 attiny26 attiny28 attiny40 attiny4313 attiny43u attiny44a attiny44 attiny45 attiny461a attiny461 attiny48 attiny4 attiny5 attiny84a attiny84 attiny85 attiny861a attiny861 attiny87 attiny88 attiny9

dl8dtl commented 1 year ago

I have never seen anyone using these bit names in the wild.

Most AVR GPIO registers are full 8 bits anyway, and for those that aren't, the missing bit names are usually not the biggest issue. ;-)

The FAQ mentions one pitfall for ATmega128 (and comparable) where port G has only 5 bits:

DDRA = DDRB = DDRC = DDRD = DDRE = DDRF = DDRG = 0xFF;

doesn't give you what you'd expect. ;-) Besides of forcing the IO registers to be read back before passing the value to the next one being pretty suboptimal, you'd end up with all registers having 0x1F as their value.

stefanrueger commented 1 year ago

I have never seen anyone using these bit names in the wild.

I just have (to figure out which ports have which general I/O bits, ie, one where PINXn, DDRXn and PORTXn exist). There will be other uses.

mentions one pitfall for ATmega128 (and comparable) where port G has only 5 bits

Glad you know. This would have been my next Issue :)

dl8dtl commented 1 year ago

to figure out which ports have which general I/O bits

Use the datasheet. :-)

stefanrueger commented 1 year ago

Use the datasheet. :-)

Overrated. :) Admittedly, I'm a bit too lazy to read the 100+ datasheets 800 pages each to cover the 300+ parts I'm interested in for generating a table of GP I/O registers addresses and bit offsets ;) when actually a 10-line scan through the header files or (correlated, but not highly correlated) ATDFs should suffice. I'm actually reporting here where I get discrepancies between the two sources...

SpenceKonde commented 1 year ago

Use the datasheet. :-)

Overrated. :) Admittedly, I'm a bit too lazy to read the 100+ datasheets 800 pages each to cover the 300+ parts I'm interested in for generating a table of GP I/O registers addresses and bit offsets ;) when actually a 10-line scan through the header files or (correlated, but not highly correlated) ATDFs should suffice. I'm actually reporting here where I get discrepancies between the two sources...

Why do we define the 31 old parts with the define as the ones that were working as intended? I It sound to me more like after releasing a few parts, the found that the DDRxn defines added confusion instead of removing it (why have three different interchangible macros for each pin?) and it's not like anyone used these and dropped them from future headers (But left them in existing onesto not break extant code), and only kept the one with the name that clearly describes what it's for. Also I vaguely recall there being some naming conflict that they tripped over, so either DDxn turned to DDRxn or vise vesa.

In any event, these problems are within the ATpacks, which are controlled and released by Microchip. I don't have any authority here, but personally I don't think fixing them falls under the portfolio of avrlibc, I think this is microchip's job (quite literally);. The list of issues with the headers should go to Microchip. They're the one who make the chips, and providing accurate headers is kina their responsibility (in fact the headers are the only thing I refuse to modify on my cores. I put in compatibility defines to fix fix shit when they break compatibility, but never as changes to the official headers.

But why not just include a header full of compatibility defines? You want DDRxn? Okay - can be made through automated means for every pin that can exist on a classic AVR.

#if !defined(DDRA0) && defined (PINA0) 
  #define DDRA0 (PINA0)
#endif 

When I need to make things like this a I use excel and sublime text. (Excel excells at like, sequential numbers in columns, and math but it useless for text, so I just compose the parts of the repetitive lines that vary in Excel, then copy-paste that into a new text file in sublime and run regex over it to put int the rest of the the debris. This is how I do stuff like this in the cores I maintain, like when I need to edit every variant file or when I was making that probly not yet released faster/lower randomness xorshift rng library and I wanted to include all 60 permutations of 16-bit xorshift that give a full period (I generated the list on an AVR, then copied it back to sublime for post processing (most likely I searched for .65535., copied all those lines (which included the shifts that generated) into another new file, then had it process the files to get the relevant data out, added it to the for editing boards.txt to modify every board on megaTinyCore or DxCore. It's a shockingly effective tactic, and almost everything can be done without resorting to Excel. Like for the above you could make the 2 columns in excel, first column being the letters second extend it out to the highest pin number found on the parts, and it will come out with the numbers separated by a tab when you copy-paste out, , then regex substitution to decorate it with the static syntax... first replace \t with empty string to get turn A 0 into A0, then regex search for ^([A-Z][\d]) replace with

#if !defined(DDR\1) && defined (PIN\1)\n  #define DDR\1 (PIN\1)\n#endif 

Then copy-paste that mess into whatever file you're putting it into, and since the compatibility defines will only apply to either modern or classic AVRs, you'd want to wrap the whole mess in #if (__AVR_ARCH__ >= 100) to get only modern AVRs or < 100 to only get classic ones...