Resetting into the DFU Bootloader

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

I'm trying to add a function to my project to reset to the standard DFU bootloader. For standard use my device is plugged into a computer and enumerated. I plan on creating a (cross platform) tool that the user can run that will send a special command to force my UC3A3 into the DFU bootloader and automatically flash the UC3A3. I'm having trouble getting the UC3A3 to jump back to the bootloader though.

I'm using this document to guide me:
http://www.atmel.com/dyn/resourc...

I'm using ASF 2.8.1, which has the FLASHC driver, which allows me to write to the GP Fuse Bits. I believe the following line of code should be sufficient to set ISP_FORCE to 1.

flashc_write_gp_fuse_bit(31, true);

After ISP_FORCE is set to 1, the DFU bootloader will launch at the next reset. According to the datasheet, the appropriate way to reset is to use the Watchdog Timer.

wdt_reset_mcu();

When triggering these two lines of code the MCU will reset instantly, but it doesn't appear to come back up running anything. I'm using a USB sniffer and I see it send the "Reset to DFU Bootloader" command, and then it drops the connection, but nothing comes back up.

I'm thinking that I'm not resetting the MCU properly, but isn't that exactly what the Watchdog Timer should be doing?

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

*sigh*

I figured this out by searching, which I probably should have done first, but it does bring up an important question.

First, the solution:

/* Reset into Bootloader */
flashc_erase_gp_fuse_bit(31, true);
flashc_write_gp_fuse_bit(31, true);

cpu_irq_disable();
wdt_opt_t opt = {
	.us_timeout_period = 1000000
};
wdt_enable(&opt);
while(1);

Need to erase the flash before you can write to it, and then you need to have the WDT not have a timeout period of 0, because that means it will never be able to disable the WDT.

I found several posts indicating this same problem going back to 2009 (ASF 2.1.x). While, yes, wdt_reset_mcu, will technically reset the MCU, it locks it into a reset loop that can never end, because the bootloader can't disable the WDT faster than 0 uS! I'm half tempted to file a bug report because it's not really a working function if it doesn't allow the MCU to start executing anything!

Essentially my solution just copies wdt_reset_mcu, except I'm setting my timeout period to 1 second, figuring that's plenty of time to start the bootloader. I suspect I could get a good estimate of boot times from the datasheet, but 1 second is good enough for me for now.

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

Hi iwoloschin,

Your post finally trigger some brain cells at my end, as I have been having issues with resetting the DFU (specifically getting the USB to enumerate after the reset). Seems I was running into the same issue with the WDT blocking the DFU from running after the reset.

I now have a working application that does a full reprogram of the flash all automated, so if you need any assistance with that part let me know.

Regards

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

daffniles wrote:
Hi iwoloschin,

Your post finally trigger some brain cells at my end, as I have been having issues with resetting the DFU (specifically getting the USB to enumerate after the reset). Seems I was running into the same issue with the WDT blocking the DFU from running after the reset.

I now have a working application that does a full reprogram of the flash all automated, so if you need any assistance with that part let me know.

Regards

Thanks for the offer, but I think I'm all set now! I've got the MCU resetting into the standard DFU bootloader, and I can create a simple tool that issues the appropriate commands to flash the MCU.

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

It seems that reseting into bootloader by setting the bit in flash makes you have to load the program. There is no regret.

Is there a way to make the bootloader clear the flash bit so that there will be a normal boot if reset is pressed?

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

AgwanII wrote:
It seems that reseting into bootloader by setting the bit in flash makes you have to load the program. There is no regret.

Is there a way to make the bootloader clear the flash bit so that there will be a normal boot if reset is pressed?

I'm not sure I understand...

If you boot into the DFU Bootloader, you can simply pass a "start" command to jump up to the user application. The DFU Bootloader will automatically clear the ISP_FORCE GP Fuse Bit before jumping to the user application. I'm using Linux (Ubuntu) and dfu-programmer to flash my UC3A3.

Here's some aliases I set up to help:

alias dfu-programmer='sudo dfu-programmer at32uc3a3256'
alias dfu-flash='dfu-programmer erase; dfu-programmer flash --suppress-bootloader-mem'
alias dfu-start='dfu-programmer start'

Once I'm loaded into the DFU Bootloader I can pass either dfu-flash or dfu-start. The UC3A3 *WILL NOT* start the user application without passing dfu-start, even if you've just flashed the MCU.

