--- /dev/null
+// Simple SPI MASTER example
+// Counts number of presses on a button connected to D2 (PD2),
+// and sends the count and the count+100 over SPI.
+// Uses a mix of Arduino and plain AVR code,
+// but does not use the Arduino SPI library.
+
+long int count=1;
+
+void setup()
+{
+ Serial.begin(115200);
+ Serial.println("Hello from MASTER")
+
+ // Declare pushbutton as input using the Arduino-way ;)
+ pinMode(2, INPUT);
+
+ // Set SCK, MOSI and SS as OUTPUTS using the AVR-way ;)
+ DDRB |= (1<<PB5)|(1<<PB3)|(1<<PB2);
+ // Enable SPI, MASTER mode, Fosc/64
+ SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1);
+
+ // Make sure SS is pulled HIGH
+ spi_ss_end();
+
+}
+
+void loop()
+{
+ // Loop with no action until button-pressed is
+ // detected
+ if (digitalRead(2)==HIGH)
+ {
+ // Wait for button to go back to "idle"
+ while (digitalRead(2)==HIGH) {}
+
+ count=count+1; // Increment count
+
+ Serial.print("Count: ");
+ Serial.println(count, DEC);
+
+ spi_ss_start(); // Set /CS (SS) LOW for transmission
+ spi_rw(count); // Send current count
+ spi_rw(count+100); // and a +100 version ;)
+ spi_ss_end(); // Re-set /CS (SS) HIGH after transmission
+
+ }
+}
+
+// Using SS as outgoing /CS pin
+void spi_ss_start()
+{
+ PORTB &= ~(1<<PB2); // Set SS low using AVR logic ;)
+}
+void spi_ss_end()
+{
+ PORTB |= (1<<PB2); // Set SS high using AVR logic ;)
+}
+
+uint8_t spi_rw( uint8_t d )
+{
+ SPDR = d; // Start the transmission
+ while (!(SPSR & (1<<SPIF))); // Wait for transmission to complete
+ return SPDR; // Return the resulting register content
+}
+
--- /dev/null
+// Interrupt-driven SPI SLAVE example
+// Recieves bytes over SPI and stuffs them in
+// a sort-of-circular-buffer that is printed to Serial.
+// Uses a mix of Arduino and plain AVR code,
+// but does not use the Arduino SPI library.
+
+#include <avr/interrupt.h>
+
+volatile uint8_t buffer[16];
+volatile uint8_t bptr;
+
+
+void setup()
+{
+ Serial.begin(115200);
+ Serial.println("Hello from SLAVE")
+
+ // A nice little debug/status pin, set as OUTPUT using the Arduino-way ;)
+ pinMode(7, OUTPUT);
+
+ // Make sure our buffer-pointer starts at the first buffer byte (pos 0)
+ bptr = 0;
+
+ // Set MISO as OUTPUT using the AVR-way ;)
+ DDRB=(1<<DDB4);
+ // Enable SPI (default Slave) and enable SPI interrupts
+ SPCR=(1<<SPE)|(1<<SPIE);
+
+ // Activate interrupts
+ sei();
+}
+
+void loop()
+{
+ // In the main loop, simply output the buffer contents, over and over again..
+ Serial.print("b ");
+ for ( uint8_t i = 0; i <= 15; i++ )
+ {
+ Serial.print(i);
+ Serial.print(" = ");
+ Serial.print(buffer[i]);
+ Serial.print(" ");
+ }
+ Serial.println(" ... ");
+ delay(500);
+}
+
+// The ISR for SPI Serial Transfer Complete gets triggered
+// on each byte transferred.
+ISR(SPI_STC_vect)
+{
+ // Put data in buffer, increment buffer pointer, wrap around on end.
+ buffer[bptr] = spi_read();
+ bptr++;
+ if (bptr > 15) bptr = 0;
+}
+
+uint8_t spi_read( ){
+ // Getting the transferred byte is as imple as reading the Data Register
+ // each time a byte has completed transfer. This and the ISR, needs to be
+ // quick, so that the next byte does not overwrite the current one.
+
+ // Sending is done by setting the data register before reading ...
+ SPDR = 0;
+ uint8_t d = SPDR;
+
+ // Let's add some fun "things happen because of transfers"...
+ if ( d == 45 ) digitalWrite(7, ( !digitalRead(7) ) );
+
+ return d;
+}
+
+
+