Skip to content

Commit 2095f53

Browse files
committed
feat(spi): add slave mode support
Signed-off-by: patricklaf <[email protected]> Co-authored-by: Frederic Pillon <[email protected]>
1 parent 34d7699 commit 2095f53

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
@@ -46,28 +46,28 @@ SPIClass::SPIClass(uint32_t mosi, uint32_t miso, uint32_t sclk, uint32_t ssel)
4646

4747
/**
4848
* @brief Initialize the SPI instance.
49+
* @param device: device mode (optional), SPI_MASTER or SPI_SLAVE. Default is master.
4950
*/
50-
void SPIClass::begin(void)
51+
void SPIClass::begin(SPIDeviceMode device)
5152
{
5253
_spi.handle.State = HAL_SPI_STATE_RESET;
5354
_spiSettings = SPISettings();
54-
spi_init(&_spi, _spiSettings.clockFreq,
55-
_spiSettings.dataMode,
56-
_spiSettings.bitOrder);
55+
_spiSettings.deviceMode = device;
56+
spi_init(&_spi, _spiSettings.clockFreq, _spiSettings.dataMode,
57+
_spiSettings.bitOrder, _spiSettings.deviceMode);
5758
}
5859

5960
/**
6061
* @brief This function should be used to configure the SPI instance in case you
6162
* don't use the default parameters set by the begin() function.
62-
* @param settings: SPI settings(clock speed, bit order, data mode).
63+
* @param settings: SPI settings(clock speed, bit order, data mode, device mode).
6364
*/
6465
void SPIClass::beginTransaction(SPISettings settings)
6566
{
6667
if (_spiSettings != settings) {
6768
_spiSettings = settings;
68-
spi_init(&_spi, _spiSettings.clockFreq,
69-
_spiSettings.dataMode,
70-
_spiSettings.bitOrder);
69+
spi_init(&_spi, _spiSettings.clockFreq, _spiSettings.dataMode,
70+
_spiSettings.bitOrder, _spiSettings.deviceMode);
7171
}
7272
}
7373

@@ -96,9 +96,8 @@ void SPIClass::setBitOrder(BitOrder bitOrder)
9696
{
9797
_spiSettings.bitOrder = bitOrder;
9898

99-
spi_init(&_spi, _spiSettings.clockFreq,
100-
_spiSettings.dataMode,
101-
_spiSettings.bitOrder);
99+
spi_init(&_spi, _spiSettings.clockFreq, _spiSettings.dataMode,
100+
_spiSettings.bitOrder, _spiSettings.deviceMode);
102101
}
103102

104103
/**
@@ -120,9 +119,8 @@ void SPIClass::setDataMode(uint8_t mode)
120119
void SPIClass::setDataMode(SPIMode mode)
121120
{
122121
_spiSettings.dataMode = mode;
123-
spi_init(&_spi, _spiSettings.clockFreq,
124-
_spiSettings.dataMode,
125-
_spiSettings.bitOrder);
122+
spi_init(&_spi, _spiSettings.clockFreq, _spiSettings.dataMode,
123+
_spiSettings.bitOrder, _spiSettings.deviceMode);
126124
}
127125

128126
/**
@@ -140,9 +138,8 @@ void SPIClass::setClockDivider(uint8_t divider)
140138
_spiSettings.clockFreq = spi_getClkFreq(&_spi) / divider;
141139
}
142140

143-
spi_init(&_spi, _spiSettings.clockFreq,
144-
_spiSettings.dataMode,
145-
_spiSettings.bitOrder);
141+
spi_init(&_spi, _spiSettings.clockFreq, _spiSettings.dataMode,
142+
_spiSettings.bitOrder, _spiSettings.deviceMode);
146143
}
147144

148145
/**

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
};
@@ -121,7 +126,7 @@ class SPIClass {
121126
_spi.pin_ssel = (ssel);
122127
};
123128

124-
void begin(void);
129+
void begin(SPIDeviceMode device = SPI_MASTER);
125130
void end(void);
126131

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

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

libraries/SPI/src/utility/spi_com.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,10 @@ static uint32_t compute_disable_delay(spi_t *obj)
203203
* @param speed : spi output speed
204204
* @param mode : one of the spi modes
205205
* @param msb : set to 1 in msb first
206+
* @param device : spi device mode: master or slave
206207
* @retval None
207208
*/
208-
void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb)
209+
void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb, SPIDeviceMode device)
209210
{
210211
if (obj == NULL) {
211212
return;
@@ -257,8 +258,8 @@ void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb)
257258
}
258259

259260
/* Fill default value */
260-
handle->Instance = obj->spi;
261-
handle->Init.Mode = SPI_MODE_MASTER;
261+
handle->Instance = obj->spi;
262+
handle->Init.Mode = (device == SPI_MASTER) ? SPI_MODE_MASTER : SPI_MODE_SLAVE;
262263

263264
spi_freq = spi_getClkFreqInst(obj->spi);
264265
/* 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)