SAMD51 SPI Slave Setup

I’ve got to Grand Central M4 boards, one setup as a Master, using the standard SPI pins, and one setup at the slave using SERCOM 1… MOSI (7), MISO (16), SCK (17), SS (6). I send one byte, and the slave sends back the proper test byte. But after that, the slave just sends the masters bytes back to it… I’m pulling my hair out over this. Any ideas? It seems like the data register isn’t getting cleared??

Master…

#include <SPI.h>
#define SS 53

SPISettings settingsA(2000, MSBFIRST, SPI_MODE0);

void setup()
{
  pinMode(SS,OUTPUT);  
  Serial.begin(115200);
  SPI.begin();
}

void loop()
{  
  
  delay(10);//  Serial.println(wut,BIN);
  SPI.beginTransaction(settingsA);
  digitalWrite(SS, LOW);
  byte byte_one = SPI.transfer(0b10101010);
  byte byte_two = SPI.transfer(0b11001100); 
  SPI.endTransaction();
  
  digitalWrite(SS, HIGH);  
  delay(2000);//  
  Serial.println(byte_one,BIN);
  Serial.println(byte_two,BIN);
}

Slave…

#include <vector>

//std::vector<uint8_t> buf;
uint8_t buf;
uint8_t buf_out[4];
//(uint8_t)SERCOM0->SPI.DATA.reg;
int i = 0;
int j = -1;

byte register_settings[6][2] =
{
  {0b00000000, 0b00000000}, //DATA-READ ONLY - RETURN POSITION SENSOR
  {0b00000011, 0b11101000}, //
  {0b00000000, 0b01100100}, //
  {0b01110101, 0b00110000}, //
  {0b10110011, 0b00110010}, //
  {0b00000000, 0b00000000}  //
};

void SERCOM1_0_Handler()
{
  //SPI Data Register Empty Interrupt
//  Serial.println("Handler 0 - Empty Data");
      SERCOM1->SPI.DATA.reg = 0b11111111;
  

}

void SERCOM1_1_Handler()
{
    // SPI Data Transmit Complete
  SERCOM1->SPI.INTFLAG.bit.TXC = 1; //clear transmit complete interrupt
}

void SERCOM1_2_Handler()
{
  byte data;
  data = SERCOM1->SPI.DATA.reg;   
  buf = data;
}

void SERCOM1_3_Handler()
{
  //  // SSL Interupt
//  Serial.println("handler3 - ss clear");
//  Serial.println(SERCOM1->SPI.DATA.reg);
  SERCOM1->SPI.INTFLAG.bit.SSL = 1; //clear slave select interrupt
}

