Custom SAMD21E16L board disable USB for compiler

Hey there,

TL;DR Where to set up which internal libarys get compiled from PIO?

i started from the example from maxgerhardt to adopt for my board variant SAMD21E16L Project Github

My current probleme is that PIO fails to compile because it is trying to use USB libarys like USB-Host, CDC.,…
But this SAMD21 dont even feature any USB hardware support.
The gethered SAMD21E16l.h for CMSIS (not included in stardard CMSIS libary) therefor wont declare USB variables and thereby the USB library wont compile

Possible solution ideas, but I am not capable of for PIO

  1. Is there a compiler flag for platform.ini like -DCRYSTALLESS, but like -NO_USB
  2. Remove USB Libarys from Compiling Queue. → possible due to original board with USB support
  3. Remove “auto generated” USB Compile Flags from compile command:
-DUSBCON -DUSB_VID=0x239A -DUSB_PID=0x801E -DUSB_PRODUCT=\\\"false\\\" -DUSB_MANUFACTURER=\\\"Custom\\\"

I am not sure what I am missing here. Can someone help me out?
Thanks

Finn

The Arduino SAMD core implementation is playing against you here, since it has fundamentally no way of preventing some headers and code to be included in that reference USB stuff.

I went ahead and forked the Arduino core and just cleared out the files in the USB folder and removed two refererenced to the USB header and code in Arduino.h and main.cpp.

Also, in your repo you say

Copy the file samd21e16l.h provided in the project under /backup to C:\Users\xx\.platformio\packages\framework-cmsis-atmel\CMSIS\Device\ATMEL\samd21\include and C:\Users\xx\.platformio\packages\framework-cmsis-atmel\CMSIS\Device\ATMEL\samd21\include\pio

Which is wrong, the samd21e16l.h in the pio/ folder is different than the one in the folder above it – it contains only PIO infos. I’ve outlined at GitHub - maxgerhardt/atmel-cmsis-with-samd21e16l at how to copy those files correctly. The above repo is also directly the needed PlatformIO package that can be referenced in platform_packages.

If you change only your platformio.ini to

[env:custom_atsamd21e16l]
platform = atmelsam
board = custom_atsamd21e16l
framework = arduino
board_build.variants_dir = custom_arduino_variant
upload_protocol = jlink
debug_tool = jlink
; prevent unneccessary USB flags from being added
build_unflags = -DUSBCON
; use custom arduino core version with no USB support
platform_packages =
   framework-arduino-samd@https://github.com/maxgerhardt/ArduinoCore-samd.git
   framework-cmsis-atmel@https://github.com/maxgerhardt/atmel-cmsis-with-samd21e16l.git

it should compile file without having to locally modify any files at all.

>pio run
Processing custom_atsamd21e16l (platform: atmelsam; board: custom_atsamd21e16l; framework: arduino)
---------------------------------------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelsam/custom_atsamd21e16l.html
PLATFORM: Atmel SAM (6.2.0) > Custom ATSAMD21E16L Board
HARDWARE: SAMD21E16L 48MHz, 8KB RAM, 64KB Flash
DEBUG: Current (jlink) External (atmel-ice, blackmagic, jlink)
PACKAGES:
 - framework-arduino-samd 1.8.11+sha.ba3d760
 - framework-cmsis 1.40500.0 (4.5.0)
 - framework-cmsis-atmel 1.2.2+sha.09a423c
 - toolchain-gccarmnoneeabi 1.70201.0 (7.2.1)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 14 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Compiling .pio\build\custom_atsamd21e16l\src\main.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduinoVariant\variant.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\Reset.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\SERCOM.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\Tone.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\Uart.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\WInterrupts.c.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\WMath.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\abi.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\api\Common.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\api\IPAddress.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\api\PluggableUSB.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\api\Print.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\api\Stream.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\api\String.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\compact\dtostrf.c.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\cortex_handlers.c.o
