Skip to content

Commit 9a9ef06

Browse files
committed
Merge branch 'spi-thread-safe'
* spi-thread-safe: remove unnecessary locks implement thread-safe spi
2 parents cb2110c + 7de6da5 commit 9a9ef06

File tree

2 files changed

+85
-17
lines changed

2 files changed

+85
-17
lines changed

cores/esp32/esp32-hal-spi.c

Lines changed: 81 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,20 @@
1313
// limitations under the License.
1414

1515
#include "esp32-hal-spi.h"
16+
#include "esp32-hal.h"
1617
#include "freertos/FreeRTOS.h"
1718
#include "freertos/task.h"
19+
#include "freertos/semphr.h"
1820
#include "rom/ets_sys.h"
1921
#include "esp_attr.h"
2022
#include "esp_intr.h"
2123
#include "rom/gpio.h"
2224
#include "soc/spi_reg.h"
25+
#include "soc/spi_struct.h"
2326
#include "soc/io_mux_reg.h"
2427
#include "soc/gpio_sig_map.h"
2528
#include "soc/dport_reg.h"
2629

27-
#define SPI_REG_BASE(p) ((p==0)?DR_REG_SPI0_BASE:((p==1)?DR_REG_SPI1_BASE:((p==2)?DR_REG_SPI2_BASE:((p==3)?DR_REG_SPI3_BASE:0))))
28-
#define SPI_DEV(i) ((spi_dev_t *)(SPI_REG_BASE(i)))
29-
3030
#define SPI_CLK_IDX(p) ((p==0)?SPICLK_OUT_IDX:((p==1)?SPICLK_OUT_IDX:((p==2)?HSPICLK_OUT_IDX:((p==3)?VSPICLK_OUT_MUX_IDX:0))))
3131
#define SPI_MISO_IDX(p) ((p==0)?SPIQ_OUT_IDX:((p==1)?SPIQ_OUT_IDX:((p==2)?HSPIQ_OUT_IDX:((p==3)?VSPIQ_OUT_IDX:0))))
3232
#define SPI_MOSI_IDX(p) ((p==0)?SPID_IN_IDX:((p==1)?SPID_IN_IDX:((p==2)?HSPID_IN_IDX:((p==3)?VSPID_IN_IDX:0))))
@@ -39,6 +39,22 @@
3939
#define SPI_INUM(u) (2)
4040
#define SPI_INTR_SOURCE(u) ((u==0)?ETS_SPI0_INTR_SOURCE:((u==1)?ETS_SPI1_INTR_SOURCE:((u==2)?ETS_SPI2_INTR_SOURCE:((p==3)?ETS_SPI3_INTR_SOURCE:0))))
4141

42+
struct spi_struct_t {
43+
spi_dev_t * dev;
44+
xSemaphoreHandle lock;
45+
uint8_t num;
46+
};
47+
48+
#define SPI_MUTEX_LOCK() do {} while (xSemaphoreTake(spi->lock, portMAX_DELAY) != pdPASS)
49+
#define SPI_MUTEX_UNLOCK() xSemaphoreGive(spi->lock)
50+
51+
static spi_t _spi_bus_array[4] = {
52+
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), NULL, 0},
53+
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 1},
54+
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 2},
55+
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 3}
56+
};
57+
4258
void spiAttachSCK(spi_t * spi, int8_t sck)
4359
{
4460
if(!spi) {
@@ -71,8 +87,10 @@ void spiAttachMISO(spi_t * spi, int8_t miso)
7187
miso = 7;
7288
}
7389
}
90+
SPI_MUTEX_LOCK();
7491
pinMode(miso, INPUT);
7592
pinMatrixInAttach(miso, SPI_MISO_IDX(spi->num), false);
93+
SPI_MUTEX_UNLOCK();
7694
}
7795

7896
void spiAttachMOSI(spi_t * spi, int8_t mosi)
@@ -193,49 +211,61 @@ void spiEnableSSPins(spi_t * spi, uint8_t cs_mask)
193211
if(!spi) {
194212
return;
195213
}
214+
SPI_MUTEX_LOCK();
196215
spi->dev->pin.val &= ~(cs_mask & SPI_CS_MASK_ALL);
216+
SPI_MUTEX_UNLOCK();
197217
}
198218

