Due to high demand, expect some shipping delays at this time - orders may not ship for up to 2-3 business days.
0

Bootloader
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Bootloader

by RogierWeekers on Wed Jan 26, 2022 8:48 pm

Is it possible to go into bootloader mode via software. My setup is with a touch panel, which is build into a case, now, if I need to change the code I have to open the case so I can push the button twice. It would be convenient if a dedicate button on the touch panel could be used to switch over.

RogierWeekers
 
Posts: 6
Joined: Wed Jan 26, 2022 8:43 pm

Re: Bootloader

by westfw on Wed Jan 26, 2022 10:10 pm

On which board?

westfw
 
Posts: 1871
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: Bootloader

by RogierWeekers on Thu Jan 27, 2022 2:37 am

Metro M0 express

RogierWeekers
 
Posts: 6
Joined: Wed Jan 26, 2022 8:43 pm

Re: Bootloader

by adafruit_support_carter on Fri Jan 28, 2022 2:18 pm


adafruit_support_carter
 
Posts: 23546
Joined: Tue Nov 29, 2016 2:45 pm

Re: Bootloader

by RogierWeekers on Fri Jan 28, 2022 3:30 pm

Is there a library for C++ (visual studio micro) ?

RogierWeekers
 
Posts: 6
Joined: Wed Jan 26, 2022 8:43 pm

Re: Bootloader

by User_UMjT7KxnxP8YN8 on Sat Jan 29, 2022 12:01 pm

I haven't used the M0 but I force reboots (which involves running the bootloader) on the Metro M4 by setting up the Watchdog Timer (WDT) then entering a tight loop that causes it to time out.

You can find my WDT code at https://github.com/SapientHetero/Watchdog-Timer-for-ATSAMD51J19A.

User_UMjT7KxnxP8YN8
 
Posts: 308
Joined: Tue Jul 17, 2018 1:28 pm

Re: Bootloader

by RogierWeekers on Sat Jan 29, 2022 3:38 pm

Thank you however this does not cover the issue. After changing the code for the M0 (see below) it does reboot, but does not get into bootloader mode.


I created this:
a variable
bool Reboot=false;

//in Setup
void SetupWdt() {
// Set up the generic clock (GCLK2) used to clock the watchdog timer at 1.024kHz
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(4) | // Divide the 32.768kHz clock source by divisor 32, where 2^(4 + 1): 32.768kHz/32=1.024kHz
GCLK_GENDIV_ID(2); // Select Generic Clock (GCLK) 2
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization

REG_GCLK_GENCTRL = GCLK_GENCTRL_DIVSEL | // Set to divide by 2^(GCLK_GENDIV_DIV(4) + 1)
GCLK_GENCTRL_IDC | // Set the duty cycle to 50/50 HIGH/LOW
GCLK_GENCTRL_GENEN | // Enable GCLK2
GCLK_GENCTRL_SRC_OSCULP32K | // Set the clock source to the ultra low power oscillator (OSCULP32K)
GCLK_GENCTRL_ID(2); // Select GCLK2
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization

// Feed GCLK2 to WDT (Watchdog Timer)
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | // Enable GCLK2 to the WDT
GCLK_CLKCTRL_GEN_GCLK2 | // Select GCLK2
GCLK_CLKCTRL_ID_WDT; // Feed the GCLK2 to the WDT
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization

REG_WDT_CONFIG = WDT_CONFIG_PER_1K; // Set the WDT reset timeout to 1 second
while (WDT->STATUS.bit.SYNCBUSY); // Wait for synchronization
REG_WDT_CTRL = WDT_CTRL_ENABLE; // Enable the WDT in normal mode
while (WDT->STATUS.bit.SYNCBUSY); // Wait for synchronization

}

in the main loop
if (!WDT->STATUS.bit.SYNCBUSY && Reboot==false) // Check if the WDT registers are synchronized
{
REG_WDT_CLEAR = WDT_CLEAR_CLEAR_KEY; // Clear the watchdog timer
}

RogierWeekers
 
Posts: 6
Joined: Wed Jan 26, 2022 8:43 pm

Re: Bootloader

by User_UMjT7KxnxP8YN8 on Sat Jan 29, 2022 5:06 pm

So, you want it to STAY in the bootloader rather than running the currently-loaded application? Is erasing the current application an option? If so, you could do so in your code, then call this function:

Code: Select all | TOGGLE FULL SIZE
 *******************************************************************************************************************************************************************************************/
 void reboot(void) {

  //*DBL_TAP_PTR = DBL_TAP_MAGIC;
  //SCB->AIRCR = (0x5FA << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk;  // force reboot (I had to modify this as shown below for M4)
    __DSB();                                                   // Ensure all outstanding memory accesses included
                                                               //   buffered write are completed before reset
  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |
                 (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
                 SCB_AIRCR_SYSRESETREQ_Msk);                   // Keep priority group unchanged
  __DSB();                                                     // Ensure completion of memory access
  while(1);                                                    // wait until reset
 
}   // reboot


If you don't want to erase your app, uncommenting this line may get you the effect you want:

Code: Select all | TOGGLE FULL SIZE
  //*DBL_TAP_PTR = DBL_TAP_MAGIC;


It's been over a year since I modified the bootloader, so you'll have to look at it to verify my recollection.

User_UMjT7KxnxP8YN8
 
Posts: 308
Joined: Tue Jul 17, 2018 1:28 pm

Re: Bootloader

by RogierWeekers on Sun Jan 30, 2022 9:41 am

Thanks a lot, but cannot get it to compile, and do not have enough info to correct.
My compiler misses "SCB_AIRCR_PRIGROUP_Msk"
and "DBL_TAP_PTR"
Any suggestions ?

RogierWeekers
 
Posts: 6
Joined: Wed Jan 26, 2022 8:43 pm

Re: Bootloader

by User_UMjT7KxnxP8YN8 on Sun Jan 30, 2022 12:22 pm

I haven't used the M0 but I had to add the register that won't compile in order for it to work on the M4. Perhaps replacing that line with the following will work:

Code: Select all | TOGGLE FULL SIZE
SCB->AIRCR = (0x5FA << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk;  // force reboot


You'll have to look at the bootloader for the M0, figure out where DBL_TAP_PTR is located, create a macro defining a pointer to that address and set it to get the desired behavior.

The bootloader source code is at https://github.com/adafruit/uf2-samdx1 in the /src directory.

User_UMjT7KxnxP8YN8
 
Posts: 308
Joined: Tue Jul 17, 2018 1:28 pm

Please be positive and constructive with your questions and comments.