Skip to content

Commit 78e0808

Browse files
committed
feat(spi): add slave mode support
Signed-off-by: patricklaf <patrick.lafarguette@gmail.com> Co-authored-by: Frederic Pillon <frederic.pillon@st.com>
1 parent b149a92 commit 78e0808

File tree

5 files changed

+56
-33
lines changed

5 files changed

+56
-33
lines changed

libraries/SPI/keywords.txt

+5-2
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,8 @@ SPI_MODE1 LITERAL1
3030
SPI_MODE2 LITERAL1
3131
SPI_MODE3 LITERAL1
3232

33-
SPI_CONTINUE LITERAL1
34-
SPI_LAST LITERAL1
33+
SPI_TRANSMITRECEIVE LITERAL1
34+
SPI_TRANSMITONLY LITERAL1
35+
SPI_MASTER LITERAL1
36+
SPI_SLAVE LITERAL1
37+

libraries/SPI/src/SPI.cpp

+14-17
Original file line numberDiff line numberDiff line change
@@ -53,28 +53,28 @@ SPIClass::SPIClass(uint32_t mosi, uint32_t miso, uint32_t sclk, uint32_t ssel)
5353

5454
/**
5555
* @brief Initialize the SPI instance.
56+
* @param device: device mode (optional), SPI_MASTER or SPI_SLAVE. Default is master.
5657
*/
57-
void SPIClass::begin(void)
58+
void SPIClass::begin(SPIDeviceMode device)
5859
{
5960
_spi.handle.State = HAL_SPI_STATE_RESET;
6061
_spiSettings = SPISettings();
61-
spi_init(&_spi, _spiSettings.clockFreq,
62-
_spiSettings.dataMode,
63-
_spiSettings.bitOrder);
62+
_spiSettings.deviceMode = device;
63+
spi_init(&_spi, _spiSettings.clockFreq, _spiSettings.dataMode,
64+
_spiSettings.bitOrder, _spiSettings.deviceMode);
6465
}
6566

6667
/**
6768
* @brief This function should be used to configure the SPI instance in case you
6869
* don't use the default parameters set by the begin() function.
69-
* @param settings: SPI settings(clock speed, bit order, data mode).
70+
* @param settings: SPI settings(clock speed, bit order, data mode, device mode).
7071
*/
7172
void SPIClass::beginTransaction(SPISettings settings)
7273
{
7374
if (_spiSettings != settings) {
7475
_spiSettings = settings;
75-
spi_init(&_spi, _spiSettings.clockFreq,
76-
_spiSettings.dataMode,
77-
_spiSettings.bitOrder);
76+
spi_init(&_spi, _spiSettings.clockFreq, _spiSettings.dataMode,
77+
_spiSettings.bitOrder, _spiSettings.deviceMode);
7878
}
7979
}
8080

@@ -103,9 +103,8 @@ void SPIClass::setBitOrder(BitOrder bitOrder)
103103
{
104104
_spiSettings.bitOrder = bitOrder;
105105

106-
spi_init(&_spi, _spiSettings.clockFreq,
107-
_spiSettings.dataMode,
108-
_spiSettings.bitOrder);
106+
spi_init(&_spi, _spiSettings.clockFreq, _spiSettings.dataMode,
107+
_spiSettings.bitOrder, _spiSettings.deviceMode);
109108
}
110109

