|
| 1 | +// Shows how to use SPISlave on a single device. |
| 2 | +// Core0 runs as an SPI master and initiates a transmission to the slave |
| 3 | +// Core1 runs the SPI Slave mode and provides a unique reply to messages from the master |
| 4 | +// |
| 5 | +// Released to the public domain 2023 by Earle F. Philhower, III <[email protected]> |
| 6 | + |
| 7 | +#include <SPI.h> |
| 8 | +#include <SPISlave.h> |
| 9 | + |
| 10 | +// Wiring: |
| 11 | +// Master RX GP0 <-> GP11 Slave TX |
| 12 | +// Master CS GP1 <-> GP9 Slave CS |
| 13 | +// Master CK GP2 <-> GP10 Slave CK |
| 14 | +// Master TX GP3 <-> GP8 Slave RX |
| 15 | + |
| 16 | +SPISettings spisettings(1000000, MSBFIRST, SPI_MODE0); |
| 17 | + |
| 18 | +// Core 0 will be SPI master |
| 19 | +void setup() { |
| 20 | + SPI.setRX(0); |
| 21 | + SPI.setCS(1); |
| 22 | + SPI.setSCK(2); |
| 23 | + SPI.setTX(3); |
| 24 | + SPI.begin(true); |
| 25 | + |
| 26 | + delay(5000); |
| 27 | +} |
| 28 | + |
| 29 | +int transmits = 0; |
| 30 | +void loop() { |
| 31 | + char msg[42]; |
| 32 | + memset(msg, 0, sizeof(msg)); |
| 33 | + sprintf(msg, "What's up? This is transmission %d", transmits); |
| 34 | + Serial.printf("\n\nM-SEND: '%s'\n", msg); |
| 35 | + SPI.beginTransaction(spisettings); |
| 36 | + SPI.transfer(msg, sizeof(msg)); |
| 37 | + SPI.endTransaction(); |
| 38 | + Serial.printf("M-RECV: '%s'\n", msg); |
| 39 | + transmits++; |
| 40 | + delay(5000); |
| 41 | +} |
| 42 | + |
| 43 | +// Core 1 will be SPI slave |
| 44 | + |
| 45 | +volatile bool recvBuffReady = false; |
| 46 | +char recvBuff[42] = ""; |
| 47 | +int recvIdx = 0; |
| 48 | +void recvCallback(uint8_t *data, size_t len) { |
| 49 | + memcpy(recvBuff + recvIdx, data, len); |
| 50 | + recvIdx += len; |
| 51 | + if (recvIdx == sizeof(recvBuff)) { |
| 52 | + recvBuffReady = true; |
| 53 | + recvIdx = 0; |
| 54 | + } |
| 55 | +} |
| 56 | + |
| 57 | +int sendcbs = 0; |
| 58 | +// Note that the buffer needs to be long lived, the SPISlave doesn't copy it. So no local stack variables, only globals or heap(malloc/new) allocations. |
| 59 | +char sendBuff[42]; |
| 60 | +void sentCallback() { |
| 61 | + memset(sendBuff, 0, sizeof(sendBuff)); |
| 62 | + sprintf(sendBuff, "Slave to Master Xmission %d", sendcbs++); |
| 63 | + SPISlave1.setData((uint8_t*)sendBuff, sizeof(sendBuff)); |
| 64 | +} |
| 65 | + |
| 66 | +// Note that we use SPISlave1 here **not** because we're running on |
| 67 | +// Core 1, but because SPI0 is being used already. You can use |
| 68 | +// SPISlave or SPISlave1 on any core. |
| 69 | +void setup1() { |
| 70 | + SPISlave1.setRX(8); |
| 71 | + SPISlave1.setCS(9); |
| 72 | + SPISlave1.setSCK(10); |
| 73 | + SPISlave1.setTX(11); |
| 74 | + // Ensure we start with something to send... |
| 75 | + sentCallback(); |
| 76 | + // Hook our callbacks into the slave |
| 77 | + SPISlave1.onDataRecv(recvCallback); |
| 78 | + SPISlave1.onDataSent(sentCallback); |
| 79 | + SPISlave1.begin(spisettings); |
| 80 | + delay(3000); |
| 81 | + Serial.println("S-INFO: SPISlave started"); |
| 82 | +} |
| 83 | + |
| 84 | +void loop1() { |
| 85 | + if (recvBuffReady) { |
| 86 | + Serial.printf("S-RECV: '%s'\n", recvBuff); |
| 87 | + recvBuffReady = false; |
| 88 | + } |
| 89 | +} |
0 commit comments