Archiving .pio\build\custom_atsamd21e16l\libFrameworkArduinoVariant.a
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\delay.c.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\hooks.c.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\itoa.c.o
Indexing .pio\build\custom_atsamd21e16l\libFrameworkArduinoVariant.a
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\main.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\new.cpp.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\pulse.c.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\pulse_asm.S.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\startup.c.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\wiring.c.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\wiring_analog.c.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\wiring_digital.c.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\wiring_private.c.o
Compiling .pio\build\custom_atsamd21e16l\FrameworkArduino\wiring_shift.c.o
Archiving .pio\build\custom_atsamd21e16l\libFrameworkArduino.a
Indexing .pio\build\custom_atsamd21e16l\libFrameworkArduino.a
Linking .pio\build\custom_atsamd21e16l\firmware.elf
Checking size .pio\build\custom_atsamd21e16l\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [          ]   3.3% (used 268 bytes from 8192 bytes)
Flash: [=         ]   7.4% (used 4824 bytes from 65536 bytes)
Building .pio\build\custom_atsamd21e16l\firmware.bin
========================================================================================== [SUCCESS] Took 3.99 seconds ==========================================================================================

Does it work? No idea, I have no board.

1 Like

Correction, I forgot to push the actual commits to the Arduino core that remove the USB stuff. That is now done. You should remove C:\Users\<user>\.platformio\packages\framework-arduino-samd\ and rebuild to trigger the redownload.

Thanks maxgerhardt, that´s amazing and is helping me a lot.
After downloading git, it even downloaded the repo via your command :grinning:

The programm is compiling and updloading via JLink. The log below is overwriting the working programm from Microchip Studio

Executing task in folder pio-custom-samd21e16l-board: C:\Users\Finn\.platformio\penv\Scripts\platformio.exe run --target upload --environment custom_atsamd21e16l <

Processing custom_atsamd21e16l (platform: atmelsam; board: custom_atsamd21e16l; framework: arduino)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelsam/custom_atsamd21e16l.html
PLATFORM: Atmel SAM (6.3.1) > Custom ATSAMD21E16L Board       
HARDWARE: SAMD21E16L 48MHz, 8KB RAM, 64KB Flash
DEBUG: Current (jlink) External (atmel-ice, blackmagic, jlink)
PACKAGES:
 - framework-arduino-samd 1.8.11+sha.9acd6ee
 - framework-cmsis 1.40500.0 (4.5.0)
 - framework-cmsis-atmel 1.2.2+sha.09a423c
 - tool-jlink 1.75001.0 (7.50.1)
 - toolchain-gccarmnoneeabi 1.70201.0 (7.2.1)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 12 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Checking size .pio\build\custom_atsamd21e16l\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [          ]   3.3% (used 268 bytes from 8192 bytes)
Flash: [=         ]   7.4% (used 4860 bytes from 65536 bytes)
Configuring upload protocol...
AVAILABLE: atmel-ice, blackmagic, jlink, sam-ba
CURRENT: upload_protocol = jlink
Uploading .pio\build\custom_atsamd21e16l\firmware.bin
SEGGER J-Link Commander V7.50a (Compiled Jul  8 2021 18:18:11)
DLL version V7.50a, compiled Jul  8 2021 18:16:52


J-Link Command File read successfully.
Processing script file...

J-Link connection not established yet but required for command.
Connecting to J-Link via USB...O.K.
Firmware: J-Link EDU Mini V1 compiled Jul 23 2021 12:49:55
Hardware version: V1.00
S/N: xxxxxx700
License(s): FlashBP, GDB
VTref=3.292V
Target connection not established yet but required for command.
Device "ATSAMD21E16" selected.


