LUFA CDC Exit Bootloader ATMega32U2

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

So sink or swim I jumped in at the deep end ... a custom made board with a blank ATMega32U2 MCU. Yep, I know ... not novice ground, but I think I've done well ....

 

  • Running from an external 16MHz clock (because of that pesky 48MHz USB clock requirement) :)
  • Programmed the fuses via AVRDUDE :)
  • Compiled and loaded a LUFA CDC bootloader using Atmel Studio 7.0 via ArduinoISP :)
  • Seeing bootloader and application USB virtual comm ports in WIndows 10 :)
  • Successfully uploaded application code via the Arduino IDE :)

 

Stuck now for two days on this problem: when I enter the bootloader via a reset, I can't get out of it without powering off/on or uploading new application code.

 

I'm a complete code buffoon but the bootloaderCDC.c file seems to mention lots of ways it's supposed to jump to the application code. I was expecting some kind of timeout, like Optiboot ... run bootloader, no attempt to upload after 10 seconds ... jump to the application code. But it just sits there forever in the bootloader. Connect with AVRDUDE or upload via Arduino IDE (or power off/on) and it jumps just fine.

 

Can somebody point me in the right direction to exiting the bootloader after some time following a reset?

 

I've attached the bootloaderCDC.c file (not modified in anyway from the LUFA CDC example)

 

Many thanks,

David.

 

p.s. my fuses are: L:E0  H:D8  E:CE  L:2F*   *locked after bootloader uploaded.

Attachment(s): 

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

Your attachment looks like a mess.

 

Some bootloaders look to see if a certain pin is high or low to determine whether to jump to the application.  That is, to see if the user has pressed a switch. 

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

Yeah, it's one if the fuse options but I really have no use for it so disabled it.

The bootloader is just set to run on reset, which works fine, but it just won't exit the bootloader (without power cycling or uploading).

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

There are two ways that I know of for the bootloader to tell if the user wants to do bootloading or just wants to run the application.  One way is with a timer, the other way is to test a certain pin on the board.  Do you know which method your bootloader uses?

 

It seems to me, your bootloader thinks you want to do bootloading, not run the application.

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

It seems fairly clear that the way that works is that it starts into the bootloader (presumably either BOOTRST or HWBE and the HWB pin) and it "does its thing" (last bullet point in your list) then, as all good bootloaders should, Dean forces a watchog reset - that's to completely reset the USB and everything else that has been used up to that point. The code then suggests that Application_Jump_Check() is code that is "inserted" near the start up of the bootloader if the reset check shows it was WDRF that reset the chip. It will depend which board you have configured for but there are various alternatives in that routine for it deciding whether to start the app code or not so which of these is true in your build...

	#if (BOARD == BOARD_LEONARDO)
...
	#elif ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
...
	#else

Finally it does this...

	/* Don't run the user application if the reset vector is blank (no app loaded) */
	bool ApplicationValid = (pgm_read_word_near(0) != 0xFFFF);

	/* If a request has been made to jump to the user application, honor it */
	if (JumpToApplication && ApplicationValid)

So I guess the question is - did the preceding set JumpToApllication and has that ApplicationValid passed?

 

You can probably flash an LED or something to monitor the result of those two questions.

 

Presumably if the two conditions are not met it will return from the function and just resume bootloading operation.

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

@steve17  I'm only using the reset to enter the bootloader, I guess this 'reset' actually resets a timer, though not sure. I purposefully disable the 'monitor this pin on start' using the fuses.

 

@clawson  I think that aspect of the code is working just fine. If I upload, a reset is performed and it does indeed jump straight to the application. I can also imagine that if there was no application code present, it would just stay in the bootloader. I think this is all good. What I'm missing is that after a reset, the bootloader runs but never exits, until I upload code (or power cycle). What I want is the bootloader to 'timeout' after some time after a reset. For example, the adafruit 'optiboot' bootloader pulses the onboard LED showing that it is in bootloader mode then, if you don't actually upload anything after ten seconds, it jumps out of the bootloader to the application. It is this behaviour I am trying to replicate ... and to be honest, guys, I just don't know how to.

 

EDIT: I've just taken a sneaky peak at the optiboot code on Github (https://github.com/adafruit/Adaf...) and I can see where the flashing LED is and the timeouts to run the application (discribed in main.c and optiboot.c) but this is so far beyond my capabilities that I might just have accept this LUFA bootloader just how it is. I really need to get on a C programming course or something.

Last Edited: Mon. Apr 24, 2017 - 05:42 PM