Multiple Device Firmware Upgrades of XMEGA with FLIP via USB.

Go To Last Post
47 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi All,

 

I have a question about mutiple Xmega Device Firmware Upgrades. I downloaded a bootloader binary for my ATXmega128A4U from the Atmel site. 

 

I used an Atmel ICE to program the bootloader over PDI with the binary, also I set BOOTRST to bootloader reset. I had my USB cable connected as well. After burning the binary

 

the XMega appeared in my windows device manager as an Atmel USB Device. I then wrote my application .hex file into flash with Atmel FLIP and all was good.

 

But as the .hex file is written ATXmega128A4U disappears from windows device manager and I loose the USB connection between Xmega and FLIP respectively.

I double checked the Xmega's flash memory and figured out that the bootloader binary touches only a bootloader section and my app touches only an application section.

 

I know that there's a possibility to force Xmega to a DFU mode with a specific pin, wich is controlled in conf_isp.h file (I have the sorce code for binary) but I have a customized board and

 

there are no "free" available pins on it (According to AVR1916.pdf default pin for ATXmega128A4U is PC3). 

 

So the questions:

1) How come the USB connection with FLIP is lost after writing a .hex file?

2) What should I do to switch my ATXmega128A4U to DFU mode if I don't have an available pin on my board?

 

AVR1916.pdf is attached.
Appreciate any suggestions. 

 

Thanks, 

Roman

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't Xmega have the equivalent of Mega AT90USB HWB/HWBE then?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Unfortunately no. There's only a RESET button

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

roman_strukov wrote:

 

1) How come the USB connection with FLIP is lost after writing a .hex file?

 

After the bootloader has done it's work, it cleans things up.  I puts the device back to it's power on state.  It "detaches" from the USB, for instance.  Then it jumps to the application.  When a device detaches, it disappears from the USB as if you unplugged it.

 

If the application wants to use USB, it then re-attaches and identifies itself as some kind of device.  Often it identifies as CDC ACM because that causes the PC to construct a virtual serial port that PC applications can easily connect to.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But that's exactly the "problem" that HWB/HWBE aims to solve for AT90USB chips. Instead of having an AVR that starts up (in the bootloader) and then USB enumerates as "DFU" for a few seconds until it decides nothing is to be done, then disconnects USB, starts the app and now enumerates as the real (CDC-ACM or whatever) device the AT90USB do NOT normally start into the bootloader (so on the whole they don't use BOOTRST). Instead they have the HWBE fuse and the HWB pin. The fuse is enabled so that at power on the AVR itself checks the HWB input pin. If held one way it just starts the app code. Only if held the other way does it then trigger the bootloader first as if BOOTRST were set.

 

I am very surprised that Xmega-USB don't have an equivalent (perhaps better?) mechanism to handle this conundrum.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

roman_strukov wrote:

 

 

2) What should I do to switch my ATXmega128A4U to DFU mode if I don't have an available pin on my board?

 

I'm not very familiar with the DFU stuff.  I think the most common way is to have the bootloader check the status of a pin when it first gets control.  To do this you want a way to force a certain pin to a certain state, high or low, depending on the bootloader programming.  So I always have a push button on my boards for this purpose.

 

Another possibility is to have the bootloader make a connection to the host, and then sit there for a couple of seconds to see if it gets commands from the host. If so, I does the bootloading.  If not, it jumps to the application.

 

The big question is how did you get the bootloader to do it's bootloading thing the first time.  The only thing I can think of is it looks at the application flash to see if it is erased.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

steve17 wrote:

So I always have a push button on my boards for this purpose.

 

Thank you for the response.

Yeah, if only I had, that would make my work way easier :)

 

steve17 wrote:

The big question is how did you get the bootloader to do it's bootloading thing the first time.  The only thing I can think of is it looks at the application flash to see if it is erased.

 

Yes, so do I. Perhaps, in order to br able to switch to DFU mode I should
1)erase application section. I can do it programmatically. Will try
OR

2)set a specific pin to GND programatically. Will also try 

