Skip to content

Commit 0718165

Browse files
committed
feat(core): third step of ArduinoCore-API migration – SPI
Signed-off-by: Aymane Bahssain <aymane.bahssain@st.com>
1 parent 1fc6588 commit 0718165

File tree

6 files changed

+180
-132
lines changed

6 files changed

+180
-132
lines changed

CI/build/examples/BareMinimum/BareMinimum.ino

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* and can not be executed.
55
*/
66

7+
#include <SPI.h>
78
#include <SoftwareSerial.h>
89
#include <Wire.h>
910

@@ -38,7 +39,6 @@ void setup() {
3839
Serial.begin(9600); // start serial for output
3940
while (!Serial) {};
4041

41-
// Test SoftwareSerial
4242
swSerial.begin(4800);
4343
swSerial.println("X");
4444
delay(20);
@@ -49,7 +49,18 @@ void setup() {
4949
}
5050
swSerial.end();
5151

52-
// Wire
52+
// SPI
53+
SPISettings settings(SPI_SPEED_CLOCK_DEFAULT, MSBFIRST, SPI_MODE0);
54+
SPI.setMISO(PIN_SPI_MISO);
55+
SPI.setMOSI(PIN_SPI_MOSI);
56+
SPI.setSCLK(PIN_SPI_SCK);
57+
SPI.setSSEL(digitalPinToPinName(PIN_SPI_SS));
58+
SPI.begin();
59+
SPI.beginTransaction(settings);
60+
SPI.endTransaction();
61+
SPI.transfer(1);
62+
SPI.end();
63+
// Wire
5364
Wire.setSCL(PIN_WIRE_SCL);
5465
Wire.setSDA(digitalPinToPinName(PIN_WIRE_SDA));
5566
Wire.setClock(400000);

CI/build/examples/BareMinimum/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@ build_sketch(TARGET "BareMinimum"
4747
# IWatchdog
4848
# Servo
4949
SoftwareSerial
50-
# SPI
50+
SPI
5151
Wire
5252
)

libraries/SPI/src/SPI.cpp

Lines changed: 108 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
#include "SPI.h"
1313

14-
SPIClass SPI;
14+
::SPIClass SPI;
1515

1616
/**
1717
* @brief Default Constructor. Uses pin configuration of default SPI
@@ -35,7 +35,54 @@ SPIClass SPI;
3535
* another CS pin and don't pass a CS pin as parameter to any functions
3636
* of the class.
3737
*/
38-
SPIClass::SPIClass(uint32_t mosi, uint32_t miso, uint32_t sclk, uint32_t ssel)
38+
39+
void ::SPIClass::applySettings(const SPISettings &settings)
40+
{
41+
_spiSettings = settings;
42+
43+
uint32_t clock = settings.getClockFreq();
44+
SPIMode dataMode = settings.getDataMode();
45+
BitOrder order = settings.getBitOrder();
46+
SPIBusMode busMode = settings.getBusMode();
47+
48+
// Mapping API dataMode → spi_mode_e C
49+
spi_mode_e cspimode;
50+
switch (dataMode) {
51+
case SPI_MODE0:
52+
cspimode = SPI_MODE0_C;
53+
break;
54+
case SPI_MODE1:
55+
cspimode = SPI_MODE1_C;
56+
break;
57+
case SPI_MODE2:
58+
cspimode = SPI_MODE2_C;
59+
break;
60+
case SPI_MODE3:
61+
cspimode = SPI_MODE3_C;
62+
break;
63+
default:
64+
cspimode = SPI_MODE0_C;
65+
break;
66+
}
67+
68+
// Mapping API busMode → spi_busmode_e C
69+
spi_busmode_e cbusmode;
70+
switch (busMode) {
71+
case SPI_CONTROLLER:
72+
cbusmode = SPI_CONTROLLER_C;
73+
break;
74+
case SPI_PERIPHERAL:
75+
cbusmode = SPI_PERIPHERAL_C;
76+
break;
77+
default:
78+
cbusmode = SPI_CONTROLLER_C;
79+
break;
80+
}
81+
82+
spi_init(&_spi, clock, cspimode, (uint8_t)order, cbusmode);
83+
}
84+
85+
::SPIClass::SPIClass(pin_size_t mosi, pin_size_t miso, pin_size_t sclk, pin_size_t ssel)
3986
{
4087
memset((void *)&_spi, 0, sizeof(_spi));
4188
_spi.pin_miso = digitalPinToPinName(miso);
@@ -46,43 +93,47 @@ SPIClass::SPIClass(uint32_t mosi, uint32_t miso, uint32_t sclk, uint32_t ssel)
4693

4794
/**
4895
* @brief Initialize the SPI instance.
49-
* @param device: device mode (optional), SPI_MASTER or SPI_SLAVE. Default is master.
96+
* @param busMode: bus mode (optional), controller or peripheral. Default is master.
5097
*/
51-
void SPIClass::begin(SPIDeviceMode device)
98+
void ::SPIClass::begin(SPIBusMode busMode)
5299
{
53100
_spi.handle.State = HAL_SPI_STATE_RESET;
54-
_spiSettings = SPISettings();
55-
_spiSettings.deviceMode = device;
56-
spi_init(&_spi, _spiSettings.clockFreq, _spiSettings.dataMode,
57-
_spiSettings.bitOrder, _spiSettings.deviceMode);
101+
102+
SPISettings defaultSettings(
103+
SPI_SPEED_CLOCK_DEFAULT, // 4 MHz
104+
MSBFIRST,
105+
SPI_MODE0,
106+
busMode
107+
);
108+
109+
applySettings(defaultSettings);
58110
}
59111

60112
/**
61113
* @brief This function should be used to configure the SPI instance in case you
62114
* don't use the default parameters set by the begin() function.
63-
* @param settings: SPI settings(clock speed, bit order, data mode, device mode).
115+
* @param settings: SPI settings(clock speed, bit order, data mode, bus mode).
64116
*/
65-
void SPIClass::beginTransaction(SPISettings settings)
117+
void ::SPIClass::beginTransaction(SPISettings settings)
66118
{
67-
if (_spiSettings != settings) {
68-
_spiSettings = settings;
69-
spi_init(&_spi, _spiSettings.clockFreq, _spiSettings.dataMode,
70-
_spiSettings.bitOrder, _spiSettings.deviceMode);
119+
if (_spiSettings == settings) {
120+
return;
71121
}
122+
applySettings(settings);
72123
}
73124

74125
/**
75126
* @brief End the transaction after beginTransaction usage
76127
*/
77-
void SPIClass::endTransaction(void)
128+
void ::SPIClass::endTransaction(void)
78129
{
79130

80131
}
81132

82133
/**
83134
* @brief Deinitialize the SPI instance and stop it.
84135
*/
85-
void SPIClass::end(void)
136+
void ::SPIClass::end(void)
86137
{
87138
spi_deinit(&_spi);
88139
}
@@ -92,35 +143,42 @@ void SPIClass::end(void)
92143
* Configure the bit order: MSB first or LSB first.
93144
* @param bitOrder: MSBFIRST or LSBFIRST
94145
*/
95-
void SPIClass::setBitOrder(BitOrder bitOrder)
146+
void ::SPIClass::setBitOrder(BitOrder bitOrder)
96147
{
97-
_spiSettings.bitOrder = bitOrder;
98-
99-
spi_init(&_spi, _spiSettings.clockFreq, _spiSettings.dataMode,
100-
_spiSettings.bitOrder, _spiSettings.deviceMode);
148+
SPISettings s(
149+
_spiSettings.getClockFreq(),
150+
bitOrder,
151+
_spiSettings.getDataMode(),
152+
_spiSettings.getBusMode()
153+
);
154+
applySettings(s);
101155
}
102156

103157
/**
104158
* @brief Deprecated function.
105159
* Configure the data mode (clock polarity and clock phase)
106-
* @param mode: SPI_MODE0, SPI_MODE1, SPI_MODE2 or SPI_MODE3
160+
* @param dataMode: SPI_MODE0, SPI_MODE1, SPI_MODE2 or SPI_MODE3
107161
* @note
108162
* Mode Clock Polarity (CPOL) Clock Phase (CPHA)
109163
* SPI_MODE0 0 0
110164
* SPI_MODE1 0 1
111165
* SPI_MODE2 1 0
112166
* SPI_MODE3 1 1
113167
*/
114-
void SPIClass::setDataMode(uint8_t mode)
168+
void ::SPIClass::setDataMode(uint8_t dataMode)
115169
{
116-
setDataMode((SPIMode)mode);
170+
setDataMode((SPIMode)dataMode);
117171
}
118172

119-
void SPIClass::setDataMode(SPIMode mode)
173+
void ::SPIClass::setDataMode(SPIMode dataMode)
120174
{
121-
_spiSettings.dataMode = mode;
122-
spi_init(&_spi, _spiSettings.clockFreq, _spiSettings.dataMode,
123-
_spiSettings.bitOrder, _spiSettings.deviceMode);
175+
SPISettings s(
176+
_spiSettings.getClockFreq(),
177+
_spiSettings.getBitOrder(),
178+
dataMode,
179+
_spiSettings.getBusMode()
180+
);
181+
applySettings(s);
124182
}
125183

126184
/**
@@ -129,17 +187,22 @@ void SPIClass::setDataMode(SPIMode mode)
129187
* @param divider: the SPI clock can be divided by values from 1 to 255.
130188
* If 0, default SPI speed is used.
131189
*/
132-
void SPIClass::setClockDivider(uint8_t divider)
190+
void ::SPIClass::setClockDivider(uint8_t divider)
133191
{
192+
uint32_t clk;
134193
if (divider == 0) {
135-
_spiSettings.clockFreq = SPI_SPEED_CLOCK_DEFAULT;
194+
clk = SPI_SPEED_CLOCK_DEFAULT;
136195
} else {
137-
/* Get clk freq of the SPI instance and compute it */
138-
_spiSettings.clockFreq = spi_getClkFreq(&_spi) / divider;
196+
clk = spi_getClkFreq(&_spi) / divider;
139197
}
140198

141-
spi_init(&_spi, _spiSettings.clockFreq, _spiSettings.dataMode,
142-
_spiSettings.bitOrder, _spiSettings.deviceMode);
199+
SPISettings s(
200+
clk,
201+
_spiSettings.getBitOrder(),
202+
_spiSettings.getDataMode(),
203+
_spiSettings.getBusMode()
204+
);
205+
applySettings(s);
143206
}
144207

145208
/**
@@ -151,7 +214,7 @@ void SPIClass::setClockDivider(uint8_t divider)
151214
* Optional, default: SPI_TRANSMITRECEIVE.
152215
* @return byte received from the slave.
153216
*/
154-
uint8_t SPIClass::transfer(uint8_t data, bool skipReceive)
217+
uint8_t ::SPIClass::transfer(uint8_t data, bool skipReceive)
155218
{
156219
spi_transfer(&_spi, &data, (!skipReceive) ? &data : NULL, sizeof(uint8_t));
157220
return data;
@@ -166,17 +229,17 @@ uint8_t SPIClass::transfer(uint8_t data, bool skipReceive)
166229
* Optional, default: SPI_TRANSMITRECEIVE.
167230
* @return bytes received from the slave in 16 bits format.
168231
*/
169-
uint16_t SPIClass::transfer16(uint16_t data, bool skipReceive)
232+
uint16_t ::SPIClass::transfer16(uint16_t data, bool skipReceive)
170233
{
171234
uint16_t tmp;
172235

173-
if (_spiSettings.bitOrder) {
236+
if (_spiSettings.getBitOrder()) {
174237
tmp = ((data & 0xff00) >> 8) | ((data & 0xff) << 8);
175238
data = tmp;
176239
}
177240
spi_transfer(&_spi, (uint8_t *)&data, (!skipReceive) ? (uint8_t *)&data : NULL, sizeof(uint16_t));
178241

179-
if (_spiSettings.bitOrder) {
242+
if (_spiSettings.getBitOrder()) {
180243
tmp = ((data & 0xff00) >> 8) | ((data & 0xff) << 8);
181244
data = tmp;
182245
}
@@ -194,7 +257,7 @@ uint16_t SPIClass::transfer16(uint16_t data, bool skipReceive)
194257
* SPI_TRANSMITRECEIVE or SPI_TRANSMITONLY.
195258
* Optional, default: SPI_TRANSMITRECEIVE.
196259
*/
197-
void SPIClass::transfer(void *buf, size_t count, bool skipReceive)
260+
void ::SPIClass::transfer(void *buf, size_t count, bool skipReceive)
198261
{
199262
spi_transfer(&_spi, (uint8_t *)buf, (!skipReceive) ? (uint8_t *)buf : NULL, count);
200263

@@ -211,7 +274,7 @@ void SPIClass::transfer(void *buf, size_t count, bool skipReceive)
211274
* the SPI transfer. If NULL, the received data will be discarded.
212275
* @param count: number of bytes to send/receive.
213276
*/
214-
void SPIClass::transfer(const void *tx_buf, void *rx_buf, size_t count)
277+
void ::SPIClass::transfer(const void *tx_buf, void *rx_buf, size_t count)
215278
{
216279
spi_transfer(&_spi, ((const uint8_t *)tx_buf), ((uint8_t *)rx_buf), count);
217280
}
@@ -220,37 +283,37 @@ void SPIClass::transfer(const void *tx_buf, void *rx_buf, size_t count)
220283
/**
221284
* @brief Not implemented.
222285
*/
223-
void SPIClass::usingInterrupt(int interruptNumber)
286+
void ::SPIClass::usingInterrupt(int interruptNumber)
224287
{
225288
UNUSED(interruptNumber);
226289
}
227290

228291
/**
229292
* @brief Not implemented.
230293
*/
231-
void SPIClass::notUsingInterrupt(int interruptNumber)
294+
void ::SPIClass::notUsingInterrupt(int interruptNumber)
232295
{
233296
UNUSED(interruptNumber);
234297
}
235298

236299
/**
237300
* @brief Not implemented.
238301
*/
239-
void SPIClass::attachInterrupt(void)
302+
void ::SPIClass::attachInterrupt(void)
240303
{
241304
// Should be enableInterrupt()
242305
}
243306

244307
/**
245308
* @brief Not implemented.
246309
*/
247-
void SPIClass::detachInterrupt(void)
310+
void ::SPIClass::detachInterrupt(void)
248311
{
249312
// Should be disableInterrupt()
250313
}
251314

252315
#if defined(SUBGHZSPI_BASE)
253-
void SUBGHZSPIClass::enableDebugPins(uint32_t mosi, uint32_t miso, uint32_t sclk, uint32_t ssel)
316+
void SUBGHZSPIClass::enableDebugPins(pin_size_t mosi, pin_size_t miso, pin_size_t sclk, pin_size_t ssel)
254317
{
255318
/* Configure SPI GPIO pins */
256319
pinmap_pinout(digitalPinToPinName(mosi), PinMap_SPI_MOSI);

0 commit comments

Comments
 (0)