How to find upload_protocol for this samd21g18a board?

I’d like to be able program this 5G-NB-IoT board with PlatformIO but I can’t work out the upload_protocol, can someone here help?

It has a custom boards manager for the Arduino IDE and flashing it with verbose upload on in the Arduino IDE shows:

Sketch uses 26448 bytes (10%) of program storage space. Maximum is 262144 bytes.
Forcing reset using 1200bps open/close on port COM26
PORTS {COM19, COM22, COM26, } / {COM19, COM22, COM26, } => {}
PORTS {COM19, COM22, COM26, } / {COM19, COM22, COM26, } => {}
PORTS {COM19, COM22, COM26, } / {COM19, COM22, COM26, COM28, } => {COM28, }
Found upload port: COM28
C:\Arduino\arduino-1.8.19\portable\packages\arduino\tools\bossac\1.7.0/bossac.exe -i -d --port=COM28 -U true -i -e -w -v C:\Users\tornt\AppData\Local\Temp\arduino_build_662860/HttpClient.ino.bin -R 
Set binary mode
readWord(addr=0)=0x20007ffc
readWord(addr=0xe000ed00)=0x410cc601
readWord(addr=0x41002018)=0x10010305
version()=v2.0 [Arduino:XYZ] Apr  6 2019 12:17:49
chipId=0x10010005
Connected at 921600 baud
readWord(addr=0)=0x20007ffc
readWord(addr=0xe000ed00)=0x410cc601
readWord(addr=0x41002018)=0x10010305
Atmel SMART device 0x10010005 found
write(addr=0x20004000,size=0x34)
writeWord(addr=0x20004030,value=0x10)
writeWord(addr=0x20004020,value=0x20008000)
Device       : ATSAMD21G18A
readWord(addr=0)=0x20007ffc
readWord(addr=0xe000ed00)=0x410cc601
readWord(addr=0x41002018)=0x10010305
Chip ID      : 10010005
version()=v2.0 [Arduino:XYZ] Apr  6 2019 12:17:49
Version      : v2.0 [Arduino:XYZ] Apr  6 2019 12:17:49
Address      : 8192
Pages        : 3968
Page Size    : 64 bytes
Total Size   : 248KB

So what can I try in the platformio.ini file:

[env:5gnbiot]
platform = atmelsam
board = samd21g18a

framework = arduino
monitor_speed = 115200
upload_protocol = ???

The upload protocol is sam-ba as e.g. referenced in

Since however samd21g18a.json does not have that in its array of possible upload protocols

You can’t use upload_protocol = sam-ba with it (without modifying the file).

Looking at their custom arduino core at https://raw.githubusercontent.com/5ghub/5G-NB-IoT/master/package_5G-NB-IoT_index.json suggests they just use a Arduino Zero, didn’t even rename the board variatn folder.

Can you just try using board = zeroUSB instead?

An issue for integration with the originally intended modded Arduino core and board is open at Support 5G-NB-IoT Board · Issue #186 · platformio/platform-atmelsam · GitHub.

I’m probably doing something wrong but when i try board = zeroUSB i get “Warning! Unknown upload protocol ???”:

Processing 5gnbiot (platform: atmelsam; board: zeroUSB; framework: arduino)
------------------------------------------------------------------------------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelsam/zeroUSB.html
PLATFORM: Atmel SAM (7.1.0) > Arduino Zero (USB Native Port)
HARDWARE: SAMD21G18A 48MHz, 32KB RAM, 256KB Flash
DEBUG: Current (atmel-ice) External (atmel-ice, blackmagic, jlink)
PACKAGES:
 - framework-arduino-samd 1.8.11
 - framework-cmsis 1.40500.0 (4.5.0)
 - framework-cmsis-atmel 1.2.2
 - tool-openocd 2.1100.211028 (11.0)
 - toolchain-gccarmnoneeabi 1.70201.0 (7.2.1)
Converting main.ino
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 18 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <TinyGSM> 0.11.5
|-- <StreamDebugger> 1.0.1
Building in release mode
Warning! Unknown upload protocol ???

You have to remove this line

Right yes. Sorry.

So yes that works and it successfuly flashes the board.

Tests don’t run though and hangs forever:

> Executing task: C:\Users\tornt\.platformio\penv\Scripts\platformio.exe test <

Verbose mode can be enabled via `-v, --verbose` option
Collected 1 items

Processing * in 5gnbiot environment
--------------------------------------------------------------------------------------------------------------------------------------------------Building...
Uploading...
Testing...
If you don't see any output for the first 10 secs, please reset board (press reset button)

Any ideas about that?

Boards where the USB serial is implemented by the target chip and is thus is “unstable” in the sense that after flashing it ejects the USB serial device and gets connected after a time needs special care. The first one is while(!Serial){} as the first line in setup() to prevent anything being sent before the serial monitor is opened, second, a delay per point 3 in Redirecting... and before attempting to open the serial monitor, see Teensy 4.1 Unit Testing Issue - #5 by maxgerhardt for the technique.

