So I am trying to have a full-duplex high-speed(I'll be reducing the delay to microseconds once the below problem is solved) comm. between two Arduino Unos. Here is the code below:
Master:
volatile uint8_t rdata;
#define SCK 13 // D13 = pin19 = PortB.5
#define MISO 12 // D12 = pin18 = PortB.4
#define MOSI 11 // D11 = pin17 = PortB.3
#define SS 10 // D10 = pin16 = PortB.2
void SPI_MasterInit(void)
{
/* Set MOSI and SCK output, all others input */
//DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
pinMode(MOSI, OUTPUT);
pinMode(MISO, INPUT);
pinMode(SCK, OUTPUT);
pinMode(SS, OUTPUT);
/* Enable SPI, Master, set clock rate fck/4 */
SPCR = (1 << SPE) | (1 << MSTR) | (0 << SPI2X) | (0 << SPR1) | (0 << SPR0) ;
SPCR |= _BV(CPOL);
//SPCR |= _BV(CPHA);
}
void SPI_MasterTransmit(uint8_t data) {
PORTB &= ~(1<<2);
SPDR = data;
//asm volatile("nop");
while (!(SPSR & (1 << SPIF)));
rdata = SPDR;
PORTB |= 1 << 2;
Serial.print("data "); Serial.print(data); Serial.print(" rdata "); Serial.println (rdata);
}
void setup (void)
{
Serial.begin(115200);
PORTB |= 1 << 2; //digitalWrite(SS, HIGH);
SPI_MasterInit();
}
void loop (void)
{
for (byte i = 0; i < 10; i++) {
SPI_MasterTransmit(i);
//Serial.print(m);
delay(100);
}
}
Slave:
volatile boolean process_it;
volatile byte indx = 129, c = 0;
#define SCK 13 // D13 = pin19 = PortB.5
#define MISO 12 // D12 = pin18 = PortB.4
#define MOSI 11 // D11 = pin17 = PortB.3
#define SS 10 // D10 = pin16 = PortB.2
void SPI_SlaveInit(void)
{
/* Set MISO output, all others input */
//DDR_SPI = (1<<DD_MISO);
pinMode(MOSI, INPUT);
pinMode(MISO, OUTPUT);
pinMode(SCK, INPUT);
pinMode(SS, INPUT);
/* Enable SPI */
SPCR |= _BV(SPE); // SPI Enable, sets this Arduino to Slave
SPCR |= _BV(SPIE); // SPI interrupt enabled
SPCR |= _BV(CPOL);
//SPCR |= _BV(CPHA);
}
void setup (void)
{
Serial.begin (115200);
SPI_SlaveInit();
}
// SPI interrupt routine
ISR (SPI_STC_vect)
{
SPDR = indx;
indx--;
if (indx < 121)
indx = 129;
c = SPDR;
process_it = true;
}
void loop (void)
{
if (process_it) {
Serial.println (c);
process_it = false;
}
}
Below output shows the o/p of the master on the left and slave one the right:
The master prints the data it has sent(to the slave, "data" variable) followed by the data it has received (from the slave, "rdata" variable). The slave simply prints the received data (from the master).
If you look carefully at the pic you would see that the master sometimes gets the same data (in the next cycle) it has sent (in the current cycle) (0 and 4 in the pic). At the same time, the slave fails to receive exactly that data (0,4). Also, you can the value of 'indx' is not decremented and the master receives the decremented value in the next cycle. These two things prove that the Slave ISR is not being called randomly (hence the data in the SPDR is not read which is then echoed back to the master plus the index variable is not decremented). Is there a solution to this? I would be really grateful if someone could help me with this.
Also, I face the exact same problem with the current SPI library too.