How Do I Create A Custom Boards Package for Atmega328PB?

Hello all! So I am trying to get a custom Atmega328PB PCB working with the Arduino IDE so that I can use the serial-to-USB connection and also use all the additional functionality that the 328PB provides. I have messed around with using boot loaders and boards packages from other projects that involve the 328PB, but many times I have not encountered much success. What I want to do now is create my own custom boards package for the my custom PCB, but I am not entirely sure where to start.

I have snooped around a bit on Arduino sites and I have found insightful information on how the Arduino IDE works:

And also the format of the JSON 3rd party board link to add 3rd party support on the board manager:

From this I have gleaned that I would require editing and including files such as platform.txt, the avr-gcc/avrdude tool chain, and most importantly a board support package. By looking at existing Arduino board packages I have not been able to distinguish what is really required and what files I need. I was wondering if anybody has some of their own insight to give me on how I would proceed to creating a custom boards package, whether if there are any tutorials and tidbits online, or if I am missing something else in my understanding of how to get my board to interact with the Arduino IDE? Thanks!

What is your 328P doing that a regular Uno with 16 MHz external resonator/crystal is not?
I would just bootload it as an Uno, and select Uno as the board type when you download code.

Hi CrossRoads,
I am actually using the Atmega328PB which is not officially supported by the Arduino IDE as of yet. I need the 328PB's multiple UARTs, SPIs, GPIOs, etc. but right now I can't even get the 328PB to communicate with the Arduino IDE via serial to flash code. If I just burned the 328P's boot loader I can only use the one UART, etc., etc.

Here are some github links of other people that have made custom board packages for their own boards which utilize the 328PB:

I have not been able to get theirs to work so I am currently figuring out how to make my own packages for my board.

Here is another link that I am looking at right now:

It gives an overview of the files that I need to edit to add support for my board (boards.txt, platform.txt, programmers.txt) but I was wondering if there was anymore that I need to add to my custom board package.

Ah, I missed the PB in the original post. I've not used that part for anything. Good luck in the adaptations.

Maybe ask about getting the Minicore by MCUdude updated to include the 328PB?

Thanks for the follow up CrossRoads, I'll take a look into seeing if they can build some support. I have been looking at different links into the organization of how the Arduino IDE flashes code. From what I've read online, the IDE runs an AVR tool chain (avr-gcc, avrdude, etc.) which then takes a look at the boards.txt, programmers.txt, etc. files in order to configure, say, the uploading specifications based off of the baud rate that it reads. With that it then begins uploading the code via some tool called UISP. This is all done in the STK500 communication protocol I believe.

I am wondering if I am missing something in this process since I looked at a board supports package and I saw files such as pins_arduino.h which I did not even read about in the searches. It seems that this file is used to specify timers and interrupts which I believe is used for the resetting of the Arduino chip to know when to reflash programs. Can anybody confirm this and is there maybe a template for editing this hardware specific information?

(This is Advanced21515 by the way... )

Most of what you mention in Reply #5 is about uploading code. I suspect that is really a secondary issue.

The bigger problem (I suspect, from the depths of ignorance) is telling the Arduino how to generate code to use the extra features. Without that there seems little point in using the new chip.

Maybe look at how products are defined that have similar features - for example a Leonardo has two serial ports.

...R

I think the “core” file(s) may need to be created, along with the pins_arduino.h to map device features with IO pins, and then the IDE files/libraries updated with the #if def (atmega328PB) kind of statements.
Hansibull and Drazzy have done that kind of stuff for many chips, maybe working from one of those would be the best place to start.
Hence the suggestion to look at the Minicore stuff on Github.

avrdude.conf (in IDE 1.8.1) does not have a 328PB section either, so I think it would need to be added there

#------------------------------------------------------------

# ATmega328

