Skip to content

Commit 1824ba1

Browse files
committed
Merge pull request #2223 from PaulStoffregen/ide-1.5.x
SPI Transactions
2 parents dcc1020 + daa7e7d commit 1824ba1

File tree

12 files changed

+862
-78
lines changed

12 files changed

+862
-78
lines changed
+84-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 2010 by Cristian Maglie <[email protected]>
3+
* Copyright (c) 2014 by Paul Stoffregen <[email protected]> (Transaction API)
34
* SPI Master library for arduino.
45
*
56
* This file is free software; you can redistribute it and/or modify
@@ -8,13 +9,20 @@
89
* published by the Free Software Foundation.
910
*/
1011

11-
#include "pins_arduino.h"
1212
#include "SPI.h"
13+
#include "pins_arduino.h"
1314

1415
SPIClass SPI;
1516

16-
void SPIClass::begin() {
17+
uint8_t SPIClass::interruptMode = 0;
18+
uint8_t SPIClass::interruptMask = 0;
19+
uint8_t SPIClass::interruptSave = 0;
20+
#ifdef SPI_TRANSACTION_MISMATCH_LED
21+
uint8_t SPIClass::inTransactionFlag = 0;
22+
#endif
1723

24+
void SPIClass::begin()
25+
{
1826
// Set SS to high so a connected chip will be "deselected" by default
1927
digitalWrite(SS, HIGH);
2028

@@ -39,28 +47,86 @@ void SPIClass::begin() {
3947
pinMode(MOSI, OUTPUT);
4048
}
4149

42-
4350
void SPIClass::end() {
4451
SPCR &= ~_BV(SPE);
4552
}
4653

47-
void SPIClass::setBitOrder(uint8_t bitOrder)
48-
{
49-
if(bitOrder == LSBFIRST) {
50-
SPCR |= _BV(DORD);
51-
} else {
52-
SPCR &= ~(_BV(DORD));
53-
}
54-
}
54+
// mapping of interrupt numbers to bits within SPI_AVR_EIMSK
55+
#if defined(__AVR_ATmega32U4__)
56+
#define SPI_INT0_MASK (1<<INT0)
57+
#define SPI_INT1_MASK (1<<INT1)
58+
#define SPI_INT2_MASK (1<<INT2)
59+
#define SPI_INT3_MASK (1<<INT3)
60+
#define SPI_INT4_MASK (1<<INT6)
61+
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
62+
#define SPI_INT0_MASK (1<<INT0)
63+
#define SPI_INT1_MASK (1<<INT1)
64+
#define SPI_INT2_MASK (1<<INT2)
65+
#define SPI_INT3_MASK (1<<INT3)
66+
#define SPI_INT4_MASK (1<<INT4)
67+
#define SPI_INT5_MASK (1<<INT5)
68+
#define SPI_INT6_MASK (1<<INT6)
69+
#define SPI_INT7_MASK (1<<INT7)
70+
#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
71+
#define SPI_INT0_MASK (1<<INT4)
72+
#define SPI_INT1_MASK (1<<INT5)
73+
#define SPI_INT2_MASK (1<<INT0)
74+
#define SPI_INT3_MASK (1<<INT1)
75+
#define SPI_INT4_MASK (1<<INT2)
76+
#define SPI_INT5_MASK (1<<INT3)
77+
#define SPI_INT6_MASK (1<<INT6)
78+
#define SPI_INT7_MASK (1<<INT7)
79+
#else
80+
#ifdef INT0
81+
#define SPI_INT0_MASK (1<<INT0)
82+
#endif
83+
#ifdef INT1
84+
#define SPI_INT1_MASK (1<<INT1)
85+
#endif
86+
#ifdef INT2
87+
#define SPI_INT2_MASK (1<<INT2)
88+
#endif
89+
#endif
5590

56-
void SPIClass::setDataMode(uint8_t mode)
91+
void SPIClass::usingInterrupt(uint8_t interruptNumber)
5792
{
58-
SPCR = (SPCR & ~SPI_MODE_MASK) | mode;
59-
}
93+
uint8_t mask;
6094

61-
void SPIClass::setClockDivider(uint8_t rate)
62-
{
63-
SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK);
64-
SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK);
95+
if (interruptMode > 1) return;
96+
97+
noInterrupts();
98+
switch (interruptNumber) {
99+
#ifdef SPI_INT0_MASK
100+
case 0: mask = SPI_INT0_MASK; break;
101+
#endif
102+
#ifdef SPI_INT1_MASK
103+
case 1: mask = SPI_INT1_MASK; break;
104+
#endif
105+
#ifdef SPI_INT2_MASK
106+
case 2: mask = SPI_INT2_MASK; break;
107+
#endif
108+
#ifdef SPI_INT3_MASK
109+
case 3: mask = SPI_INT3_MASK; break;
110+
#endif
111+
#ifdef SPI_INT4_MASK
112+
case 4: mask = SPI_INT4_MASK; break;
113+
#endif
114+
#ifdef SPI_INT5_MASK
115+
case 5: mask = SPI_INT5_MASK; break;
116+
#endif
117+
#ifdef SPI_INT6_MASK
118+
case 6: mask = SPI_INT6_MASK; break;
119+
#endif
120+
#ifdef SPI_INT7_MASK
121+
case 7: mask = SPI_INT7_MASK; break;
122+
#endif
123+
default:
124+
interruptMode = 2;
125+
interrupts();
126+
return;
127+
}
128+
interruptMode = 1;
129+
interruptMask |= mask;
130+
interrupts();
65131
}
66132

0 commit comments

Comments
 (0)