199219
void spiDisableSSPins(spi_t * spi, uint8_t cs_mask)
200220
{
201221
if(!spi) {
202222
return;
203223
}
224+
SPI_MUTEX_LOCK();
204225
spi->dev->pin.val |= (cs_mask & SPI_CS_MASK_ALL);
226+
SPI_MUTEX_UNLOCK();
205227
}
206228

207229
void spiSSEnable(spi_t * spi)
208230
{
209231
if(!spi) {
210232
return;
211233
}
234+
SPI_MUTEX_LOCK();
212235
spi->dev->user.cs_setup = 1;
213236
spi->dev->user.cs_hold = 1;
237+
SPI_MUTEX_UNLOCK();
214238
}
215239

216240
void spiSSDisable(spi_t * spi)
217241
{
218242
if(!spi) {
219243
return;
220244
}
245+
SPI_MUTEX_LOCK();
221246
spi->dev->user.cs_setup = 0;
222247
spi->dev->user.cs_hold = 0;
248+
SPI_MUTEX_UNLOCK();
223249
}
224250

225251
void spiSSSet(spi_t * spi)
226252
{
227253
if(!spi) {
228254
return;
229255
}
256+
SPI_MUTEX_LOCK();
230257
spi->dev->pin.cs_keep_active = 1;
258+
SPI_MUTEX_UNLOCK();
231259
}
232260

233261
void spiSSClear(spi_t * spi)
234262
{
235263
if(!spi) {
236264
return;
237265
}
266+
SPI_MUTEX_LOCK();
238267
spi->dev->pin.cs_keep_active = 0;
268+
SPI_MUTEX_UNLOCK();
239269
}
240270

241271
uint32_t spiGetClockDiv(spi_t * spi)
@@ -251,7 +281,9 @@ void spiSetClockDiv(spi_t * spi, uint32_t clockDiv)
251281
if(!spi) {
252282
return;
253283
}
284+
SPI_MUTEX_LOCK();
254285
spi->dev->clock.val = clockDiv;
286+
SPI_MUTEX_UNLOCK();
255287
}
256288

257289
uint8_t spiGetDataMode(spi_t * spi)
@@ -278,6 +310,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode)
278310
if(!spi) {
279311
return;
280312
}
313+
SPI_MUTEX_LOCK();
281314
switch (dataMode) {
282315
case SPI_MODE1:
283316
spi->dev->pin.ck_idle_edge = 0;
@@ -297,6 +330,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode)
297330
spi->dev->user.ck_out_edge = 0;
298331
break;
299332
}
333+
SPI_MUTEX_UNLOCK();
300334
}
301335

302336
uint8_t spiGetBitOrder(spi_t * spi)
@@ -312,20 +346,23 @@ void spiSetBitOrder(spi_t * spi, uint8_t bitOrder)
312346
if(!spi) {
313347
return;
314348
}
349+
SPI_MUTEX_LOCK();
315350
if (SPI_MSBFIRST == bitOrder) {
316351
spi->dev->ctrl.wr_bit_order = 0;
317352
spi->dev->ctrl.rd_bit_order = 0;
318353
} else if (SPI_LSBFIRST == bitOrder) {
319354
spi->dev->ctrl.wr_bit_order = 1;
320355
spi->dev->ctrl.rd_bit_order = 1;
321356
}
357+
SPI_MUTEX_UNLOCK();
322358
}
323359

324360
void spiStopBus(spi_t * spi)
325361
{
326362
if(!spi) {
327363
return;
328364
}
365+
SPI_MUTEX_LOCK();
329366
spi->dev->slave.trans_done = 0;
330367
spi->dev->slave.slave_mode = 0;
331368
spi->dev->pin.val = 0;
@@ -335,18 +372,23 @@ void spiStopBus(spi_t * spi)
335372
spi->dev->ctrl1.val = 0;
336373
spi->dev->ctrl2.val = 0;
337374
spi->dev->clock.val = 0;
375+
SPI_MUTEX_UNLOCK();
338376
}
339377

