Muxing it up

So, wow, 6 SERCOMs, totally configurable - best thing ever! So what's the catch?

It's just a little one really - when setting up the SERCOM you have to configure what pins it will use (you have many options) and it takes a little time to look up the exact multiplexing setup and make sure you have it right. Not a huge deal, but has to be done right.

Multiplex Table

If you look in the ATSAMD21 datasheet, there's a big table in section 6 called  Multiplexing and Considerations, and it says...

Each pin is by default controlled by the PORT as a general purpose I/O and alternatively it can be assigned to one of the peripheral functions A, B, C, D, E, F, G or H. To enable a peripheral function on a pin, the Peripheral Multiplexer Enable bit in the Pin Configuration register corresponding to that pin (PINCFGn.PMUXEN, n = 0-31) in the PORT must be written to one.
The selection of peripheral function A to H is done by writing to the Peripheral Multiplexing Odd and Even bits in the Peripheral Multiplexing register (PMUXn.PMUXE/O) in the PORT

Which basically means - each pin has different capabilities, such as digital I/O, analog input, timer/pwm output, and sercom connectivity. On most chips, there's only one pin that can act as the I2C clock pin, but on this chip, there's quite a few pins that can be selected. So the trick is figuring out which pin you want to have that capability and 'MUXing it'

Here's how to read the table, here we've got the first page:

The chip we're using is the ATSAMD21G note that the J series does have more pins so for example, pins 5-10 on the ATSAMD21J (PB04 thru PB07) don't apply to our chips.

In columns C and D, you can see the SERCOM pads available. I've also circled in blue the matching I/O Pins.

Each SERCOM has 4 possible pads: SERCOM#/PAD[x] where # can be 0 thru 5 (6 total SERCOMs), and x can be 0 thru 3 (4 total pads).

Some pins can only act as a single SERCOM's pads - for example PA00 is the first pin in the table and can only act as SERCOM1.PAD[0]

On the other hand, some pins can do dual duty: PA08 lower on the list can act as either SERCOM #0's PAD 0 or it can act as SERCOM #2's PAD 0.

Arduino's MUX Table

To map the raw pin name to the Arduino Zero 'board pin' you can read the table in variants.cpp (in the board package)

