Skip to content

Commit 392469a

Browse files
committed
chore(SPI): align with ArduinoCoreAPI
Signed-off-by: Frederic Pillon <[email protected]>
1 parent 0ada13f commit 392469a

File tree

4 files changed

+164
-94
lines changed

4 files changed

+164
-94
lines changed

Diff for: libraries/SPI/src/SPI.cpp

+50-45
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ SPIClass::SPIClass(uint32_t mosi, uint32_t miso, uint32_t sclk, uint32_t ssel)
5757
void SPIClass::begin(void)
5858
{
5959
_spi.handle.State = HAL_SPI_STATE_RESET;
60-
spi_init(&_spi, _spiSettings.clk,
61-
_spiSettings.dMode,
62-
_spiSettings.bOrder);
60+
_spiSettings = DEFAULT_SPI_SETTINGS;
61+
spi_init(&_spi, _spiSettings.getClockFreq(),
62+
_spiSettings.getDataMode(),
63+
_spiSettings.getBitOrder());
6364
}
6465

6566
/**
@@ -69,14 +70,12 @@ void SPIClass::begin(void)
6970
*/
7071
void SPIClass::beginTransaction(SPISettings settings)
7172
{
72-
_spiSettings.clk = settings.clk;
73-
_spiSettings.dMode = settings.dMode;
74-
_spiSettings.bOrder = settings.bOrder;
75-
_spiSettings.noReceive = settings.noReceive;
76-
77-
spi_init(&_spi, _spiSettings.clk,
78-
_spiSettings.dMode,
79-
_spiSettings.bOrder);
73+
if (_spiSettings != settings) {
74+
_spiSettings = settings;
75+
spi_init(&_spi, _spiSettings.getClockFreq(),
76+
_spiSettings.getDataMode(),
77+
_spiSettings.getBitOrder());
78+
}
8079
}
8180

8281
/**
@@ -102,39 +101,37 @@ void SPIClass::end()
102101
*/
103102
void SPIClass::setBitOrder(BitOrder bitOrder)
104103
{
105-
_spiSettings.bOrder = bitOrder;
104+
_spiSettings.setBitOrder(bitOrder);
106105

107-
spi_init(&_spi, _spiSettings.clk,
108-
_spiSettings.dMode,
109-
_spiSettings.bOrder);
106+
spi_init(&_spi, _spiSettings.getClockFreq(),
107+
_spiSettings.getDataMode(),
108+
_spiSettings.getBitOrder());
110109
}
111110

112111
/**
113112
* @brief Deprecated function.
114113
* Configure the data mode (clock polarity and clock phase)
115-
* @param _mode: SPI_MODE0, SPI_MODE1, SPI_MODE2 or SPI_MODE3
114+
* @param mode: SPI_MODE0, SPI_MODE1, SPI_MODE2 or SPI_MODE3
116115
* @note
117116
* Mode Clock Polarity (CPOL) Clock Phase (CPHA)
118117
* SPI_MODE0 0 0
119118
* SPI_MODE1 0 1
120119
* SPI_MODE2 1 0
121120
* SPI_MODE3 1 1
122121
*/
123-
void SPIClass::setDataMode(uint8_t _mode)
122+
123+
void SPIClass::setDataMode(uint8_t mode)
124124
{
125-
if (SPI_MODE0 == _mode) {
126-
_spiSettings.dMode = SPI_MODE_0;
127-
} else if (SPI_MODE1 == _mode) {
128-
_spiSettings.dMode = SPI_MODE_1;
129-
} else if (SPI_MODE2 == _mode) {
130-
_spiSettings.dMode = SPI_MODE_2;
131-
} else if (SPI_MODE3 == _mode) {
132-
_spiSettings.dMode = SPI_MODE_3;
133-
}
125+
setDataMode((SPIMode)mode);
126+
}
134127

135-
spi_init(&_spi, _spiSettings.clk,
136-
_spiSettings.dMode,
137-
_spiSettings.bOrder);
128+
void SPIClass::setDataMode(SPIMode mode)
129+
{
130+
_spiSettings.setDataMode(mode);
131+
132+
spi_init(&_spi, _spiSettings.getClockFreq(),
133+
_spiSettings.getDataMode(),
134+
_spiSettings.getBitOrder());
138135
}
139136

