Skip to content

Commit 4217e49

Browse files
me-no-devigrr
authored andcommitted
Initial SPI Slave implementation and examples (#2234)
* Initial SPI Slave implementation and examples * Update style and info
1 parent 2364ad4 commit 4217e49

File tree

9 files changed

+704
-0
lines changed

9 files changed

+704
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
SPI Master Demo Sketch
3+
Connect the SPI Master device to the following pins on the esp8266:
4+
5+
GPIO NodeMCU Name | Uno
6+
===================================
7+
15 D8 SS | D10
8+
13 D7 MOSI | D11
9+
12 D6 MISO | D12
10+
14 D5 SCK | D13
11+
12+
Note: If the ESP is booting at a moment when the SPI Master has the Select line HIGH (deselected)
13+
the ESP8266 WILL FAIL to boot!
14+
See SPISlave_SafeMaster example for possible workaround
15+
16+
*/
17+
#include <SPI.h>
18+
19+
class ESPMaster
20+
{
21+
private:
22+
uint8_t _ss_pin;
23+
24+
public:
25+
ESPMaster(uint8_t pin):_ss_pin(pin) {}
26+
void begin()
27+
{
28+
pinMode(_ss_pin, OUTPUT);
29+
digitalWrite(_ss_pin, HIGH);
30+
}
31+
32+
uint32_t readStatus()
33+
{
34+
digitalWrite(_ss_pin, LOW);
35+
SPI.transfer(0x04);
36+
uint32_t status = (SPI.transfer(0) | ((uint32_t)(SPI.transfer(0)) << 8) | ((uint32_t)(SPI.transfer(0)) << 16) | ((uint32_t)(SPI.transfer(0)) << 24));
37+
digitalWrite(_ss_pin, HIGH);
38+
return status;
39+
}
40+
41+
void writeStatus(uint32_t status)
42+
{
43+
digitalWrite(_ss_pin, LOW);
44+
SPI.transfer(0x01);
45+
SPI.transfer(status & 0xFF);
46+
SPI.transfer((status >> 8) & 0xFF);
47+
SPI.transfer((status >> 16) & 0xFF);
48+
SPI.transfer((status >> 24) & 0xFF);
49+
digitalWrite(_ss_pin, HIGH);
50+
}
51+
52+
void readData(uint8_t * data)
53+
{
54+
digitalWrite(_ss_pin, LOW);
55+
SPI.transfer(0x03);
56+
SPI.transfer(0x00);
57+
for(uint8_t i=0; i<32; i++) {
58+
data[i] = SPI.transfer(0);
59+
}
60+
digitalWrite(_ss_pin, HIGH);
61+
}
62+
63+
void writeData(uint8_t * data, size_t len)
64+
{
65+
uint8_t i=0;
66+
digitalWrite(_ss_pin, LOW);
67+
SPI.transfer(0x02);
68+
SPI.transfer(0x00);
69+
while(len-- && i < 32) {
70+
SPI.transfer(data[i++]);
71+
}
72+
while(i++ < 32) {
73+
SPI.transfer(0);
74+
}
75+
digitalWrite(_ss_pin, HIGH);
76+
}
77+
78+
String readData()
79+
{
80+
char data[33];
81+
data[32] = 0;
82+
readData((uint8_t *)data);
83+
return String(data);
84+
}
85+
86+
void writeData(const char * data)
87+
{
88+
writeData((uint8_t *)data, strlen(data));
89+
}
90+
};
91+
92+
ESPMaster esp(SS);
93+
94+
void send(const char * message)
95+
{
96+
Serial.print("Master: ");
97+
Serial.println(message);
98+
esp.writeData(message);
99+
delay(10);
100+
Serial.print("Slave: ");
101+
Serial.println(esp.readData());
102+
Serial.println();
103+
}
104+
105+
void setup()
106+
{
107+
Serial.begin(115200);
108+
SPI.begin();
109+
esp.begin();
110+
delay(1000);
111+
send("Hello Slave!");
112+
}
113+
114+
void loop()
115+
{
116+
delay(1000);
117+
send("Are you alive?");
118+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
SPI Safe Master Demo Sketch
3+
Connect the SPI Master device to the following pins on the esp8266:
4+
5+
GPIO NodeMCU Name | Uno
6+
===================================
7+
15 D8 SS | D10
8+
13 D7 MOSI | D11
9+
12 D6 MISO | D12
10+
14 D5 SCK | D13
11+
12+
Note: If the ESP is booting at a moment when the SPI Master has the Select line HIGH (deselected)
13+
the ESP8266 WILL FAIL to boot!
14+
This sketch tries to go around this issue by only pulsing the Slave Select line to reset the command
15+
and keeping the line LOW all other time.
16+
17+
*/
18+
#include <SPI.h>
19+
20+
class ESPSafeMaster
21+
{
22+
private:
23+
uint8_t _ss_pin;
24+
void _pulseSS()
25+
{
26+
digitalWrite(_ss_pin, HIGH);
27+
delayMicroseconds(5);
28+
digitalWrite(_ss_pin, LOW);
29+
}
30+
public:
31+
ESPSafeMaster(uint8_t pin):_ss_pin(pin) {}
32+
void begin()
33+
{
34+
pinMode(_ss_pin, OUTPUT);
35+
_pulseSS();
36+
}
37+
38+
uint32_t readStatus()
39+
{
40+
_pulseSS();
41+
SPI.transfer(0x04);
42+
uint32_t status = (SPI.transfer(0) | ((uint32_t)(SPI.transfer(0)) << 8) | ((uint32_t)(SPI.transfer(0)) << 16) | ((uint32_t)(SPI.transfer(0)) << 24));
43+
_pulseSS();
44+
return status;
45+
}
46+
47+
void writeStatus(uint32_t status)
48+
{
49+
_pulseSS();
50+
SPI.transfer(0x01);
51+
SPI.transfer(status & 0xFF);
52+
SPI.transfer((status >> 8) & 0xFF);
53+
SPI.transfer((status >> 16) & 0xFF);
54+
SPI.transfer((status >> 24) & 0xFF);
55+
_pulseSS();
56+
}
57+
58+
void readData(uint8_t * data)
59+
{
60+
_pulseSS();
61+
SPI.transfer(0x03);
62+
SPI.transfer(0x00);
63+
for(uint8_t i=0; i<32; i++) {
64+
data[i] = SPI.transfer(0);
65+
}
66+
_pulseSS();
67+
}
68+
69+
void writeData(uint8_t * data, size_t len)
70+
{
71+
uint8_t i=0;
72+
_pulseSS();
73+
SPI.transfer(0x02);
74+
SPI.transfer(0x00);
75+
while(len-- && i < 32) {
76+
SPI.transfer(data[i++]);
77+
}
78+
while(i++ < 32) {
79+
SPI.transfer(0);
80+
}
81+
_pulseSS();
82+
}
83+
84+
String readData()
85+
{
86+
char data[33];
87+
data[32] = 0;
88+
readData((uint8_t *)data);
89+
return String(data);
90+
}
91+
92+
void writeData(const char * data)
93+
{
94+
writeData((uint8_t *)data, strlen(data));
95+
}
96+
};
97+
98+
ESPSafeMaster esp(SS);
99+
100+
void send(const char * message)
101+
{
102+
Serial.print("Master: ");
103+
Serial.println(message);
104+
esp.writeData(message);
105+
delay(10);
106+
Serial.print("Slave: ");
107+
Serial.println(esp.readData());
108+
Serial.println();
109+
}
110+
111+
void setup()
112+
{
113+
Serial.begin(115200);
114+
SPI.begin();
115+
esp.begin();
116+
delay(1000);
117+
send("Hello Slave!");
118+
}
119+
120+
void loop()
121+
{
122+
delay(1000);
123+
send("Are you alive?");
124+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
SPI Slave Demo Sketch
3+
Connect the SPI Master device to the following pins on the esp8266:
4+
5+
GPIO NodeMCU Name | Uno
6+
===================================
7+
15 D8 SS | D10
8+
13 D7 MOSI | D11
9+
12 D6 MISO | D12
10+
14 D5 SCK | D13
11+
12+
Note: If the ESP is booting at a moment when the SPI Master has the Select line HIGH (deselected)
13+
the ESP8266 WILL FAIL to boot!
14+
See SPISlave_SafeMaster example for possible workaround
15+
16+
*/
17+
18+
#include "SPISlave.h"
19+
20+
void setup()
21+
{
22+
Serial.begin(115200);
23+
Serial.setDebugOutput(true);
24+
25+
// data has been received from the master. Beware that len is always 32
26+
// and the buffer is autofilled with zeroes if data is less than 32 bytes long
27+
// It's up to the user to implement protocol for handling data length
28+
SPISlave.onData([](uint8_t * data, size_t len) {
29+
String message = String((char *)data);
30+
if(message.equals("Hello Slave!")) {
31+
SPISlave.setData("Hello Master!");
32+
} else if(message.equals("Are you alive?")) {
33+
char answer[33];
34+
sprintf(answer,"Alive for %u seconds!", millis() / 1000);
35+
SPISlave.setData(answer);
36+
} else {
37+
SPISlave.setData("Say what?");
38+
}
39+
Serial.printf("Question: %s\n", (char *)data);
40+
});
41+
42+
// The master has read out outgoing data buffer
43+
// that buffer can be set with SPISlave.setData
44+
SPISlave.onDataSent([]() {
45+
Serial.println("Answer Sent");
46+
});
47+
48+
// status has been received from the master.
49+
// The status register is a special register that bot the slave and the master can write to and read from.
50+
// Can be used to exchange small data or status information
51+
SPISlave.onStatus([](uint32_t data) {
52+
Serial.printf("Status: %u\n", data);
53+
SPISlave.setStatus(millis()); //set next status
54+
});
55+
56+
// The master has read the status register
57+
SPISlave.onStatusSent([]() {
58+
Serial.println("Status Sent");
59+
});
60+
61+
// Setup SPI Slave registers and pins
62+
SPISlave.begin();
63+
64+
// Set the status register (if the master reads it, it will read this value)
65+
SPISlave.setStatus(millis());
66+
67+
// Sets the data registers. Limited to 32 bytes at a time.
68+
// SPISlave.setData(uint8_t * data, size_t len); is also available with the same limitation
69+
SPISlave.setData("Ask me a question!");
70+
}
71+
72+
void loop() {}

libraries/SPISlave/keywords.txt

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#######################################
2+
# Syntax Coloring Map SPI Slave
3+
#######################################
4+
5+
#######################################
6+
# Datatypes (KEYWORD1)
7+
#######################################
8+
9+
SPISlave KEYWORD1
10+
11+
#######################################
12+
# Methods and Functions (KEYWORD2)
13+
#######################################
14+
15+
begin KEYWORD2
16+
setData KEYWORD2
17+
setStatus KEYWORD2
18+
onData KEYWORD2
19+
onDataSent KEYWORD2
20+
onStatus KEYWORD2
21+
onStatusSent KEYWORD2
22+
23+
#######################################
24+
# Constants (LITERAL1)
25+
#######################################

libraries/SPISlave/library.properties

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name=SPISlave
2+
version=1.0
3+
author=Hristo Gochkov
4+
maintainer=Hristo Gochkov <[email protected]>
5+
sentence=SPI Slave library for ESP8266
6+
paragraph=
7+
category=Signal Input/Output
8+
url=
9+
architectures=esp8266

0 commit comments

Comments
 (0)