Frage

I'm hacking a stk500v2 bootloader for a custom Atmega2560 board based on this code, so it uses UART2 instead of UART0, I changed also the led pin to match my board pin definition and changed the WDT reset detection code so it increases the boot timeout instead of going straight to application code. See below for the detailed changes and setup I've made on the board.

My problem is that the MCU does not run the bootloader when I do a pin reset or a WDT reset, but only does it when doing a brown out reset (plug/unplug) or power on reset (at first boot after flashing the firmware). I tried looking for documentation on the topic on the intertubes, I've read the datasheet of the Atmega2560 (though it's quite lengthy and I may have missed relevant parts), and I found nothing relevant to solve that problem.

I guess, I'm doing something wrong in my code and/or setup, but I can't tell what.

So basically, I updated the code to add a preprocessor condition (_USE_UART2_) that enables the following, in the line 315 block:

[...]
#elif defined(_M2560_UART2_)
  #define    UART_BAUD_RATE_LOW           UBRR2L
  #define    UART_STATUS_REG              UCSR2A
  #define    UART_CONTROL_REG             UCSR2B
  #define    UART_ENABLE_TRANSMITTER      TXEN2
  #define    UART_ENABLE_RECEIVER         RXEN2
  #define    UART_TRANSMIT_COMPLETE       TXC2
  #define    UART_RECEIVE_COMPLETE        RXC2
  #define    UART_DATA_REG                UDR2
  #define    UART_DOUBLE_SPEED            U2X2
[...]

and also made another change for the pin, around line 155 :

[...]
#elif defined(_M2560_UART2_)
#define PROGLED_PORT       PORTJ
#define PROGLED_DDR        DDRJ
#define PROGLED_PIN        PINJ0
[...]

I'm also working on changing the boot timeout value depending on whether it has been a brown out reset, or a WDT/pin reset (my goal being to make the bootloader wait longer on WDT/pin resets). So I made the following change at line 545:

    unsigned long long  boot_timeout    =   1200000;

and at line 560:

    WDTCSR    =    0;
    __asm__ __volatile__ ("sei");
    // check if WDT generated the reset, if so, go straight to app
#ifndef SOFTWARE_RESET
    if (mcuStatusReg & _BV(WDRF))
    {
        app_start();
    }
#else
    // if WDT generated the reset, increase the boot timeout time
    if (mcuStatusReg & _BV(WDRF))
        boot_timeout =  3500000; // 7 seconds
#endif

Finally, I set up the fuses as follows:

  • BOOTRST set to 0 (enabled)
  • BOOTSZ set to 00 (4096 words bootloader section)
  • WDTON set to 1 (disabled)
  • BODLEVEL set to 101 (VBOTmin=2.5V, though I think that 100 would make more sense, though Vcc is regulated and should never vary except on power failures)

Thank you for reading all that, and even more if you can answer!

War es hilfreich?

Lösung

as stupid it might seem, the thing that was unclear to me until then, is that flashing the bootloader and the firmware separately does not work. What needs to be done is to use the srec_cat utility to join bootloader and firmware, and upload the joined firmware.

srec_cat firmware.hex -Intel bootloader.hex -Intel -o combined-bootloader.hex -I

It's somehow described in page 3-4 of The Bootloader FAQ

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top