Resources

https://www.arduino.cc/en/reference/SPI

Arduino As SPI Master


#include <SPI.h>

  SPI.begin();

  SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0));   //  Speed (e.g.15000000=15MHz), BitOrder (MSBFIRST), Mode (SPI_MODE0 - SPI_MODE3)

  rx_data = SPI.transfer(0x01);
  rx_data = SPI.transfer(0x02);
 
  SPI.endTransaction();

Arduino As SPI Slave

#include <SPI.h>

volatile byte spi_receive_buffer [100];
volatile byte spi_receive_index;

  //----- CONFIGURE SPI SLAVE PORT -----
  pinMode(SS,INPUT_PULLUP);
  pinMode(MOSI,INPUT_PULLUP);
  pinMode(SCK,INPUT);
  pinMode(MISO,OUTPUT);
  
  //Turn on SPI in Slave Mode using SPI Control Register
  SPCR |= _BV(SPE);     //SPI default mode 0 (CPOL=0 and CPHA=0), SPE = SPI enable

  //Turn on SPI interrupts
  SPCR |= _BV(SPIE);

  //Turn ON interrupt for SPI communication
  SPI.attachInterrupt();        //If a data is received from master the Interrupt Routine is called and the received value is taken from SPDR (SPI data Register)

  spi_receive_index = 0;
  


//*******************************************
//*******************************************
//********** SPI RECEIVE INTERRUPT **********
//*******************************************
//*******************************************
ISR (SPI_STC_vect)
{

  if (spi_receive_index < sizeof(spi_receive_buffer))
  {
    //Get received byte
    spi_receive_buffer[spi_receive_index] = SPDR;
  
    //Set next byte to be transmitted (on next byte transfer)
    SPDR = spi_receive_buffer[spi_receive_index] + 0x10;      //Send a copy with 0x10 added for this test
  }
  else
  {
    SPDR = 0;;
  }
}