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

Lines changed: 5 additions & 2 deletions
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

Lines changed: 14 additions & 17 deletions
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

Lines changed: 26 additions & 10 deletions
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

Lines changed: 4 additions & 3 deletions
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

Lines changed: 7 additions & 1 deletion
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)
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