BOOT_FLASH attached to a pin?

Okay that is useful to know, thanks for your response.

When you mention PORTG pin3 - that is a pin that is internal to seed though right? It is not attached to one of the inline physical pins around the seed perimeter?

If it is just an internal ‘pin’, I don’t think that will allow me to easily add an off-seed boot button by connecting to an external seed pin. The only way I see to add another boot switch with your response is to put a version of the RebootToBootloader code you included in every version of the code I put on the seed and trigger the RebootToBootloader function by pulling one of the seed’s external pins high or low. Let me know if your response suggested a different solution and I missed something though.

Correct, what I mentioned was how you could trigger that function from any UI action on your hardware instead of having to have a physical connection to the boot and reset pins, which are not readily available on the Daisy pinout.

The caveat is that, yes, you would have to include that function in your code.

Okay thanks again, that is very useful to know!

@shensley, RebootToBootloader() is very interesting! I am not sure though, which file to include to be able to use NVIC_SystemReset()? Tried grep but I don’t understand the results (or rather, which header to include).

This is almost @shensley’s pseudocode, just had to add the #include, “correct” the Reset-call, and add a small delay to let the cap charge (as noted on the schematic: https://github.com/electro-smith/Hardware/blob/master/reference/daisy_seed/ES_Daisy_Seed_Rev4.pdf).

This small program blinks the LED two times then is ready to accept another download:

#include <daisy_seed.h>
#include "stm32h7xx_hal.h"

daisy::DaisySeed hw;

void RebootToBootloader()
{
    // Initialize Boot Pin
    dsy_gpio_pin bootpin = {DSY_GPIOG, 3};
    dsy_gpio pin;
    pin.mode = DSY_GPIO_MODE_OUTPUT_PP;
    pin.pin = bootpin;
    dsy_gpio_init(&pin);

    // Pull Pin HIGH
    dsy_gpio_write(&pin, 1);

	// wait a few ms for cap to charge
	hw.DelayMs(10);

    // Software Reset
	HAL_NVIC_SystemReset();
}

int main()
{

	hw.Configure();
	hw.Init();

	hw.SetLed(1);
	hw.DelayMs(500);
	hw.SetLed(0);
	hw.DelayMs(500);
	hw.SetLed(1);
	hw.DelayMs(500);
	hw.SetLed(0);

	RebootToBootloader();

}

I’ll just add a button to my breadboard and connect it to this function, and speed up my numerous uploads! :slight_smile:

1 Like

So I added a (momentary) button to pin 28 and to ground (remember to connect AGND and DGND too).

And in my main() I added this code:

// Configure and initialize button
Switch button1;
button1.Init(hardware.GetPin(28), 10);

// Loop forever
for(;;)
{

	// Reset to upload

	button1.Debounce();
	if (button1.Pressed())
	{
		RebootToBootloader();
	}

	// wait 1 ms
	System::Delay(1);
}
1 Like

Fantastic!

I should be able to add this as a static system function in libdaisy some time this week: System::ResetToBootloader()

I also want to get something set up to call this from USB to have a simplified reprogram via USB workflow.

2 Likes

I think it’s also necessary to disable interrupts before bootloader jump, i.e. add

  RCC->CIER = 0x00000000;

before the NVIC_SystemReset();

And it may be better to replace the delay with while(1);. That said, CMSIS calls this in reset function:

  for(;;)                                                           /* wait until reset */
  {
    __NOP();
  }

So this would only matter if building with a terribly broken version of CMSIS.

3 Likes

I just tried this - works great! tho I had issues with that #include “stm32h7xx_hal.h”

it’s easier to forget the include and :

extern “C” void HAL_NVIC_SystemReset();

in case the include structure changes e.t.c.

I didn’t know about that, thanks!

Hmmm…I also include “core_cm7.h” for measuring MCU utilization, and that seems to require “stm32h7xx_hal.h”…

With:

//#include "stm32h7xx_hal.h" // for HAL_NVIC_SystemReset();
extern "C" void HAL_NVIC_SystemReset();
#include "core_cm7.h"

I get

../../DaisyExamples/libdaisy/Drivers/CMSIS/Include/core_cm7.h:103:8: error: #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
       #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
        ^~~~~
In file included from main.cpp:18:0:
../../DaisyExamples/libdaisy/Drivers/CMSIS/Include/core_cm7.h:1867:39: error: variable or field '__NVIC_EnableIRQ' declared void
 __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
                                       ^~~~~~~~~

../../DaisyExamples/libdaisy/Drivers/CMSIS/Include/core_cm7.h:103:8: error: #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
       #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
        ^~~~~
In file included from main.cpp:18:0:
../../DaisyExamples/libdaisy/Drivers/CMSIS/Include/core_cm7.h:1867:39: error: variable or field '__NVIC_EnableIRQ' declared void
 __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
                                       ^~~~~~~~~

Looks like you’re missing preprocessors flags that normally get defined by HAL. Building with GCC flags like this may help - -DARM_MATH_CM7 -D__FPU_PRESENT -D__FPU_USED=1. This is what OWL uses to include CMSIS without HAL.

2 Likes

you could extern the other function as well, so there’s no need to include #include “core_cm7.h” e.t.c.

1 Like

hey, this is really cool! i was wondering if there was anything of the sort available for the custom Daisy bootloader?

i want to be able to extend the 2.5 second grace period with an external push button but i’m not sure how i would be able to do that from the software in this context… is it even possible?

At the moment, there’s not a way to extend the grace period apart from physically pressing the boot button on the back.
However, we did just find a bug that we’re currently fixing in the bootloader.
So we will be publishing a new version shortly.

In the new version we’re going to add a method of jumping to the bootloader from software with (and without) an infinite extension of the grace period (or until it finds a file on media, per usual functionality).

This will let you jump to, and optionally stay in the bootloader from software using any button, or communication interface (MIDI, Serial, GPIO, etc.) you want.

3 Likes

I’m right at the point of needing this extension of grace time with my project as of today : )
I was able to trigger reboot using the piece of code you guys kindly provided, now the only issue is that it only lasts less than a second.

I was helping someone figure out how to reimplement ResetToBootloader in Arduino and this works (requires additional #include "utility/gpio.h")

#include "DaisyDuino.h"
#include "utility/gpio.h"

void resetToBootloader() {
  // Initialize Boot Pin
  dsy_gpio_pin bootpin = {DSY_GPIOG, 3};
  dsy_gpio pin;
  pin.mode = DSY_GPIO_MODE_OUTPUT_PP;
  pin.pin = bootpin;
  dsy_gpio_init(&pin);
  dsy_gpio_write(&pin, 1);
  delay(10);
  HAL_NVIC_SystemReset();
}

I was hoping to figure out how to do this with typical Arduino functions, i.e. pinMode and digitalWrite but I can’t figure out the pin identifier in Arduino-world. PG3 is not recognized by the compiler and PG_3 is recognized but does not work.

Regardless adding the dsy_gpio version as a function exposed by DaisyDuino on the DaisyHardware class should be possible, might whip up a Pull Request for that.

2 Likes

Hello @shensley ,

This sounds great, is there any more information on how to do this?

Thanks,
Brett

The new version of the Daisy Bootloader is not out yet, but we should include these information in a documentation when it’s released.

@Takumi_Ogata ,
Is there any ETA on when this may come out?

Thanks,
Brett

Hi Brett,

I’m not sure the ETA for the new Daisy Bootloader.
You can edit in that question to here: Need help: "Failed to launch GDB: Load failed" -- when the load succussed - #6 by BHAudio