void initSPI()
{

  // Configure the peripheral clock
  MCLK->APBAMASK.bit.SERCOM1_ = 1;
  GCLK->PCHCTRL[SERCOM1_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN;

  PORT->Group[PORTC].PINCFG[22].bit.PMUXEN = 0x1;
  PORT->Group[PORTC].PMUX[22 >> 1].bit.PMUXE = 0x2;

  // Set PA17 as SERCOM1:1
  PORT->Group[PORTC].PINCFG[23].bit.PMUXEN = 0x1;
  PORT->Group[PORTC].PMUX[23 >> 1].bit.PMUXO = 0x2;

  // Set PA18 as SERCOM1:2
  PORT->Group[PORTD].PINCFG[20].bit.PMUXEN = 0x1;
  PORT->Group[PORTD].PMUX[20 >> 1].bit.PMUXE = 0x2;

  // Set PA19 as SERCOM1:3
  PORT->Group[PORTD].PINCFG[21].bit.PMUXEN = 0x1;
  PORT->Group[PORTD].PMUX[21 >> 1].bit.PMUXO = 0x2;

  //Enable SPI
  SERCOM1->SPI.CTRLA.bit.ENABLE = 0;
  while (SERCOM1->SPI.SYNCBUSY.bit.ENABLE);

  //Reset SPI 1
  SERCOM1->SPI.CTRLA.bit.SWRST = 1;
  while (SERCOM1->SPI.CTRLA.bit.SWRST || SERCOM1->SPI.SYNCBUSY.bit.SWRST);

  NVIC_EnableIRQ(SERCOM1_0_IRQn);
  NVIC_SetPriority(SERCOM1_0_IRQn, 2);
  NVIC_EnableIRQ(SERCOM1_1_IRQn);
  NVIC_SetPriority(SERCOM1_1_IRQn, 2);
  NVIC_EnableIRQ(SERCOM1_2_IRQn);
  NVIC_SetPriority(SERCOM1_2_IRQn, 2);
  NVIC_EnableIRQ(SERCOM1_3_IRQn);
  NVIC_SetPriority(SERCOM1_3_IRQn, 2);

  // Configure SERCOM1
  SERCOM1->SPI.CTRLA.bit.ENABLE = 0;
  while (SERCOM1->SPI.SYNCBUSY.bit.ENABLE);
  SERCOM1->SPI.CTRLA.bit.DORD = 0; //MSB first
  SERCOM1->SPI.CTRLA.bit.CPOL = 0; //SCK is low when idle, leading edge is rising edge
  SERCOM1->SPI.CTRLA.bit.CPHA = 0; //data sampled on leading sck edge and changed on a trailing sck edge
  SERCOM1->SPI.CTRLA.bit.FORM = 0x0; //Frame format = SPI
  SERCOM1->SPI.CTRLA.bit.MODE = 0x2; // set SPI Operating Mode to slave
  SERCOM1->SPI.CTRLA.bit.DIPO = 3; //DATA PAD3 MOSI is used as input (slave mode)
  SERCOM1->SPI.CTRLA.bit.DOPO = 0; //DATA PAD0 MISO is used as output
  SERCOM1->SPI.CTRLA.bit.IBON = 0x1; //Buffer Overflow notification
  SERCOM1->SPI.CTRLA.bit.RUNSTDBY = 1; //wake on receiver complete
  //  SERCOM1->SPI.CTRLB.bit.RXEN = 0x1; // Enable RX
  SERCOM1->SPI.CTRLB.bit.SSDE = 0x1; //Slave Select Detection Enabled
  SERCOM1->SPI.CTRLB.bit.CHSIZE = 0; //character size 8 Bit
  SERCOM1->SPI.CTRLB.bit.PLOADEN = 1; //character size 8 Bit

  //Set up SPI interrupts
  SERCOM1->SPI.INTENSET.bit.SSL = 0x1; //Enable Slave Select low interrupt
  SERCOM1->SPI.INTENSET.bit.RXC = 0x1; //Receive complete interrupt
  SERCOM1->SPI.INTENSET.bit.TXC = 0x1; //Receive complete interrupt
  SERCOM1->SPI.INTENSET.bit.ERROR = 0x1; //Receive complete interrupt
  SERCOM1->SPI.INTENSET.bit.DRE = 0x1; //Data Register Empty interrupt

  //Enable SPI
  SERCOM1->SPI.CTRLA.bit.ENABLE = 1;
  while (SERCOM1->SPI.SYNCBUSY.bit.ENABLE);

  SERCOM1->SPI.CTRLB.bit.RXEN = 0x1; //Enable Receiver, this is done here due to errate issue
  while (SERCOM1->SPI.SYNCBUSY.bit.CTRLB); //wait until receiver is enabled
}

void setup()
{
  pinMode(6,INPUT_PULLUP);
//  pinMode(7,INPUT);
//  pinMode(17,INPUT);
//  pinMode(16,OUTPUT);
  Serial.begin(115200);
  while (!Serial);
  delay(500);
  initSPI();
}

void loop()
{
}

This is what I get back…
16:10:34.221 → 11111111
16:10:34.221 → 10101010
16:10:36.214 → 11001100
16:10:36.214 → 10101010
16:10:38.245 → 11001100
16:10:38.245 → 10101010
16:10:40.231 → 11001100
16:10:40.231 → 10101010

Change

void SERCOM1_2_Handler()
{
  byte data;
  data = SERCOM1->SPI.DATA.reg;   
  buf = data;
}

to

void SERCOM1_2_Handler()
{
  byte data;
  data = SERCOM1->SPI.DATA.reg;
  SERCOM1->SPI.DATA.reg = 0xFF;
  buf = data;
}

What do you get then?