-
Notifications
You must be signed in to change notification settings - Fork 3
/
TurboSPI_AVR.cpp
134 lines (122 loc) · 2.54 KB
/
TurboSPI_AVR.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "TurboSPI.h"
#ifdef __AVR__
//------------------------------------------------------------------------------
void TurboSPI::Begin()
{
#ifdef __AVR_ATmega328P__
// Save a few bytes for 328 CPU - gcc optimizes single bit '|' to sbi.
PORTB |= 1 << 2; // SS high
DDRB |= 1 << 2; // SS output mode
DDRB |= 1 << 3; // MOSI output mode
DDRB |= 1 << 5; // SCK output mode
#else // __AVR_ATmega328P__
// set SS high - may be chip select for another SPI device
digitalWrite(SS, HIGH);
// SS must be in output mode even it is not chip select
pinMode(SS, OUTPUT);
pinMode(MOSI, OUTPUT);
pinMode(SCK, OUTPUT);
#endif // __AVR_ATmega328P__
Init(2);
}
//------------------------------------------------------------------------------
void TurboSPI::Init(uint8_t divisor)
{
uint8_t b = 2;
uint8_t r = 0;
// See AVR processor documentation.
for (; divisor > b && r < 7; b <<= 1, r += r < 5 ? 1 : 2)
{
}
SPCR = (1 << SPE) | (1 << MSTR) | (r >> 1);
SPSR = r & 1 ? 0 : 1 << SPI2X;
}
//------------------------------------------------------------------------------
uint8_t TurboSPI::Receive()
{
SPDR = 0XFF;
while (!(SPSR & (1 << SPIF)))
;
return SPDR;
}
//------------------------------------------------------------------------------
uint8_t TurboSPI::Receive(uint8_t * buf, size_t n)
{
if (n-- == 0)
{
return 0;
}
SPDR = 0XFF;
for (size_t i = 0; i < n; i++)
{
while (!(SPSR & (1 << SPIF)))
;
uint8_t b = SPDR;
SPDR = 0XFF;
buf[i] = b;
}
while (!(SPSR & (1 << SPIF)))
;
buf[n] = SPDR;
return 0;
}
//------------------------------------------------------------------------------
void TurboSPI::Send(uint8_t data)
{
SPDR = data;
while (!(SPSR & (1 << SPIF)))
;
}
//------------------------------------------------------------------------------
void TurboSPI::Send(const uint8_t * buf, size_t n)
{
if (n == 0)
{
return;
}
SPDR = buf[0];
if (n > 1)
{
uint8_t b = buf[1];
size_t i = 2;
while (1)
{
while (!(SPSR & (1 << SPIF)))
;
SPDR = b;
if (i == n)
{
break;
}
b = buf[i++];
}
}
while (!(SPSR & (1 << SPIF)))
;
}
//////////////////////////////////////////////////////////////////////////
DigitalPin::DigitalPin()
: m_Pin(0)
, m_Port(0)
, m_Mask(0)
{
}
void DigitalPin::Begin(uint8_t pinID)
{
m_Pin = pinID;
m_Port = portOutputRegister(digitalPinToPort(pinID));
m_Mask = digitalPinToBitMask(pinID);
}
void DigitalPin::PinMode(uint8_t dwMode)
{
pinMode(m_Pin, dwMode);
}
void DigitalPin::High()
{
*m_Port |= m_Mask;
}
void DigitalPin::Low()
{
*m_Port &= ~m_Mask;
}
#endif // __AVR__