Testing Arduino as SPI with one controller and different Arduino-based peripherals. Use with spi-test-controller and spi-test-peripheral-odd counter.

spi-test-peripheral-even.ino
/**
 * spi-peripheral-even.ino
 * Mithat Konar
 * GPL3
 * 
 * An SPI peripheral that returns even number(s).
 * Commands:
 *   * '0': reset the number to 0
 *   * 'i': get most recent number, then increment the value by 2
 *   * 'r': get most recent number
 * 
 * After you have made this device active by bringing pin SS/CS low, you
 * can send a transaction using one of these commands.
 * 
 * On the controller, this would look like:
 * 
 * byte rv = 0;  // used to get responses from peripheral
 * 
 * // reset the counter:
 * SPI.beginTransaction(SPISettings(400000, MSBFIRST, SPI_MODE0));
 * digitalWrite(PERIPHERAL_CS, LOW);   // make peripheral active
 * rv = SPI.transfer('r');
 * digitalWrite(PERIPHERAL_CS, HIGH);  // make peripheral inactive
 * SPI.endTransaction();
 * 
 * // get some numbers:
 * SPI.beginTransaction(SPISettings(400000, MSBFIRST, SPI_MODE0));
 * digitalWrite(PERIPHERAL_CS, LOW);   // make peripheral active
 * SPI.transfer('0');                  // ALWAYS reset before using
 * rv = SPI.transfer('i');             // rv has 0, peripheral internal counter is 2
 * rv = SPI.transfer('i');             // rv has 2, peripheral internal counter is 4
 * rv = SPI.transfer('i');             // rv has 4, peripheral internal counter is 6
 * digitalWrite(PERIPHERAL_CS, HIGH);  // make peripheral inactive
 * SPI.endTransaction();
 * 
 * SPI.beginTransaction(SPISettings(400000, MSBFIRST, SPI_MODE0));
 * digitalWrite(PERIPHERAL_CS, LOW);   // make peripheral active
 * rv = SPI.transfer('r');             // rv has 6, peripheral internal counter is 6
 * rv = SPI.transfer('i');             // rv has 6, peripheral internal counter is 8
 * rv = SPI.transfer('r');             // rv has 8, peripheral internal counter is 8
 * digitalWrite(PERIPHERAL_CS, HIGH);  // make peripheral inactive
 * SPI.endTransaction();
 * 
 * Pinout (ATmega328P-based Arduinos):
 * SCK:  13
 * PICO: 12
 * POCI: 11
 * CS:   10
 */
 
#include <Arduino.h>
#include <SPI.h>
 
volatile byte num = 0;    // state variable used to hold count
 
void setup (void)
{
  // configure POCI as output
  pinMode(MISO, OUTPUT);  // TODO: what happens when everyone is an output
                          // all at once?
 
  SPCR |= bit(SPE);   // turn on SPI in peripheral mode
  SPDR = 0;           // initialize SPI data -- works on H/W reset but not
                      // consistently on power up
  SPI.attachInterrupt();
}
 
// SPI interrupt routine
ISR (SPI_STC_vect)
{
  // Before we got here, the old value in SPDR was already automagically
  // transferred back to the controller.
  byte cmd = SPDR;
 
  switch(cmd)
  {
    case '0':   // reset
      num = 0;
      break;
    case 'i':   // increment
      num += 2;
      break;
    case 'r':   // do nothing -- also the default, so 'r' isn't necessary;  
      break;    // it makes for semantic code though.
  }
  SPDR = num;   // set SPDR to num, ready to be transferred to the controller
                // on the next transfer.
}
 
void loop (void)
{
  // nothing to do here :-)
}