MicroMod SAMD51 SERCOM (Modifying variants for 3x SPI)

Hello!

My goal is to have three sperate SPI interfaces on my SAMD51 but I am a bit confused on how to achieve that. So… I have the variant.cpp file in which I configure my pins. As far as I can see, five out of six SERCOMs are in use:

SERCOM0: SPI

{ PORTA,  4, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 },  // COPI SERCOM 0 / PAD[0]
{ PORTA,  5, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 },  // SCK  SERCOM 0 / PAD[1]
{ PORTA,  6, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_13 },  // CIPO SERCOM 0 / PAD[2]
{ PORTA,  7, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_13 },  // CS   SERCOM 0 / PAD[3]

SERCOM1: UART

{ PORTB, 31, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, TC0_CH0, EXTERNAL_INT_15 },  // 5 UART TX SERCOM 1 / PAD[0]
{ PORTB, 30, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, TC0_CH0, EXTERNAL_INT_14 },  // 6 UART RX SERCOM 1 / PAD[1]

SERCOM2: SPI1

{ PORTA,  9,  PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 },  // SPI1 COPI1 SERCOM 2 / PAD[0]
{ PORTA,  8,  PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 },  // SPI1 SCK1  SERCOM 2 / PAD[1]
{ PORTA, 10,  PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 },  // SPI1 CIPO1 SERCOM 2 / PAD[2]
{ PORTA, 11,  PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 },  // SPI1 CS1   SERCOM 2 / PAD[3]

SERCOM3: I2C

{ PORTA, 16, PIO_SERCOM_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH0, TC2_CH0, EXTERNAL_INT_0 },  // I2C SCL  SERCOM 3 / PAD[1]
{ PORTA, 17, PIO_SERCOM_ALT, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH5, TC2_CH1, EXTERNAL_INT_1 },  // I2C SDA  SERCOM 3 / PAD[0]

SERCOM4: I2C1

{ PORTA, 12, PIO_SERCOM_ALT, PIN_ATTR_PWM_G, No_ADC_Channel, TCC1_CH2, TC2_CH0, EXTERNAL_INT_12 },  // I2C1 SCL1 (RX) SERCOM 4 / PAD[1]
{ PORTA, 13, PIO_SERCOM_ALT, PIN_ATTR_PWM_G, No_ADC_Channel, TCC1_CH3, TC2_CH1, EXTERNAL_INT_13 },  // I2C1 SDA1 (TX) SERCOM 4 / PAD[0]

SERCOM5: unused(?)

The part I do not understand can be found at the bottom of the variant.cpp:

/* Multi-serial objects instantiation */
SERCOM sercom0(SERCOM0);
SERCOM sercom1(SERCOM1);
SERCOM sercom2(SERCOM2);
SERCOM sercom3(SERCOM3);
SERCOM sercom4(SERCOM4);
SERCOM sercom5(SERCOM5);

Uart Serial1( &sercom5, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ;

void SERCOM5_0_Handler() { Serial1.IrqHandler(); }
void SERCOM5_1_Handler() { Serial1.IrqHandler(); }
void SERCOM5_2_Handler() { Serial1.IrqHandler(); }
void SERCOM5_3_Handler() { Serial1.IrqHandler(); }

Serial1 is using the UART pins, configured in the pin description array, isn’t it? According to that, it should not use SERCOM5. Am I missing something here? Also: I do not really understand, why Serial1 has four IRQ handlers…

Maybe someone is able to enlighten me. Thanks!

Greetings - Vulpecula

Edit: My Plan was to use SERCOM5 for the third SPI Interface and ‘sacrifice’ the I2S interface which I don’t need. The pins/ports/pads do offer SERCOM5. Also… Am I actually able to use SPI1 in my case or is it internally connected to something else?

  /****** I2S (SDO, SDI, FS, SCK) Pins 40...44 **************************************************************************************/
  { PORTA, 21, PIO_DIGITAL, PIN_ATTR_PWM_F,   No_ADC_Channel, TCC0_CH1,   TC7_CH0,      EXTERNAL_INT_5 },   // SDO   SERCOM 5 / PAD[3]
  { PORTA, 22, PIO_DIGITAL, PIN_ATTR_PWM_F,   No_ADC_Channel, TCC0_CH2,   TC4_CH0,      EXTERNAL_INT_6 },   // SDI   SERCOM 3 / PAD[0]
  { PORTB, 16, PIO_DIGITAL, PIN_ATTR_PWM_G,   No_ADC_Channel, TCC3_CH0,   TC4_CH0,      EXTERNAL_INT_12 },  // SCK   SERCOM 5 / PAD[0]
  { PORTB, 17, PIO_DIGITAL, PIN_ATTR_PWM_F,   No_ADC_Channel, TCC3_CH1,   TC6_CH1,      EXTERNAL_INT_12 },  // MCLK  SERCOM 5 / PAD[1]
  { PORTA, 20, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 },   // FS    SERCOM 5 / PAD[2]

Okay, I did find a mistake I made. PB30 and PB31 are in fact connected to SERCOM5, which means I could try to have another SPI on SERCOM1. I wonder why I did not see that after spending half a day with the datasheet… well well. Nevermind then. (Edit: I guess it’s because PA30/31 and PB30/31 are right next to each other…)

But… I still don’t understand, why Serial1 needs to have four Handlers.