Download: file
/*
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * + Pin number +  ZERO Board pin  |  PIN   | Label/Name      | Comments (* is for default peripheral in use)
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * |            | Digital Low      |        |                 |
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * | 0          | 0 -> RX          |  PA11  |                 | EIC/EXTINT[11] ADC/AIN[19]           PTC/X[3] *SERCOM0/PAD[3]  SERCOM2/PAD[3]  TCC0/WO[3]  TCC1/WO[1]
 * | 1          | 1 <- TX          |  PA10  |                 | EIC/EXTINT[10] ADC/AIN[18]           PTC/X[2] *SERCOM0/PAD[2]                  TCC0/WO[2]  TCC1/WO[0]
 * | 2          | 2                |  PA14  |                 | EIC/EXTINT[14]                                 SERCOM2/PAD[2]  SERCOM4/PAD[2]  TC3/WO[0]   TCC0/WO[4]
 * | 3          | ~3               |  PA09  |                 | EIC/EXTINT[9]  ADC/AIN[17]           PTC/X[1]  SERCOM0/PAD[1]  SERCOM2/PAD[1] *TCC0/WO[1]  TCC1/WO[3]
 * | 4          | ~4               |  PA08  |                 | EIC/NMI        ADC/AIN[16]           PTC/X[0]  SERCOM0/PAD[0]  SERCOM2/PAD[0] *TCC0/WO[0]  TCC1/WO[2]
 * | 5          | ~5               |  PA15  |                 | EIC/EXTINT[15]                                 SERCOM2/PAD[3]  SERCOM4/PAD[3] *TC3/WO[1]   TCC0/WO[5]
 * | 6          | ~6               |  PA20  |                 | EIC/EXTINT[4]                        PTC/X[8]  SERCOM5/PAD[2]  SERCOM3/PAD[2]             *TCC0/WO[6]
 * | 7          | 7                |  PA21  |                 | EIC/EXTINT[5]                        PTC/X[9]  SERCOM5/PAD[3]  SERCOM3/PAD[3]              TCC0/WO[7]
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * |            | Digital High     |        |                 |
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * | 8          | ~8               |  PA06  |                 | EIC/EXTINT[6]  ADC/AIN[6]  AC/AIN[2] PTC/Y[4]  SERCOM0/PAD[2]                 *TCC1/WO[0]
 * | 9          | ~9               |  PA07  |                 | EIC/EXTINT[7]  ADC/AIN[7]  AC/AIN[3] PTC/Y[5]  SERCOM0/PAD[3]                 *TCC1/WO[1]
 * | 10         | ~10              |  PA18  |                 | EIC/EXTINT[2]                        PTC/X[6] +SERCOM1/PAD[2]  SERCOM3/PAD[2] *TC3/WO[0]    TCC0/WO[2]
 * | 11         | ~11              |  PA16  |                 | EIC/EXTINT[0]                        PTC/X[4] +SERCOM1/PAD[0]  SERCOM3/PAD[0] *TCC2/WO[0]   TCC0/WO[6]
 * | 12         | ~12              |  PA19  |                 | EIC/EXTINT[3]                        PTC/X[7] +SERCOM1/PAD[3]  SERCOM3/PAD[3]  TC3/WO[1]   *TCC0/WO[3]
 * | 13         | ~13              |  PA17  | LED             | EIC/EXTINT[1]                        PTC/X[5] +SERCOM1/PAD[1]  SERCOM3/PAD[1] *TCC2/WO[1]   TCC0/WO[7]
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * |            | Analog Connector |        |                 |
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * | 14         | A0               |  PA02  | A0              | EIC/EXTINT[2] *ADC/AIN[0]  DAC/VOUT  PTC/Y[0]
 * | 15         | A1               |  PB08  | A1              | EIC/EXTINT[8] *ADC/AIN[2]            PTC/Y[14] SERCOM4/PAD[0]                  TC4/WO[0]
 * | 16         | A2               |  PB09  | A2              | EIC/EXTINT[9] *ADC/AIN[3]            PTC/Y[15] SERCOM4/PAD[1]                  TC4/WO[1]
 * | 17         | A3               |  PA04  | A3              | EIC/EXTINT[4] *ADC/AIN[4]  AC/AIN[0] PTC/Y[2]  SERCOM0/PAD[0]                  TCC0/WO[0]
 * | 18         | A4               |  PA05  | A4              | EIC/EXTINT[5] *ADC/AIN[5]  AC/AIN[1] PTC/Y[5]  SERCOM0/PAD[1]                  TCC0/WO[1]
 * | 19         | A5               |  PB02  | A5              | EIC/EXTINT[2] *ADC/AIN[10]           PTC/Y[8]  SERCOM5/PAD[0]
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * |            | Wire             |        |                 |
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * | 20         | SDA              |  PA22  | SDA             | EIC/EXTINT[6]                        PTC/X[10] *SERCOM3/PAD[0] SERCOM5/PAD[0] TC4/WO[0] TCC0/WO[4]
 * | 21         | SCL              |  PA23  | SCL             | EIC/EXTINT[7]                        PTC/X[11] *SERCOM3/PAD[1] SERCOM5/PAD[1] TC4/WO[1] TCC0/WO[5]
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * |            |SPI (Legacy ICSP) |        |                 |
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * | 22         | 1                |  PA12  | MISO            | EIC/EXTINT[12] SERCOM2/PAD[0] *SERCOM4/PAD[0] TCC2/WO[0] TCC0/WO[6]
 * |            | 2                |        | 5V0             |
 * | 23         | 4                |  PB10  | MOSI            | EIC/EXTINT[10]                *SERCOM4/PAD[2] TC5/WO[0]  TCC0/WO[4]
 * | 24         | 3                |  PB11  | SCK             | EIC/EXTINT[11]                *SERCOM4/PAD[3] TC5/WO[1]  TCC0/WO[5]
 * |            | 5                |        | RESET           |
 * |            | 6                |        | GND             |
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * |            | EDBG             |        |                 |
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * | 30         |                  |  PB22  | EDBG_UART TX    | *SERCOM5/PAD[2]
 * | 31         |                  |  PB23  | EDBG_UART RX    | *SERCOM5/PAD[3]
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * | 32         |                  |  PA22  | EDBG_SDA        | Pin 20 (SDA)
 * | 33         |                  |  PA23  | EDBG_SCL        | Pin 21 (SCL)
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * | 34         |                  |  PA19  | EDBG_MISO       | EIC/EXTINT[3] *SERCOM1/PAD[3] SERCOM3/PAD[3] TC3/WO[1]  TCC0/WO[3]
 * | 35         |                  |  PA16  | EDBG_MOSI       | EIC/EXTINT[0] *SERCOM1/PAD[0] SERCOM3/PAD[0] TCC2/WO[0] TCC0/WO[6]
 * | 36         |                  |  PA18  | EDBG_SS         | EIC/EXTINT[2] *SERCOM1/PAD[2] SERCOM3/PAD[2] TC3/WO[0]  TCC0/WO[2]
 * | 37         |                  |  PA17  | EDBG_SCK        | EIC/EXTINT[1] *SERCOM1/PAD[1] SERCOM3/PAD[1] TCC2/WO[1] TCC0/WO[7]
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * | 38         | ATN              |  PA13  | EDBG_GPIO0      | EIC/EXTINT[13] SERCOM2/PAD[1] SERCOM4/PAD[1] *TCC2/WO[1] TCC0/WO[7]
 * | 39         |                  |  PA21  | EDBG_GPIO1      | Pin 7
 * | 40         |                  |  PA06  | EDBG_GPIO2      | Pin 8
 * | 41         |                  |  PA07  | EDBG_GPIO3      | Pin 9
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * |            |32.768KHz Crystal |        |                 |
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 * |            |                  |  PA00  | XIN32           | EIC/EXTINT[0] SERCOM1/PAD[0] TCC2/WO[0]
 * |            |                  |  PA01  | XOUT32          | EIC/EXTINT[1] SERCOM1/PAD[1] TCC2/WO[1]
 * +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
 */