Last Edited: Tue. Jul 4, 2017 - 12:30 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Instead they have the HWBE fuse and the HWB pin. The fuse is enabled so that at power on the AVR itself checks the HWB input pin. If held one way it just starts the app code. Only if held the other way does it then trigger the bootloader first as if BOOTRST were set.

 

Thank you for the response!

I've written in the very first post that there is a pin (PC3 for ATXmega128A4U) which plays the role of HWB input pin. But the problem is that the board I'm working with has only a RESET button and has no pins available to play with (to connect two pins with a jumper or to set a pin to a GND pin physically etc). 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sounds like a cut/link job for your prototype then so that PC3 can be freed for its designed purpose? Maybe you have something like button inputs that could all be grouped together onto one ADC input with a resistor ladder or something?

Last Edited: Tue. Jul 4, 2017 - 12:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

at power on the AVR itself checks the HWB input pin. If held one way it just starts the app code. Only if held the other way does it then trigger the bootloader first as if BOOTRST were set.

What holds this pin one way or the other?  Is there a push button built into the chip, or maybe it's done by mental telepathy?

 

The stupid smart phones everybody walks around with these days knows which way is up.  If the AVRs had that, we could just turn the board upside down when we wanted to use the bootloader.  It wouldn't work on the space station though. Well maybe it would, if the astronaut accelerated the board in the proper direction.

 

The Xmegas have temperature sensors.  Maybe if we blew on the chip, a bootloder could detect that as a sign we wanted to use it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

steve17 wrote:
What holds this pin one way or the other? Is there a push button built into the chip,
Nope, the PCB designer is expected to provide such a button. If you look at boards that Atmel supply that have an AT90USB chip (that includes things like Atmega32U4 etc) then you will likely find there is a button attached to HWB. The idea is that the end user holds it while applying power on the very odd occasion they really do want the chip to start into the bootloader and enumerate as DFU first.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

roman_strukov wrote:

steve17 wrote:

 

Yes, so do I. Perhaps, in order to br able to switch to DFU mode I should
1)erase application section. I can do it programmatically. 

That sounds goofy, but maybe it would work.  Notice that this is not guaranteed to be 100 % reliable.  It depends on your application not being buggy.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

steve17 wrote:

 

 That sounds goofy, but maybe it would work.  Notice that this is not guaranteed to be 100 % reliable.  It depends on your application not being buggy.

Agree but it's a new hope anyway 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Sounds like a cut/link job for your prototype then so that PC3 can be freed for its designed purpose? Maybe you have something like button inputs that could all be grouped together onto one ADC input with a resistor ladder or something?


Remaking the board itlsef is not desirable. At first I should try all options that don't require any hardware changes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

roman_strukov wrote:

 

2)set a specific pin to GND programatically. Will also try 

I don't see that working, but maybe I'm missing something.  The bootloader gets control at power on,  but the chip gets reset at power on first, so anything you did earlier gets wiped out.

 

 

The bootloader invokes a pullup or pulldown on the specified pin.  Then it waits a while, I guess a millisecond or less will do,  for the pin to react to the pullup/down.  Then it reads the pin level.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

roman_strukov wrote:

Yes, so do I. Perhaps, in order to br able to switch to DFU mode I should
1)erase application section. I can do it programmatically. Will try 

On second thought, that is probably impractical.  The flash can't be erased by any code in application flash.  It can only be done by code running in the bootlaoder.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

steve17 wrote:

On second thought, that is probably impractical.  The flash can't be erased by any code in application flash.  It can only be done by code running in the bootlaoder.

 

Hmm.. Sensible. But I can set a pin output low which is "close to ground". Will the pin remain output low after turn off-turn on?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

On several AT90USB projects I have tied the HWB pin to GND through a 1.0K resistor.

On power up, the application is executed. When the RESET pin is activated, the bootloader is executed., since the HWB is sampled on the rising edge of RESET.

The use of the 1.0K pull down allows the HWB pin to be used for other functions during normal operation.

