|
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