To save me from having to constantly look it up, here's a table of all the ATSAMD21G's SERCOM MUXs:

Download: file
Pin	Arduino 'Pin'	SERCOM		SERCOM alt
-----------------------------------------
PA00	Used by xtal			SERCOM1.0
PA01	Used by xtal			SERCOM1.1
PB08	A1				SERCOM4.0
PB09	A2				SERCOM4.1
PA04	A3				SERCOM0.0
PA05	A4				SERCOM0.1
PA06	D8				SERCOM0.2
PA07	D9				SERCOM0.3
PA08	D4		SERCOM0.0	SERCOM2.0
PA09	D3		SERCOM0.1	SERCOM2.1
PA10	D1		SERCOM0.2	SERCOM2.2
PA11	D0		SERCOM0.3	SERCOM2.3
PB10	D23 / MOSI			SERCOM4.2
PB11	D24 / SCK			SERCOM4.3
PA12	D22 / MISO	SERCOM2.0	SERCOM4.0
PA13	Used by EDBC	SERCOM2.1	SERCOM4.1
PA14	D2		SERCOM2.2	SERCOM4.2
PA15	D5		SERCOM2.3	SERCOM4.3
PA16	D11		SERCOM1.0	SERCOM3.0
PA17	D13		SERCOM1.1	SERCOM3.1
PA18	D10		SERCOM1.2	SERCOM3.2
PA19	D12		SERCOM1.3	SERCOM3.3
PA20	D6		SERCOM5.2	SERCOM3.2
PA21	D7		SERCOM5.3	SERCOM3.3
PA22	D20 / SDA	SERCOM3.0	SERCOM5.0
PA23	D21 / SCL	SERCOM3.1	SERCOM5.1
PA24	Used by USB	SERCOM3.2	SERCOM5.2
PA25	Used by USB	SERCOM3.3	SERCOM5.3
PB22	D30 / EDBG TX			SERCOM5.2
PB23	D31 / EDBG RX			SERCOM5.3
PA30	Used by SWCLK			SERCOM1.2
PA31	Used by SWDIO			SERCOM1.3
PB02	A5				SERCOM5.0
PB03	D25 / RX LED			SERCOM5.1

Note that a bunch of these pins are simply *not available* if you've got a Zero or Feather M0, because they are used for programming or LEDs, or not brought out to headers in some other way, so lets remove them & sort by pin

Download: file
Pin	Arduino 'Pin'	SERCOM		SERCOM alt
-----------------------------------------
PA11	D0		SERCOM0.3	SERCOM2.3
PA10	D1		SERCOM0.2	SERCOM2.2
PA14	D2		SERCOM2.2	SERCOM4.2
PA09	D3		SERCOM0.1	SERCOM2.1
PA08	D4		SERCOM0.0	SERCOM2.0
PA15	D5		SERCOM2.3	SERCOM4.3
PA20	D6		SERCOM5.2	SERCOM3.2
PA21	D7		SERCOM5.3	SERCOM3.3
PA06	D8				SERCOM0.2
PA07	D9				SERCOM0.3
PA18	D10		SERCOM1.2	SERCOM3.2
PA16	D11		SERCOM1.0	SERCOM3.0
PA19	D12		SERCOM1.3	SERCOM3.3
PA17	D13		SERCOM1.1	SERCOM3.1
PB08	A1				SERCOM4.0
PB09	A2				SERCOM4.1
PA04	A3				SERCOM0.0
PA05	A4				SERCOM0.1
PB02	A5				SERCOM5.0
PA22	D20 / SDA	SERCOM3.0	SERCOM5.0
PA23	D21 / SCL	SERCOM3.1	SERCOM5.1
PA12	D22 / MISO	SERCOM2.0	SERCOM4.0
PB10	D23 / MOSI			SERCOM4.2
PB11	D24 / SCK			SERCOM4.3

Predefined SERCOMs

OK so first things we want to sort out is what SERCOMs are already taken, this tutorial will assume you won't 'bash' existing SERCOMs (altho you are free to, if you want to give up the hardware serial UART for I2C, say).

The debug hardware serial port

