SoftwareSerial does not compile with XIAO nRF52840

Hi, I’m using XIAO nRF52840pinout ; with the following platformi.ini config:

[env]
framework = arduino
platform = nordicnrf52

[env:xiaoble_arduinocore_mbed]
platform = https://github.com/maxgerhardt/platform-nordicnrf52
board = xiaoble
lib_deps = 
	adafruit/Adafruit GFX Library@^1.11.9
	adafruit/Adafruit LED Backpack Library@^1.5.0
	adafruit/Adafruit BusIO@^1.15.0
	featherfly/SoftwareSerial@^1.0

Only including the library results in the compile error as seen below:

#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>
#include <SoftwareSerial.h>

void setup() {
   // code
}

void loop() {
   // code
}

Compilation errors:

.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:285:2: error: #error This version of SoftwareSerial supports only 20, 16 and 8MHz processors
 #error This version of SoftwareSerial supports only 20, 16 and 8MHz processors
  ^~~~~
Compiling .pio\build\xiaoble_arduinocore_mbed\FrameworkArduino\USB\USBCDC.cpp.o
Compiling .pio\build\xiaoble_arduinocore_mbed\FrameworkArduino\USB\USBSerial.cpp.o
Compiling .pio\build\xiaoble_arduinocore_mbed\FrameworkArduino\WMath.cpp.o
Compiling .pio\build\xiaoble_arduinocore_mbed\FrameworkArduino\abi.cpp.o
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp: In member function 'bool SoftwareSerial::listen()':
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:341:23: error: 'SREG' was not declared in this scope
     uint8_t oldSREG = SREG;
                       ^~~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:341:23: note: suggested alternative: 'SING'
     uint8_t oldSREG = SREG;
                       ^~~~
                       SING
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:342:5: error: 'cli' was not declared in this scope
     cli();
     ^~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp: In member function 'void SoftwareSerial::setTX(uint8_t)':
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:516:22: error: 'digitalPinToBitMask' was not declared in this scope
   _transmitBitMask = digitalPinToBitMask(tx);
                      ^~~~~~~~~~~~~~~~~~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:516:22: note: suggested alternative: 'digitalPinToPinName'
   _transmitBitMask = digitalPinToBitMask(tx);
                      ^~~~~~~~~~~~~~~~~~~
                      digitalPinToPinName
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:518:27: error: 'portOutputRegister' was not declared in this scope
   _transmitPortRegister = portOutputRegister(port);
                           ^~~~~~~~~~~~~~~~~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:518:27: note: suggested alternative: '_transmitPortRegister'
   _transmitPortRegister = portOutputRegister(port);
                           ^~~~~~~~~~~~~~~~~~
                           _transmitPortRegister
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp: In member function 'void SoftwareSerial::setRX(uint8_t)':
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:527:21: error: 'digitalPinToBitMask' was not declared in this scope
   _receiveBitMask = digitalPinToBitMask(rx);
                     ^~~~~~~~~~~~~~~~~~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:527:21: note: suggested alternative: 'digitalPinToPinName'
   _receiveBitMask = digitalPinToBitMask(rx);
                     ^~~~~~~~~~~~~~~~~~~
                     digitalPinToPinName
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:529:26: error: 'portInputRegister' was not declared in this scope
   _receivePortRegister = portInputRegister(port);
                          ^~~~~~~~~~~~~~~~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp: In member function 'void SoftwareSerial::begin(long int)':
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:540:31: error: 'table' was not declared in this scope
   for (unsigned i=0; i<sizeof(table)/sizeof(table[0]); ++i)
                               ^~~~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:540:31: note: suggested alternative: 'tanl'
   for (unsigned i=0; i<sizeof(table)/sizeof(table[0]); ++i)
                               ^~~~~
                               tanl
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:556:9: error: 'digitalPinToPCICR' was not declared in this scope
     if (digitalPinToPCICR(_receivePin))
         ^~~~~~~~~~~~~~~~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:556:9: note: suggested alternative: 'digitalPinToPort'
     if (digitalPinToPCICR(_receivePin))
         ^~~~~~~~~~~~~~~~~
         digitalPinToPort
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:558:46: error: 'digitalPinToPCICRbit' was not declared in this scope
       *digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
                                              ^~~~~~~~~~~~~~~~~~~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:558:46: note: suggested alternative: 'digitalPinToPort'
       *digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
                                              ^~~~~~~~~~~~~~~~~~~~
                                              digitalPinToPort
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:558:42: error: '_BV' was not declared in this scope
       *digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
                                          ^~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:559:8: error: 'digitalPinToPCMSK' was not declared in this scope
       *digitalPinToPCMSK(_receivePin) |= _BV(digitalPinToPCMSKbit(_receivePin));
        ^~~~~~~~~~~~~~~~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:559:8: note: suggested alternative: 'digitalPinToPort'
       *digitalPinToPCMSK(_receivePin) |= _BV(digitalPinToPCMSKbit(_receivePin));
        ^~~~~~~~~~~~~~~~~
        digitalPinToPort
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:559:46: error: 'digitalPinToPCMSKbit' was not declared in this scope
       *digitalPinToPCMSK(_receivePin) |= _BV(digitalPinToPCMSKbit(_receivePin));
                                              ^~~~~~~~~~~~~~~~~~~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:559:46: note: suggested alternative: 'digitalPinToPort'
       *digitalPinToPCMSK(_receivePin) |= _BV(digitalPinToPCMSKbit(_receivePin));
                                              ^~~~~~~~~~~~~~~~~~~~
                                              digitalPinToPort
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp: In member function 'void SoftwareSerial::end()':
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:574:7: error: 'digitalPinToPCMSK' was not declared in this scope
   if (digitalPinToPCMSK(_receivePin))
       ^~~~~~~~~~~~~~~~~
