Skip to content

Commit 841e75d

Browse files
committed
[avr] Use a bitfield structure to save SPI state (Andrew Kroll)
1 parent 51dcd9c commit 841e75d

File tree

2 files changed

+21
-20
lines changed

2 files changed

+21
-20
lines changed

hardware/arduino/avr/libraries/SPI/SPI.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,9 @@
1313
#include "pins_arduino.h"
1414

1515
SPIClass SPI;
16-
17-
uint8_t SPIClass::interruptMode = 0;
16+
SPIflags_t SPIClass::modeFlags = {false, false, 0};
1817
uint8_t SPIClass::interruptMask = 0;
1918
uint8_t SPIClass::interruptSave = 0;
20-
#ifdef SPI_TRANSACTION_MISMATCH_LED
21-
uint8_t SPIClass::inTransactionFlag = 0;
22-
#endif
2319

2420
void SPIClass::begin()
2521
{
@@ -92,7 +88,7 @@ void SPIClass::usingInterrupt(uint8_t interruptNumber)
9288
{
9389
uint8_t mask;
9490

95-
if (interruptMode > 1) return;
91+
if (modeFlags.interruptMode > 1) return;
9692

9793
noInterrupts();
9894
switch (interruptNumber) {
@@ -121,11 +117,11 @@ void SPIClass::usingInterrupt(uint8_t interruptNumber)
121117
case 7: mask = SPI_INT7_MASK; break;
122118
#endif
123119
default:
124-
interruptMode = 2;
120+
modeFlags.interruptMode = 2;
125121
interrupts();
126122
return;
127123
}
128-
interruptMode = 1;
124+
modeFlags.interruptMode = 1;
129125
interruptMask |= mask;
130126
interrupts();
131127
}

hardware/arduino/avr/libraries/SPI/SPI.h

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@
4949
#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR
5050
#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR
5151

52+
// Flags for the state of SPI, used as needed.
53+
// Normally inTransaction is not used.
54+
typedef struct SPIflags {
55+
bool padding : 1;
56+
bool inTransaction : 1;
57+
uint8_t interruptMode : 6; // 0=none, 1=mask, 2=global (more can be added)
58+
} __attribute__((packed)) SPIflags_t;
59+
5260
// define SPI_AVR_EIMSK for AVR boards with external interrupt pins
5361
#if defined(EIMSK)
5462
#define SPI_AVR_EIMSK EIMSK
@@ -158,9 +166,9 @@ class SPIClass {
158166
// this function is used to gain exclusive access to the SPI bus
159167
// and configure the correct settings.
160168
inline static void beginTransaction(SPISettings settings) {
161-
if (interruptMode > 0) {
169+
if (modeFlags.interruptMode > 0) {
162170
#ifdef SPI_AVR_EIMSK
163-
if (interruptMode == 1) {
171+
if (modeFlags.interruptMode == 1) {
164172
interruptSave = SPI_AVR_EIMSK;
165173
SPI_AVR_EIMSK &= ~interruptMask;
166174
} else
@@ -171,11 +179,11 @@ class SPIClass {
171179
}
172180
}
173181
#ifdef SPI_TRANSACTION_MISMATCH_LED
174-
if (inTransactionFlag) {
182+
if (modeFlags.inTransaction) {
175183
pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
176184
digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
177185
}
178-
inTransactionFlag = 1;
186+
modeFlags.inTransaction = true;
179187
#endif
180188
SPCR = settings.spcr;
181189
SPSR = settings.spsr;
@@ -230,15 +238,15 @@ class SPIClass {
230238
// signal, this function allows others to access the SPI bus
231239
inline static void endTransaction(void) {
232240
#ifdef SPI_TRANSACTION_MISMATCH_LED
233-
if (!inTransactionFlag) {
241+
if (!modeFlags.inTransaction) {
234242
pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
235243
digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
236244
}
237-
inTransactionFlag = 0;
245+
modeFlags.inTransaction = false;
238246
#endif
239-
if (interruptMode > 0) {
247+
if (modeFlags.interruptMode > 0) {
240248
#ifdef SPI_AVR_EIMSK
241-
if (interruptMode == 1) {
249+
if (modeFlags.interruptMode == 1) {
242250
SPI_AVR_EIMSK = interruptSave;
243251
} else
244252
#endif
@@ -275,12 +283,9 @@ class SPIClass {
275283
inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); }
276284

277285
private:
278-
static uint8_t interruptMode; // 0=none, 1=mask, 2=global
286+
static SPIflags_t modeFlags; // Flags for the state and mode of SPI
279287
static uint8_t interruptMask; // which interrupts to mask
280288
static uint8_t interruptSave; // temp storage, to restore state
281-
#ifdef SPI_TRANSACTION_MISMATCH_LED
282-
static uint8_t inTransactionFlag;
283-
#endif
284289
};
285290

286291
extern SPIClass SPI;

0 commit comments

Comments
 (0)