Skip to content

Commit bdeef89

Browse files
authored
fixing beginTransaction() thread safety (#6425)
1 parent ca77502 commit bdeef89

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

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

+39
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@
2020
*/
2121

2222
#include "SPI.h"
23+
#include "esp32-hal-log.h"
24+
25+
#if !CONFIG_DISABLE_HAL_LOCKS
26+
#define SPI_PARAM_LOCK() do {} while (xSemaphoreTake(paramLock, portMAX_DELAY) != pdPASS)
27+
#define SPI_PARAM_UNLOCK() xSemaphoreGive(paramLock)
28+
#else
29+
#define SPI_PARAM_LOCK()
30+
#define SPI_PARAM_UNLOCK()
31+
#endif
2332

2433
SPIClass::SPIClass(uint8_t spi_bus)
2534
:_spi_num(spi_bus)
@@ -32,7 +41,31 @@ SPIClass::SPIClass(uint8_t spi_bus)
3241
,_div(0)
3342
,_freq(1000000)
3443
,_inTransaction(false)
44+
#if !CONFIG_DISABLE_HAL_LOCKS
45+
,paramLock(NULL)
46+
{
47+
if(paramLock==NULL){
48+
paramLock = xSemaphoreCreateMutex();
49+
if(paramLock==NULL){
50+
log_e("xSemaphoreCreateMutex failed");
51+
return;
52+
}
53+
}
54+
}
55+
#else
3556
{}
57+
#endif
58+
59+
SPIClass::~SPIClass()
60+
{
61+
end();
62+
#if !CONFIG_DISABLE_HAL_LOCKS
63+
if(paramLock!=NULL){
64+
vSemaphoreDelete(paramLock);
65+
paramLock = NULL;
66+
}
67+
#endif
68+
}
3669

3770
void SPIClass::begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
3871
{
@@ -106,19 +139,23 @@ void SPIClass::setHwCs(bool use)
106139

107140
void SPIClass::setFrequency(uint32_t freq)
108141
{
142+
SPI_PARAM_LOCK();
109143
//check if last freq changed
110144
uint32_t cdiv = spiGetClockDiv(_spi);
111145
if(_freq != freq || _div != cdiv) {
112146
_freq = freq;
113147
_div = spiFrequencyToClockDiv(_freq);
114148
spiSetClockDiv(_spi, _div);
115149
}
150+
SPI_PARAM_UNLOCK();
116151
}
117152

118153
void SPIClass::setClockDivider(uint32_t clockDiv)
119154
{
155+
SPI_PARAM_LOCK();
120156
_div = clockDiv;
121157
spiSetClockDiv(_spi, _div);
158+
SPI_PARAM_UNLOCK();
122159
}
123160

124161
uint32_t SPIClass::getClockDivider()
@@ -138,6 +175,7 @@ void SPIClass::setBitOrder(uint8_t bitOrder)
138175

139176
void SPIClass::beginTransaction(SPISettings settings)
140177
{
178+
SPI_PARAM_LOCK();
141179
//check if last freq changed
142180
uint32_t cdiv = spiGetClockDiv(_spi);
143181
if(_freq != settings._clock || _div != cdiv) {
@@ -153,6 +191,7 @@ void SPIClass::endTransaction()
153191
if(_inTransaction){
154192
_inTransaction = false;
155193
spiEndTransaction(_spi);
194+
SPI_PARAM_UNLOCK(); // <-- Im not sure should it be here or right after spiTransaction()
156195
}
157196
}
158197

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

+6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <stdlib.h>
2525
#include "pins_arduino.h"
2626
#include "esp32-hal-spi.h"
27+
#include "freertos/FreeRTOS.h"
28+
#include "freertos/semphr.h"
2729

2830
#define SPI_HAS_TRANSACTION
2931

@@ -50,10 +52,14 @@ class SPIClass
5052
uint32_t _div;
5153
uint32_t _freq;
5254
bool _inTransaction;
55+
#if !CONFIG_DISABLE_HAL_LOCKS
56+
SemaphoreHandle_t paramLock=NULL;
57+
#endif
5358
void writePattern_(const uint8_t * data, uint8_t size, uint8_t repeat);
5459

5560
public:
5661
SPIClass(uint8_t spi_bus=HSPI);
62+
~SPIClass();
5763
void begin(int8_t sck=-1, int8_t miso=-1, int8_t mosi=-1, int8_t ss=-1);
5864
void end();
5965

0 commit comments

Comments
 (0)