Only One Serial Port?

From the data sheet for the SAM D21G, it looks like it supports up to six serial interfaces, so I'm curious as to why only one is supported in the IDE? It would be very useful to have access to more than 1 serial interface for some applications, especially when using devices like GPS modules, RF Modems, etc.

Wayne

Hi Wayne,

great idea, it should be possible to use SERCOM to obtain another spare UART I need to figure out what could be the correct combination of pin that didn't "interefere" with the current configuration.

(SPI, I2C and UART on the SAMD21 are all managed by a device called SERCOM, it's a quite complex device with a lot of different mux/configurations possible)

Can someone clarify this? It's my understanding that the SAMD21 offers 6 SERCOM interfaces which can be configured as I2C, USART, SPI or whatever. Is this functionality already available on the Arduino IDE? Will it ever be? How many of these six interfaces are readily free to use and not bounded to other purposes like EDGB communication/default SPI header/ default I2C pins?

Hi JMoro86,

SERCOM0 is for USART on pins 0/1 (Serial1)
SERCOM1 is free
SERCOM2 is free
SERCOM3 is for Wire
SERCOM4 is for SPI
SERCOM5 is for USART via EDBG (Serial)

I'm currently investigating if SERCOM1 or 2 are viable to be used as additional UARTS

Thank you cmaglie for the fast replay!

I was wondering if even if SERCOM0,3,4,5 are already taken for specific purposes would it still be possible to reconfigure them to other interfaces... after all it's just a matter of pinout, isn't it? Leaving out maybe SERCOM5... I would really make good use of six i2c interfaces without the need of a multiplexer...

News?

Hi, Is possible to implement SERCOM1 as Half-Duplex?

Hi, I'm wondering the same thing about the serial ports. It's really lame that the Arduino libraries only support one serial UART on the Zero. I don't have one yet, but I will if I can squeeze another couple of UARTs out of this.

Any news?

I read here [SOLVED] I2C Communication on pins D3/D4 - Arduino Zero - Arduino Forum that some sort of ideas are moving underground. Is there some github repository or any source of development code to at least to watch? maybe I can be of some help!

Well...GitHub - arduino/ArduinoCore-samd: Arduino Core for SAMD21 CPU

Finally managed to get a second UART going on the Zero.

The example code below creates a UART class "Serial2" and connects it to SERCOM1. The Tx pin is on digital pin 10 (D10) and Rx on digital pin 12 (D12). It simply echos back characters sent from the COM terminal.

// Serial2 pin and pad definitions (in Arduino files Variant.h & Variant.cpp)
#define PIN_SERIAL2_RX       (34ul)               // Pin description number for PIO_SERCOM on D12
#define PIN_SERIAL2_TX       (36ul)               // Pin description number for PIO_SERCOM on D10
#define PAD_SERIAL2_TX       (UART_TX_PAD_2)      // SERCOM pad 2
#define PAD_SERIAL2_RX       (SERCOM_RX_PAD_3)    // SERCOM pad 3

// Instantiate the Serial2 class
Uart Serial2(&sercom1, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX);

void setup() 
{
  Serial2.begin(115200);          // Begin Serial2
}

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

void SERCOM1_Handler()    // Interrupt handler for SERCOM1
{
  Serial2.IrqHandler();
}

:slight_smile:

Also managed to get a third UART going on the Zero as well.

Add the two following lines to the end of the "g_APinDescription" array in the file ..Computer\AppData\Roaming\Arduino15\packages\arduino\hardware\samd\1.6.1\variants\arduino_zero\variant.cpp:

// 44..45 - SERCOM2
  { PORTA, 14, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SERCOM2/PAD[2]
  { PORTA, 15, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SERCOM2/PAD[3]

The example code below creates a UART class "Serial3" and connects it to SERCOM2. The Tx pin is on digital pin 2 (D2) and Rx on digital pin 5 (D5). It simply echos back characters sent from the COM terminal. Note that on Arduino.org's Zero Pro/M0 Pro/M0 the Tx pin is on digital pin 4 (D4).

// Serial3 pin and pad definitions (in Arduino files Variant.h & modified Variant.cpp)
#define PIN_SERIAL3_RX       (45ul)               // Pin description number for PIO_SERCOM on D5
#define PIN_SERIAL3_TX       (44ul)               // Pin description number for PIO_SERCOM on D2
#define PAD_SERIAL3_TX       (UART_TX_PAD_2)      // SERCOM pad 2
#define PAD_SERIAL3_RX       (SERCOM_RX_PAD_3)    // SERCOM pad 3

// Instantiate the Serial3 class
Uart Serial3(&sercom2, PIN_SERIAL3_RX, PIN_SERIAL3_TX, PAD_SERIAL3_RX, PAD_SERIAL3_TX);

void setup() 
{
  Serial3.begin(115200);          // Begin Serial3
}

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

void SERCOM2_Handler()    // Interrupt handler for SERCOM2
{
  Serial3.IrqHandler();
}

Hi MartinL,

With this issue would be possible to use SERCOM1 as Half-Duplex? Perhaps using just PORTA16 and PAD0? Is there any more changes that should be made for Serial with half-Duplex?

Best regards.

The UARTs are full-duplex.

When you say half-duplex, do you mean using only one pin either as a transmitter or receiver?

Yes, using only one pin for tx/rx.

The UARTs can be used as full-duplex, half-duplex or simplex(one direction only). My question is, How Can I configure SERCOM1 to use it as Half-Duplex?

The UARTs can be used as full-duplex, half-duplex or simplex(one direction only).

Thanks for correcting me. That's jolted my memory, half-duplex can be used for the old RS-485 twisted pair transceivers.

In half-duplex both the transmitter and receiver are enabled, but I believe you need to set the collision detection (COLDEN) bit in the sercom USART's CTRLB register. This can be set using the following code, in setup{}, just before Serial2.begin(). The CTRLB register needs to be synchronized by waiting for the CTRLB bit in the USART's SYNCBUSY register to clear.

REG_SERCOM1_USART_CTRLB |= SERCOM_USART_CTRLB_COLDEN;
while(SERCOM1->USART.SYNCBUSY.bit.CTRLB);

The details for clearing down and re-enabling the transmitter after a collision are given on page 449 of the SAMD21 datasheet. The datasheet states:

When a collision is detected, the USART automatically follows this sequence:
The current transfer is aborted.
The transmit buffer is flushed.
The transmitter is disabled (CTRLB.TXEN=0).
This commences immediately and is complete after synchronization time. The CTRLB Synchronization
Busy bit (SYNCBUSY.CTRLB) will be set until this is complete.
This results in the TxD pin being tri-stated.
The Collision Detected bit (STATUS.COLL) is set along with the Error interrupt flag (INTFLAG.ERROR).
Since the transmit buffer no longer contains data, the Transmit Complete interrupt flag (INTFLAG.TXC) is set.
After a collision, software must manually enable the transmitter before continuing. Software must ensure CTRLB
Synchronization Busy bit (SYNCBUSY.CTRLB) is not asserted before re-enabling the transmitter.

You can check the STATUS.COLL bit with:

if (REG_SERCOM1_USART_STATUS & SERCOM_USART_STATUS_COLL)

INTFLAG.ERROR with:

if (REG_SERCOM1_USART_INTFLAG & SERCOM_USART_INTFLAG_ERROR)

INTFLAG.TXC with:

if (REG_SERCOM1_USART_INTFLAG & SERCOM_USART_INTFLAG_TXC)

The transmitter can be re-enabled with:

while(SERCOM1->USART.SYNCBUSY.bit.CTRLB);          // Wait for SYNCBUSY.CTRLB to clear
REG_SERCOM1_USART_CTRLB |= SERCOM_USART_CTRLB_TXEN;
while(SERCOM1->USART.SYNCBUSY.bit.CTRLB);          // Wait for synchronization

By the way, all the register maniplulation definitions are stored in the directories:

..Computer\AppData\Roaming\Arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel\Device\ATMEL\samd21\include\component

which contains the SAMD21 peripheral component definitions, e.g. sercom.h, tcc.h, tc.h etc...

and

..Computer\AppData\Roaming\Arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel\Device\ATMEL\samd21\include\instance

which contains the SAMD21 peripheral instance definitions, e.g. sercom0.h, sercom1.h etc...

Thank you MartinL,

I will try make this code and if i get sucess i will be sharing!

Thank you again!

best regards!

MartinL:
Finally managed to get a second UART going on the Zero.

Thanks! I'll try this our right away. I just happen to be working on a project that could really use a 2nd HW serial port on the Zero.

Wayne