22 * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
33 * Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
44 * Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
5+ * Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (atomicity fixes)
56 * SPI Master library for arduino.
67 *
78 * This file is free software; you can redistribute it and/or modify
@@ -20,32 +21,47 @@ uint8_t SPIClass::interruptSave = 0;
2021
2122void SPIClass::begin ()
2223{
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);
2530
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);
3035
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);
3641
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;
4552}
4653
4754void 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;
4965}
5066
5167// mapping of interrupt numbers to bits within SPI_AVR_EIMSK
0 commit comments