I modified one of the examples (Gammon Forum : Electronics : Microprocessors : SPI - Serial Peripheral Interface - for Arduino) such that the Master sends the string "Hello, World!\n" to the Slave.
My intention was to have the Slave send back the same string to the master as it is received, although that is not what is occuring.
Here is the Master Code:
/* SPI Master - Hello World (derived from Nick Gammon's samples)
Arduino Mega is acting as an SPI Master for
a corresponding Arduino Mega board
Circuit:
SS_PIN: pin 53
MISO: pin 50
MOSI: pin 51
SCK: pin 52
*/
#include <stdlib.h>
#include <SPI.h>
long int count = 1;
byte config = B01010000;
#define SCK_PIN 52
#define MISO_PIN 50
#define MOSI_PIN 51
#define SS_PIN 53
uint8_t buffer[128];
char respBuffer[100];
volatile byte pos;
volatile boolean process_it;
void setup()
{
byte tmp;
// Put SCK, MOSI, SS pins into output mode
// also put SCK, MOSI into LOW state, and SS into HIGH state.
// Then put SPI hardware into Master mode and turn SPI on
pinMode(MOSI_PIN, OUTPUT);
pinMode(MISO_PIN, INPUT);
pinMode(SCK_PIN, OUTPUT);
pinMode(SS_PIN, OUTPUT);
digitalWrite(SS_PIN, HIGH); // Ensure SS stays high for now
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV16);
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1);
byte clr;
clr=SPSR;
clr=SPDR;
Serial.begin(115200);
}
byte transferAndWait(const byte what)
{
byte a = SPI.transfer(what);
delayMicroseconds(20);
return a;
} // end of transferAndWait
void loop()
{
char c;
byte r;
// enable Slave Select
digitalWrite(SS_PIN, LOW);
pos=0;
// Send test string
for (const char *p="Hello, world!\n";c=*p;p++)
{
//SPI.transfer(c);
r=transferAndWait(c);
respBuffer[pos++]=r;
Serial.print(c);
Serial.print(r);
}
//respBuffer[pos]=0;
Serial.println("RX:");
Serial.println(pos,DEC);
Serial.println(respBuffer);
pos=0;
delay(100);
// Disable slave select
digitalWrite(SS_PIN, HIGH);
// 1 second delay
delay(100);
}
Here is the Slave code:
/* SPI Slave - Hello World (from Nick Gammon's sample)
Arduino Mega ADK is acting as an SPI Slave while
a corresponding Arduino Duemilanove is acting as the
SPI Master
Circuit:
SS_PIN: pin 53
MISO: pin 50
MOSI: pin 51
SCK: pin 52
*/
#include <stdlib.h>
#include <SPI.h>
long int count = 1;
uint8_t buffer[3];
char buf [100];
volatile byte pos;
volatile boolean process_it;
#define SCK_PIN 52
#define MISO_PIN 50
#define MOSI_PIN 51
#define SS_PIN 53
void setup (void)
{
Serial.begin (115200); // debugging
// have to send on master in, *slave out*
pinMode(MOSI_PIN, INPUT);
pinMode(MISO_PIN, OUTPUT);
pinMode(SCK_PIN, INPUT);
pinMode(SS_PIN, INPUT);
//SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV16);
DDRB=(1<<DDB4); //prev
SPCR=(1<<SPE); //prev
// turn on SPI in slave mode
SPCR |= _BV(SPE);
// turn on interrupts
SPCR != _BV(SPIE);
// get ready for an interrupt
pos = 0; // buffer empty
process_it = false;
// now turn on interrupts
SPI.attachInterrupt();
// interrupt for SS falling edge
//attachInterrupt (0, ss_falling, FALLING);
} // end of setup
// SPI interrupt routine
ISR (SPI_STC_vect)
{
byte c = SPDR; // grab byte from SPI Data Register
// add to buffer if room
if (pos < sizeof buf)
{
buf [pos++] = c;
SPDR = c; // Added response - return same string
// example: newline means time to process buffer
if (c == '\n')
process_it = true;
} // end of room available
} // end of interrupt routine SPI_STC_vect
// main loop - wait for flag set in interrupt routine
void loop (void)
{
char c;
if (process_it)
{
buf [pos] = 0;
Serial.println (buf);
pos = 0;
process_it = false;
// Send response test string to Master
//for (const char * p = "Goodbye, earth!\n" ; c = *p; p++)
// SPDR=c; //SPI.transfer(c);
} // end of flag set
} // end of loop
The slave outputs the expected message:
Hello, world!
However, the master outputs the following (what is expected to be Hello World! from the slave are non visible chars - left blank here):
H e l l o W o r l d !
RX:
14
Do you know what I am doing wrong ?