Problems starting debug session with jlink on feather M0

I ran into that issue as well. After a lot of troubleshooting, the only way I was able to get USB Serial working during debug mode was to remove the bootloader from the Feather M0 entirely. I’m entirely lost as to why this would fix the issue, but I am happy to report that debugging seems to work normally now.

To flash your Feather M0 with no bootloader, you will need to use Atmel Studio to set the BOOTPROT fuse to 0 bytes (should be the same process as the instructions I posted earlier). Once the bootloader partition is unprotected, you can use the following custom board JSON to tell PlatformIO to compile for a no-bootloader Feather M0:

{
    "build": {
        "arduino": {
            "ldscript": "flash_without_bootloader.ld"
        },
        "core": "adafruit",
        "cpu": "cortex-m0plus",
        "extra_flags": "-DARDUINO_ARCH_SAMD -DARDUINO_SAMD_ZERO -DARDUINO_SAMD_FEATHER_M0 -DARM_MATH_CM0PLUS -D__SAMD21G18A__",
        "f_cpu": "48000000L",
        "hwids": [
            [
                "0x239A",
                "0x800B"
            ],
            [
                "0x239A",
                "0x000B"
            ],
            [
                "0x239A",
                "0x0015"
            ]
        ],
        "mcu": "samd21g18a",
        "system": "samd",
        "usb_product": "Adafruit Feather M0",
        "variant": "feather_m0",
        "zephyr": {
            "variant": "adafruit_feather_m0_basic_proto"
        }
    },
    "debug": {
        "jlink_device": "ATSAMD21G18",
        "openocd_chipname": "at91samd21g18",
        "openocd_target": "at91samdXX",
        "svd_path": "ATSAMD21G18A.svd"
    },
    "frameworks": [
        "arduino",
        "zephyr"
    ],
    "name": "Adafruit Feather M0",
    "upload": {
        "disable_flushing": true,
        "maximum_ram_size": 32768,
        "maximum_size": 262144,
        "native_usb": true,
        "offset_address": "0x0000",
        "protocol": "sam-ba",
        "protocols": [
            "sam-ba",
            "blackmagic",
            "jlink",
            "atmel-ice"
        ],
        "require_upload_port": true,
        "use_1200bps_touch": true,
        "wait_for_upload_port": true
    },
    "url": "https://www.adafruit.com/product/2772",
    "vendor": "Adafruit"
}

This JSON is the same as the standard Feather M0 board profile, except upload.offset_address and build.arduino.ldscript were changed to place your program where the bootloader would normally be. To use this file, save it as adafruit_feather_m0_no_bootloader.json under a boards directory in your PlatformIO project, then edit your platformio.ini to reference it:

[env:your_env]
...
board = adafruit_feather_m0_no_bootloader
...

PlatformIO will now compile and upload your project assuming that there is no bootloader present. Note that this means PlatformIO will overwrite the bootloader on your Feather M0 upon upload: as a result you will only be able to program your Feather via an external debugger going forward (though you can always put the bootloader back by following the instructions in my previous post).

Once I implemented the fix above, the only other modification I needed to make was to ensure that I didn’t interrupt Serial when it was establishing a connection to the serial monitor:

...
void setup() {
  // Don't put any breakpoints on the following code
  Serial.begin(115200);
  while(!Serial) 
    yield(); // make sure to call `yield()` here, otherwise the device will hang forever
  ... // Now that the connection to the serial monitor is established, we can proceed as usual
}
...

With those two modifications I was able to get debugging and the serial monitor to function normally.

6 Likes