XBoot – Quick Start Guide (for a sweet XMega bootloader!)
So in my recent XMega wanderings, I needed a good bootloader. After muddling through various app notes and forum postings, I came across the culmination of what I couldn’t do on my own – XBoot!
In my defense, I’ve worked on bootloaders before. But the errata sheet on the XMegas is longer than the list of men Princess Leia has broken the hearts of. And I’ve become one of the many casualties of that list. (Erm, the errata list… awkward…)
Big thanks to Alex Forencich! XBoot, a fantastic reincarnation of the AVR1605 app note, is open source and highly configurable bootloader, which at the time of writing is capable of UART or I2C bootloading XMega processors. I believe his intentions are to expand both processor compatibility and protocol options, so visit the XBoot Google Code project for more info.
I’ll be going through and explaining the options that I used, so this isn’t an exhaustive tutorial. This guide assumes you have a working XMega development environment, AVRDude installed, and SVN (if you want to download the code this way). WinAVR should work just fine with a few minor alterations, but I’ve only tested this on Kubuntu with the development environment described in this previous blog post. Also, as a side note, I’ve been using XBoot with XBee Series 1 wireless modules and it works fantabulous (that’s so good, I had to come up with a new word for it).
Here’s the step-by-step big picture:
- Download the code.
- Pick a bootloader entry method.
- Configure communication parameters (Port/Baud Rate/I2C addressing, etc.).
- Compile & program XBoot onto the MCU.
- Send main application via XBoot and AVRDude.
Download the Code
So let’s get started. Download the code from the XBoot download page and uncompress it, or (my preference) use SVN to download the code:
svn checkout http://avr-xboot.googlecode.com/svn/trunk/ avr-xboot
Once the code is downloaded, find the file named “xboot.h”. Most configuration changes, if not all, will be made here. We’ll take it one section at a time. Line item references are from Rev12 out of the repository, but you should be able to match them up to any version. The idea is that all available options are enabled, so comment out what you won’t be using.
// AVR1008 fixes // Really only applicable to 256a3 rev A and B devices //#define USE_AVR1008_EEPROM
Uncomment this line if you’ll be using an XMega256a3. This fixes certain problems (remember Princess Leia the errata list?). I’ve heard this has hit some people but not others, even on the same silicon revision. It may be useful for certain other chips and families – YMMV. Check with Google if concerned.
Line 64: // bootloader entrance #define USE_ENTER_DELAY //#define USE_ENTER_PIN #define USE_ENTER_UART //#define USE_ENTER_I2C
Here I picked the “USE_ENTER_DELAY” and “USE_ENTER_UART”, hence I commented the other two out. Note that the “USE_ENTER_DELAY” just puts a delay at the start of the program, and isn’t mutually exclusive with the other options. Here’s what the options mean:
- USE_ENTER_DELAY: Delays entry by a timeout. Timeout is set by “ENTER_BLINK_COUNT” and “ENTER_BLINK_WAIT”, but I found the default settings worked well.
- USE_ENTER_PIN: Select this option if you want to enter the bootloader when a pin is in a certain state at power on. Ex: You press a switch when you power cycle to enter the bootloader. You’ll have to configure which port/pin at line 95, at the section titled “ENTER_PIN”.
- USE_ENTER_UART: Select this option if you want to enter the bootloader if a character is received on the UART. This requires using “USE_ENTER_DELAY” by necessity. You’ll need to configure the UART options at line 111.
- USE_ENTER_I2C: Select this option if you want to enter the bootloader if a byte is received through I2C. I haven’t used this option, hence I won’t try to elaborate.
On to the next section:
Line 73: // bootloader communication #define USE_LED #define USE_UART //#define USE_I2C //#define USE_I2C_ADDRESS_NEGOTIATION //#define USE_ATTACH_LED
I’ll be using the UART and LED, so everything else is commented out. If you use the LED, configure the next section also:
Line 106: // LED #define LED_PORT PORTA #define LED_PIN 0 #define LED_INV 1
If you’re using the UART, configure this section:
Line 111: // UART #define UART_BAUD_RATE 19200 #define UART_PORT PORTD #define UART_DEVICE_PORT D1 #define UART_DEVICE token_paste2(USART, UART_DEVICE_PORT) #define UART_DEVICE_RXC_ISR token_paste3(USART, UART_DEVICE_PORT, _RXC_vect) #define UART_DEVICE_DRE_ISR token_paste3(USART, UART_DEVICE_PORT, _DRE_vect) #define UART_DEVICE_TXC_ISR token_paste3(USART, UART_DEVICE_PORT, _TXC_vect) #define UART_TX_PIN PIN7_bm
Should be pretty self-explanatory. You should only need to change UART_BAUD_RATE, UART_PORT, UART_DEVICE_PORT, and UART_TX_PIN. If you use an exotic baud rate (non-standard and/or fast), you might want to change the settings at line 51 and select the 32MHz clock option.
That’s pretty much it for this section!
Compile & Program
This should work if you’re using AVR-GCC in Linux. I can’t vouch for WinAVR, but it shouldn’t take much to change it. That said, the only thing that really needs to change in the Makefile is the programmer name and the chip you’re compiling it for:
Line 42: # MCU name ## MCU = atxmega16a4 ## MCU = atxmega32a4 ## MCU = atxmega64a1 ## MCU = atxmega64a3 ## MCU = atxmega64a4 ## MCU = atxmega128a1 ## MCU = atxmega128a3 ## MCU = atxmega128a4 ## MCU = atxmega192a1 ## MCU = atxmega192a3 ## MCU = atxmega256a1 ## MCU = atxmega256a3b MCU = atxmega256a3 #MCU = atxmega64a3 #MCU = atxmega128a1 #MCU = atxmega32a4
For me, I’ve been using the XMega256A3 chip. At random, I decided to uncomment the atxmega256a3 line. YMMV.
Line 209: #AVRDUDE_PROGRAMMER = jtag2pdi #AVRDUDE_PROGRAMMER = avr109 AVRDUDE_PROGRAMMER = avrispmkII
And I’m using an AVRISP mkII programmer, which is pretty cheap for an authentic Atmel programmer. It only does PDI programming (no debugging), and needs to be updated to the latest firmware using AVR Studio (sorry, penguins – you’ll have to boot into Windows), but it does the XMega trick right nicely.
To compile and subsequently program:
$ make $ make program
This should compile and program XBoot into the programmer. Shazaam! If you get any errors, feel free to leave me a comment and I’ll try to help you out.
Programming an Application Via XBoot
So now that you’ve got XBoot loaded, you can use AVRDude again to program your application to your XMega:
avrdude -p atxmega64a3 -P /dev/ttyUSB0 -c avr109 -b 19200 -U flash:w:main.hex
For those of you who may have installed Eclipse as described in previous posts, you can make Eclipse use the bootloader by:
- Click on “Run -> Run Configurations…”
- Right click on “C/C++ Application” on the left and select “New”
- In the “Name:” textbox, enter “Program via XBoot”
- In the “C/C++ Application:” textbox, enter “/usr/bin/avrdude” (or where ever it’s installed if you’re using Windows)
- Click on the “Arguments” tab. Enter the following line, modify to suit your needs, and then click “Apply” and “Close”
-c avr109 -p x256a3 -P /dev/ttyUSB0 -b 19200 -e -U flash:w:Debug/eclipse_project_name.hex
There you have it. As always, if you need any help just ask in the comments below!