2
2
* Copyright (c) 2010 by Cristian Maglie <[email protected] >
3
3
* Copyright (c) 2014 by Paul Stoffregen <[email protected] > (Transaction API)
4
4
* Copyright (c) 2014 by Matthijs Kooijman <[email protected] > (SPISettings AVR)
5
+ * Copyright (c) 2014 by Andrew J. Kroll <[email protected] > (atomicity fixes)
5
6
* SPI Master library for arduino.
6
7
*
7
8
* This file is free software; you can redistribute it and/or modify
@@ -20,32 +21,47 @@ uint8_t SPIClass::interruptSave = 0;
20
21
21
22
void SPIClass::begin ()
22
23
{
23
- // Set SS to high so a connected chip will be "deselected" by default
24
- digitalWrite (SS, HIGH);
24
+ uint8_t sreg = SREG;
25
+ noInterrupts (); // Protect from a scheduler and prevent transactionBegin
26
+ if (!modeFlags.initialized ) {
27
+ modeFlags.initialized = true ;
28
+ // Set SS to high so a connected chip will be "deselected" by default
29
+ digitalWrite (SS, HIGH);
25
30
26
- // When the SS pin is set as OUTPUT, it can be used as
27
- // a general purpose output port (it doesn't influence
28
- // SPI operations).
29
- pinMode (SS, OUTPUT);
31
+ // When the SS pin is set as OUTPUT, it can be used as
32
+ // a general purpose output port (it doesn't influence
33
+ // SPI operations).
34
+ pinMode (SS, OUTPUT);
30
35
31
- // Warning: if the SS pin ever becomes a LOW INPUT then SPI
32
- // automatically switches to Slave, so the data direction of
33
- // the SS pin MUST be kept as OUTPUT.
34
- SPCR |= _BV (MSTR);
35
- SPCR |= _BV (SPE);
36
+ // Warning: if the SS pin ever becomes a LOW INPUT then SPI
37
+ // automatically switches to Slave, so the data direction of
38
+ // the SS pin MUST be kept as OUTPUT.
39
+ SPCR |= _BV (MSTR);
40
+ SPCR |= _BV (SPE);
36
41
37
- // Set direction register for SCK and MOSI pin.
38
- // MISO pin automatically overrides to INPUT.
39
- // By doing this AFTER enabling SPI, we avoid accidentally
40
- // clocking in a single bit since the lines go directly
41
- // from "input" to SPI control.
42
- // http://code.google.com/p/arduino/issues/detail?id=888
43
- pinMode (SCK, OUTPUT);
44
- pinMode (MOSI, OUTPUT);
42
+ // Set direction register for SCK and MOSI pin.
43
+ // MISO pin automatically overrides to INPUT.
44
+ // By doing this AFTER enabling SPI, we avoid accidentally
45
+ // clocking in a single bit since the lines go directly
46
+ // from "input" to SPI control.
47
+ // http://code.google.com/p/arduino/issues/detail?id=888
48
+ pinMode (SCK, OUTPUT);
49
+ pinMode (MOSI, OUTPUT);
50
+ }
51
+ SREG = sreg;
45
52
}
46
53
47
54
void SPIClass::end () {
48
- SPCR &= ~_BV (SPE);
55
+ uint8_t sreg = SREG;
56
+ noInterrupts (); // Protect from a scheduler and prevent transactionBegin
57
+ if (!modeFlags.interruptMode && modeFlags.initialized ) {
58
+ SPCR &= ~_BV (SPE);
59
+ modeFlags.initialized = false ;
60
+ #ifdef SPI_TRANSACTION_MISMATCH_LED
61
+ modeFlags.inTransaction = false ;
62
+ #endif
63
+ }
64
+ SREG = sreg;
49
65
}
50
66
51
67
// mapping of interrupt numbers to bits within SPI_AVR_EIMSK
0 commit comments