SAMD51 multiple serial

Hi everyone,

I am trying to create multiple UARTs on an ItsyBitsy M4 board using the sercoms, but I cannot get it to work. I also searched this forum, but the given answers wont work either.

Here is my code (from the Adafruit Sercom Tutorial (link)

#include <Arduino.h>   // required before wiring_private.h
#include "wiring_private.h" // pinPeripheral() function

#define SERIAL2_RX 10
#define SERIAL2_TX 11

Uart Serial2 (&sercom1, SERIAL2_RX, SERIAL2_TX, SERCOM_RX_PAD_2, UART_TX_PAD_0); //rx, tx

void SERCOM1_0_Handler()
{
  Serial2.IrqHandler();
}
void SERCOM1_1_Handler()
{
  Serial2.IrqHandler();
}
void SERCOM1_2_Handler()
{
  Serial2.IrqHandler();
}
void SERCOM1_3_Handler()
{
  Serial2.IrqHandler();
}

void setup() {
  Serial1.begin(115200);
  Serial2.begin(115200);
  
  // Assign SERCOM functionality
  pinPeripheral(SERIAL2_RX, PIO_SERCOM);
  pinPeripheral(SERIAL2_TX, PIO_SERCOM);
}

uint8_t i=0;

void loop() {
  Serial1.print(i);
  Serial2.write(i++);
  if (Serial2.available()) {
    Serial1.print(" -> 0x"); Serial1.print(Serial2.read(), HEX);
  }
  Serial1.println();
  
  delay(1000);

}

There is a jumper between RX and TX on serial 2 (Pin D11 and D10).

The Output is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

where is should be:

1 -> 0x1
2 -> 0x2
3 -> 0x3
4 -> 0x4
5 -> 0x5
6 -> 0x6
7 -> 0x7
8 -> 0x8
9 -> 0x9
10 -> 0xA
11 -> 0xB
12 -> 0xC
13 -> 0xD
14 -> 0xE

Neither RX nor TX of Serial 2 work. Do you have an idea where my mistake is? Thanks alot for the help

@nerb12 The reason why it doesn't work is that on the SAMD51 the UART transmit pin needs be on SERCOM/PAD[0]. On the Itsy Bitsy M4, digital pins 10 and 11 use PAD[2] and PAD[3] respectively, on either SERCOM5 or SERCOM3. Both can only be used as receiver pins.

To determine the sercom and pads are available, use the Itsy Bitsy M4 schematic to find out which Arduino pin (D0, D1, etc...) is connected to which microcontroller port pin (PA00, PA01, etc...). The schematic can be found on Adafruit's website here: https://cdn-learn.adafruit.com/assets/assets/000/055/481/original/adafruit_products_schem.png?1529261754](https://cdn-learn.adafruit.com/assets/assets/000/055/481/original/adafruit_products_schem.png?1529261754.

Then cross reference this with the Multiplexed Signals table, section 6 in the SAMD51 datasheet to determine which sercom and pads are supported by the port pins in question.

Note that by default, the Itsy Bitsy M4 already uses SERCOM1, SERCOM2 and SERCOM3 for the SPI, I2C and Serial1 ports.

Here's an some example code for an additional serial port (Serial2) on pins A2 (Tx) and A3 (Rx):

#include "wiring_private.h"             // pinPeripheral() function

// Create Serial2 object
Uart Serial2 (&sercom4, A3, A2, SERCOM_RX_PAD_1, UART_TX_PAD_0);

void SERCOM4_0_Handler()                // Interrupt handler functions
{
  Serial2.IrqHandler();
}
void SERCOM4_1_Handler()
{
  Serial2.IrqHandler();
}
void SERCOM4_2_Handler()
{
  Serial2.IrqHandler();
}
void SERCOM4_3_Handler()
{
  Serial2.IrqHandler();
}
 
void setup() {
  Serial2.begin(115200);              // Open the Serial2 port at 115200 baud
 
  pinPeripheral(A2, PIO_SERCOM_ALT);  // Assign SERCOM functionality to A2
  pinPeripheral(A3, PIO_SERCOM_ALT);  // Assign SERCOM functionality to A3
}

void loop() {
  if (Serial2.available())            // Check if incoming data is available on A3
  {
    byte byteRead = Serial2.read();   // Read the most recent byte on A3
    Serial2.write(byteRead);          // Echo the byte back out on A2
  }
}

Thanks a lot Martin. I didnt think of checking the pinouts... Now everything works :slight_smile:

Pins 10 and 11 aren't usable for USART.
USART TX has to be PAD0 on SAMD51 (annoying quirk of the SAMD5x chips!)
Pins 10 and 11 are PA20 and PA21, which aren't connected to "sercom1"; they're either Sercom3 or Sercom5. Sercom3 is already in use for Serial1.
Sercom5 is fully available on Pins 10..13, but PAD0 is on pin13.
Sercom0 is available on Pins A1, A4, A5, D2 (PAD0 on A4.)
In theory, you could also re-purpose Sercom2 (I2C pins) or Sercom1 (SPI pins.)