I can save £0.40 per device if I move from the ATMEGA328P to an ATMEGA328PB, given that I am expecting to use around 4000 of these microcontrollers a year this looks like a no brainer decision to me… The ATMEGA328P has been around for a few years now and I did check that the device was supported in avr-gcc *before* I committed to a PCB. The device on the surface appears to be a simple B revision, with a few changes over the original part as described in Application Note AN_42559 – AT15007: Differences between ATmega328/P and ATmega328PB. There are potential issues around the crystal drive for the clock (but I am pretty sure that I have done the appropriate calculations so this will work – famous last words I know).
I have had my PCBs back for a couple of weeks now, I have populated the boards and confirmed that electrically they work fine, the interface to the Raspberry Pi has also been tested. I took a week out for the DebConf Videoteam sprint and a couple of extra days to recover from FOSDEM (catch up on much needed sleep) so today I picked up the project once again.
My first task was to change my firmware build away from an Arduino Uno R3 platform to my own PCB – simple right? Just move around my #defines to match the GPIO pins I am using to drive my hardware, and change my build flags from -mmcu=atmega328p to -mmcu=atmega328pb and then rebuild.
If only things were that simple….
It turns out that even though the avr-gcc in Stretch knows about the atmega328pb it doesn’t know how to deal with it.
The internet suggested in all its wisdom that this was a known bug, so I updated my trusty laptop to Buster to take a look (where known bug is old and apparently resolved in a version number lower than that of gcc-avr in buster).
Good news – my upgrade to buster went without hitch :-)
Bad news – my program still does not compile – I still have the same error
avr/include/avr/io.h:404:6: warning: #warning " device type not defined"
My googlefoo must be getting better these days because it didn’t take long to track down a solution:
I need to download a “pack” from Atmel / Microchip that tells gcc about the 328pb. I downloaded the Atmel ATmega Series Device Support Pack from packs.download.atmel.com
Once I copied all the *.h files from within the pack to /usr/lib/avr/include to get the avr io headers to work properly. I also put all the other files from the pack into a folder called `packs` in my project folder. Inside the packs folder should be folder like “gcc, include, templates…”
I now needed to update my build script to add another GCC flag to tell it to use the atmega328pb definition from the ‘pack’
We are finally getting somewhere, my errors about undefined device type has gone away, however I am now getting new errors about the SPI control registers being unrecognized.
One of the differences between the two chip ‘revisions’ is that the atmega328pb has an additional SPI port, so it makes sense that registers have been renamed following the convention of adding device number after the register.
Thus the interrupt vector SPI_STC_vect becomes SPI0_STC_vect and the registers simply gain a 0 suffix.
A few #if statements later and my code now compiles and I can commence testing… Happy days!
The ‘pack’ which contains the details for the ATMEGA328PB is 1.2.132 (2016-12-14) which means it has had quite a while to be included in the tool-chain. Should this be included as part of avr-gcc for buster? I would hope so, but we are now in a freeze so perhaps it will be missed.
Next task – avr-dude. Does the buster build recognize the ATMEGA328PB signatures / program correctly?
[EDIT 20190213 AS] Yes avr-dude recognises and programs the ATMEGA328PB just fine.