74 SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
75 if (__builtin_constant_p(clock)) {
76 init_AlwaysInline(clock, bitOrder, dataMode);
78 init_MightInline(clock, bitOrder, dataMode);
82 init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);
85 void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
86 init_AlwaysInline(clock, bitOrder, dataMode);
88 void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
89 __attribute__((__always_inline__)) {
113 if (__builtin_constant_p(clock)) {
114 if (clock >= F_CPU / 2) {
116 }
else if (clock >= F_CPU / 4) {
118 }
else if (clock >= F_CPU / 8) {
120 }
else if (clock >= F_CPU / 16) {
122 }
else if (clock >= F_CPU / 32) {
124 }
else if (clock >= F_CPU / 64) {
130 uint32_t clockSetting = F_CPU / 2;
132 while (clockDiv < 6 && clock < clockSetting) {
146 spcr = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) |
147 (dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK);
148 spsr = clockDiv & SPI_2XCLOCK_MASK;
166 static void usingInterrupt(uint8_t interruptNumber);
168 static void notUsingInterrupt(uint8_t interruptNumber);
178 inline static void beginTransaction(
SPISettings settings) {
179 if (interruptMode > 0) {
184 if (interruptMode == 1) {
185 interruptSave = SPI_AVR_EIMSK;
186 SPI_AVR_EIMSK &= ~interruptMask;
191 interruptSave = sreg;
195 #ifdef SPI_TRANSACTION_MISMATCH_LED
196 if (inTransactionFlag) {
197 pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
198 digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
200 inTransactionFlag = 1;
203 SPCR = settings.spcr;
204 SPSR = settings.spsr;
208 inline static uint8_t transfer(uint8_t data) {
217 while (!(SPSR & _BV(SPIF))) ;
220 inline static uint16_t transfer16(uint16_t data) {
221 union { uint16_t val;
struct { uint8_t lsb; uint8_t msb; }; } in, out;
223 if (!(SPCR & _BV(DORD))) {
226 while (!(SPSR & _BV(SPIF))) ;
230 while (!(SPSR & _BV(SPIF))) ;
235 while (!(SPSR & _BV(SPIF))) ;
239 while (!(SPSR & _BV(SPIF))) ;
244 inline static void transfer(
void *buf,
size_t count) {
245 if (count == 0)
return;
246 uint8_t *p = (uint8_t *)buf;
248 while (--count > 0) {
249 uint8_t out = *(p + 1);
250 while (!(SPSR & _BV(SPIF))) ;
255 while (!(SPSR & _BV(SPIF))) ;
260 inline static void endTransaction(
void) {
261 #ifdef SPI_TRANSACTION_MISMATCH_LED
262 if (!inTransactionFlag) {
263 pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
264 digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
266 inTransactionFlag = 0;
269 if (interruptMode > 0) {
275 if (interruptMode == 1) {
276 SPI_AVR_EIMSK = interruptSave;
281 SREG = interruptSave;
291 inline static void setBitOrder(uint8_t bitOrder) {
292 if (bitOrder == LSBFIRST) SPCR |= _BV(DORD);
293 else SPCR &= ~(_BV(DORD));
297 inline static void setDataMode(uint8_t dataMode) {
298 SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
302 inline static void setClockDivider(uint8_t clockDiv) {
303 SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK);
304 SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK);
309 inline static void attachInterrupt() { SPCR |= _BV(SPIE); }
310 inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); }
313 static uint8_t initialized;
314 static uint8_t interruptMode;
315 static uint8_t interruptMask;
316 static uint8_t interruptSave;
317 #ifdef SPI_TRANSACTION_MISMATCH_LED
318 static uint8_t inTransactionFlag;