140137
/**
@@ -146,15 +143,15 @@ void SPIClass::setDataMode(uint8_t _mode)
146143
void SPIClass::setClockDivider(uint8_t _divider)
147144
{
148145
if (_divider == 0) {
149-
_spiSettings.clk = SPI_SPEED_CLOCK_DEFAULT;
146+
_spiSettings.setClockFreq(SPI_SPEED_CLOCK_DEFAULT);
150147
} else {
151-
/* Get clk freq of the SPI instance and compute it */
152-
_spiSettings.clk = spi_getClkFreq(&_spi) / _divider;
148+
/* Get clock freq of the SPI instance and compute it */
149+
_spiSettings.setClockFreq(spi_getClkFreq(&_spi) / _divider);
153150
}
154151

155-
spi_init(&_spi, _spiSettings.clk,
156-
_spiSettings.dMode,
157-
_spiSettings.bOrder);
152+
spi_init(&_spi, _spiSettings.getClockFreq(),
153+
_spiSettings.getDataMode(),
154+
_spiSettings.getBitOrder());
158155
}
159156

160157
/**
@@ -163,9 +160,9 @@ void SPIClass::setClockDivider(uint8_t _divider)
163160
* @param data: byte to send.
164161
* @return byte received from the slave.
165162
*/
166-
byte SPIClass::transfer(uint8_t data)
163+
uint8_t SPIClass::transfer(uint8_t data)
167164
{
168-
spi_transfer(&_spi, &data, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT, _spiSettings.noReceive);
165+
spi_transfer(&_spi, &data, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT, _spiSettings.getSkipRecv());
169166
return data;
170167
}
171168