111110
/**
@@ -127,9 +126,8 @@ void SPIClass::setDataMode(uint8_t mode)
127126
void SPIClass::setDataMode(SPIMode mode)
128127
{
129128
_spiSettings.dataMode = mode;
130-
spi_init(&_spi, _spiSettings.clockFreq,
131-
_spiSettings.dataMode,
132-
_spiSettings.bitOrder);
129+
spi_init(&_spi, _spiSettings.clockFreq, _spiSettings.dataMode,
130+
_spiSettings.bitOrder, _spiSettings.deviceMode);
133131
}
134132

135133
/**
@@ -147,9 +145,8 @@ void SPIClass::setClockDivider(uint8_t divider)
147145
_spiSettings.clockFreq = spi_getClkFreq(&_spi) / divider;
148146
}
149147

150-
spi_init(&_spi, _spiSettings.clockFreq,
151-
_spiSettings.dataMode,
152-
_spiSettings.bitOrder);
148+
spi_init(&_spi, _spiSettings.clockFreq, _spiSettings.dataMode,
149+
_spiSettings.bitOrder, _spiSettings.deviceMode);
153150
}
154151

155152
/**

libraries/SPI/src/SPI.h

+26-10
Original file line numberDiff line numberDiff line change
@@ -43,27 +43,31 @@ extern "C" {
4343

4444
class SPISettings {
4545
public:
46-
constexpr SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode)
46+
constexpr SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, SPIDeviceMode deviceMode = SPI_MASTER)
4747
: clockFreq(clock),
4848
bitOrder(bitOrder),
49-
dataMode((SPIMode)dataMode)
49+
dataMode((SPIMode)dataMode),
50+
deviceMode(deviceMode)
5051
{ }
51-
constexpr SPISettings(uint32_t clock, BitOrder bitOrder, SPIMode dataMode)
52+
constexpr SPISettings(uint32_t clock, BitOrder bitOrder, SPIMode dataMode, SPIDeviceMode deviceMode = SPI_MASTER)
5253
: clockFreq(clock),
5354
bitOrder(bitOrder),
54-
dataMode(dataMode)
55+
dataMode(dataMode),
56+
deviceMode(deviceMode)
5557
{ }
5658
constexpr SPISettings()
5759
: clockFreq(SPI_SPEED_CLOCK_DEFAULT),
5860
bitOrder(MSBFIRST),
59-
dataMode(SPI_MODE0)
61+
dataMode(SPI_MODE0),
62+
deviceMode(SPI_MASTER)
6063
{ }
6164

6265
bool operator==(const SPISettings &rhs) const
6366
{
6467
if ((this->clockFreq == rhs.clockFreq) &&
6568
(this->bitOrder == rhs.bitOrder) &&
66-
(this->dataMode == rhs.dataMode)) {
69+
(this->dataMode == rhs.dataMode) &&
70+
(this->deviceMode == rhs.deviceMode)) {
6771
return true;
6872
}
6973
return false;
@@ -75,9 +79,10 @@ class SPISettings {
7579
}
7680

7781
private:
78-
uint32_t clockFreq; //specifies the spi bus maximum clock speed
79-
BitOrder bitOrder; //bit order (MSBFirst or LSBFirst)
80-
SPIMode dataMode; //one of the data mode
82+
uint32_t clockFreq; // specifies the spi bus maximum clock speed
83+
BitOrder bitOrder; // bit order (MSBFirst or LSBFirst)
84+
SPIMode dataMode; // one of the data mode
85+
SPIDeviceMode deviceMode; // device mode: master or slave
8186

8287
friend class SPIClass;
8388
};
@@ -122,7 +127,7 @@ class SPIClass {
122127
_spi.pin_ssel = (ssel);
123128
};
124129

125-
void begin(void);
130+
void begin(SPIDeviceMode device = SPI_MASTER);
126131
void end(void);
127132

128133
/* This function should be used to configure the SPI instance in case you
@@ -163,6 +168,17 @@ class SPIClass {
163168
return &(_spi.handle);
164169
}
165170

171+
// Dedicated to SPI Slave
172+
void attachSlaveInterrupt(uint8_t pin, callback_function_t callback)
173+
{
174+
::attachInterrupt(pin, callback, FALLING);
175+
}
176+
177+
void detachSlaveInterrupt(uint8_t pin)
178+
{
179+
::detachInterrupt(pin);
180+
}
181+
166182
protected:
167183
// spi instance
168184
spi_t _spi;

libraries/SPI/src/utility/spi_com.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,10 @@ static uint32_t compute_disable_delay(spi_t *obj)
198198
* @param speed : spi output speed
199199
* @param mode : one of the spi modes
200200
* @param msb : set to 1 in msb first
201+
* @param device : spi device mode: master or slave
201202
* @retval None
202203
*/
203-
void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb)
204+
void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb, SPIDeviceMode device)
204205
{
205206
if (obj == NULL) {
206207
return;
@@ -252,8 +253,8 @@ void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb)
252253
}
253254

254255
/* Fill default value */
255-
handle->Instance = obj->spi;
256-
handle->Init.Mode = SPI_MODE_MASTER;
256+
handle->Instance = obj->spi;
257+
handle->Init.Mode = (device == SPI_MASTER) ? SPI_MODE_MASTER : SPI_MODE_SLAVE;
257258

258259
spi_freq = spi_getClkFreqInst(obj->spi);
259260
/* For SUBGHZSPI, 'SPI_BAUDRATEPRESCALER_*' == 'SUBGHZSPI_BAUDRATEPRESCALER_*' */

libraries/SPI/src/utility/spi_com.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ typedef enum {
7474
SPI_MODE3 = 3,
7575
} SPIMode;
7676

77+
// Device mode
78+
typedef enum {
79+
SPI_MASTER, /* Device is master */
80+
SPI_SLAVE /* Device is slave */
81+
} SPIDeviceMode;
82+
7783
///@brief SPI errors
7884
typedef enum {
7985
SPI_OK = 0,
@@ -82,7 +88,7 @@ typedef enum {
8288
} spi_status_e;
8389

8490
/* Exported functions ------------------------------------------------------- */
85-
void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb);
91+
void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb, SPIDeviceMode device);
8692
void spi_deinit(spi_t *obj);
8793
spi_status_e spi_transfer(spi_t *obj, const uint8_t *tx_buffer, uint8_t *rx_buffer, uint16_t len);
8894
uint32_t spi_getClkFreq(spi_t *obj);

0 commit comments

Comments
 (0)