This page is about the bootloader, to update firmware via serial port

Users simply

without much interest on what goes on behind the scenes.

In special, rare cases, eg. when firmware upload is interrupted or unable to communicate with firmware for some other reason

[Bootloader upgrade]

All assembled controllers and mainboards shipped since 2011-03-01 already have uhex type (universal, also called "crypto") bootloader and therefore does NOT need bootloader upgrade to use new fw (eg. 1.2.x).

The bootloader upgrade involves a

Text below is not much use for anyone except the most curious.

Why do we like the bootloader?

The atmega128 can be programmed quite easily via the ISP port with a simple parallel port cable or other means: GenBoard/Firmware/Upload

However you might want to upgrade firmware it while installed in the car (not during driving), where you might have problems accessing the ISP port mechanically or you might be (with cause) concerned about driving silly signals to the fuel pump, injector or frying the ignition coil (you must verify this not happening before using bootloader on an installed unit. Simple use your DVM to measure the injector signals - at least at the FET gate - on the table in bootloader mode. This is important, since bootloader was ported from v2 => v3 later than the rest of the firmware and v2 bootloader activates a LED, which happens to be an injector on v3!!! (TODO: more on config options). The bootloader is the solution, which was developed by MembersPage/DanaScott .

Where is the bootloader?

[[Manual: Detailed.Central.Boot.Operate]]

When does the bootloader remain in bootloader code instead of starting the engine management application?

In addition to the normal operating code, a marker word gets placed in the last 2 bytes of the application code space by the bootloader. This marker word gets erased at the start of a bootload sequence and gets written at the end of bootloading after the data is verified. If the bootloader starts and it finds the marker word missing, it assumes that the application is also missing and it remains in the bootload mode.

The bootloader will also check for a hardware indication that it is to remain in bootload mode. This is needed in case a faulty firmware build gets loaded in and it crashes before a Manmcbxxmcb command can be received on the serial port. The bootloader uses the serial port lines for this hardware indication of a bootload request. The bootloader code (inside the AVR!) disables the USART and directly toggles the serial Xmit line a few times at a rate much higher than any normal baud rate. It then looks for the same state changes to appear on the Rcv line. If it sees that the Xmit is shorted to the Rcv, it remains in bootload mode.

How can I make the engine management application go back to bootloader?

This can be more convenient than loopbacking the serial port, but it assumes the engine management application is working properly.

The bootloader can also be entered by the application program when

Manmcbfemcb serial port command is entered during normal operation.

At this point the MS-AVR code does some safety checks, verifies that the engine is stopped before starting the bootloader. The Manmcbfemcb is a bit special: it forces entering bootloader even if trigger is applied, but only use for table setups (not when real engine is running).

The guts: how menu.c starts bootloader

The above menucommand starts the bootloader by loading 0x35 into the SPCR register and jumping to address 0x1FFFC. Since 0x35 is in SPCR register, the bootloader sets the I/O ports to the default standard configuration(ports to input, pullups, 19200 baud on).

Command Manmcbxxmcb<esc>

sets the baudrate to xx, where xx is hexa, 33 (decimal 51) means 1000000 / 52 = 19230

(crystal clock/16 /(xx+1) = rougly same baudrate as will be set on PC bootloader program). This time 0x36 is written into the SPCR register, the bootloader leaves the I/O ports as they are and assumes that the application has set the ports to the correct states.

Summary of operation

To summarize normal bootloader operation on system power-up:

OBSOLETE Steps to Upload bootloader (boot/main.hex) to AVR .... Only For developers ! Using ISP is NOT needed, causes unnecessary complications and inconvenience, and NOT supported (also voids warranty)

At the DOS prompt program the main.hex file into the genboard using the following

avrdude commands: ( replace the -c parameter with your appropriate cable id )

avrdude -p m128 -c stk200 -t

w efuse 0 0xff

w hfuse 0 0xcc (0xc4 can be also used, so eeprom is not cleared at erase, take care)

w lfuse 0 0x0F


avrdude -p m128 -c stk200 -C avrdude.conf -e -f i -i main.hex

Roughly translated, this means...

Write Extended Fuse bits with 0xff. This disables ("unprogrammes") ATMega 103 compatibility mode and Watchdog Timer always on.

Write High Fuse bits with 0xcc. This disables OCD and JTAG interfaces, and enables SPI programming and "oscillator options" required for high speed crystal use. It allows EEPROM to be erased during chip-erase, and sets the boot size to 1024 words (8 pages).

Write Low Fuse bits with 0x2f. This enables brownout detection, sets start-up time for use with brownout detection and sets the clock source to external crystal.

NOTE: Currently being tested is the ATMEGA2561 chip. The fuse bits are slightly different on this MCU and the the CKOPT bit of the high fuse byte is used for enabling the watchdog timer. As a result it needs to be programmed as 0xDC instead of 0xCC

Newer versions of avrdude may need to be run with options like

avrdude -p m128 -c stk200 -e -U flash:w:main.hex

Another program uisp can also be used:

uisp -dprog=stk200 --erase

uisp -dprog=stk200 --upload if=boot/main.hex --verify

uisp -dprog=stk200 --wr_fuse_l=2f

uisp -dprog=stk200 --wr_fuse_h=c4

uisp -dprog=stk200 --wr_fuse_e=ff

uisp -dprog=stk200 --wr_lock=3c

Once Avrdude has finished, power down and disconnect the isp cable.

Now power the Genboard up and connect a serial port cable from Genboard to the PC. Now run Avrprog.exe on the PC. In the Avrprog window you can select the file that you wish to load, either a program file for the flash or data file for the EEPROM. The programming session with Avrprog must be ended by clicking on the Exit button in the Avrprog window. This writes the marker word as described above.

Should you ever need to update your Genboard with a new version of the bootloader, only the last avrdude command above needs to be performed. The fuses should not need to be changed.

Another option is the sp12 program. It has a very simple hardware config and uses some of the output lines to power the AVR. I've tested it and no power needs to be applied to my board in order to accomplish the flash...

Upload the bootloader code:

sp12 -wpf main.hex

Burn the fuses:

sp12 -wH0xCC -wF0xFF -wL0x2F

OR on the ATMEGA2561 use:

sp12 -wH0xDC -wF0xFF -wL0x2F

Check the bootloader operation:

loopback serial port of the AVR (not of the PC!), reset (AVR, by powering down and up), talk to it from bray-terminal at 19200 say 'S' should report back AVREFI1, say 'v', report should say "20".

This is a good time to verify that your output signals (measure FET and IGBT gates with DVM) are as you like. You don't want to find any related problems the hard way.

Avrprog from atmel is a shameful mswin style program, no command line switch, not even -h or /? ,

no support for COM5, documentation refers to command line siblings like avrprogf, which handles -p com4 but not -p com5 arghh.... showed a Megaload2.3

which works with com5 (it has a small terminal-like monitor where I verified), but somehow did not work for me.

bootloader protocol:

This section is an attempt to document some of the bootloader protocol. May not be 100% complete or correct.

'a' Polls to see if autoincrement is available? The bootloader always returns 'Y'

'Axx' Specify address. xx in this case are the MSB and LSB of the word address respectively. We use word addresses here so the entire flash area of 128k can be accessed using only 16 bits of addressing.

'b' Polls to see if buffer load support is available. Bootloader currently responds with Yxx where xx is the MSB and LSB respectively of the buffer size.

'BF' something to do with buffered load into flash

'BE' something to do with buffered load into eeprom

'Dl\0' Special fast verify. The 3rd byte is reserved. This code appears to generate the checksum of a block of data (addressed by Axx) and it returns 4 bytes. The first 2 are the sum and the last 2 are the xor.

'Dk\0' Special fast write to flash. This is used by PC software VemsTune (and obsolete and PSITuner). The 3rd byte is reserved. This will begin to flash a gob of 128 words (and 4 bytes checksum) to the address last specified in the 'A' command.

'De\0' Special fast write to flash. Similar to Dk\0 but also erases the actual page so the 'e' command becomes unnecessary (erasing the whole flash is sometimes a bad idea, eg. when uploading themperature-calibration config pages).

command to send crypted blocks. not documented

'gxx' Reads and returns a block starting at address xx

'cx' Loads the low byte of program data specified in x. Returns \r when done.

'Cx' Loads the high byte of program data specified in x and writes it to the address last set by the 'A' command, then increments A by 2, ready for the next cxCx pair. Returns \r when done.

'e' Erase the entire flash. Returns a \r when complete. Note this may take a few seconds.

'E' Attempt to exit the bootloader. Returns \r then exits. This assumes that a valid flash image has been loaded.

'P' or 'L' Enter programming mode. Currently the bootloader returns a \r no matter what...

'p' returns 'S'. In this appears to sync the program before doing the flash.

'x' currently disabled... turns LEDs on

'y' currently disabled... turns LEDs off

'T' doesn't appear to do anything but eat the next sent character. and return a \r

'S' Identifies the bootloader code with 'AVREFI1'

's' Returns 3 signature bytes.

'v' or 'V' return software version. This appears to be present for programmer compatibility and returns '20'

Anything else that's not recognised returns a '?'

PC Side Software for uploading firmware images

Please add to this list as others are tested. (see below)

PSITuner (OtherTuningSoftware/PSITuner) Has the ability to upload firmware images. It runs natively in Win32 so there is no need to install perl.

A few words on bootloader implementation - only as last chance. Normally use VemsTune instead !

a crossplatform PC-side client: bin/ written in PERL - see MegaLoader (also crossplatform and more often used lately: easier to install)

MembersPage/MarcellGal and MembersPage/MichaelKristensen wrote a (PC side) bootloader in perl. Find it in the released firmware, as


bin/ requirements

For win32 I (if remember correctly) used this module for Win32::Serialport :

and there is now a new page for it: RunningProgOnWin? (not works, but I pasted it from the obsolete wiki)

The rest of this section should not be needed, I hope others confirm that RunningProgOnWin? is OK.

I fetched the required libs (only Win32::API if I remember well) via ppm install of the activestate perl (v5.8.0).

Since people are having difficulties making WIN32::Serialport to work, I zipped the libs from my working setup:

so they can verify the is the real one, or try to use these...

[[Manual: Basics.Install.Upgrade]]

Assuming a working firmware is present on the board, I upload + verify:

perl bin/ vems.hex :COM5 57600 Etw

I verify (without upload):

perl bin/ vems.hex :COM5 57600 Et

Speed is astonishing compared to anything else.

On linux 115200 is also working for me, not on win (and win crashes sometimes when several applications try to use the serial port,at least the USB-based one I tried, but what do we expect from such inferior system)?

If bootloader is entered into(because no marker word is present or serial port was loopbacked at powerup)only 19200 baudrate will work, and the 't' (talk to MSAVR and drive her to bootloader with mcb.. menucommand)is not needed: I first verify the bootloader itself:

perl bin/ boot/main.hex :COM5

Then upload the application:

perl bin/ vems.hex :COM5 19200 Ew

but 19200 is the default baudrate, so equivalent:

perl bin/ vems.hex :COM5 Ew

COM5 means use COM5 serial port, easy to change to whatever you have.
'E' is redundant when 'w' is specified (w implies E), I just use

perl bin/ vems.hex :COM5 57600 Et[w]

because it's the smallest difference when using the command-buffer (CTRL-r <pattern> or uparrow in sh)for the 2 most often used commands, and Et is easy to remember :-)

perl bin/

prints it's usage, not as complex as it seems.

Maybe should check up the existence of hex file.

Fixed, now checks for the hex-file.

Avrprog is obsolete (very old, without checksum anyway)

For reference, the command format used by Avrprog is described in application note 109

Check the boot.h in recent avr-gcc avr-libc, it (now) contains off the shelf parts for a bootloader.

Q: Why does AVRProg give me a 'no supported board found ' message? It was working just before I started Bray Terminal.

A: Bray terminal has taken control of the serial port. Exit Bray Terminal and try again.