Skip to content

Commit 6568acf

Browse files
committed
Port SPI to ArduinoAPI
1 parent 2d27337 commit 6568acf

File tree

2 files changed

+30
-71
lines changed

2 files changed

+30
-71
lines changed

libraries/SPI/SPI.cpp

+25-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,29 @@
2626
#define SPI_IMODE_EXTINT 1
2727
#define SPI_IMODE_GLOBAL 2
2828

29-
SPIClass::SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad PadTx, SercomRXPad PadRx) : settings(SPISettings(0, MSBFIRST, SPI_MODE0))
29+
//const SPISettings DEFAULT_SPI_SETTINGS = SPISettings();
30+
31+
static inline SercomDataOrder getBitOrder(SPISettings& settings) {
32+
return (settings.getBitOrder() == MSBFIRST ? MSB_FIRST : LSB_FIRST);
33+
}
34+
35+
static inline SercomSpiClockMode getDataMode(SPISettings& settings) {
36+
switch (settings.getDataMode())
37+
{
38+
case SPI_MODE0:
39+
return SERCOM_SPI_MODE_0; break;
40+
case SPI_MODE1:
41+
return SERCOM_SPI_MODE_1; break;
42+
case SPI_MODE2:
43+
return SERCOM_SPI_MODE_2; break;
44+
case SPI_MODE3:
45+
return SERCOM_SPI_MODE_3; break;
46+
default:
47+
return SERCOM_SPI_MODE_0; break;
48+
}
49+
}
50+
51+
SPIClass::SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad PadTx, SercomRXPad PadRx)
3052
{
3153
initialized = false;
3254
assert(p_sercom != NULL);
@@ -70,8 +92,8 @@ void SPIClass::config(SPISettings settings)
7092
this->settings = settings;
7193
_p_sercom->disableSPI();
7294

73-
_p_sercom->initSPI(_padTx, _padRx, SPI_CHAR_SIZE_8_BITS, settings.bitOrder);
74-
_p_sercom->initSPIClock(settings.dataMode, settings.clockFreq);
95+
_p_sercom->initSPI(_padTx, _padRx, SPI_CHAR_SIZE_8_BITS, getBitOrder(settings));
96+
_p_sercom->initSPIClock(getDataMode(settings), settings.getClockFreq());
7597

7698
_p_sercom->enableSPI();
7799
}

libraries/SPI/SPI.h

+5-68
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define _SPI_H_INCLUDED
2222

2323
#include <Arduino.h>
24+
#include <api/HardwareSPI.h>
2425

2526
// SPI_HAS_TRANSACTION means SPI has
2627
// - beginTransaction()
@@ -45,75 +46,9 @@
4546
#define SPI_MIN_CLOCK_DIVIDER (uint8_t)(1 + ((F_CPU - 1) / 12000000))
4647
#endif
4748

48-
class SPISettings {
49+
class SPIClassSAMD : public arduino::HardwareSPI {
4950
public:
50-
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
51-
if (__builtin_constant_p(clock)) {
52-
init_AlwaysInline(clock, bitOrder, dataMode);
53-
} else {
54-
init_MightInline(clock, bitOrder, dataMode);
55-
}
56-
}
57-
58-
// Default speed set to 4MHz, SPI mode set to MODE 0 and Bit order set to MSB first.
59-
SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); }
60-
61-
bool operator==(const SPISettings& rhs) const
62-
{
63-
if ((this->clockFreq == rhs.clockFreq) &&
64-
(this->bitOrder == rhs.bitOrder) &&
65-
(this->dataMode == rhs.dataMode)) {
66-
return true;
67-
}
68-
return false;
69-
}
70-
71-
bool operator!=(const SPISettings& rhs) const
72-
{
73-
return !(*this == rhs);
74-
}
75-
76-
uint32_t getClockFreq() const {return clockFreq;}
77-
uint8_t getDataMode() const {return (uint8_t)dataMode;}
78-
BitOrder getBitOrder() const {return (bitOrder == MSB_FIRST ? MSBFIRST : LSBFIRST);}
79-
80-
private:
81-
void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
82-
init_AlwaysInline(clock, bitOrder, dataMode);
83-
}
84-
85-
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) {
86-
this->clockFreq = (clock >= (F_CPU / SPI_MIN_CLOCK_DIVIDER) ? F_CPU / SPI_MIN_CLOCK_DIVIDER : clock);
87-
88-
this->bitOrder = (bitOrder == MSBFIRST ? MSB_FIRST : LSB_FIRST);
89-
90-
switch (dataMode)
91-
{
92-
case SPI_MODE0:
93-
this->dataMode = SERCOM_SPI_MODE_0; break;
94-
case SPI_MODE1:
95-
this->dataMode = SERCOM_SPI_MODE_1; break;
96-
case SPI_MODE2:
97-
this->dataMode = SERCOM_SPI_MODE_2; break;
98-
case SPI_MODE3:
99-
this->dataMode = SERCOM_SPI_MODE_3; break;
100-
default:
101-
this->dataMode = SERCOM_SPI_MODE_0; break;
102-
}
103-
}
104-
105-
uint32_t clockFreq;
106-
SercomSpiClockMode dataMode;
107-
SercomDataOrder bitOrder;
108-
109-
friend class SPIClass;
110-
};
111-
112-
const SPISettings DEFAULT_SPI_SETTINGS = SPISettings();
113-
114-
class SPIClass {
115-
public:
116-
SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad, SercomRXPad);
51+
SPIClassSAMD(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad, SercomRXPad);
11752

11853
byte transfer(uint8_t data);
11954
uint16_t transfer16(uint16_t data);
@@ -156,6 +91,8 @@ class SPIClass {
15691
uint32_t interruptMask;
15792
};
15893

94+
#define SPIClass SPIClassSAMD
95+
15996
#if SPI_INTERFACES_COUNT > 0
16097
extern SPIClass SPI;
16198
#endif

0 commit comments

Comments
 (0)