David (aka frog_jr)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was a bit wrong when I said the bootloader gets control after power on reset.  It does of course, but it also gets control after any reset.  Programming the pin ahead of time still probably won't work. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Buying pre-built boards can be annoying.  I have some boards from Atmel.  None of them have a reset button, but they do have other buttons.  They do have 10 pin headers and some of these headers do have the external reset connection. Usually for JTAG.  So I make little boards with a pushbutton that I plug into the JTAG header.  If they are Xmegas, I also put a PDI connector on the little board.

 

Last Edited: Tue. Jul 4, 2017 - 01:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe I should clean up my quick and dirty bootloader project and make it available.  It has limitations.  It only does flash, but maybe a few other things could be added.  It uses CDC and those nitwits at Microsoft don't understand communications so it's possible it would not complete correctly under peculiar circumstances.  I've never had that happen to me.  It's written in C++ which could be a bit of a puzzle to C programmers.  It's over 7k in size so you need 8k bootloader flash, which you have.

 

The advantages are that it builds with GCC.  It's easy to specify which pin to use to indicate bootloader wanted.  Another feature you might find handy is the application can invoke the bootloader just by issuing a software reset.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have reserved an area in EEPROM which is set when the application is running and this tells the bootloader that it should attempt to receive firmware.  If bootload fails the result is stored in EEPROM and can be read from the application.  No pins are needed and I just do a watchdog reset from the application to enter the bootloader.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, using an input pin is one way to do it but a very clumsy way.

 

To get back into bootloader mode, simply jump to the correct place in the bootloader.  For the XMega128A4U which we are also using, use this code.

 

udc_stop();

EIND = 1;

asm(" jmp 0x100fe");

 

For DFU programming from the command line, try this program: https://dfu-programmer.github.io

Avrdude can also do this using the -flip2 option but someone forgot the program launch command.

Electronic System Design
http://www.esdn.com.au

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

steve17 wrote:

Maybe I should clean up my quick and dirty bootloader project and make it available.


If it's feasible please share the project. Perhaps I'll find something helpful

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hefty wrote:

Yes, using an input pin is one way to do it but a very clumsy way.

 

To get back into bootloader mode, simply jump to the correct place in the bootloader.  For the XMega128A4U which we are also using, use this code.

 

udc_stop();

EIND = 1;

asm(" jmp 0x100fe");

 

For DFU programming from the command line, try this program: https://dfu-programmer.github.io

Avrdude can also do this using the -flip2 option but someone forgot the program launch command.

1) Could you explain a litle bit mroe detailed about https://dfu-programmer.github.io? I've tried using it before but got stuck and put it aside. I use Windows 10. Installed MinGW, the DFU project itself but didn't find a kinf of user guide. How to launch it at least?

2) As far as I understand, the code you've mentioned above stops USB connection and gets back to the binary which I uploaded to my board before first time of DFU with FLIP. Right? I tried it in different variants but FLIP still doesn't have an access to the board via USB

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

roman_strukov wrote:

1) Could you explain a litle bit mroe detailed about https://dfu-programmer.github.io? I've tried using it before but got stuck and put it aside. I use Windows 10. Installed MinGW, the DFU project itself but didn't find a kinf of user guide. How to launch it at least?

I've mastered the dfu-programmer but GUI is mandatory, so a console app doesn't work for me

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

roman_strukov wrote:
I've mastered the dfu-programmer but GUI is mandatory, so a console app doesn't work for me
So wrap 5 lines of Python around the command line app to give it a GUI interface. It only needs one button marked "[Start]" ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

roman_strukov wrote:
I've mastered the dfu-programmer but GUI is mandatory, so a console app doesn't work for me
So wrap 5 lines of Python around the command line app to give it a GUI interface. It only needs one button marked "[Start]" ;-)


Yeah, it's a possible solution. But when we have Atmel FLIP I simply don't think it's worth a try. I guess that dfu-programmer was made as a cross-platform version of FLIP or something

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

roman_strukov wrote:
I guess that dfu-programmer was made as a cross-platform version of FLIP or something
Yup, as far as I know that is EXACTLY what it was developed for.

 