which is used when connecting to the Programming/Debug Port on an Arduino Zero is on SERCOM 5, pads 2 & 3. It's not used on an Adafruit Feather because there's no debug port

Download: file
PB22	D30 / EDBG TX			SERCOM5.2
PB23	D31 / EDBG RX			SERCOM5.3

I2C (SDA & SCL)

use SERCOM 3 (pads 0 & 1)

Download: file
PA22	D20 / SDA	SERCOM3.0	SERCOM5.0
PA23	D21 / SCL	SERCOM3.1	SERCOM5.1

The SPI port

is on SERCOM 4, and uses pads 0, 2, and 3

Download: file
PA12	D22 / MISO	SERCOM2.0	SERCOM4.0
PB10	D23 / MOSI			SERCOM4.2
PB11	D24 / SCK			SERCOM4.3

And finally, the

hardware Serial interface (e.g. Serial1)

is on SERCOM 0

Download: file
PA11	D0		SERCOM0.3	SERCOM2.3
PA10	D1		SERCOM0.2	SERCOM2.2

That leaves you with:

SERCOMs 1 & 2 on an Arduino Zero

and

SERCOMs 1, 2, and 5 on a Feather M0

Available SERCOM & Pins

OK we're nearly done paring down that table to the SERCOMs that we can use and pins that are available.

SERCOM 1

Available on both Zero's and Feathers, you can use pins 10, 11, 12 and 13 for SERCOM 1

Download: file
Pin	Arduino 'Pin'	SERCOM		SERCOM alt
-----------------------------------------
PA18	D10		SERCOM1.2	SERCOM3.2
PA16	D11		SERCOM1.0	SERCOM3.0
PA19	D12		SERCOM1.3	SERCOM3.3
PA17	D13		SERCOM1.1	SERCOM3.1

SERCOM 2

This one has more options

Download: file
Pin	Arduino 'Pin'	SERCOM		SERCOM alt
-----------------------------------------
PA11	D0		SERCOM0.3	SERCOM2.3
PA10	D1		SERCOM0.2	SERCOM2.2
PA14	D2		SERCOM2.2	SERCOM4.2
PA09	D3		SERCOM0.1	SERCOM2.1
PA08	D4		SERCOM0.0	SERCOM2.0
PA15	D5		SERCOM2.3	SERCOM4.3
PA12	D22 / MISO	SERCOM2.0	SERCOM4.0

but some are already used, so while you could theoretically use D0 & D1 those are already used for the Hardware Serial UART, and D22/MISO is used for SPI. So that leaves D2 thru D5

Download: file
Pin	Arduino 'Pin'	SERCOM		SERCOM alt
-----------------------------------------
PA14	D2		SERCOM2.2	SERCOM4.2
PA09	D3		SERCOM0.1	SERCOM2.1
PA08	D4		SERCOM0.0	SERCOM2.0
PA15	D5		SERCOM2.3	SERCOM4.3

SERCOM 5

This one is used for programming on the Zero with EDBG interface but you can use it on the Feather M0 since only native USB is used.

Download: file
Pin	Arduino 'Pin'	SERCOM		SERCOM alt
-----------------------------------------
PA20	D6		SERCOM5.2	SERCOM3.2
PA21	D7		SERCOM5.3	SERCOM3.3
PB02	A5				SERCOM5.0
PA22	D20 / SDA	SERCOM3.0	SERCOM5.0
PA23	D21 / SCL	SERCOM3.1	SERCOM5.1

Two of those are used by SDA/SCL which, unless you want to reuse for a different SERCOM, you'll only have:

Download: file
Pin	Arduino 'Pin'	SERCOM		SERCOM alt
-----------------------------------------
PA20	D6		SERCOM5.2	SERCOM3.2
PA21	D7		SERCOM5.3	SERCOM3.3
PB02	A5				SERCOM5.0

Note that you don't get access to SERCOM5.1!

Freeing up SERCOM5

If you'd like to free up SERCOM5 on a Zero, and you won't be using the programming port (because that's how Serial data is passed back and forth) you can comment out

Download: file
Uart Serial( &sercom5, PIN_SERIAL_RX, PIN_SERIAL_TX, PAD_SERIAL_RX, PAD_SERIAL_TX ) ;

and

Download: file
void SERCOM5_Handler()
{
  Serial.IrqHandler();
}

At the end of the variants file (you'll need to dig for where this is downloaded after you've added SAMD support, and you'll also have to re-remove after each board manager update of that package.

Note that you'll definitely not be able to use Serial anymore, you can only use USBSerial. Like I said, its a bit annoying, you may want to grab the Adafruit SAMD package, and 'pretend' like your Zero is a Feather M0, it'll work just fine, and then Serial will point to USBSerial. whee!

This guide was first published on Jan 24, 2016. It was last updated on Jan 24, 2016. This page (Muxing it up) was last updated on Jun 24, 2019.