Compiling .pio\build\xiaoble_arduinocore_mbed\FrameworkArduino\api\Common.cpp.o
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:574:7: note: suggested alternative: 'digitalPinToPort'
   if (digitalPinToPCMSK(_receivePin))
       ^~~~~~~~~~~~~~~~~
       digitalPinToPort
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:575:45: error: 'digitalPinToPCMSKbit' was not declared in this scope
     *digitalPinToPCMSK(_receivePin) &= ~_BV(digitalPinToPCMSKbit(_receivePin));
                                             ^~~~~~~~~~~~~~~~~~~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:575:45: note: suggested alternative: 'digitalPinToPort'
     *digitalPinToPCMSK(_receivePin) &= ~_BV(digitalPinToPCMSKbit(_receivePin));
                                             ^~~~~~~~~~~~~~~~~~~~
                                             digitalPinToPort
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:575:41: error: '_BV' was not declared in this scope
     *digitalPinToPCMSK(_receivePin) &= ~_BV(digitalPinToPCMSKbit(_receivePin));
                                         ^~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp: In member function 'virtual size_t SoftwareSerial::write(uint8_t)':
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:610:21: error: 'SREG' was not declared in this scope
   uint8_t oldSREG = SREG;
                     ^~~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:610:21: note: suggested alternative: 'SING'
   uint8_t oldSREG = SREG;
                     ^~~~
                     SING
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:611:3: error: 'cli' was not declared in this scope
   cli();  // turn off interrupts for a clean txmit
   ^~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:615:26: error: 'XMIT_START_ADJUSTMENT' was not declared in this scope
   tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT);
                          ^~~~~~~~~~~~~~~~~~~~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp: In member function 'virtual void SoftwareSerial::flush()':
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:658:21: error: 'SREG' was not declared in this scope
   uint8_t oldSREG = SREG;
                     ^~~~
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:658:21: note: suggested alternative: 'SING'
   uint8_t oldSREG = SREG;
                     ^~~~
                     SING
.pio\libdeps\xiaoble_arduinocore_mbed\SoftwareSerial\SoftwareSerial.cpp:659:3: error: 'cli' was not declared in this scope
   cli();
   ^~~
Compiling .pio\build\xiaoble_arduinocore_mbed\FrameworkArduino\api\IPAddress.cpp.o
*** [.pio\build\xiaoble_arduinocore_mbed\libee8\SoftwareSerial\SoftwareSerial.cpp.o] Error 1

There are HW TX+RX ports, however these require to set the device into undesireable modes (for my usecase)

I’m just wondering whether somebody encountered this issue (and solved it) as I’ve browsed nearly half of the internet and tried nearly every “alternative” under the sun. I’ve tried porting the library for my board, however I’m starting out with embedded and was unable to complete it with my current knowledge (and I don’t have enough time for porting it rn).

Any help would be appreciated!

That’s for AVR processors. This library is expected to not compile for nRF52.

If the Arduino core won’t provide a SoftwareSerial library, you may need to look for external ones that support nRF52, such as https://github.com/micooke/SoftwareSerial, https://github.com/adafruit/Adafruit_nRF52_Arduino/tree/master/libraries/SoftwareSerial, etc., or use the the other Arduino core instead.

That seems very weird. You want to use an inferior softwareserial on hardware-UART capable pins? Serial1 should access those UART pins just fine.

Hi, thanks for your responses!

You’re right, Serial1 should access those UART pins, however after some testing, it does not. I’ve written a code using SoftwareSerial and tested it on my secondary board (Arduino uno) and everything worked as expected (board communicating with 3d device). Then I connected it to my XIAO the same way I did to my Arduino with the same code (used Serial1 instead of SoftwareSerial tho) however the 3d device does not receive the commands. I even tried connecting rx-rx;tx-tx just to make sure that I didn’t wire it incorrectly. I’ve also tried setting the build_flags, but I was unable to get it working

build_flags = 
    -D PIN_SERIAL1_RX=7
    -D PIN_SERIAL1_TX=6

I’ve even tried measuring the pin output using a multimeter during the period where there should be writes to the 3d device, however the pin (rx – or D7 on the board) stayed inactive.

After browsing the docs it seems that UART is only available if I don’t use the USB communication, ref:

So, SoftwareSerial is my best bet atm :confused:. The Adafruit_nRF52 Arduino core you linked looks very promising, however I was unable to integrate it into my paltformio.ini… Could you please guide me through the process of integrating it?

EDIT:
Hi, sorry, I am officially the dumbest person alive lol :smiley: … sooo, what happened is:

  1. I went again to read the docs to found out that UART pins CAN be used concurrently with USB
  2. Then I noticed I’m using non-standard baudrate of 115000 instead of 115200
  3. I changed the baudrate to standard and everything works correctly. (for some reason the non-standard still seems to work on an Arduino tho)

I’m still wondering about the part where I measured the pin output (with a multimeter) and it was not changing when there should have been writes tho. Does the board ignore writes when the baudrate is set to a non-standard?

Anyways, thanks for (and sorry for wasting) your time!

It would be weird if so, I think it will have some troubles though to generate a suitable UART clock that has an acceptable amount of error if the main clock cannot be divided cleanly to get the 11500 clock. You would have to check with a logic analyer (e.g. cheap Salae logic clone) to see what exactly is being output at the TX pin. I am willing to bet it’s not “nothing”, but at least some UART signal. If it’s nothing, the core has a bug.

Hm, ok, will finish this project and then measure it in a more “controlled” environment and let you know.

Hey, just to give a closure, I’ve re-measured the output of the TX pin and it seems that I must have made an error somewhere before, because everything behaves as expected.