(on the whole Linux developers don't care too much for "eye candy" - but that's because, if needed any command line utility can easily have a GUI wrapper added with some simple scripting - just look at "avrdude" for example - there are any number of "GUI wrappers" written for that to supposedly make it "easier to use").

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

(on the whole Linux developers don't care too much for "eye candy" - but that's because, if needed any command line utility can easily have a GUI wrapper added with some simple scripting - just look at "avrdude" for example - there are any number of "GUI wrappers" written for that to supposedly make it "easier to use").

Okay, thanks for the experience sharing :) 
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've found a way to jump to the bootloader programmatically:
 

void (*start_bootloader) (void) = (void (*)(void))(BOOT_SECTION_START/2+0xFE);

	EIND = BOOT_SECTION_START>>17;
	start_bootloader();

It lets jump to the bootloader and accordingly set the connection between FLIP and Xmega via USB. 
But the problem is following: if an user doesn't have a PDI programmer/debugger they won't be able to run the code above and we again come to the only firmware upgrade instead of multiple

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think I'll clean up and post my quick and dirty bootloader within a few days,.   I use avrdude and run it from the command line via a batch file.  I use the command line to run my editor so that's not a problem for me.

 

Here's the batch file I call dude_cdc.bat

avrdude -c avr911  -p x128a4u  -P com16  -e -U flash:w:Steve_atmel/debug/steve_atmel.hex

For testing, I like to do a verify by changing the :w: to :v:

 

Note that avrdude.exe must be in the PATH for this batch file to work.  I guess you could instead put in the whole path to avrdude.exe.

 

Unfortunately I don't know any good way to make this a "gui" program.  Maybe someone could do it with python, or find something else on the internet.

 

 

 

Well well, maybe I came up with something that would work.  In Studio, I went to Tools > external tools.  I came up  with this.

 

 

 

 

The freaking thing works.  If I get the bootloader running on the Xmega and go to Tools > external tools, and click on avrdude_cmd, this pops up.  Mission accomplished.

 

Last Edited: Wed. Jul 5, 2017 - 09:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

steve17 wrote:

I think I'll clean up and post my quick and dirty bootloader within a few days,.

 

Okay it would be great. 

steve17 wrote:

I use avrdude and run it from the command line via a batch file.  I use the command line to run my editor so that's not a problem for me.

 

As I was saying I managed to launch dfu-programmer from https://dfu-programmer.github.io and play with it also. Unfortunately it didn't solve the multiple DFU problem.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IdiocyCubed wrote:

I have reserved an area in EEPROM which is set when the application is running and this tells the bootloader that it should attempt to receive firmware.  If bootload fails the result is stored in EEPROM and can be read from the application.  No pins are needed and I just do a watchdog reset from the application to enter the bootloader.

Could you please give a more detailed explanation how to actually "tell" bootloader what to do? I mean where the code which is responsible for the "telling" should be located?
As far as I understand everything that is inside a "main" method is located in application section.

Thanks,
Roman

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Be very wary of bootloading mechanisms that rely on something (/ anything) the app has to do to trigger their operation. There may well be scenarios where a bootloading operation is started, the reprogramming fails part way through (comms failure or power failure) and now you no longer have a valid app in the flash at all. If the bootloader is waiting for some trigger from the app (that no longer exists) you may have a problem.

 

