Skip to content

Commit 5902b53

Browse files
committed
Add SPI class abstraction
1 parent f6ae2b5 commit 5902b53

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed

api/HardwareSPI.h

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
Copyright (c) 2018 Arduino LLC. All right reserved.
3+
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
9+
This library is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
See the GNU Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#pragma once
20+
21+
#include "Common.h"
22+
#include <inttypes.h>
23+
#include "Stream.h"
24+
25+
namespace arduino {
26+
27+
typedef enum {
28+
SPI_MODE0 = 0,
29+
SPI_MODE1 = 1,
30+
SPI_MODE2 = 2,
31+
SPI_MODE3 = 3,
32+
} SPIMode;
33+
34+
35+
class SPISettings {
36+
public:
37+
SPISettings(uint32_t clock, BitOrder bitOrder, SPIMode dataMode) {
38+
if (__builtin_constant_p(clock)) {
39+
init_AlwaysInline(clock, bitOrder, dataMode);
40+
} else {
41+
init_MightInline(clock, bitOrder, dataMode);
42+
}
43+
}
44+
45+
SPISettings(uint32_t clock, BitOrder bitOrder, int dataMode) {
46+
if (__builtin_constant_p(clock)) {
47+
init_AlwaysInline(clock, bitOrder, (SPIMode)dataMode);
48+
} else {
49+
init_MightInline(clock, bitOrder, (SPIMode)dataMode);
50+
}
51+
}
52+
53+
// Default speed set to 4MHz, SPI mode set to MODE 0 and Bit order set to MSB first.
54+
SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); }
55+
56+
bool operator==(const SPISettings& rhs) const
57+
{
58+
if ((this->clockFreq == rhs.clockFreq) &&
59+
(this->bitOrder == rhs.bitOrder) &&
60+
(this->dataMode == rhs.dataMode)) {
61+
return true;
62+
}
63+
return false;
64+
}
65+
66+
bool operator!=(const SPISettings& rhs) const
67+
{
68+
return !(*this == rhs);
69+
}
70+
71+
uint32_t getClockFreq() const {
72+
return clockFreq;
73+
}
74+
SPIMode getDataMode() const {
75+
return dataMode;
76+
}
77+
BitOrder getBitOrder() const {
78+
return (bitOrder);
79+
}
80+
81+
private:
82+
void init_MightInline(uint32_t clock, BitOrder bitOrder, SPIMode dataMode) {
83+
init_AlwaysInline(clock, bitOrder, dataMode);
84+
}
85+
86+
// Core developer MUST use an helper function in beginTransaction() to use this data
87+
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, SPIMode dataMode) __attribute__((__always_inline__)) {
88+
this->clockFreq = clock;
89+
this->dataMode = dataMode;
90+
this->bitOrder = bitOrder;
91+
}
92+
93+
uint32_t clockFreq;
94+
SPIMode dataMode;
95+
BitOrder bitOrder;
96+
97+
friend class HardwareSPI;
98+
};
99+
100+
const SPISettings DEFAULT_SPI_SETTINGS = SPISettings();
101+
102+
class HardwareSPI
103+
{
104+
public:
105+
virtual uint8_t transfer(uint8_t data);
106+
virtual uint16_t transfer16(uint16_t data);
107+
virtual void transfer(void *buf, size_t count);
108+
109+
// Transaction Functions
110+
virtual void usingInterrupt(int interruptNumber);
111+
virtual void notUsingInterrupt(int interruptNumber);
112+
virtual void beginTransaction(SPISettings settings);
113+
virtual void endTransaction(void);
114+
115+
// SPI Configuration methods
116+
virtual void attachInterrupt();
117+
virtual void detachInterrupt();
118+
119+
virtual void begin();
120+
virtual void end();
121+
};
122+
123+
// Alias SPIClass to HardwareSPI since it's already the defacto standard for SPI classe name
124+
typedef HardwareSPI SPIClass;
125+
126+
}

0 commit comments

Comments
 (0)