Starting T1000-E Bootloader in uf2 mode

Hello
I have a Zephyr application that I’m porting to run on T1000-E.
To enter the bootloader in uf2 mode, where it mounts the usb volume to drag and drop firmware images, I use the same code as Meshtastic does
With the exception of sd_softdevice_disable() because I’m on Zephyr
However the bootloader does not start - it starts my app instead.
I looked at the bootloader code and it checks the NRF_POWER->GPREGRET value and if is set to 0x57 it starts the tinyusb and mounts the volume. That’s not happening on my T1000-E
I can still enter the bootloader manually using this sequence
Press button
Connect-disconnect-connect charger
Wait ~1second.
Release the button
I noticed that when the bootloader usb volume is mounted the “INFO_UF2.TXT” file has the following information
UF2 Bootloader 1.00
Model: Seeed T1000-E for LoRaWAN
Board-ID: nRF52840-T1000-E-v1
This is not the same version as Arduino github has so I’m assuming this is a custom branch, right?
Any ideas why the bootloader does not start for me?
Thank you!

Hi there,

This sounds to me like a mismatch between how UF2 bootloader is expected to be triggered (as designed for Adafruit/Arduino stack) and how Zephyr interacts with the nRF52840 boot and power registers, especially with regard to GPREGRET-based bootloader entry.

and that the mounted bootloader reports:

UF2 Bootloader 1.00
Model: Seeed T1000-E for LoRaWAN
Board-ID: nRF52840-T1000-E-v1

This differs from the stock Adafruit bootloader, so you suspected it may be a custom bootloader.

Yes, you’re absolutely right to suspect that.
That INFO_UF2.TXT file shows custom board ID and bootloader version, so it’s a Seeed-specific fork.

Even if you set NRF_POWER->GPREGRET = 0x57, the bootloader may not honor that value unless Seeed implemented that logic explicitly.

In Adafruit’s UF2 bootloader, setting GPREGRET to 0x57 is the standard way to trigger UF2 mode from code.

However, Seeed’s custom bootloader may:

Require additional bits set (e.g. specific RAM values or softdevice flags)

Not support software entry into UF2 mode at all

Only support manual button sequence, which you described works fine.

  1. Confirm if GPREGRET is supported by the Seeed bootloader:

Try writing NRF_POWER->GPREGRET = 0x57; NVIC_SystemReset(); and immediately reboot. If it still skips bootloader, it’s not implemented in their fork.

HTH
GL :grin: PJ :v:

I have a strong hunch ,button only is built that way? Maybe a security reason , above my pay grade .:+1:

Meshtastic firmware works with a WebFlasher app. It has UI to download a firmware image to a connected device. The app sends a byte over a serial connection and in response Meshtastic firmware does the following

void enterDfuMode()
{
// SDK kit does not have native USB like almost all other NRF52 boards
#ifdef NRF_USE_SERIAL_DFU <–only defined in the wio-sdk-wm1000 variant
enterSerialDfu();
#else
enterUf2Dfu();
#endif
}
And enterUf2Dfu() in Aurduino SDK sets NRF_POWER->GPREGRET = 0x57, and calls NVIC_SystemReset();
My zephyr code does exactly that but bootloader is not entered. The only thing I’m doing differently is not call sd_softdevice_disable() which disables the Softdevice. But Nordic says this is only for directly accessing the GPREGRET register which cannot be done while SoftDevice is running. So I’m at a loss why the same code works on Meshtastic (built with nRF SDK and Segger) and does not work in my Zephyr app. Is there a way to examine the bootloader code that runs on T1000-E ? Who do I ask?
Thanks

Hi there,

Yes Indeed , I’m familiar with the App, very much so. you have done your homework and have you verified the GPREGRET = 0x57, stay and indeed is set? Have you tested that ?
Try writing NRF_POWER->GPREGRET = 0x57; NVIC_SystemReset(); and immediately reboot.
If it still skips bootloader, it’s not implemented
, so then I would send an e-mail to tech support at seeed and see what comes back, I’m certain there is a person responsible and or a group of seeedineers that could say one way or the other. Would be good to know the Answer.:+1:
, but as I intimated , it may be for security reasons beyond my limited understanding when dealing with Meshtastic devices :person_shrugging:

HTH
GL :slight_smile: PJ :v:

Yes, my app uses the same code as meshtastic in the links I provided earlier and sets GPREGRET=0x57.
NVIC_SystemReset() resets the board so not sure what you mean by “immediately reboot”
Upon board reset it does not enter the bootloader.
I verified that GPREGRET is set to 0x57 before rebooting. So unless NVIC_SystemReset does something to that register I’m reasonably certain that it contains the value 0x57. Of course I have no way to verify it 100% as I don’t have access to the bootloader code.

Hi there,

Yes, agree you are doing the same, the difference is the seeed bootloader is ignoring the GPREGRET being set. fire the e-mail to seeed
see what comes back. something is missing maybe they can tell us.

I think they have a number of Meshtasic devices so I’m relatively certain , someone there knows what’s what in the BL dept.

HTH
GL :slight_smile: PJ :v:

Sorry I’m a newbie here :slight_smile:
Who should I send the email to ? I thought this is the place as the forum is for “seedstudio”
Thanks
Andy

Hi there,

not to worry , we all started the same. So

go there and click message.

Yes this is the user support forum, they monitor it mostly jumping in when they can, You need a specific piece of info and your not asking like it’s a hand-out or needs a SPOON… anyone can see you posted and put in the work, looked at the info and found :grin: the lack of any for the BL flashing directions. If they used the vanilla BL it wouldn’t be a thing
I’m hoping a answer comes back for both.

HTH
GL :slight_smile: PJ :v:

Got it, thank you much, I’ll update here

1 Like