Some would say that an ATmega328 with two identities is not possible. However, it depends on who you ask. 🙄 First though, before we ask, here is some necessary background information.
Microcontrollers from Atmel (AVR) and Microchip (PIC) have a built in ‘signature’ or identity. This signature is a unique code that identifies its model. When you program a chip (for example, upload a sketch in the Arduino IDE), the process checks that the chip selected matches the type it’s connected to. This protects the microcontroller from user error. Therefore, a chip has only one built in identity, that is, if you ask it. However, sometimes, a program it runs speaks for it and tells a different story. So an ATmega328 with two identities is possible. Let’s find out how.
While making a new batch of my DIY Arduino UNOs I bought some ATmega328 microcontroller chips. An original Arduino UNO has an ATmega328P microcontroller. The P designation means picopower. There are ‘minor’ differences between the ATmega328 and ATmega328P but for my purposes the ATmega328 works essentially the same as the P version. Even though they function the same, they have different signatures. Since the ATmega328 is not used in an Arduino, that chip is not recognized/used by the Arduino IDE unless we make some changes.
Let’s take an example of how the Arduino IDE burns the bootloader for an ATmega328(P). Here is how things are physically connected:
Get the fritzing diagram HERE.
Behind the scenes, the Arduino IDE uses the AVRDUDE software to do the programmimg (uploading the sketch). AVRDUDE ‘talks’ to various hardware (and software) programmers which physically connect it to the microcontroller chip. The Arduino IDE runs AVRDUDE in the background with specific parameters on how it should run. We are specifically interested in three parameters (-C -c -p). I will leave it up to the reader to consult the AVRDUDE documentation if they are interested in the other parameters.
The -C parameter specifies the file with various microcontrollers AVRDUDE can program and their respective identities. (By the way, this configuration file does specify and recognize both the ATmega328 and ATmega328P.) The -p parameter specifies the part (i.e. the chip) being programmed. The -c parameter specifies the ‘hardware’ programmer being used. That ‘hardware’ programmer could also be emulated in software.
The specific parts of the AVRDUDE command which the Arduino IDE creates to burn the bootloader is similar to the following:
/opt/arduino/arduino-1.6.12/hardware/tools/avr/bin/avrdude -C/opt/arduino/arduino-1.6.12/hardware/tools/avr/etc/avrdude.conf -v -patmega328p -cstk500v1 ...
Notice that the part is the ATmega328p and the programmer is the stk500v1. It is not in reality an stk500v1 piece of hardware but in our case it is being emulated in the sketch called ArduinoISP. Looking at the above hardware diagram, notice that the device we are using to program the chip is an Arduino UNO to which we must first upload that ArduinoISP sketch for it to act as an stk500v1. Now comes the identity problem. When we try this command when the physical chip is an ATmega328 and the -p is an ATmega328P we will get the following error:
avrdude: Device signature = 0x1e9514 avrdude: Expected signature for ATMEGA328P is 1E 95 0F Double check chip, or use -F to override this check.
This is because the sketch (emulating the stk500v1) talks directly to the chip and gets its identity (0x1e9514) which does not match the identity (0x1e950f) which AVRDUDE has in its configuration file. There are several ways to get around this problem.
- Copy the command generated by the Arduino IDE and manually run it after changing the -p to atmega328 (instead of atmega328p)
- Edit the AVRDUDE configuration file and change the signature of the atmega328p to match that of the atmega328
Personally, I do not like either of these, specifically due to all the manual effort involved. A better solution is to use a sketch called ArduinoISP_Multi (which is an updated version of the ArduinoISP sketch). You can get the Arduino_Multi sketch HERE. The ArduinoISP_Multi sketch will tell AVRDUDE that the chip identity is 0x1E950F for both the ATmega328P and ATmega328. Remember that the identity matching is there to protect from putting code into the wrong chip. Since the ATmega328 and ATmega328P are essentially the same, the identity can be ignored for our purposes in this case. So now the bootloader can be burned in and all is well.
Wait a minute you say? If the Arduino IDE only uses the part (-p atmega328p) what happens when you upload a sketch to that new ATmega328 that has the new bootloader. Won’t it give the signature error?
Here is where the two identities come into play. Notice the command that the Arduino IDE builds to upload a sketch:
/opt/arduino/arduino-1.6.12/hardware/tools/avr/bin/avrdude -C/opt/arduino/arduino-1.6.12/hardware/tools/avr/etc/avrdude.conf -v -patmega328p -carduino ...
The part (-p) is ATmega328p but the programmer is different. The -c parameter is arduino (not stk500v1). In this case the programmer that AVRDUDE is talking to is the bootloader. The bootloader was designed to return an identity of 0x1E950F (the ATmega328P) which it does even if it is running on an ATmega328.
So, you can have an ATmega328 with two Identities. The real identity of the chip internally and its ‘fake’ identity returned by its bootloader. Once the bootloader is there, when you load sketches via the Arduino IDE, it thinks its talking to a real ATmega328p even though physically it is an ATmega328.
So in the end, the identity of the chip all depends on who you are talking too. 🙄
Recent Comments