@@ -179,14 +176,14 @@ uint16_t SPIClass::transfer16(uint16_t data)
179176
{
180177
uint16_t tmp;
181178

182-
if (_spiSettings.bOrder) {
179+
if (_spiSettings.getBitOrder()) {
183180
tmp = ((data & 0xff00) >> 8) | ((data & 0xff) << 8);
184181
data = tmp;
185182
}
186183
spi_transfer(&_spi, (uint8_t *)&data, sizeof(uint16_t),
187-
SPI_TRANSFER_TIMEOUT, _spiSettings.noReceive);
184+
SPI_TRANSFER_TIMEOUT, _spiSettings.getSkipRecv());
188185

189-
if (_spiSettings.bOrder) {
186+
if (_spiSettings.getBitOrder()) {
190187
tmp = ((data & 0xff00) >> 8) | ((data & 0xff) << 8);
191188
data = tmp;
192189
}
@@ -197,22 +194,30 @@ uint16_t SPIClass::transfer16(uint16_t data)
197194
/**
198195
* @brief Transfer several bytes. Only one buffer used to send and receive data.
199196
* begin() or beginTransaction() must be called at least once before.
200-
* @param _buf: pointer to the bytes to send. The bytes received are copy in
197+
* @param buf: pointer to the bytes to send. The bytes received are copy in
201198
* this buffer.
202-
* @param _count: number of bytes to send/receive.
199+
* @param count: number of bytes to send/receive.
203200
*/
204-
void SPIClass::transfer(void *_buf, size_t _count)
201+
void SPIClass::transfer(void *buf, size_t count)
205202
{
206203
if ((count != 0) && (buf != NULL)) {
207204
spi_transfer(&_spi, ((uint8_t *)buf), count,
208-
SPI_TRANSFER_TIMEOUT, _spiSettings.noReceive);
205+
SPI_TRANSFER_TIMEOUT, _spiSettings.getSkipRecv());
209206
}
210207
}
211208

212209
/**
213210
* @brief Not implemented.
214211
*/
215-
void SPIClass::usingInterrupt(uint8_t interruptNumber)
212+
void SPIClass::usingInterrupt(int interruptNumber)
213+
{
214+
UNUSED(interruptNumber);
215+
}
216+
217+
/**
218+
* @brief Not implemented.
219+
*/
220+
void SPIClass::notUsingInterrupt(int interruptNumber)
216221
{
217222
UNUSED(interruptNumber);
218223
}

Diff for: libraries/SPI/src/SPI.h

+104-40
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,6 @@ extern "C" {
3838
#define SPI_CLOCK_DIV64 64
3939
#define SPI_CLOCK_DIV128 128
4040

41-
// SPI mode parameters for SPISettings
42-
#define SPI_MODE0 0x00
43-
#define SPI_MODE1 0x01
44-
#define SPI_MODE2 0x02
45-
#define SPI_MODE3 0x03
46-
4741
#define SPI_TRANSMITRECEIVE 0x0
4842
#define SPI_TRANSMITONLY 0x1
4943

@@ -54,37 +48,105 @@ extern "C" {
5448

5549
class SPISettings {
5650
public:
57-
constexpr SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, bool noRecv = SPI_TRANSMITRECEIVE)
58-
: clk(clock),
59-
bOrder(bitOrder),
60-
dMode((spi_mode_e)(
61-
(SPI_MODE0 == dataMode) ? SPI_MODE_0 :
62-
(SPI_MODE1 == dataMode) ? SPI_MODE_1 :
63-
(SPI_MODE2 == dataMode) ? SPI_MODE_2 :
64-
(SPI_MODE3 == dataMode) ? SPI_MODE_3 :
65-
SPI_MODE0
66-
)),
67-
noReceive(noRecv)
68-
{ }
69-
constexpr SPISettings()
70-
: clk(SPI_SPEED_CLOCK_DEFAULT),
71-
bOrder(MSBFIRST),
72-
dMode(SPI_MODE_0),
73-
noReceive(SPI_TRANSMITRECEIVE)
74-
{ }
51+
SPISettings(uint32_t clock, BitOrder bitOrder, SPIMode dataMode, bool skipRecv = SPI_TRANSMITRECEIVE)
52+
{
53+
if (__builtin_constant_p(clock)) {
54+
init_AlwaysInline(clock, bitOrder, dataMode, skipRecv);
55+
} else {
56+
init_MightInline(clock, bitOrder, dataMode, skipRecv);
57+
}
58+
}
59+
60+
SPISettings(uint32_t clock, BitOrder bitOrder, int dataMode, bool skipRecv = SPI_TRANSMITRECEIVE)
61+
{
62+
if (__builtin_constant_p(clock)) {
63+
init_AlwaysInline(clock, bitOrder, (SPIMode)dataMode, skipRecv);
64+
} else {
65+
init_MightInline(clock, bitOrder, (SPIMode)dataMode, skipRecv);
66+
}
67+
}
68+
69+
// Default speed set to 4MHz, SPI mode set to MODE 0 and Bit order set to MSB first.
70+
SPISettings()
71+
{
72+
init_AlwaysInline(SPI_SPEED_CLOCK_DEFAULT, MSBFIRST, SPI_MODE0, SPI_TRANSMITRECEIVE);
73+
}
74+
75+
bool operator==(const SPISettings &rhs) const
76+
{
77+
if ((this->clockFreq == rhs.clockFreq) &&
78+
(this->bitOrder == rhs.bitOrder) &&
79+
(this->dataMode == rhs.dataMode) &&
80+
(this->skipRecv == rhs.skipRecv)) {
81+
return true;
82+
}
83+
return false;
84+
}
85+
86+
bool operator!=(const SPISettings &rhs) const
87+
{
88+
return !(*this == rhs);
89+
}
90+
91+
uint32_t getClockFreq() const
92+
{
93+
return clockFreq;
94+
}
95+
SPIMode getDataMode() const
96+
{
97+
return dataMode;
98+
}
99+
BitOrder getBitOrder() const
100+
{
101+
return (bitOrder);
102+
}
103+
bool getSkipRecv() const
104+
{
105+
return skipRecv;
106+
}
107+
108+
void setClockFreq(uint32_t clkFreq)
109+
{
110+
clockFreq = clkFreq;
111+
}
112+
void setDataMode(SPIMode mode)
113+
{
114+
dataMode = mode;
115+
}
116+
void setBitOrder(BitOrder order)
117+
{
118+
bitOrder = order;
119+
}
120+
void setSkipRecv(bool skip)
121+
{
122+
skipRecv = skip;
123+
}
124+
75125
private:
76-
uint32_t clk; //specifies the spi bus maximum clock speed
77-
BitOrder bOrder; //bit order (MSBFirst or LSBFirst)
78-
spi_mode_e dMode; //one of the data mode
79-
//Mode Clock Polarity (CPOL) Clock Phase (CPHA)
80-
//SPI_MODE0 0 0
81-
//SPI_MODE1 0 1
82-
//SPI_MODE2 1 0
83-
//SPI_MODE3 1 1
84-
friend class SPIClass;
85-
bool noReceive;
126+
void init_MightInline(uint32_t clock, BitOrder bitOrder, SPIMode dataMode, bool skipRecv)
127+
{
128+
init_AlwaysInline(clock, bitOrder, dataMode, skipRecv);
129+
}
130+
131+
// Core developer MUST use an helper function in beginTransaction() to use this data
132+
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, SPIMode dataMode, bool skipRecv) __attribute__((__always_inline__))
133+
{
134+
this->clockFreq = clock;
135+
this->dataMode = dataMode;
136+
this->bitOrder = bitOrder;
137+
this->skipRecv = skipRecv;
138+
}
139+
140+
uint32_t clockFreq;
141+
SPIMode dataMode;
142+
BitOrder bitOrder;
143+
bool skipRecv;
144+
145+
friend class HardwareSPI;
86146
};
87147

148+
const SPISettings DEFAULT_SPI_SETTINGS = SPISettings();
149+
88150
class SPIClass {
89151
public:
90152
SPIClass();
@@ -125,7 +187,7 @@ class SPIClass {
125187
_spi.pin_ssel = (ssel);
126188
};
127189

128-
virtual void begin();
190+
virtual void begin(void);
129191
void end(void);
130192

131193
/* This function should be used to configure the SPI instance in case you
@@ -137,19 +199,21 @@ class SPIClass {
137199
/* Transfer functions: must be called after initialization of the SPI
138200
* instance with begin() or beginTransaction().
139201
*/
140-
virtual byte transfer(uint8_t _data);
202+
virtual uint8_t transfer(uint8_t _data);
141203
virtual uint16_t transfer16(uint16_t _data);
142-
virtual void transfer(void *_buf, size_t _count);
204+
virtual void transfer(void *buf, size_t count);
143205

144206
/* These methods are deprecated and kept for compatibility.
145207
* Use SPISettings with SPI.beginTransaction() to configure SPI parameters.
146208
*/
147209
void setBitOrder(BitOrder);
148210
void setDataMode(uint8_t);
211+
void setDataMode(SPIMode);
149212
void setClockDivider(uint8_t);
150213

151-
// Not implemented functions. Kept for backward compatibility.
152-
void usingInterrupt(uint8_t interruptNumber);
214+
// Not implemented functions. Kept for compatibility.
215+
void usingInterrupt(int interruptNumber);
216+
void notUsingInterrupt(int interruptNumber);
153217
void attachInterrupt(void);
154218
void detachInterrupt(void);
155219

@@ -165,7 +229,7 @@ class SPIClass {
165229

166230
private:
167231
/* Current SPISettings */
168-
SPISettings _spiSettings = SPISettings();
232+
SPISettings _spiSettings = DEFAULT_SPI_SETTINGS;
169233
};
170234

171235
extern SPIClass SPI;

Diff for: libraries/SPI/src/utility/spi_com.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ static uint32_t compute_disable_delay(spi_t *obj)
227227
* @param msb : set to 1 in msb first
228228
* @retval None
229229
*/
230-
void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb)
230+
void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb)
231231
{
232232
if (obj == NULL) {
233233
return;
@@ -313,13 +313,13 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb)
313313

314314
handle->Init.Direction = SPI_DIRECTION_2LINES;
315315

316-
if ((mode == SPI_MODE_0) || (mode == SPI_MODE_2)) {
316+
if ((mode == SPI_MODE0) || (mode == SPI_MODE2)) {
317317
handle->Init.CLKPhase = SPI_PHASE_1EDGE;
318318
} else {
319319
handle->Init.CLKPhase = SPI_PHASE_2EDGE;
320320
}
321321

322-
if ((mode == SPI_MODE_0) || (mode == SPI_MODE_1)) {
322+
if ((mode == SPI_MODE0) || (mode == SPI_MODE1)) {
323323
handle->Init.CLKPolarity = SPI_POLARITY_LOW;
324324
} else {
325325
handle->Init.CLKPolarity = SPI_POLARITY_HIGH;

0 commit comments

Comments
 (0)