One *VERY* important thing to note, on Linux, dfu-programmer needs either root access or modification of device rules to allow user access to the dfu "device" that appears on USB. Due to how my computer is setup, I've found it easier to just use "sudo" to gain root access. I'm not familiar with other current Linux distros, so I can't comment on what the best way to setup dfu-programmer would be.

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

Hi AgwanII

The other option (using BatchISP at least) is to have the DFU set the fuses manually, using the memory configuration commands.

Here is the one I use to reset the three DFU fuses.

cmd.exe /C batchisp -device AT32UC3A3256 -hardware usb -operation onfail abort memory configuration addrange 0x1D 0x1D fillbuffer 0x0 program addrange 0x1E 0x1E fillbuffer 0x1 program addrange 0x1F 0x1F fillbuffer 0x0 program

This causes the DFU to not start on the next reset.

Note: I have the option to manually enter the DFU using a switch which is why the 0x1E is set to 0x1. If you ALWAYS want the application to run, and not have the DFU check a switch option (Set in the last 4 bytes of the userpage) then set this value to 0x0

Regards.

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

Ok, I see what you are saying. (I think) If I have entered bootloader I have to talk to the bootloader to get out of it. I tested now and this works for me

batchisp -device at32uc3a3128S -hardware usb -operation start reset 0

I was hoping that there was a config of the bootloader to make it clear the bit always directly on entry.

I want this since I will have one program for programming the flash, and one for controlling the device. But the latter can send the device into bootloader by setting this bit. And then, without having the bootloader program, the unit will be stuck.

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

Modify the bootloader source code and add the functionality you need.

Daniel Campora http://www.wipy.io

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

Yes, but I was hoping I would not have too. I was hoping that there would be a setting when I program the bootloader. One of the check boxes...

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

Why not just modify your "control" program to always attempt to clear the bit? I believe if batchisp can't find a device it just prints an error message. That could be completely hidden from the user and wouldn't even take that much time to run. Or don't allow the control program to enter the bootloader, restrict that to the bootloader program.

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

The "control" program can't clear the bit if it can't talk to the device. And it can't talk to the device if it is in bootloader mode.

Suggestion two is better, it would be best that the "control" program cannot make the unit go into bootloader mode. At least not if we don't implement the batchisp connection to the "control" software too.

Thanks for all the suggestions guys! I think I have the info now of what I need to do.

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

AgwanII wrote:
The "control" program can't clear the bit if it can't talk to the device. And it can't talk to the device if it is in bootloader mode.

Both programs are running on the same host computer, correct? I'm confused why you think the "control" program can't talk to the device if it's in bootloader mode. I mean, yes, your application specific commands won't work since your application won't be enumerated on USB, but the DFU Bootloader will be enumerated, and then your "control" program can make the appropriate calls through batchisp to "talk" to the device in bootloader mode.

Perhaps you have other reasons for splitting it (honestly, the user should not be flashing the device often anyways), but if the only reason you've got two separate programs running on the host computer is because you're having problems communicating in different modes, I think you might be making it harder on yourself.

Either way, glad you've got your answers and your off onto one solution or another.

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

Hi Agwanll,

You just need to make one application to do both the controlling of the device, as well as programming the flash.

This is what I do for an updater application. Application sends command to the device to reset itself into the DFU. Then once the DFU is running, the application does batchISP command line calls, which the application monitors the output from batchISP to see what the results are.

I use java, but any language should have the same capability.

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

daffniles,

One quick question, how are you determining that the DFU Bootloader is now active? For instance, when I issue the "Reset to DFU" command, it will take several seconds before it is ready to flash a new firmware. I was thinking I could just wait 5-10 seconds, but I'm curious if there's a better way of handling that?

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

Currently I wait as you do, as within Java (what my updater is written in) I do not get any indication of when a USB device is connected.

If you are using .NET tho, you can probably get a notification of when a USB device is attached.

I am toying with the idea of using batchISP to tell me tho, as it does its own checks. Funny tho, this takes about as long, as the delay I have anyway. so I don't gain a lot.

My device pretty resets into the DFU, with a very consistent time, so waiting is not really a big problem.

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

Great, thanks, that's pretty useful to know! Not sure what my plan is yet, so far I've just been using a simple Bash script in Linux, I might make something nicer than that, but it works for now.

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

In Linux you can use inotify if your device shows up in /dev. That way you can be notified immediately as soon as your device is recognised.