atsamd icon indicating copy to clipboard operation
atsamd copied to clipboard

How to keep the device in bootloader mode?

Open rvdende opened this issue 2 years ago • 3 comments

I'm using the metro_m0 board example blinky. However, I have to double press the physical reset button every time and this gets annoying. The arduino IDE somehow gets around this limitation. I think I read somewhere that its related to a few bits at the end of the memory, but I'm not sure how to set those. Can anyone help?

This is the physical board I'm using: https://www.robotics.org.za/6970622930204?search=m0 and the chip says ATSAMD21 G18A-U and I can alter the blink durations in the rust code and that works when I do an upload. I'm on linux and using this script to upload:

echo "Building"
cargo build --example blinky_basic

echo "Converting to binary"
arm-none-eabi-objcopy -O binary target/thumbv6m-none-eabi/debug/examples/blinky_basic target/thumbv6m-none-eabi/debug/examples/blinky_basic.bin

echo "Setting baud rate to 1200"
stty -F /dev/ttyACM0 ospeed 1200

echo "Uploading"
~/.arduino15/packages/arduino/tools/bossac/1.7.0-arduino3/bossac -i -d --port=ttyACM0 -U true -e -w -v target/thumbv6m-none-eabi/debug/examples/blinky_basic.bin -R

rvdende avatar Mar 18 '23 15:03 rvdende

I think this is related, but for a different board? Seems like this code is no longer in master. https://github.com/atsamd-rs/atsamd/pull/161

rvdende avatar Mar 18 '23 15:03 rvdende

@rvdende, here is a snippet which should achieve what your're after:

    use atsamd_hal::pac::SCB;

    /// RAM size (32 kB for ATSAMD21E18A)
    const HMCRAMC0_SIZE: u32 = 0x00008000;
    /// RAM base address
    const HMCRAMC0_ADDR: u32 = 0x20000000;

    /// Writing this value into `BOOTLOADER_DBL_TAP_PTR` and resetting will
    /// cause the bootloader to 'stick'
    const BOOTLOADER_DBL_TAP_MAGIC: u32 = 0xF01669EF;
    /// Writing this value into `BOOTLOADER_DBL_TAP_PTR` and resetting will
    /// cause the bootloader pass right through to the app
    const BOOTLOADER_DBL_TAP_MAGIC_QUICK_BOOT: u32 = 0xF02669EF;
    /// Bootloader magic values need to be written here
    const BOOTLOADER_DBL_TAP_PTR: *mut u32 = (HMCRAMC0_ADDR + HMCRAMC0_SIZE - 4) as *mut _;

    /// Reset into the bootloader, and stay there in order to flash a new
    /// firmware image.
    #[inline]
    pub fn reset() -> ! {
        unsafe {
            core::ptr::write_volatile(BOOTLOADER_DBL_TAP_PTR, BOOTLOADER_DBL_TAP_MAGIC);
        }
        SCB::sys_reset();
    }

jbeaurivage avatar May 14 '23 18:05 jbeaurivage

@rvdende - did @jbeaurivage's code snippet work for you?

I wonder if we should find some place to document this, because it seems like a lot of folks using atsamd-rs will also be using the Adafruit bootloader and potentially interested.

ianrrees avatar Nov 14 '23 04:11 ianrrees

I've added @jbeaurivage 's snippet to a page to the atsamd wiki https://github.com/atsamd-rs/atsamd/wiki/Code-Snippets

ianrrees avatar Aug 22 '24 06:08 ianrrees