Using SCOM4 for another HW serial port on the Sodaq 1

I would like to add an additional serial port for my application on a Sodaq One. The processor has an available SCOM (SCOM4). Is it possible to configure the serial port and have it treated the same way with the serial class as the existing serial ports?

Yes it would be possible to map SERCOM4 as an additional UART.

Using the pin data pp.33-34 of the datasheet (note: the SodaqOne uses the SAMD21G variant): http://ww1.microchip.com/downloads/en/DeviceDoc/40001882A.pdf

SERCOM4 is available on these pins (Alt mapping):

PB08: PAD0
PB09: PAD1
PB10: PAD2
PB11: PAD3

PA12: PAD0
PA13: PAD1
PA14: PAD2
PA15: PAD3

If you have a look at the SodaqOne schematic: http://support.sodaq.com/wp-content/uploads/2016/07/sodaq_one_v2-1.png

You can see that the only available pins are PB8 (PAD0), and PB9 (PAD1). These can be setup as a UART and they are available on the external pins J1-11 & J1-12.

In order to achieve this you will need to modify the board variant files.
In variant.h the existing ‘Serial’ objects are defined with:

/*
 * Serial interfaces
 */
// Serial
#define PIN_SERIAL_RX       (39u)
#define PIN_SERIAL_TX       (40u)
#define PAD_SERIAL_TX       (UART_TX_PAD_0)
#define PAD_SERIAL_RX       (SERCOM_RX_PAD_1)

// Serial1
#define PIN_SERIAL1_RX      (41u)
#define PIN_SERIAL1_TX      (42u)
#define PAD_SERIAL1_TX      (UART_TX_PAD_0)
#define PAD_SERIAL1_RX      (SERCOM_RX_PAD_1)
//
//...
//
extern Uart Serial;
extern Uart Serial1;
//
//...
//
// Serial has no physical pins broken out, so it's not listed as HARDWARE port
#define SERIAL_PORT_HARDWARE        Serial
#define SERIAL_PORT_HARDWARE_OPEN   Serial

#define SERIAL_PORT_HARDWARE1       Serial1
#define SERIAL_PORT_HARDWARE_OPEN1  Serial1

and in variant.cpp where the values in variant.h are the array indicies.

  // 39..40 Serial
  { PORTB, 3,  PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL),                                     No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3    }, // SERIAL_RX
  { PORTB, 2,  PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL),                                     No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2    }, // SERIAL_TX

  // 41..42 Serial1
  { PORTA, 13, PIO_SERCOM,     (PIN_ATTR_DIGITAL),                                     No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_13   }, // SERIAL1_RX
  { PORTA, 12, PIO_SERCOM,     (PIN_ATTR_DIGITAL),                                     No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12   }, // SERIAL1_TX

You will need to add the appropriate rows to main pin description array in variant.cpp, you should do so at the end of the array otherwise you will affect references to other entries (note: the SERCOM_ALT mappings). You will also add the required definitions to variant.h , the naming scheme would suggest you use Serial2.

Finally, at the end of variant.cpp you need to instantiate the new Serial object and hook up the IRQ handler, e.g.

Uart Serial(&sercom5, PIN_SERIAL_RX, PIN_SERIAL_TX, PAD_SERIAL_RX, PAD_SERIAL_TX ) ;
Uart Serial1(&sercom2, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX);

void SERCOM2_Handler()
{
  Serial1.IrqHandler();
}

void SERCOM5_Handler()
{
  Serial.IrqHandler();
}
1 Like

Awesome. I will get right on it.