Connecting to target via SWD
InitTarget() start
InitTarget()
InitTarget() end
Found SW-DP with ID 0x0BC11477
DPIDR: 0x0BC11477
Scanning AP map to find all available APs
AP[1]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x04770031)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0x41003000
CPUID register: 0x410CC601. Implementer code: 0x41 (ARM)
Found Cortex-M0 r0p1, Little endian.
FPUnit: 4 code (BP) slots and 0 literal slots
CoreSight components:
ROMTbl[0] @ 41003000
ROMTbl[0][0]: E00FF000, CID: B105100D, PID: 000BB4C0 ROM Table
ROMTbl[1] @ E00FF000
ROMTbl[1][0]: E000E000, CID: B105E00D, PID: 000BB008 SCS
ROMTbl[1][1]: E0001000, CID: B105E00D, PID: 000BB00A DWT
ROMTbl[1][2]: E0002000, CID: B105E00D, PID: 000BB00B FPB
ROMTbl[0][1]: 41006000, CID: B105900D, PID: 001BB932 MTB-M0+
Cortex-M0 identified.
PC = 00000200, CycleCnt = 00000000
R0 = 00000000, R1 = 00011A4C, R2 = 0000411B, R3 = 00000201
R4 = 00000000, R5 = 00008000, R6 = 200006B4, R7 = CEC23C99
R8 = C97E426F, R9 = 3F2AF72A, R10= CFB7B6A1, R11= 96A3BBB6
R12= 60000000
SP(R13)= 20000800, MSP= 20000800, PSP= 2456D758, R14(LR) = 000001D7
XPSR = 21000000: APSR = nzCvq, EPSR = 01000000, IPSR = 000 (NoException)
CFBP = 00000000, CONTROL = 00, FAULTMASK = 00, BASEPRI = 00, PRIMASK = 00
FPU regs: FPU not enabled / not implemented on connected CPU.

Downloading file [.pio\build\custom_atsamd21e16l\firmware.bin]...
Comparing flash   [100%] Done.
Erasing flash     [100%] Done.
Programming flash [100%] Done.
J-Link: Flash download: Bank 0 @ 0x00000000: 1 range affected (4864 bytes)
J-Link: Flash download: Total: 0.175s (Prepare: 0.059s, Compare: 0.011s, Erase: 0.008s, Program & Verify: 0.073s, Restore: 0.023s)
J-Link: Flash download: Program & Verify speed: 64 KiB/s
O.K.

Reset delay: 0 ms
Reset type NORMAL: Resets core & peripherals via SYSRESETREQ & VECTRESET bit.
ResetTarget() start
ResetTarget() end


Script processing completed.

=================================================================================== [SUCCESS] Took 3.01 seconds ===================================================================================

And if onced uploaded, skips new upload. Perfect :+1:

The new problem

The uploaded program wont execute the example code, because no led starts flashing.

Using the PIO Debugger I noticed that the Debugger wont break at my defined Breakpoints in my main.cpp and wont even trip at SAMD-Core main.cpp
If manual halting, the processor it is already at SAMD-Core cortec Handler at an infinity loop.

Possible solution ideas

  1. Under boards/custom_atsamd21e16l.json: I havent changed the hwids for my new µC. Is that a problem or is this this USB related/ where can i find them?
  2. Under boards/custom_atsamd21e16l.json: I havent changed the offset_adress for my µC.
  3. Is there a way to trigger the debugger automatically at the first executed code line. This should be without error and only later trigger the error handler?

Debugger Console Log

Processing custom_atsamd21e16l (platform: atmelsam; board: custom_atsamd21e16l; framework: arduino)
--------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelsam/custom_atsamd21e16l.html
PLATFORM: Atmel SAM (6.3.1) > Custom ATSAMD21E16L Board
HARDWARE: SAMD21E16L 48MHz, 8KB RAM, 64KB Flash
DEBUG: Current (jlink) External (atmel-ice, blackmagic, jlink)
PACKAGES:
 - framework-arduino-samd 1.8.11+sha.9acd6ee
 - framework-cmsis 1.40500.0 (4.5.0)
 - framework-cmsis-atmel 1.2.2+sha.09a423c
 - toolchain-gccarmnoneeabi 1.70201.0 (7.2.1)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 12 compatible libraries