340378
spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t bitOrder)
341379
{
342-
343-
spi_t* spi = (spi_t*) malloc(sizeof(spi_t));
344-
if(spi == 0) {
380+
if(spi_num > 3){
345381
return NULL;
346382
}
347383

348-
spi->num = spi_num;
349-
spi->dev = (spi_dev_t *)SPI_DEV(spi_num);
384+
spi_t * spi = &_spi_bus_array[spi_num];
385+
386+
if(spi->lock == NULL){
387+
spi->lock = xSemaphoreCreateMutex();
388+
if(spi->lock == NULL) {
389+
return NULL;
390+
}
391+
}
350392

351393
if(spi_num == HSPI) {
352394
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_CLK_EN_1);
@@ -364,6 +406,7 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_
364406
spiSetBitOrder(spi, bitOrder);
365407
spiSetClockDiv(spi, clockDiv);
366408

409+
SPI_MUTEX_LOCK();
367410
spi->dev->user.usr_mosi = 1;
368411
spi->dev->user.usr_miso = 1;
369412
spi->dev->user.doutdin = 1;
@@ -372,6 +415,7 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_
372415
for(i=0; i<16; i++) {
373416
spi->dev->data_buf[i] = 0x00000000;
374417
}
418+
SPI_MUTEX_UNLOCK();
375419

376420
return spi;
377421
}
@@ -393,13 +437,15 @@ void spiWrite(spi_t * spi, uint32_t *data, uint8_t len)
393437
if(len > 16) {
394438
len = 16;
395439
}
440+
SPI_MUTEX_LOCK();
396441
while(spi->dev->cmd.usr);
397442
spi->dev->mosi_dlen.usr_mosi_dbitlen = (len * 32) - 1;
398443
spi->dev->miso_dlen.usr_miso_dbitlen = (len * 32) - 1;
399444
for(i=0; i<len; i++) {
400445
spi->dev->data_buf[i] = data[i];
401446
}
402447
spi->dev->cmd.usr = 1;
448+
SPI_MUTEX_UNLOCK();
403449
}
404450

405451
void spiRead(spi_t * spi, uint32_t *data, uint8_t len)
@@ -411,31 +457,39 @@ void spiRead(spi_t * spi, uint32_t *data, uint8_t len)
411457
if(len > 16) {
412458
len = 16;
413459
}
460+
SPI_MUTEX_LOCK();
414461
while(spi->dev->cmd.usr);
415462
for(i=0; i<len; i++) {
416463
data[i] = spi->dev->data_buf[i];
417464
}
465+
SPI_MUTEX_UNLOCK();
418466
}
419467

420468
void spiWriteByte(spi_t * spi, uint8_t data)
421469
{
422470
if(!spi) {
423471
return;
424472
}
473+
SPI_MUTEX_LOCK();
425474
while(spi->dev->cmd.usr);
426475
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
427476
spi->dev->miso_dlen.usr_miso_dbitlen = 7;
428477
spi->dev->data_buf[0] = data;
429478
spi->dev->cmd.usr = 1;
479+
SPI_MUTEX_UNLOCK();
430480
}
431481

432482
uint8_t spiReadByte(spi_t * spi)
433483
{
434484
if(!spi) {
435485
return 0;
436486
}
487+
uint8_t data;
488+
SPI_MUTEX_LOCK();
437489
while(spi->dev->cmd.usr);
438-
return spi->dev->data_buf[0] & 0xFF;
490+
data = spi->dev->data_buf[0] & 0xFF;
491+
SPI_MUTEX_UNLOCK();
492+
return data;
439493
}
440494

441495
uint32_t __spiTranslate16(uint16_t data, bool msb)
@@ -480,41 +534,53 @@ void spiWriteWord(spi_t * spi, uint16_t data)
480534
if(!spi) {
481535
return;
482536
}
537+
SPI_MUTEX_LOCK();
483538
while(spi->dev->cmd.usr);
484539
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
485540
spi->dev->miso_dlen.usr_miso_dbitlen = 15;
486541
spi->dev->data_buf[0] = __spiTranslate16(data, !spi->dev->ctrl.wr_bit_order);
487542
spi->dev->cmd.usr = 1;
543+
SPI_MUTEX_UNLOCK();
488544
}
489545

