// Listing 10.3. Szkic kodu ustawiającego tryb master w rejestrze
const int bufferSize = 64; // ustawienie wielkości buforów txBuffer oraz rxBuffer
byte txBuffer[bufferSize]; // bufor na dane oczekujące na wysłanie do urządzenia slave
byte rxBuffer[bufferSize]; // bufor na dane odebrane z urządzenia slave

void setup() {
  Serial.begin(115200);
  DDRB |= 0b00101101;  // wyjście LED(8) MOSI SCK SS
  PORTB |= 0b00000100; // ustawienie stanu wysokiego na SS
  SPCR |= 0b01010000;  // rejestr sterujący SPI; bit SPE (nr 6) włącza SPI, a MSTR (bit 4) ustawia urządzenie jako master
  SPSR |= 0b00000000;  // domyślne ustawienia SPI i przerwań
}
void loop() {
  if (Serial.available() > 0) {
    int count = 0;
    delay(50); // zwłoka na ukończenie odbioru na porcie szeregowym 
      while (Serial.available() > 0) {
        txBuffer[count] = Serial.read(); // zapisanie bufora portu szeregowego do txBuffer
        count++;  
      }
    PORTB &= 0b11111011; // włączenie sygnału SS
    transferSPI(count);
    PORTB |= 0b00000100; // wyłączenie sygnału SS
  }
  // miganie diody
  PORTB |= 0b00000001;
  delay(1000);              // oczekiwanie 1 s
  PORTB &= 0b11111110;
  delay(1000);              // oczekiwanie 1 s
}
int transferSPI(int txBytes) { 
  int count = 0;
    while (count < txBytes) {
      SPDR = txBuffer[count]; // zapis do rejestru rozpoczyna transmisję SPI
      while (!(SPSR & (1 << SPIF))); // oczekiwanie na skończenie transmisji
      rxBuffer[count] = SPDR; // odczyt odebranego pakietu
      count++;
    }
  displayBuffer(count);  
}
int displayBuffer(int nBytes) { // wyświetlenie buforów txBuffer i rxBuffer na ekranie
  Serial.write (txBuffer, nBytes);
  Serial.println();
  Serial.write (rxBuffer, nBytes);
  Serial.println();
}