Scanning dependencies...
No dependencies
Building in debug mode
Checking size .pio\build\custom_atsamd21e16l\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [          ]   3.3% (used 268 bytes from 8192 bytes)
Flash: [=         ]   8.4% (used 5496 bytes from 65536 bytes)
========================= [SUCCESS] Took 2.35 seconds =========================
SEGGER J-Link GDB Server V7.50a Command Line Version

JLinkARM.dll V7.50a (DLL compiled Jul  8 2021 18:16:52)

Command line: -singlerun -if SWD -select USB -device ATSAMD21E16 -port 2331
-----GDB Server start settings-----
GDBInit file:                  none
GDB Server Listening port:     2331
SWO raw output listening port: 2332
Terminal I/O port:             2333
Accept remote connection:      localhost only
Generate logfile:              off
Verify download:               off
Init regs on start:            off
Silent mode:                   off
Single run mode:               on
Target connection timeout:     0 ms
------J-Link related settings------
J-Link Host interface:         USB
J-Link script:                 none
J-Link settings file:          none
------Target related settings------
Target device:                 ATSAMD21E16
Target interface:              SWD
Target interface speed:        4000kHz
Target endian:                 little

Connecting to J-Link...
J-Link is connected.
Firmware: J-Link EDU Mini V1 compiled Jul 23 2021 12:49:55
Hardware: V1.00
S/N: xxxxxx700
Feature(s): FlashBP, GDB
Checking target voltage...
Target voltage: 3.29 V
Listening on TCP/IP port 2331
Connecting to target...
Connected to target
Waiting for GDB connection...
Reading symbols from C:\Users\Finn\Documents\GitHub\pio-custom-samd21e16l-board\.pio\build\custom_atsamd21e16l\firmware.elf...
done.
PlatformIO Unified Debugger -> http://bit.ly/pio-debug
PlatformIO: debug_tool = jlink
PlatformIO: Initializing remote target...
Connected to 127.0.0.1
Reading all registers
Read 4 bytes @ address 0x00000878 (Data = 0x0000E7FE)
Reading 64 bytes @ address 0x20003FC0
WARNING: Failed to read memory @ address 0x20003FC0
WARNING: Failed to read memory @ address 0x20003FEC
Reading 64 bytes @ address 0x20003FC0
WARNING: Failed to read memory @ address 0x20003FC0
WARNING: Failed to read memory @ address 0x20003FEC
Reading 64 bytes @ address 0x20003FC0
WARNING: Failed to read memory @ address 0x20003FC0
WARNING: Failed to read memory @ address 0x20003FEC
0x00000878 in Uart::write (this=0x200006ec, data=<optimized out>) at C:\Users\Finn\.platformio\packages\framework-arduino-samd\cores\arduino\Uart.cpp:180
180	      if (sercom->isDataRegisterEmptyUART()) {
Select auto target interface speed (2000 kHz)
Reading 64 bytes @ address 0x20003FC0
WARNING: Failed to read memory @ address 0x20003FC0
WARNING: Failed to read memory @ address 0x20003FEC
Received monitor command: clrbp
Received monitor command: speed auto
Select auto target interface speed (2000 kHz)
Received monitor command: reset
Resetting target
Loading section .text, size 0x1564 lma 0x0
Loading section .ramfunc, size 0x4c lma 0x1564
Loading section .data, size 0x14 lma 0x15b0
Resetting target
Received monitor command: halt
Halting target CPU...
...Target halted (PC = 0x00000890)
Downloading 5476 bytes @ address 0x00000000
Downloading 76 bytes @ address 0x00001564
Downloading 20 bytes @ address 0x000015B0
Start address 0x9a0, load size 5572
Transfer rate: 1360 KB/sec, 1857 bytes/write.
Temporary breakpoint 1 at 0xaf2: file C:\Users\Finn\.platformio\packages\framework-arduino-samd\cores\arduino\main.cpp, line 37.
PlatformIO: Initialization completed
Writing register (PC = 0x     9a0)
Read 4 bytes @ address 0x000009A0 (Data = 0x4A12B510)
Reading 64 bytes @ address 0x00000AC0
Read 2 bytes @ address 0x00000AF2 (Data = 0xF000)
Reading 64 bytes @ address 0x00000100
Read 2 bytes @ address 0x00000122 (Data = 0x2101)
Read 2 bytes @ address 0x00000122 (Data = 0x2101)
Read 2 bytes @ address 0x00000AF2 (Data = 0xF000)
Read 2 bytes @ address 0x00000AF2 (Data = 0xF000)
Reading register (MSP = 0x20004000)
Reading register (PSP = 0x2456D758)
Reading register (PRIMASK = 0x       0)
Reading register (BASEPRI = 0x       0)
Reading register (FAULTMASK = 0x       0)
Reading register (CONTROL = 0x       0)
PlatformIO: Resume the execution to `debug_init_break = tbreak main`
PlatformIO: More configuration options -> http://bit.ly/pio-debug
Setting breakpoint @ address 0x00000122, Size = 2, BPHandle = 0x0001
Setting breakpoint @ address 0x00000AF2, Size = 2, BPHandle = 0x0002
Starting target CPU...

Program
 received signal SIGTRAP, Trace/breakpoint trap.
Dummy_Handler () at C:\Users\Finn\.platformio\packages\framework-arduino-samd\cores\arduino\cortex_handlers.c:30
30	{
Debugger requested to halt target...
...Target halted (PC = 0x00000988)
Reading all registers
Removing breakpoint @ address 0x00000122, Size = 2
Removing breakpoint @ address 0x00000AF2, Size = 2
Read 4 bytes @ address 0x00000988 (Data = 0x0000E7FE)
Reading register (MSP = 0x20003FE0)
Reading register (PSP = 0x2456D758)
Reading register (PRIMASK = 0x       0)
Reading register (BASEPRI = 0x       0)
Reading register (FAULTMASK = 0x       0)
Reading register (CONTROL = 0x       0)
WARNING: Failed to read memory @ address 0x20003FFC
Reading 64 bytes @ address 0x20003FC0
WARNING: Failed to read memory @ address 0x20003FC0
WARNING: Failed to read memory @ address 0x20003FF8
Reading 64 bytes @ address 0x20003FC0
WARNING: Failed to read memory @ address 0x20003FC0
WARNING: Failed to read memory @ address 0x20003FF8

The HWIDs are only used by PlatformIO to either compile them back in as the VID/PID info or try and autodetect a USB device so that it can upload to it. It should not affect this error in any way.

Since you’ve also chosen the flash_without_bootloader.ld (which is good, since you’re flashing directly via JLink you don’t need a bootloader and controll all code running on it directly) I think the offset_address of 0x0 is correct.

The firmware has landed in

aka some interrupt handler which did not have an implementation and was thus mapped to the default handler which was designed to trigger the debug breakpoint. A hardfault could have been occurred, anything.

On the other hand, the output also shows

which looks to say that the chip was in the middle of executing some UART function.

You should try the following things:

debug_init_break = break Reset_Handler

to the platformio.ini and start debugging. You should land in the very first instruction of the firmware that is executed, stemming from the C implementation

use line-by-line (Step Into) debugging (and breakpoints + Continue at specific checkpoints, e.g. after loops) to see which parts it reaches and where it crashes.

Holdup –

the linker script in your new variant can’t be correct. Per https://www.microchip.com/en-us/product/ATSAMD21E16L the chip has 64K Flash and 8K RAM. The LENGTH fields in the linker script tell the compiler it has 128KByte of Flash and 16KByte of RAM. That can’t be right. The initial stack pointer will be pointing to invalid memory (since it’s initialized with RAM_START + RAM_LENGTH) and crash the whole MCU the moment it tries to do anything with the stack.

Correct that first before continuing.