Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
  • dice
2 results

README.md

Blame
  • Yonder D51

    The ATSAMD51 is an ARM Cortex-M4F microcontroller manufactured by Microchip (Atmel).

    As of Oct 13 2019, -> CBA ❤️ D51 <-

    Circuits using the D51

    feather m4 pic Adafruit Feather M4

    module pic squidworks module

    Toolchains

    Adafruit Bootloader / Platformio (or Arduino Compatible)

    Since Adafruit has adopted the SAMD51, it is well supported by the open source community, and we can borrow their development tools.

    fair warning

    Use of the arduino bootloader does assume that your circuit has a USB port available, as well as a 32.678kHz clock on the RTC Xout / Xin pins. During cycles, the bootloader (assuming it is on a Feather M4) will toggle 'D13' (PA23) as well as send Neopixel Data to (?).

    To get started, find the latest build of the adafruit bootloader and download that (probably a .bin or .elf or .hex file). The Adafruit Feather M4 uses the SAMD51J19A, so grab that one for the current generation squidworks module.

    We need to write this file into the micro's memory. I have been using the Serial Wire Debug interface, which is enabled by default on the D51 hardware (but JTAG is also available, but requires an enable pin pulled low somewhere I think). SWCLK is on PA30 and SWDIO is on PA31.

    To speak SWD, I just use the Atmel-Ice programmer, and Atmel Studio 7 (a windows application, sorry). Any programmer that speaks SWD should be capable of doing this. In Atmel Studio, go to Tools -> Device Programming, and select the Atmel-Ice Tool, the ATSAMD51xxxx device you'd like to program (the bootloader is written for the ATSAMD51J19A), and the SWD interface. You should be able to read the device signature. If this works, your SWD connection is all super-gucci (as they say). You can navigate to Memories - and write that bootloader in. OK. The device should now enumerate over USB as an Adafruit Feather M4 / FeatherBoot (or something similar).

    Platformio

    To write code and load it, I use PlatformIO, which is an open source 'IOT' (embedded) programming tool written as a package for either atom code-editor, or vscode. See their doc for setting up a new project for the D51 / Feather M4.

    Real Registers in an Arduino World

    One of the troubles with Arduino is that people forget that it is just a big C++ library. This means that everything under the sun (that compiles) is legal here. That means that we can use Arduino as a crutch, but write really nice Special Function Register code inside of the same executable. Great!

    Indeed, in the PlatformIO environment, we even have wonderful autocomplete handles on the D51's core register map. For some examples of this kind of manipulation, check out the hunks in the ponyo project.

    Bare Metal development

    Okay, bare-ish metal development. If you want to work with the SAMD51 using the command line, a text editor, Makefiles, and a few open-source tools, it's possible to do so with a bit of setup. You should use Linux to do this work; your mileage may vary on other operating systems.

    Credit to Alex Kaspar for sorting through openocd setup in 2018. These instructions build on that work.

    First, install openocd. Until recently, this tool didn't officially support the SAMD51 series, requiring the use of a patch and manual compilation to work with the chipset. According to the patch notes, the patch was merged in early 2019 so the standard installation should work fine. Put the program in directory such as ~/openocd. If you're building from source, navigate to this directory and run:

    ./bootstrap
    ./configure --enable-cmsis-dap
    make
    make install

    Second, install a handful of other helpful tools. Depending on your other work you may already have many of these on your machine:

    sudo apt install autoconf build-essential cmake gdb-arm-none-eabi libtool libtool-bin libhidapi-dev libusb-dev libusb-1.0-0-dev pkg-config

    Third, clone this repo. Navigate to the baremetal directory and run make. You should see something like this result:

    zach@crudite:~/Documents/atsamd51/baremetal$ make
    Building file: main.c
    ARM/GNU C Compiler
    "arm-none-eabi-gcc" -x c -DDEBUG -Os -ffunction-sections -g3 -Wall -c -std=gnu99 -mthumb -mabi=aapcs-linux -mlong-calls -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -DSAMD51 -D__SAMD51J19A__ -I"samd51" -I"samd51/CMSIS/Include" -I"samd51/include" -I"samd51/startup" \
    -MD -MP -MF "main.d" -MT"main.d" -MT"main.o"  -o "main.o" "main.c"
    Finished building: main.c
    Building file: samd51/startup/system_samd51.c
    ARM/GNU C Compiler
    "arm-none-eabi-gcc" -x c -DDEBUG -Os -ffunction-sections -g3 -Wall -c -std=gnu99 -mthumb -mabi=aapcs-linux -mlong-calls -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -DSAMD51 -D__SAMD51J19A__ -I"samd51" -I"samd51/CMSIS/Include" -I"samd51/include" -I"samd51/startup" \
    -MD -MP -MF "samd51/startup/system_samd51.d" -MT"samd51/startup/system_samd51.d" -MT"samd51/startup/system_samd51.o"  -o "samd51/startup/system_samd51.o" "samd51/startup/system_samd51.c"
    Finished building: samd51/startup/system_samd51.c
    Building file: samd51/startup/startup_samd51.c
    ARM/GNU C Compiler
    "arm-none-eabi-gcc" -x c -DDEBUG -Os -ffunction-sections -g3 -Wall -c -std=gnu99 -mthumb -mabi=aapcs-linux -mlong-calls -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -DSAMD51 -D__SAMD51J19A__ -I"samd51" -I"samd51/CMSIS/Include" -I"samd51/include" -I"samd51/startup" \
    -MD -MP -MF "samd51/startup/startup_samd51.d" -MT"samd51/startup/startup_samd51.d" -MT"samd51/startup/startup_samd51.o"  -o "samd51/startup/startup_samd51.o" "samd51/startup/startup_samd51.c"
    Finished building: samd51/startup/startup_samd51.c
    Building target: main.elf
    Invoking: ARM/GNU Linker
    "arm-none-eabi-gcc" -o main.elf main.o samd51/startup/system_samd51.o samd51/startup/startup_samd51.o  -Wl,--start-group -lm -Wl,--end-group -mthumb -mabi=aapcs-linux -mlong-calls -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -DSAMD51 \
    -Wl,-Map="main.map" --specs=nano.specs -Wl,--gc-sections \
     \
     \
    -T"samd51/startup/samd51j19a_flash.ld" \
    -L"samd51/startup"
    /usr/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld: warning: main.o uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail
    /usr/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld: warning: samd51/startup/system_samd51.o uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail
    /usr/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld: warning: samd51/startup/startup_samd51.o uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail
    Finished building target: main.elf
    "arm-none-eabi-objcopy" -O binary "main.elf" "main.bin"
    "arm-none-eabi-objcopy" -O ihex -R .eeprom -R .fuse -R .lock -R .signature  \
            "main.elf" "main.hex"
    "arm-none-eabi-objcopy" -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma \
            .eeprom=0 --no-change-warnings -O binary "main.elf" \
            "main.eep" || exit 0
    "arm-none-eabi-objdump" -h -S "main.elf" > "main.lss"
    "arm-none-eabi-size" "main.elf"
       text	   data	    bss	    dec	    hex	filename
        968	      0	  49184	  50152	   c3e8	main.elf
    Deleting intermediate files...
    rm -f main.o samd51/startup/system_samd51.o samd51/startup/startup_samd51.o
    rm -f main.d samd51/startup/system_samd51.d samd51/startup/startup_samd51.d
    rm -f main.a main.hex main.bin \
    	main.lss main.eep main.map \
    	main.srec

    Errors are not uncommon and are usually related to the directory structure of the Makefile. However, this repo includes all of the required SAMD51 libraries (from Atmel/Microchip's ASF4 framework, as shared by Adafruit), so if you grabbed the entire repo you should be fine. Post an issue if it doesn't work. Note one modification to the Makefile is that it deletes all the intermediate files (.o, .eep, etc) after producing the .elf file. If you want them, remove the lines in the Makefile after the phrase 'Deleting intermediate files...'.

    Fourth, after you have your .elf file (in this case main.elf), connect your target board to power and an Atmel ICE programmer (make sure you use the correct pinout and the SAM port!) and run openocd. You should see the following:

    zach@crudite:~/Documents/atsamd51/baremetal$ openocd
    Open On-Chip Debugger 0.10.0+dev-00409-g1ae106de-dirty (2019-10-14-20:41)
    Licensed under GNU GPL v2
    For bug reports, read
    	http://openocd.org/doc/doxygen/bugs.html
    none separate
    adapter speed: 400 kHz
    cortex_m reset_config sysresetreq
    Info : Listening on port 6666 for tcl connections
    Info : Listening on port 4444 for telnet connections
    Info : CMSIS-DAP: SWD  Supported
    Info : CMSIS-DAP: JTAG Supported
    Info : CMSIS-DAP: Interface Initialised (SWD)
    Info : CMSIS-DAP: FW Version = 1.0
    Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 1 nTRST = 0 nRESET = 1
    Info : CMSIS-DAP: Interface ready
    Info : clock speed 400 kHz
    Info : SWD DPIDR 0x2ba01477
    Info : at91samd51j18.cpu: hardware has 6 breakpoints, 4 watchpoints
    Info : Listening on port 3333 for gdb connections

    If you see Error: unable to open CMSIS-DAP device 0x3eb:0x2141, it probably means openocd needs root privileges to access the programmer. You could run sudo openocd, but a better solution is to follow the instructions here to create a new rule. Don't forget to restart udev after doing this with sudo udevadm trigger.

    Fifth, now that openocd is running, open a second terminal window and type arm-none-eabi-gdb main.elf. When gdb opens, type tar ext :3333 (a shortcut for target extended-remote :3333), then load. This should flash the microcontroller with the new code, at which point you can exit gdb with quit and y. In the openocd window, close the connection with Ctrl-C. If you're flashing one of Jake's moduleboards, the red and green LEDs should blink.