But on a more basic level, did you test that Serial outputs something in the main firmware before trying to test? Pin mappings might be different.

Mmm, Serial on its own doesn’t output anything so this doesn’t output anything to a terminal:

void setup() {
  Serial.begin(115200);
  while(!Serial);
  Serial.println("setup");
}

It looks like its SerialUSB instead, so this works in main:

#define Serial SerialUSB

void setup() {
  Serial.begin(115200);
  while(!Serial);
  Serial.println("setup");
}

But adding that #define Serial SerialUSB in test_main.cpp doesn’t fix the tests to run. And adding those delays in extra_script.py and the start of the test_main.cpp setup don’t help either.

Then the board can’t be treated as a pin-compatible Arduino Zero and the issue needs to be resolved by actually using their modified arduino core + variant. I’ll have a look at it.

Yes it doesn’t seem quite compatible - this is another sketch that works when running in the Arduino IDE but doesn’t work from main in PlatformIO - in the Arduino IDE it does power on the cellular modem which then after a moment outputs RDY on the serial port and then will respond to AT commands, but from PlatformIO no RDY and no response:

#include <Arduino.h>

void setup() {
  Serial1.begin(115200);
  SerialUSB.begin(115200);
  while(!SerialUSB);
  SerialUSB.println("setup");

  initModem();

  SerialUSB.println("setup ok");
}

#define POWKEY_PIN  4
#define RESET_PIN   3

void initModem() {
  pinMode(RESET_PIN, OUTPUT);
  digitalWrite(RESET_PIN, LOW); 

  pinMode(POWKEY_PIN, OUTPUT);
  digitalWrite(POWKEY_PIN, LOW);
  delay(800);
  digitalWrite(POWKEY_PIN, HIGH);
  delay(800);
  digitalWrite(POWKEY_PIN, LOW);
}

void loop() {
  if (Serial1.available()) {
    SerialUSB.write(Serial1.read());
  }

  if (SerialUSB.available()) {
    Serial1.write(SerialUSB.read());
  }
}

BTY, thanks so much for your help

I’ve adapted platform-atmelsam. Please try the example GitHub - maxgerhardt/pio-5g-nbiot: PlatformIO example of using the 5G NB-IOT board.. Does it blink the two LEDs and prints stuff over the USB serial? If yes, try the more complicated sketch 5G-NB-IoT/GNSS.ino at master · 5ghub/5G-NB-IoT · GitHub.

Yes that works and blinky outputs text and flashes the LEDs, and the more complicated sketch can talk to the modem and get GPS output.

Great, thank you!

I still can’t get Unity tests to work though and they just hang. It feels like maybe there is just somewhere else I need to configure serial to be SerialUSB. Any ideas?

Turns out if I add test_transport = custom to platformio.ini and then have a unittest_transport.h as below in the test directory then it all works. So great (though it would be nicer if it didn’t need the custom transport).

unittest_transport.h:

#ifndef UNITTEST_TRANSPORT_H
#define UNITTEST_TRANSPORT_H

#include <Arduino.h>

#define TESTING_SERIAL SerialUSB

void unittest_uart_begin() {
    TESTING_SERIAL.begin(115200);
    while(!TESTING_SERIAL){} 
}

void unittest_uart_putchar(char c) {
    TESTING_SERIAL.print(c);
}

void unittest_uart_flush() {
    TESTING_SERIAL.flush();
}

void unittest_uart_end() {
}

#endif

That’s because PlatformIO, with no test_transport explicitly set, defaults to using Serial as the unit testing serial ,not SerialUSB – sadly this is non-configurable and everything else needs the custom transport protocol. That could actually be improved by letting the user specify the serial object…

Great! I’ll try and push these extensions to mainline platformio/platform-atmelsam then.

PR is open in Add 5G-NB-IoT Board + Arduino Core Support by maxgerhardt · Pull Request #187 · platformio/platform-atmelsam · GitHub.

Also open in Allow Serial object configurability for unit tests · Issue #4233 · platformio/platformio-core · GitHub.

Please upgrade to the PlatformIO Core 6.0 (pio upgrade --dev) and implement your own unity_config. See docs Unity — PlatformIO latest documentation

That breaks things for me and the build fails with lots of errors:

c:/users/tornt/.platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: C:\Users\tornt\.platformio\packages\framework-arduinoespressif32\tools\sdk\esp32\lib\libunity.a(unity.c.obj):/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/unity/unity/src/unity.c:56: multiple definition of UnityStrErrFloat’; .pio\build\ql-uecc\libe4e\libUnity.a(unity.c.o):C:\CQ\quarklink-client/.pio/libdeps/ql-uecc/Unity/src/unity.c:61: first defined here`

Now hunting aorund for how to go back to the non-dev version of platformio…