490546
uint16_t spiReadWord(spi_t * spi)
491547
{
492548
if(!spi) {
493549
return 0;
494550
}
551+
uint16_t data;
552+
SPI_MUTEX_LOCK();
495553
while(spi->dev->cmd.usr);
496-
return __spiTranslate16(spi->dev->data_buf[0] & 0xFFFF, !spi->dev->ctrl.rd_bit_order);
554+
data = __spiTranslate16(spi->dev->data_buf[0] & 0xFFFF, !spi->dev->ctrl.rd_bit_order);
555+
SPI_MUTEX_UNLOCK();
556+
return data;
497557
}
498558

499559
void spiWriteLong(spi_t * spi, uint32_t data)
500560
{
501561
if(!spi) {
502562
return;
503563
}
564+
SPI_MUTEX_LOCK();
504565
while(spi->dev->cmd.usr);
505566
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
506567
spi->dev->miso_dlen.usr_miso_dbitlen = 31;
507568
spi->dev->data_buf[0] = __spiTranslate32(data, !spi->dev->ctrl.wr_bit_order);
508569
spi->dev->cmd.usr = 1;
570+
SPI_MUTEX_UNLOCK();
509571
}
510572

511573
uint32_t spiReadLong(spi_t * spi)
512574
{
513575
if(!spi) {
514576
return 0;
515577
}
578+
uint32_t data;
579+
SPI_MUTEX_LOCK();
516580
while(spi->dev->cmd.usr);
517-
return __spiTranslate32(spi->dev->data_buf[0], !spi->dev->ctrl.rd_bit_order);
581+
data = __spiTranslate32(spi->dev->data_buf[0], !spi->dev->ctrl.rd_bit_order);
582+
SPI_MUTEX_UNLOCK();
583+
return data;
518584
}
519585

520586
void spiTransferBits(spi_t * spi, uint32_t data, uint32_t * out, uint8_t bits)
@@ -529,6 +595,7 @@ void spiTransferBits(spi_t * spi, uint32_t data, uint32_t * out, uint8_t bits)
529595
uint32_t bytes = (bits + 7) / 8;//64 max
530596
uint32_t mask = (((uint64_t)1 << bits) - 1) & 0xFFFFFFFF;
531597

598+
SPI_MUTEX_LOCK();
532599
while(spi->dev->cmd.usr);
533600
spi->dev->mosi_dlen.usr_mosi_dbitlen = (bits - 1);
534601
spi->dev->miso_dlen.usr_miso_dbitlen = (bits - 1);
@@ -555,6 +622,7 @@ void spiTransferBits(spi_t * spi, uint32_t data, uint32_t * out, uint8_t bits)
555622
*out = __spiTranslate32(spi->dev->data_buf[0] & mask, !spi->dev->ctrl.wr_bit_order);
556623
}
557624
}
625+
SPI_MUTEX_UNLOCK();
558626
}
559627

560628
void __spiTransferBytes(spi_t * spi, uint8_t * data, uint8_t * out, uint32_t bytes)
@@ -605,6 +673,7 @@ void spiTransferBytes(spi_t * spi, uint8_t * data, uint8_t * out, uint32_t size)
605673
if(!spi) {
606674
return;
607675
}
676+
SPI_MUTEX_LOCK();
608677
while(size) {
609678
if(size > 64) {
610679
__spiTransferBytes(spi, data, out, 64);
@@ -620,6 +689,7 @@ void spiTransferBytes(spi_t * spi, uint8_t * data, uint8_t * out, uint32_t size)
620689
size = 0;
621690
}
622691
}
692+
SPI_MUTEX_UNLOCK();
623693
}
624694

625695

cores/esp32/esp32-hal-spi.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
extern "C" {
2020
#endif
2121

22-
#include "esp32-hal.h"
23-
#include "soc/spi_struct.h"
22+
#include <stdint.h>
23+
#include <stdbool.h>
2424

2525
#define SPI_HAS_TRANSACTION
2626

@@ -51,10 +51,8 @@ extern "C" {
5151
#define SPI_LSBFIRST 0
5252
#define SPI_MSBFIRST 1
5353

54-
typedef struct {
55-
spi_dev_t * dev;
56-
uint8_t num;
57-
} spi_t;
54+
struct spi_struct_t;
55+
typedef struct spi_struct_t spi_t;
5856

5957
spi_t * spiStartBus(uint8_t spi_num, uint32_t freq, uint8_t dataMode, uint8_t bitOrder);
6058
void spiStopBus(spi_t * spi);

0 commit comments

Comments
 (0)