#----------------------------------------------------------

 part

 id = "m328";

 desc = "ATmega328";

 has_debugwire = yes;

 flash_instr = 0xB6, 0x01, 0x11;

 eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,

 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,

 0x99, 0xF9, 0xBB, 0xAF;

 stk500_devcode = 0x86;

 # avr910_devcode = 0x;

 signature = 0x1e 0x95 0x14;

 pagel = 0xd7;

 bs2 = 0xc2;

 chip_erase_delay = 9000;

 pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",

 "x x x x x x x x x x x x x x x x";

 chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",

 "x x x x x x x x x x x x x x x x";

 timeout = 200;

 stabdelay = 100;

 cmdexedelay = 25;

 synchloops = 32;

 bytedelay = 0;

 pollindex = 3;

 pollvalue = 0x53;

 predelay = 1;

 postdelay = 1;

 pollmethod = 1;

 pp_controlstack =

 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,

 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,

 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,

 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;

 hventerstabdelay = 100;

 progmodedelay = 0;

 latchcycles = 5;

 togglevtg = 1;

 poweroffdelay = 15;

 resetdelayms = 1;

 resetdelayus = 0;

 hvleavestabdelay = 15;

 rsetdelay = 15;

 chiperasepulsewidth = 0;

 chiperasepolltimeout = 10;

 programfusepulsewidth = 0;

 programfusepolltimeout = 5;

 programlockpulsewidth = 0;

 programlockpolltimeout = 5;

 ocdrev = 1;

 memory "eeprom"

 paged = no;

 page_size = 4;

 size = 1024;

 min_write_delay = 3600;

 max_write_delay = 3600;

 readback_p1 = 0xff;

 readback_p2 = 0xff;

 read = " 1 0 1 0 0 0 0 0",

 " 0 0 0 x x x a9 a8",

 " a7 a6 a5 a4 a3 a2 a1 a0",

 " o o o o o o o o";

 write = " 1 1 0 0 0 0 0 0",

 " 0 0 0 x x x a9 a8",

 " a7 a6 a5 a4 a3 a2 a1 a0",

 " i i i i i i i i";

 loadpage_lo = " 1 1 0 0 0 0 0 1",

 " 0 0 0 0 0 0 0 0",

 " 0 0 0 0 0 0 a1 a0",

 " i i i i i i i i";

 writepage = " 1 1 0 0 0 0 1 0",

 " 0 0 x x x x a9 a8",

 " a7 a6 a5 a4 a3 a2 0 0",

 " x x x x x x x x";

 mode = 0x41;

 delay = 20;

 blocksize = 4;

 readsize = 256;

 ;

 memory "flash"

 paged = yes;

 size = 32768;

 page_size = 128;

 num_pages = 256;

 min_write_delay = 4500;

 max_write_delay = 4500;

 readback_p1 = 0xff;

 readback_p2 = 0xff;

 read_lo = " 0 0 1 0 0 0 0 0",

 " 0 0 a13 a12 a11 a10 a9 a8",

 " a7 a6 a5 a4 a3 a2 a1 a0",

 " o o o o o o o o";

 read_hi = " 0 0 1 0 1 0 0 0",

 " 0 0 a13 a12 a11 a10 a9 a8",

 " a7 a6 a5 a4 a3 a2 a1 a0",

 " o o o o o o o o";

 loadpage_lo = " 0 1 0 0 0 0 0 0",

 " 0 0 0 x x x x x",

 " x x a5 a4 a3 a2 a1 a0",

 " i i i i i i i i";

 loadpage_hi = " 0 1 0 0 1 0 0 0",

 " 0 0 0 x x x x x",

 " x x a5 a4 a3 a2 a1 a0",

 " i i i i i i i i";

 writepage = " 0 1 0 0 1 1 0 0",

 " 0 0 a13 a12 a11 a10 a9 a8",

 " a7 a6 x x x x x x",

 " x x x x x x x x";

 mode = 0x41;

 delay = 6;

 bocksize = 128;

 readsize = 256;

 ;

 memory "lfuse"

 size = 1;

 min_write_delay = 4500;

 max_write_delay = 4500;

 read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",

 "x x x x x x x x o o o o o o o o";

 write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",

 "x x x x x x x x i i i i i i i i";

 ;

 memory "hfuse"

 size = 1;

 min_write_delay = 4500;

 max_write_delay = 4500;

 read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",

 "x x x x x x x x o o o o o o o o";

 write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",

"x x x x x x x x i i i i i i i i";

 ;

 memory "efuse"

 size = 1;

 min_write_delay = 4500;

 max_write_delay = 4500;

 read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",

 "x x x x x x x x o o o o o o o o";

 write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",

 "x x x x x x x x x x x x x i i i";

 ;

 memory "lock"

 size = 1;

 min_write_delay = 4500;

 max_write_delay = 4500;

 read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",

 "x x x x x x x x x x o o o o o o";

 write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",

 "x x x x x x x x 1 1 i i i i i i";

 ;

 memory "calibration"

 size = 1;

 read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",

 "0 0 0 0 0 0 0 0 o o o o o o o o";

 ;

 memory "signature"

 size = 3;

 read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",

 "x x x x x x a1 a0 o o o o o o o o";

 ;

 ;

 part parent "m328"

 id = "m328p";

 desc = "ATmega328P";

 signature = 0x1e 0x95 0x0F;

 ocdrev = 1;

 ;

Maybe a simple change to the end of the section is all that is needed:

 part parent "m328"

 id = "m328pb

 desc = "ATmega328PB";

 signature = 0x1e 0x95 0x0F;  <<<change as needed

 ocdrev = 1;

 ;

as that is what the 168 section has:

#------------------------------------------------------------

 # ATmega168P

 #------------------------------------------------------------

 part parent "m168"

 id = "m168p";

 desc = "ATmega168P";

 signature = 0x1e 0x94 0x0b;

 ocdrev = 1;

 ;

 #------------------------------------------------------------

 # ATmega168PB

 #-----------------------------------------------------------

 part parent "m168"

 id = "m168pb";

 desc = "ATmega168PB";

 signature = 0x1e 0x94 0x15;

 ocdrev = 1;

 ;

Advanced21515:
I have not been able to get theirs to work

Please explain exactly what problems you encountered.

Bump. Has the OP disappeared? Maybe he got his 328PB working because he already had everything he needed in the Github repo he mentioned above:

FYI to Crossroads: The repo contains an updated version of avrdude.conf that includes the PB with a signature of 1E-95-16.