SAMD51 Multiple Serial [SOLVED]

Hello,
I am starting a project that is very COMM heavy. I need SPI, I2C, and 2 Uarts. I am using the Feather M4 Express board from Adafruit Adafruit Feather M4 Express.

I am trying to use the defaults:
I2C (Pin 17/18:SDA/SCL)
SPI (Pin 11/12/13:SCK/MOSI/MISO)
Serail1 (PIN 14/15:RX/TX)

and I would like Serial2 (Pin 22/23:D10/D11)

I have tried to follow the example at Creating a new Serial by Adafruit, but I have no luck.

my code is:

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

#define PIN_SERIAL2_RX 11  // PA21 Pin 23
#define PAD_SERIAL2_RX (SERCOM_RX_PAD_3)
#define PIN_SERIAL2_TX 10  // PA20 Pin 22
#define PAD_SERIAL2_TX (UART_TX_PAD_2)

Uart Serial2( &sercom3, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX );



void SERCOM3_0_Handler()
{
  Serial2.IrqHandler();
}
void SERCOM3_1_Handler()
{
  Serial2.IrqHandler();
}
void SERCOM3_2_Handler()
{
  Serial2.IrqHandler();
}
void SERCOM3_3_Handler()
{
  Serial2.IrqHandler();
}
void setup() {
  Serial.begin(115200);

  Serial2.begin(115200);
  
  // Assign pins 3 & 4 SERCOM functionality
  pinPeripheral(PIN_SERIAL2_RX, PIO_SERCOM_ALT);
  pinPeripheral(PIN_SERIAL2_TX, PIO_SERCOM_ALT);
}

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

}

the Hardware has a jumper between pin Pin 22/D10 and 23/D11.

I have run the example code on the webpage on a Feather M0 basic and works perfectly, but when I modify it for the M4 I get nothing back on Serial2, Just the counting up numbers on Serial.

Output:

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

as I get with the M0.

I can not see where I am going wrong. Just wondering if someone has any ideas?
Thanks for the help in advance.

Feather M0 basic and works perfectly, but when I modify it for the M4 I get nothing back on Serial2

The M4 has multiple interrupt vectors for each Serial port; you'll need to add them all, IIRC.
This has been discussed in the Adafruit forums.

The adafruit tutorial I was follow mentions that you needed to add 4 for the M4 and only 1 for the M0, and I did the 4 for the M4, but that did not work. Do you know where I can find more about the others (other than the 4 I added)?

Thanks

So after more testing I have noticed that the RX pin works, but the TX pin does not(UART can receive but not send) all the other example I got working use UART_TX_PAD_0 not UART_TX_PAD_2, could there be a bug in UART_TX_PAD_2?

Hi hippled,

So after more testing I have noticed that the RX pin works, but the TX pin does not(UART can receive but not send) all the other example I got working use UART_TX_PAD_0 not UART_TX_PAD_2, could there be a bug in UART_TX_PAD_2?

The SAMD51 found on the Feather M4 uses a similar SERCOM peripheral to the SAMD21, however the transmit pin options are less flexible (about the only thing that is on the SAMD51), in that you can only use SERCOM3/PAD0. This is the reason why your receive pin works, but your transmit doesn't.

You'll need to use a different pin for SERCOM3/PAD[0], such as digtial pin D12 on PA22. D12 requires the PIO_SERCOM argument for the pinPeripheral() function:

pinPeripheral(12, PIO_SERCOM);

Thank you so much for the answer and knowing it is not me, so I can stop pulling my hair out. I was wondering if you know where this is all documented. I will confess that if it is in the data sheet, I have not read it in it's entirety, or if this is just an arduino IDE thing.

Again thanks for the answer.

Hi hippled,

The SERCOM's USART output pads are determined by the RXPO and TXPO bitfields in CTRLA register, SAMD51 Datasheet, Section 34. Sercom USART.

The TXPO bitfield doesn't leave you with many transmit pin options, other than PAD[0]:

TXPO.png

TXPO.png

Thank you again , Very helpful.