OTOH I guess there's no problem with an "auxiliary" way for the app to trigger the bootloader. Perhaps it sets some magic value in EEPROM then forces a chip reset. At restart the bootloader sees the EEPROM value and takes this as a "command" to "get on and do your thing". But do not make this the ONLY way for it to be triggered.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just have an EEPROM address which holds a byte of flags and one of these is used to indicate that a new firmware is available.  This address is set to some value (whatever you want to use) in the application to indicate that a new firmware is ready to be loaded, the application then issues a reset or jumps to the bootloader whatever method you prefer to use.  The bootloader then checks EEPROM address and new firmware flag then you do whatever you want regarding your bootloader and at the end you clear the flag which indicates that a new firmware is needed (if successful) and you could also use other flags to indicate failure or hold retry counts etc.  If this flag is not set you just go to your application.  I have a FLASH chip which the program is downloaded to and verified before bootloading and also have the possibility of restoring a previous firmware if the application has not booted successfully.  I still put a FLASH chip on boards for bootloading because they are cheap and because I didn't have to worry about USB stuff in the bootloader and corrupt transfer etc.  I am very interested in this thread and will have a go at using the bootloader posted here.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just posted below while you were writing this and hence the FLASH chip, and I have a flag used to indicate that the application has booted and runs so the bootloader knows that a valid app is loaded.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IdiocyCubed wrote:
and hence the FLASH chip,
Yup, it's a nice strategy if you can afford it  - very difficult to "lose" the thing if you always have room for a "backup".

 

(incidentally this is the way Sky TV recorders do their firmware - they have double flash - it receives a "new image" into one while the other is still active)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IdiocyCubed wrote:

 the application then issues a reset or jumps to the bootloader whatever method you prefer to use.  The bootloader then checks EEPROM address

 

So the question is how to make sure that the bootloader checks exactly the address that I need? In what way to control the bootloader's behavior in this particular case?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

All that requires is that the app and the bootloader AGREE on some "flag" location in the EEPROM. A common choice (to keep this out of the way of "normal" EEPROM use) might be to use the very last byte or two in the EEPROM. As long as both writer and reader agree the location it can be anywhere though. The address is hard coded into both the app code and the bootloader code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can post my quick and dirty bootloader.  It's pretty well cleaned up.  The application uses a software reset to go to the bootloader.  

 

Like any method that uses the application, it becomes non-operational if you load a non-functioning application.

 

It seems the only reliable way to get to the bootloader if your board has no switches, is to use the time delay after reset method.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

steve17 wrote:

I can post my quick and dirty bootloader.  It's pretty well cleaned up.  The application uses a software reset to go to the bootloader.  

 

Like any method that uses the application, it becomes non-operational if you load a non-functioning application.

 

It seems the only reliable way to get to the bootloader if your board has no switches, is to use the time delay after reset method.

 

Please, post it. I'm gonna examine its ins and outs

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Here it is.  It's written in C++.  I copied the USB stuff and my "operating system" I call Task_runner from my application code.  Most of the configuring is done in executive.h.  It should be set up for your board.  As configured it doesn't check a pin.  It can light a LED but I've commented it out. You would need to set the proper Port_X_regs and the proper pin.

 

It enters the bootloader if it gets control via a software reset.

 

I do check to see if flash location zero is 0xff.  If so, I enter the bootloader.  If that causes trouble you can remove it by commenting out the first few lines of code in is_bootloader_wanted.h.

 

This USB code does not use the USB SOF as the DFLL reference because I don't need or use that.  If it is required, I can add it fairly easily because I've added it in the past just to check it out.

 

The project is built with AS 6.2.  I think you can use AS 7.0 without problems.

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I noticed that I can program the bootloader without erasing the application, and vice versa.  I set the project properties "Programming settings" to "Incremental programming", and then start debugging.  I'd never seen that option before.

 

Actually I think my bootloader does incremental programming.  I think it ignores the "erase" command.  Whenever it writes a flash page it uses the NVM command "erase and write flash page".

 

By the way, I think some versions of avrdude needs the -e option when writing flash or it has problems.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

With the bootloader, it can be activated by jumping to address 100fe using

asm(" jmp 0x100fe");

 

We have a bootloader working, and it gets activated by detecting the USB plug is connected (the USB is only used for firmware updates). When plugged in, the program jumps to a special routines, flashes two lights quickly and then jumps into bootloader mode. We use the fuses set to Application reset.

 

Also, the firmware update takes around 2-3 seconds for a 10kB update.

Electronic System Design
http://www.esdn.com.au

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you very much! 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah I used a similar method. But my application differs in the fact that USB is used even if it is not firmware upgrade.