-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathAikoDeviceSPIBus.cpp
66 lines (55 loc) · 2.22 KB
/
AikoDeviceSPIBus.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include "AikoDeviceSPIBus.h"
#include <Arduino.h>
#define bitValue(bit, bitValue) ((bitValue) ? (1UL << (bit)) : 0)
namespace Aiko {
namespace Device {
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__)
SPIBusManager SPIBus(13, 12, 11, 10);
#elif defined(__AVR_ATmega1280__)
SPIBusManager SPIBus(52, 50, 51, 53);
#endif
SPIBusManager::SPIBusManager(unsigned char sclkPin, unsigned char misoPin, unsigned char mosiPin, unsigned char ssPin) {
sclkPin_ = sclkPin;
misoPin_ = misoPin;
mosiPin_ = mosiPin;
ssPin_ = ssPin;
isSetUp_ = false;
}
void SPIBusManager::setup() {
pinMode(ssPin_, OUTPUT);
pinMode(mosiPin_, OUTPUT);
pinMode(misoPin_, INPUT);
pinMode(sclkPin_, OUTPUT);
digitalWrite(mosiPin_, LOW);
digitalWrite(sclkPin_, LOW);
bitClear(SPSR, SPI2X); // Double SPI Speed (off)
SPCR = bitValue(SPE, 1) // SPI Enable (on)
| bitValue(SPIE, 0) // Interrupt Enable (off)
| bitValue(DORD, 0) // Data Order (MSB first)
| bitValue(MSTR, 1) // Master/Slave Select (master)
| bitValue(CPOL, 0) // Clock Polarity (mode 0)
| bitValue(CPHA, 0) // Clock Phase (mode 0)
| bitValue(SPR1, 0) // SPI Clock Rate Select (1/16th of CPU clock)
| bitValue(SPR0, 1);
isSetUp_ = true;
}
unsigned char SPIBusManager::transfer(unsigned char output) {
if (!isSetUp_) setup();
// FIXME: We shouldn't need to set the master flag before each write,
// but it seems to get pulled low sometimes. There's a danger that
// it'll get pulled low between the bitSet and SPDR being set, which
// would cause a lockup.
//
// In theory, as long as we have the SS line set high, the MSTR flag
// should never be pulled low. I'd love to know why it happens
// sometimes.
//
// A good safety valve would be to check the MSTR flag in the loop,
// and bomb out if it's low.
// bitSet(SPCR, MSTR);
SPDR = output;
while (bitRead(SPSR, SPIF) == 0); // FIXME: This can lock us up if we're not careful!
return SPDR;
}
};
};