// Pin definitions:
// The first 74HC595 uses a type of serial connection called SPI
// (Serial Peripheral Interface) that requires three pins:
const int clockPin  = 13;
const int dataPin   = 11;
const int latchPin  = 10;
const int signalPin =  9;
#define SPI_RX_BUFF_SIZE 128

// Pin definitions:
// The 74HC595 uses a type of serial connection called SPI
// (Serial Peripheral Interface) that requires three pins:
const int softClockPin  = 3;
const int softDataPin   = 2;
const int softLatchPin  = 4;

// We'll also declare a global variable for the data we're
// sending to the shift register:

volatile char buf [SPI_RX_BUFF_SIZE];
volatile byte pos = 0;

// SPI interrupt routine
ISR (SPI_STC_vect)
{
  PORTB |= 0b00000100;  // Latch the transmitted data
  byte c = SPDR;  // grab byte from SPI Data Register
  SPDR = pos;
  asm volatile("nop");

  // add to buffer if room
  if (pos < SPI_RX_BUFF_SIZE) {
    buf [pos++] = c;
  }
  // pos &= 0b01111111;

  PORTB &= ~0b00000100;  // Release the latch
}  // end of interrupt routine SPI_STC_vect

void setup()
{
  Serial.begin(115200);
  pinMode(signalPin, OUTPUT);

  // Set the three software SPI pins to be outputs:
  pinMode(softDataPin, OUTPUT);
  pinMode(softClockPin, OUTPUT);
  pinMode(softLatchPin, OUTPUT);

  // Set hardware SPI speed & Mode
  // Configure SPI as Master
  SPCR |= (1 << SPE) | (1 << MSTR) | (1 << SPIE); // Enable SPI, set as Master, enable SPI interrupt

  // Set clock speed to 8 MHz (maximum)
  SPCR &= ~((1 << SPR1) | (1 << SPR0)); // Set SPR1 = 0, SPR0 = 0 (Prescaler = 4)
  SPSR |= (1 << SPI2X);                 // Set SPI2X = 1 (Double the clock speed to Prescaler = 2)

  // Set data order to MSB first (default)
  // SPCR &= ~(1 << DORD);

  // Set SPI mode to Mode 0 (CPOL = 0, CPHA = 0)
  // SPCR &= ~((1 << CPHA) | (1 << CPOL)); // Clear CPHA and CPOL for Mode 0

  // Set MOSI, SCK, and SS as outputs
  DDRB |= (1 << PB3) | (1 << PB5) | (1 << PB2);

  PORTB |= 0b00000010;  // Start of transmission, set signal HIGH

  // Start transmission with the first byte
  SPDR = 0xA5;
  // Enable global interrupts
  sei();

  asm volatile("nop");

  PORTB &= ~0b00000010;

  // Set the softLatchPin to make "data" appear at the outputs
  digitalWrite(latchPin, HIGH);
  digitalWrite(latchPin, LOW);

  PORTB |= 0b00000010;
  shiftOut(softDataPin, softClockPin, MSBFIRST, 0xA5);

  // Set the softLatchPin to make "data" appear at the outputs
  PORTB &= ~0b00000010;
  digitalWrite(softLatchPin, HIGH);
  digitalWrite(softLatchPin, LOW);
  Serial.println("Done!");
}


void loop()
{
  // Looping code here
}
74HC595
74HC595
D0D1D2D3D4D5D6D7GNDLOGIC