Software SPI
Software SPI is likely to be of use only for ESP8266, but is enabled for all architectures.
The ESP8266 can manage a minimum of about 70ns between bit edges, with a maximum of about 1.8 MBit/s at normal CPU clock frequency or 2.5 MHz if CPU clock set to fast.
Configuration Variables
- SPISOFT_DELAY_VARIABLE
default: 0 (disabled)
This setting must be enabled in order to use
SPISoft::setDelay()
. The base clock speed (i.e. delay=0) is reduced to about 1.4 MBit/s (2.1 MBit/s for fast CPU).The appropriate delay factor can be provided in the
SPISoft
constructor, or by callingSPISoft::setDelay()
.With the ESP8266, then the appropriate delay factor is calculated automatically from the speed passed in
SPISettings
. This will override any previously set delay factor. Use a speed of 0 to use the manually configured delay value.
- SPISOFT_DELAY_FIXED
default: 0 (disabled) maximum: 10
Adds the requested number of ‘NOP’ CPU instructions to every clock transition.
Has less impact than enabling variable delays.
Use variable delays if 10 is insufficient.
Will be ignored if variable delays are enabled.
Performance
The following information has been obtained by measurement. The test application was built using:
make SPISOFT_CALIBRATE=1 SPISOFT_DELAY_VARIABLE=1 CPU_FAST=0
then flashed to an ESP-12F. An oscilliscope was hooked up to the SCK output and the maximum frequency at each delay setting noted. (Not too awkward, just note down the frequency each time the figure changes.)
Entering these into the spisoft.ods spreadsheet allows the values to be charted and co-efficients calculated.
Curiously values from 8 upward form a straight line so we can calculate those. Smaller values are non-linear so a small lookup table is used.
Repeat for CPU_FAST=1.
Note that these figures are concerned with maximum (i.e. burst) frequencies at each delay setting, since that is what devices are sensitive to.
80 MHz CPU

. |
Frequency (kHz) |
|
---|---|---|
Delay |
Variable |
Fixed |
0 |
1357 |
2288 |
1 |
1315 |
1869 |
2 |
1215 |
1824 |
3 |
1129 |
1780 |
4 |
1055 |
1744 |
5 |
990 |
1709 |
6 |
932 |
1639 |
7 |
881 |
1575 |
8 |
819 |
1511 |
9 |
743 |
1462 |
10 |
680 |
1408 |
11 |
626 |
1338 |
12 |
578 |
1294 |
20 |
367 |
|
30 |
251 |
|
40 |
192 |
|
50 |
155 |
|
60 |
129 |
|
70 |
112 |
|
80 |
98 |
|
90 |
87 |
|
100 |
79 |
160 MHz CPU

. |
Frequency (kHz) |
|
---|---|---|
Delay |
Variable |
Fixed |
0 |
2133 |
2857 |
1 |
2126 |
2510 |
2 |
2106 |
2500 |
3 |
1958 |
2439 |
4 |
1861 |
2429 |
5 |
1745 |
2372 |
6 |
1668 |
2353 |
7 |
1573 |
2294 |
8 |
1482 |
2283 |
9 |
1357 |
2242 |
10 |
1250 |
2222 |
11 |
1160 |
2174 |
12 |
1081 |
2165 |
20 |
702 |
|
30 |
488 |
|
40 |
374 |
|
50 |
303 |
|
60 |
255 |
|
70 |
220 |
|
80 |
193 |
|
90 |
172 |
|
100 |
156 |
API Documentation
-
class SPISoft : public SPIBase
- #include <SPISoft.h>
Software-based SPI master.
Intended for ESP8266 due to limited I/O but will work on any architecture.
Constructors
-
SPISoft()
Default constructor uses same pins as hardware SPI.
-
inline SPISoft(uint8_t miso, uint8_t mosi, uint8_t sck, uint8_t delay = 0)
Specify pins to use plus optional delay.
Delay is ignored if code is not compiled with SPISOFT_DELAY < 0.
-
SPISoft(uint8_t delay)
Use default pins but provide a delay.
Public Functions
-
virtual bool begin() override
Initialize the SPI bus by setting SCK and MOSI to outputs, pulling SCK and MOSI low.
-
inline virtual void end() override
Disable the SPI bus (leaving pin modes unchanged).
-
virtual void endTransaction() override
Stop using the SPI bus. Normally this is called after de-asserting the chip select, to allow other libraries to use the SPI bus.
-
virtual uint32_t transfer32(uint32_t val, uint8_t bits = 32) override
Send/receive a word of variable size.
Word is transferred either MSB first (bits-1) or LSB first (bit 0) depending on the currently applied bitOrder setting.
- Parameters:
val – Word to send
bits – Size of word
-
virtual void transfer(uint8_t *buffer, size_t size) override
Send/receive a variable-length block of data.
- Parameters:
buffer – IN: The data to send; OUT: The received data
size – Number of bytes to transfer
-
inline void setDelay(uint8_t delay)
Set delay factor for the SCK signal. Impacts SPI speed.
Requires code to be compiled with SPISOFT_DELAY < 0.
ESP8266 only: The delay will be automatically calculated for a requested clock speed when
begin()
orbeginTransaction()
are called. To use only the manually programmed delay, set the clock speed to zero.
-
inline virtual bool loopback(bool enable) override
For testing, tie MISO <-> MOSI internally.
Note: Not included in std Arduino lib
-
inline uint8_t transfer(uint8_t val)
Send/receive one byte of data.
- Parameters:
val – The byte to send
- Return values:
uint8_t – The received byte
-
void transfer(uint8_t *buffer, size_t size) = 0
Send/receive a variable-length block of data.
- Parameters:
buffer – IN: The data to send; OUT: The received data
size – Number of bytes to transfer
-
SPISoft()