AVR header messed up for 328

I've run across a number of problems with existing code and libraries when compiling for the ATmega328. What I've found is that the included AVR header file for the chip has a significant number of define names changed for no apparent reason. When existing code is compiled for the 328 either it fails to compile because of a missing define, or in the case of changed interrupt vectors builds code that locks up.

The header used for the ATmega8/168 is:
/hardware/tools/avr/avr/include/avr/iomx8.h

The header used for the ATmega328 is:
/hardware/tools/avr/avr/include/avr/iom328p.h

Some examples of changes that have caused problems:

PORTB references

ATmega8/168 (iomx8.h):

#define PORTB   _SFR_IO8 (0x05)
/* PORTB */
#define PB7     7
#define PB6     6
#define PB5     5
#define PB4     4
#define PB3     3
#define PB2     2
#define PB1     1
#define PB0     0

ATmega328 (iom328p.h):

#define PORTB _SFR_IO8(0x05)
#define PORTB0 0
#define PORTB1 1
#define PORTB2 2
#define PORTB3 3
#define PORTB4 4
#define PORTB5 5
#define PORTB6 6
#define PORTB7 7

There's a lot of code that references PB0 - PB7 and this all breaks because the definitions are changed to PORTB0 - PORTB7. PORTC and PORTD have the same problems.

Interrupt Vectors

ATmega8/168 (iomx8.h):

#define INT0_vect                  _VECTOR(1)
#define SIG_INTERRUPT0                  _VECTOR(1)

/* External Interrupt Request 1 */
#define INT1_vect                  _VECTOR(2)
#define SIG_INTERRUPT1                  _VECTOR(2)

/* Pin Change Interrupt Request 0 */
#define PCINT0_vect                  _VECTOR(3)
#define SIG_PIN_CHANGE0                  _VECTOR(3)

/* Pin Change Interrupt Request 0 */
#define PCINT1_vect                  _VECTOR(4)
#define SIG_PIN_CHANGE1                  _VECTOR(4)

ATmega328 (iom328p.h):

#define INT0_vect         _VECTOR(1)   /* External Interrupt Request 0 */
#define INT1_vect         _VECTOR(2)   /* External Interrupt Request 1 */
#define PCINT0_vect       _VECTOR(3)   /* Pin Change Interrupt Request 0 */
#define PCINT1_vect       _VECTOR(4)   /* Pin Change Interrupt Request 0 */

It looks like the "old" names for all of the interrupt vectors have been left out. While I understand that the old names like "SIG_PIN_CHANGE0" are deprecated and should be changed to "PCINT0_vect", there's a large base of existing libraries that reference the old interrupt vector names. I don't see any reason to break all of that code by removing the old names when they don't hurt anything to be there.

I wouldn't be so bad if the code failed to compile, but it doesn't. There's only a warning about a possibly misspelled signal handler. Invalid code still gets built that crashes the chip whenever the interrupt is triggered.

There are probably more differences in the support for 328's but this is what I've come across so far.

Good research, thanks for your effort in documenting this.

I vote for not trying to get headers out of sync with AVR-GCC as tempting as that may be--at least not in the standard distribution. Maybe include an "unsupported" patched version of the 328 headers for download somewhere that will help un-upgraded third party libraries work.

An officially supported 3rd party library repository would really be a great thing...

--Phil.

I'm okay with an "unsupported" patch version as long as it's "supported" by the IDE. In other words the Arduino core could conditionally include this enhancement to the standard AVR-GCC code if the target was the 328. The enhanced 328 header definitions would be part of the Arduino core distribution, not the AVR-GCC includes.

This would allow the existing code to seamlessly compile without forcing people to track down a relatively esoteric fix.

Indeed!

On linux one uses the avr-gcc that comes with the OS. Messing with additional packages would be horrid. If it can be easily solved by including a header file for compatibility this should be done that way.

Has anyone complained to the gcc team? Atmega328 really is in the same family as Atmega168, and so should include the same base iomx8.h instead of doing its own thing...

Could this be why, with my brand new Duemilanove (with 328) and arduino-0015, that nothing works when I download it from the playground?

The problems I had with the LedControl library were simple and have been fixed.

The problems I'm having with FrequencyTimer2 are IMMENSE. All I have to do is unzip the file, put it in arduino=0015\hardware\libraries and the IDE spits out 19 lines of errors at startup!!! (see http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1239820770)

I'm pretty much a noob, never was much of a coder, but doing OK with the arduino wrappers. However, when it gets down to mucking around with #define statements inside header files, I'm not so confident.

It would be great to be able to contact the authors of all those libraries, many of which I'm guessing have been there quite some time. They're posted as gospel, with the instructions saying effectively, "download it, unzip it, put it here, and everything will work perfectly". So I do, and nothing works at all. Some of those libraries have been there for at least a couple years. Do the authors of these libraries ever check that their libraries still work when an new version of the IDE is released? Do the authors of the new IDEs even care that when they are released, that they break libraries that have otherwise worked for years?

Having been a validation engineer for a long long time, I'd think that a code release would have been checked against all the libraries that are out there and in common use (i.e. at the bare minimum ALL the ones on the playground) before they release it to the public.

Frustrated and completely 100% stalled on my project until somebody can help me with making the FrequencyTimer2 library work under 0015 with a Duemilanove. I'm stumped.

The reason that libraries are on the playground and not in the distribution is because I don't have time to test them all against every release of the software. I hope that their authors will test and update them (or submit patches to support them). Unfortunately, many of the contributed libraries seem to get only limited updates and support from their authors or the community.

Hence my statement that it would be great to be able to contact the authors of those libraries.

Providing contact information and ongoing support would be the responsibility of the author. If you feel you're not getting the support you need from said author, then simply don't use their (free) library.

Alternately you could work on finding a solution and contributing that to the community so that others can benefit.

And yes, the solutions to your compilation problem can be found be examining the header files referenced in my original post and adjusting for the differences between the 168 and 328 chips.

Alternately you could work on finding a solution and contributing that to the community so that others can benefit.

I kinda didn't want to say anything until I made further progress, but I'm actually in the process of trying to set up some regression testing infrastructure so we can avoid some of the issues that have occurred (particularly with 3rd party libraries) with recent releases.

I've currently implemented it (using BuildBot) on an Ubuntu VM but for it to be most useful an internet-facing machine/VM somewhere would be helpful if anyone else wanted to get involved.

--Phil.