-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslave_spi_speedtest.ino
108 lines (76 loc) · 2.38 KB
/
slave_spi_speedtest.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//
// SPI slave - SPI slave speedtest
//
// (see SPI master speedtest for details)
//
// -Rolf (Oct 2020)
//
// Credits:
// the SPI code below is inspired by an excellent post on the Arduino forum by user GolamMostafa:
// https://forum.arduino.cc/index.php?topic=66998.0
//
#include <stdio.h>
#include <SPI.h>
#include <Arduino.h>
#define MAGIC_BYTE 0xf0
#define NUM_BYTES 20
volatile boolean receivedFlag;
// there are two buffers - for this code, we only use the "A" buffer
volatile byte valsA[NUM_BYTES], valsB[NUM_BYTES], *vals_p;
volatile int valCount;
volatile int valIndex;
volatile boolean val_A_flag;
void setup()
{
Serial.begin(115200);
//SPI.begin(); // note: do not call this on the "slave" side
pinMode(SS, INPUT_PULLUP);
pinMode(MISO, OUTPUT); // Sets MISO as OUTPUT (Slave Out)
pinMode(SCK, INPUT);
SPCR |= _BV(SPE); // Turn on SPI in Slave Mode (AVR-only hack)
receivedFlag = false;
Serial.println("enable SPI interrupt");
SPI.attachInterrupt(); // interrupt is set for SPI communication
#ifdef NOTDEF
byte r = SPCR;
Serial.print("SPCR: (hex) "); Serial.println(r, HEX); // typically 0xC0 for slave
#endif
// now setup data buffer
valIndex = 0;
vals_p = valsA; // initially we point to the "A" buffer
val_A_flag = true;
// load current buffer with known data to send to master (0x59 0x58 0x57 ... )
byte val = 0x59;
for (int i = 0; i < NUM_BYTES; i++) {
vals_p[i] = val;
if (val == 0x50) {
val = 0x49;
} else {
val--;
}
}
valCount = NUM_BYTES; // set byte count
}
void loop()
{
if (receivedFlag) {
receivedFlag = false;
/* maybe do something interesting here? */
}
delay(10); // XXX needed??
}
ISR (SPI_STC_vect) // interrupt handler (SPI serial transfer complete)
{
byte rx, tx;
rx = SPDR; // receive a byte from master
receivedFlag = true; // Sets received as True
if (rx == MAGIC_BYTE) { // detect magic byte, which indicates "start" of transfer
valIndex = 0;
}
if (valIndex < valCount) {
tx = vals_p[valIndex++]; // access current buffer via pointer
} else {
tx = 0;
}
SPDR = tx; // return (send) a byte to master via SPDR register
}