|
20 | 20 | // usingInterrupt(), and SPISetting(clock, bitOrder, dataMode)
|
21 | 21 | #define SPI_HAS_TRANSACTION 1
|
22 | 22 |
|
| 23 | +// SPI_ATOMIC_VERSION means that SPI has atomicity fixes and what version. |
| 24 | +// This way when there is a bug fix you can check this define to alert users |
| 25 | +// of your code if it uses better version of this library. |
| 26 | +// This also implies everything that SPI_HAS_TRANSACTION as documented above is |
| 27 | +// available too. |
| 28 | +#define SPI_ATOMIC_VERSION 1 |
| 29 | + |
23 | 30 | // Uncomment this line to add detection of mismatched begin/end transactions.
|
24 | 31 | // A mismatch occurs if other libraries fail to use SPI.endTransaction() for
|
25 | 32 | // each SPI.beginTransaction(). Connect an LED to this pin. The LED will turn
|
@@ -167,25 +174,33 @@ class SPIClass {
|
167 | 174 | // this function is used to gain exclusive access to the SPI bus
|
168 | 175 | // and configure the correct settings.
|
169 | 176 | inline static void beginTransaction(SPISettings settings) {
|
170 |
| - if (modeFlags.interruptMode > 0) { |
171 |
| - #ifdef SPI_AVR_EIMSK |
172 |
| - if (modeFlags.interruptMode == 1) { |
173 |
| - interruptSave = SPI_AVR_EIMSK; |
174 |
| - SPI_AVR_EIMSK &= ~interruptMask; |
175 |
| - } else |
176 |
| - #endif |
177 |
| - { |
178 |
| - interruptSave = SREG; |
179 |
| - cli(); |
180 |
| - } |
181 |
| - } |
| 177 | + uint8_t sreg = SREG; |
| 178 | + noInterrupts(); |
182 | 179 | #ifdef SPI_TRANSACTION_MISMATCH_LED
|
183 | 180 | if (modeFlags.inTransaction) {
|
184 | 181 | pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
|
185 | 182 | digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
|
186 | 183 | }
|
187 | 184 | modeFlags.inTransaction = true;
|
188 | 185 | #endif
|
| 186 | + |
| 187 | + #ifndef SPI_AVR_EIMSK |
| 188 | + if (modeFlags.interruptMode) { |
| 189 | + interruptSave = sreg; |
| 190 | + } |
| 191 | + #else |
| 192 | + if (modeFlags.interruptMode == 2) { |
| 193 | + interruptSave = sreg; |
| 194 | + } else if (modeFlags.interruptMode == 1) { |
| 195 | + interruptSave = SPI_AVR_EIMSK; |
| 196 | + SPI_AVR_EIMSK &= ~interruptMask; |
| 197 | + SREG = sreg; |
| 198 | + } |
| 199 | + #endif |
| 200 | + else { |
| 201 | + SREG = sreg; |
| 202 | + } |
| 203 | + |
189 | 204 | SPCR = settings.spcr;
|
190 | 205 | SPSR = settings.spsr;
|
191 | 206 | }
|
@@ -238,23 +253,31 @@ class SPIClass {
|
238 | 253 | // After performing a group of transfers and releasing the chip select
|
239 | 254 | // signal, this function allows others to access the SPI bus
|
240 | 255 | inline static void endTransaction(void) {
|
| 256 | + uint8_t sreg = SREG; |
| 257 | + noInterrupts(); |
241 | 258 | #ifdef SPI_TRANSACTION_MISMATCH_LED
|
242 | 259 | if (!modeFlags.inTransaction) {
|
243 | 260 | pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
|
244 | 261 | digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
|
245 | 262 | }
|
246 | 263 | modeFlags.inTransaction = false;
|
247 | 264 | #endif
|
248 |
| - if (modeFlags.interruptMode > 0) { |
249 |
| - #ifdef SPI_AVR_EIMSK |
| 265 | + #ifndef SPI_AVR_EIMSK |
| 266 | + if (modeFlags.interruptMode) { |
| 267 | + SREG = interruptSave; |
| 268 | + } else { |
| 269 | + SREG = sreg; |
| 270 | + } |
| 271 | + #else |
| 272 | + if (modeFlags.interruptMode == 2) { |
| 273 | + SREG = interruptSave; |
| 274 | + } else { |
250 | 275 | if (modeFlags.interruptMode == 1) {
|
251 | 276 | SPI_AVR_EIMSK = interruptSave;
|
252 |
| - } else |
253 |
| - #endif |
254 |
| - { |
255 |
| - SREG = interruptSave; |
256 | 277 | }
|
| 278 | + SREG = sreg; |
257 | 279 | }
|
| 280 | + #endif |
258 | 281 | }
|
259 | 282 |
|
260 | 283 | // Disable the SPI bus
|
|
0 commit comments