28Pins
Learn To Design Your Own Boards
Learn To Design Your Own Boards
On this page you will learn how to compile the firmware inside ATMEGA16U2, so it can use a 8 MHz clock frequency so the MCU can be supplied from 3.3 V. The ATMEGA328P can be used with a 10 MHz clock frequency to reliably run from a 3.3 V source
Why recompile the boot loader?: If you read the datasheet of the ATMEGA16U2 and the ATMEGA328P from Atmel, you can find that the AVR MCU's can be operated from a source voltage of 1.8 V to 5.5 V DC. However operating the MCU from a lower source voltage limits the maximum clock frequency we can actually reliably use. In the Speed grade section of the datasheets we can find a graph of the different clock frequencies to source voltages. From there we can select a safe clock frequency of 10 MHz for the ATMEGA328P and 8 MHz for the ATMEGA16U2 for a source voltage of 3.3 v. The Arduino boot loader is configured to use a 16 MHz clock frequency, so we must recompile the firmware to use the new clock frequencies. Below are the exact steps how to do it.
To compile the firmware using the make command you will need to install the AVR toolchain from Atmel:
1. Download AVR tool chain from http://www.atmel.com/tools/atmelavrtoolchainforwindows.aspx
2. Install the AVR tool chain (just follow the installation wizard).
3. For windows users we need to add the binaries directory to the path variable; For more information see http://geekswithblogs.net/renso/archive/2009/10/21/how-to-set-the-windows-path-in-windows-7.aspx
Now we are going to obtain the source code for the Arduino boot loader firmware:
1. Download the source code from the Arduino Git Hub.
Alternatively: The source code can be found in the Arduino IDE program files, usually located in 'C:\Program Files (x86)\Arduino\hardware\arduino\avr'
2. It is a good idea to copy the firmware into another folder, in case you make an error and want to get back the original source code. We will refer to this as the working directory.
The ATMEGA16u2 firmware uses the LUFA project for the USB to serial interface.
Important: We need to use an older version of the LUFA project (version 100807).
1. Download the LUFA project from http://www.fourwalledcubicle.com/files/LUFA/LUFA-100807.zip
2. Copy the files from the .zip file into your working directory.
3. Copy the arduino source code into the LUFA projects folder, such as; "{working directory}\LUFA\Projects\28pins"
In this step, we will change the clock frequency of the ATMEGA16u2. There are 2 firmwares we need to edit, the USBDFU and the USBserial.
1. Open the makefile in '{working directory}\LUFA\Projects\28pins\usbdfu\' in your favorite text editor
2. Edit the following;
# MCU name
MCU = atmega16u2
MCU_AVRDUDE = atmega16u2
MCU_DFU = atmega16u2
3. Add the following;
# 28 Pins PID:
ARDUINO_MODEL_PID = 0x6051
4. Change CPU frequency;
F_CPU = 8000000
5. Change bootloader address;
BOOT_START = 0x3000
Note: this address is specific for the ATMEGA16u2, if you are using a different AVR you will need to find the bootloader start address from the datasheet.
6. Open descriptors.c in '{working directory}\LUFA\Projects\28pins\usbdfu\'
7. Add the following
#elif (ARDUINO_MODEL_PID == FA28PINS_PID)
.Header = {.Size = USB_STRING_LEN(21), .Type = DTYPE_String},
.UnicodeString = L"28pins DFU"
#endif
8. Open descriptors.h in '{working directory}\LUFA\Projects\28pins\usbdfu\'
9. Add the following;
#define FA28PINS_PID 0x6051
10. Open LEDS.h in '{working directory}\LUFA\Projects\28pins\usbdfu\boards'
11. Change RX LED to pin 4:
/** LED mask for the first LED on the board. */
#define LEDS_LED1 (1 << 5)
/** LED mask for the second LED on the board. */
#define LEDS_LED2 (1 << 4)
1. Open the makefile in '{working directory}\LUFA\Projects\28pins\usbserial\'
2. Edit the following;
# MCU name
MCU = atmega16u2
MCU_AVRDUDE = atmega16u2
MCU_DFU = atmega16u2
3. Add the following;
# 28 Pins PID:
ARDUINO_MODEL_PID = 0x6051
4. Change CPU frequency;
F_CPU = 8000000
5. Open descriptors.c in '{working directory}\LUFA\Projects\28pins\usbserial\'
6. Change PID;
.VendorID = 0x1d50, // LUFA
.ProductID = 0x6051, // FA28PINS USB-to-serial programmer
7. Add the following;
const USB_Descriptor_String_t PROGMEM ManufacturerString =
{
#if (ARDUINO_MODEL_PID == FA28PINS_PID)
.Header = {.Size = USB_STRING_LEN(8), .Type = DTYPE_String},
.UnicodeString = L"28PINS"
#else
.Header = {.Size = USB_STRING_LEN(32), .Type = DTYPE_String},
.UnicodeString = L"Fedevel Academy (www.28pins.com)"
#endif
};
8. Also add the following;
#elif (ARDUINO_MODEL_PID == FA28PINS_PID)
.Header = {.Size = USB_STRING_LEN(8), .Type = DTYPE_String},
.UnicodeString = L"28pins"
#endif
9. Open descriptors.h in '{working directory}\LUFA\Projects\28pins\usbserial\'
10. Add the following;
#define FA28PINS_PID 0x6051
11. Open LEDS.h in '{working directory}\LUFA\Projects\28pins\usbserial\boards'
12. Change RX LED to pin 4:
/** LED mask for the first LED on the board. */
#define LEDS_LED1 (1 << 5)
/** LED mask for the second LED on the board. */
#define LEDS_LED2 (1 << 4)
13. We are now ready to compile the firmware for the ATMEGA16u2
In this step, we will change the clock frequency of the ATMEGA328p.
bootloader:
1. Open the makefile in '{working directory}\hardware\arduino\avr\bootloaders\atmega'
2. Add the following;
atmega328_28pins_10MHz: TARGET = atmega328_28pins_10MHz
atmega328_28pins_10MHz: MCU_TARGET = atmega328p
atmega328_28pins_10MHz: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600
atmega328_28pins_10MHz: AVR_FREQ = 10000000L
atmega328_28pins_10MHz: LDSECTION = --section-start=.text=0x7800
atmega328_28pins_10MHz: $(PROGRAM)_atmega328_28pins_10MHz.hex
atmega328_28pins_isp: atmega328_28pins
atmega328_28pins_isp: TARGET = atmega328_28pins_10MHz
atmega328_28pins_isp: MCU_TARGET = atmega328p
atmega328_28pins_isp: HFUSE = DA
atmega328_28pins_isp: LFUSE = FF
atmega328_28pins_isp: EFUSE = 05
atmega328_28pins_isp: isp
3. Open the atmegaboot_168.c in '{working directory}\hardware\arduino\avr\bootloaders\atmega'
4. Edit the following;
#define BAUD_RATE 57600
In this step, we will compile the 3 different binaries:
1. Open up the command prompt and change the directory to the location of the USBDFU files
In this step, we will compile the 3 different binaries:
cd {working dir}\LUFA\Projects\28pins\usbdfu\
2. Clean out the previous binaries, and compile
make clean
make
1. Change the directory to the location of the USBSerial files
cd {working dir}\LUFA\Projects\28pins\usbserial\
2. Clean out the previous binaries, and compile
make clean
make
1. Change the directory to the location of the USBSerial files
cd {working directory}\hardware\arduino\avr\bootloaders\atmega
2. Clean out the previous binaries, and compile
make clean
make atmega328_28pins_10MHz
Congratulations, you have just successfully compiled the binaries for the 28pins board. But we are not finished completely, to use this board with the Arduino IDE we will need to make some changes to the IDE settings.
In this step, we will add our custom board into the Arduino IDE so we can compile sketches for our new clock frequencies and also upload sketches directly.
1. Open boards.txt file in 'C:\Program Files (x86)\Arduino\hardware\arduino'
2. Add the following under another board definition;
#################################################################
28pins.name=28pins
28pins.upload.tool=avrdude
28pins.upload.protocol=arduino
28pins.upload.maximum_size=30720
28pins.upload.speed=57600
28pins.bootloader.tool=avrdude
28pins.bootloader.unlock_bits=0x3F
28pins.bootloader.lock_bits=0x0F
## Arduino 28pins (3.3V, 10 MHz) w/ ATmega328
## --------------------------------------------------
28pins.menu.cpu.10MHzatmega328=ATmega328 (3.3V, 10 MHz)
28pins.menu.cpu.10MHzatmega328.upload.maximum_size=30720
28pins.menu.cpu.10MHzatmega328.upload.maximum_data_size=2048
28pins.menu.cpu.10MHzatmega328.upload.speed=57600
28pins.menu.cpu.10MHzatmega328.bootloader.low_fuses=0xFF
28pins.menu.cpu.10MHzatmega328.bootloader.high_fuses=0xDA
28pins.menu.cpu.10MHzatmega328.bootloader.extended_fuses=0x05
28pins.menu.cpu.10MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_28pins_10MHz.hex
28pins.menu.cpu.10MHzatmega328.build.mcu=atmega328p
28pins.menu.cpu.10MHzatmega328.build.f_cpu=10000000L
28pins.menu.cpu.10MHzatmega328.build.board=AVR_28PINS
28pins.menu.cpu.10MHzatmega328.build.core=arduino
28pins.menu.cpu.10MHzatmega328.build.variant=standard
## Arduino 28pins (5V, 16 MHz) w/ ATmega328
## --------------------------------------------------
28pins.menu.cpu.16MHzatmega328=ATmega328 (5V, 16 MHz)
28pins.menu.cpu.16MHzatmega328.upload.maximum_size=30720
28pins.menu.cpu.16MHzatmega328.upload.maximum_data_size=2048
28pins.menu.cpu.16MHzatmega328.upload.speed=57600
28pins.menu.cpu.16MHzatmega328.bootloader.low_fuses=0xFF
28pins.menu.cpu.16MHzatmega328.bootloader.high_fuses=0xDA
28pins.menu.cpu.16MHzatmega328.bootloader.extended_fuses=0x05
28pins.menu.cpu.16MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_28pins_16MHz.hex
28pins.menu.cpu.16MHzatmega328.build.mcu=atmega328p
28pins.menu.cpu.16MHzatmega328.build.f_cpu=16000000L
28pins.menu.cpu.16MHzatmega328.build.board=AVR_28PINS
28pins.menu.cpu.16MHzatmega328.build.core=arduino
28pins.menu.cpu.16MHzatmega328.build.variant=standard
##############################################################
3. Save the file, and reload the IDE to check the new 28pins board is there.
4. You should now be able to compile and upload the sketches to the board with the correct timings for the new clock.
The 28pins board can be flashed with AVRdude by using another Arduino board as an AVRISP.
An example AVRdude command to flash the USBSerial firmware to the ATMEGA16U2 is as follows: (where comX is the com port number of the AVRISP)
avrdude -p m16u2 -F -P comX -c arduino -b 19200 -U flash:w:28pins-usbserial.hex -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xF4:m -U lock:w:0x0F:m
To include the USBDFU firmware we can use the following AVRdude command; Notice the -D switch.
avrdude -p m16u2 -F -P comX -c arduino -b 19200 -U flash:w:28pins-usbdfu.hex -D -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xF4:m -U lock:w:0x0F:m
To flash the bootloader to the ATMEGA328P we can use the following AVRdude command:
avrdude -p m328p -F -P comX -c arduino -b 19200 -U flash:w:atmegaboot_168.hex -U lfuse:w:0xFF:m -U hfuse:w:0xDA:m -U efuse:w:0x05:m -U lock:w:0x0F:m
Note: Initially 16U2 will run in the Atmel Studio mode, if you would like to change it, Fit and Unfit a Link on ICSP1 between pins 5-6 (this will reset the 16U2 and it will change the mode, you will see the LEDs blinking 4-5 times). If you are using Arduino Uno R3, you will need to pull HWB pin to +5V before you use the Reset Link, otherwise your 16U2 will go into DFU mode and will not toggle between Atmel Studio and Avrdude mode.
For further instructions on flashing the firmware, please see this article; How To FLASH 28Pins Firmware