Skip to content

Commit ca7b32d

Browse files
committed
Fix SPI
1 parent f25e3da commit ca7b32d

File tree

2 files changed

+60
-29
lines changed

2 files changed

+60
-29
lines changed

libraries/SPI/SPI.cpp

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,7 @@
2626
#define SPI_IMODE_EXTINT 1
2727
#define SPI_IMODE_GLOBAL 2
2828

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)
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))
5230
{
5331
initialized = false;
5432
assert(p_sercom != NULL);
@@ -86,14 +64,14 @@ void SPIClass::init()
8664
initialized = true;
8765
}
8866

89-
void SPIClass::config(SPISettings settings)
67+
void SPIClass::config(SPISettingsSAMD settings)
9068
{
9169
if (this->settings != settings) {
9270
this->settings = settings;
9371
_p_sercom->disableSPI();
9472

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

9876
_p_sercom->enableSPI();
9977
}
@@ -155,7 +133,7 @@ void SPIClass::notUsingInterrupt(int interruptNumber)
155133
interrupts();
156134
}
157135

158-
void SPIClass::beginTransaction(SPISettings settings)
136+
void SPIClass::beginTransaction(SPISettingsSAMD settings)
159137
{
160138
if (interruptMode != SPI_IMODE_NONE)
161139
{

libraries/SPI/SPI.h

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,53 @@
4646
#define SPI_MIN_CLOCK_DIVIDER (uint8_t)(1 + ((F_CPU - 1) / 12000000))
4747
#endif
4848

49+
class SPISettingsSAMD : public arduino::SPISettings {
50+
public:
51+
SPISettingsSAMD(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
52+
if (__builtin_constant_p(clock)) {
53+
init_AlwaysInline(clock, bitOrder, dataMode);
54+
} else {
55+
init_MightInline(clock, bitOrder, dataMode);
56+
}
57+
}
58+
59+
// Default speed set to 4MHz, SPI mode set to MODE 0 and Bit order set to MSB first.
60+
SPISettingsSAMD() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); }
61+
62+
SPISettingsSAMD(SPISettings& x) { SPISettingsSAMD(x.getClockFreq(), x.getBitOrder(), x.getDataMode()); }
63+
64+
private:
65+
void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
66+
init_AlwaysInline(clock, bitOrder, dataMode);
67+
}
68+
69+
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) {
70+
this->clockFreq = (clock >= (F_CPU / SPI_MIN_CLOCK_DIVIDER) ? F_CPU / SPI_MIN_CLOCK_DIVIDER : clock);
71+
72+
this->bitOrder = (bitOrder == MSBFIRST ? MSB_FIRST : LSB_FIRST);
73+
74+
switch (dataMode)
75+
{
76+
case SPI_MODE0:
77+
this->dataMode = SERCOM_SPI_MODE_0; break;
78+
case SPI_MODE1:
79+
this->dataMode = SERCOM_SPI_MODE_1; break;
80+
case SPI_MODE2:
81+
this->dataMode = SERCOM_SPI_MODE_2; break;
82+
case SPI_MODE3:
83+
this->dataMode = SERCOM_SPI_MODE_3; break;
84+
default:
85+
this->dataMode = SERCOM_SPI_MODE_0; break;
86+
}
87+
}
88+
89+
uint32_t clockFreq;
90+
SercomSpiClockMode dataMode;
91+
SercomDataOrder bitOrder;
92+
93+
friend class SPIClassSAMD;
94+
};
95+
4996
class SPIClassSAMD : public arduino::HardwareSPI {
5097
public:
5198
SPIClassSAMD(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad, SercomRXPad);
@@ -57,7 +104,10 @@ class SPIClassSAMD : public arduino::HardwareSPI {
57104
// Transaction Functions
58105
void usingInterrupt(int interruptNumber);
59106
void notUsingInterrupt(int interruptNumber);
60-
void beginTransaction(SPISettings settings);
107+
void beginTransaction(SPISettingsSAMD settings);
108+
void beginTransaction(SPISettings settings) {
109+
beginTransaction(SPISettingsSAMD(settings));
110+
}
61111
void endTransaction(void);
62112

63113
// SPI Configuration methods
@@ -73,7 +123,10 @@ class SPIClassSAMD : public arduino::HardwareSPI {
73123

74124
private:
75125
void init();
76-
void config(SPISettings settings);
126+
void config(SPISettingsSAMD settings);
127+
void config(SPISettings settings) {
128+
config(SPISettingsSAMD(settings));
129+
}
77130

78131
SERCOM *_p_sercom;
79132
uint8_t _uc_pinMiso;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy