13
13
// limitations under the License.
14
14
15
15
#include "esp32-hal-spi.h"
16
+ #include "esp32-hal.h"
16
17
#include "freertos/FreeRTOS.h"
17
18
#include "freertos/task.h"
19
+ #include "freertos/semphr.h"
18
20
#include "rom/ets_sys.h"
19
21
#include "esp_attr.h"
20
22
#include "esp_intr.h"
21
23
#include "rom/gpio.h"
22
24
#include "soc/spi_reg.h"
25
+ #include "soc/spi_struct.h"
23
26
#include "soc/io_mux_reg.h"
24
27
#include "soc/gpio_sig_map.h"
25
28
#include "soc/dport_reg.h"
26
29
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
-
30
30
#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))))
31
31
#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))))
32
32
#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
39
#define SPI_INUM (u ) (2)
40
40
#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))))
41
41
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
+
42
58
void spiAttachSCK (spi_t * spi , int8_t sck )
43
59
{
44
60
if (!spi ) {
@@ -71,8 +87,10 @@ void spiAttachMISO(spi_t * spi, int8_t miso)
71
87
miso = 7 ;
72
88
}
73
89
}
90
+ SPI_MUTEX_LOCK ();
74
91
pinMode (miso , INPUT );
75
92
pinMatrixInAttach (miso , SPI_MISO_IDX (spi -> num ), false);
93
+ SPI_MUTEX_UNLOCK ();
76
94
}
77
95
78
96
void spiAttachMOSI (spi_t * spi , int8_t mosi )
@@ -193,49 +211,61 @@ void spiEnableSSPins(spi_t * spi, uint8_t cs_mask)
193
211
if (!spi ) {
194
212
return ;
195
213
}
214
+ SPI_MUTEX_LOCK ();
196
215
spi -> dev -> pin .val &= ~(cs_mask & SPI_CS_MASK_ALL );
216
+ SPI_MUTEX_UNLOCK ();
197
217
}
198
218
199
219
void spiDisableSSPins (spi_t * spi , uint8_t cs_mask )
200
220
{
201
221
if (!spi ) {
202
222
return ;
203
223
}
224
+ SPI_MUTEX_LOCK ();
204
225
spi -> dev -> pin .val |= (cs_mask & SPI_CS_MASK_ALL );
226
+ SPI_MUTEX_UNLOCK ();
205
227
}
206
228
207
229
void spiSSEnable (spi_t * spi )
208
230
{
209
231
if (!spi ) {
210
232
return ;
211
233
}
234
+ SPI_MUTEX_LOCK ();
212
235
spi -> dev -> user .cs_setup = 1 ;
213
236
spi -> dev -> user .cs_hold = 1 ;
237
+ SPI_MUTEX_UNLOCK ();
214
238
}
215
239
216
240
void spiSSDisable (spi_t * spi )
217
241
{
218
242
if (!spi ) {
219
243
return ;
220
244
}
245
+ SPI_MUTEX_LOCK ();
221
246
spi -> dev -> user .cs_setup = 0 ;
222
247
spi -> dev -> user .cs_hold = 0 ;
248
+ SPI_MUTEX_UNLOCK ();
223
249
}
224
250
225
251
void spiSSSet (spi_t * spi )
226
252
{
227
253
if (!spi ) {
228
254
return ;
229
255
}
256
+ SPI_MUTEX_LOCK ();
230
257
spi -> dev -> pin .cs_keep_active = 1 ;
258
+ SPI_MUTEX_UNLOCK ();
231
259
}
232
260
233
261
void spiSSClear (spi_t * spi )
234
262
{
235
263
if (!spi ) {
236
264
return ;
237
265
}
266
+ SPI_MUTEX_LOCK ();
238
267
spi -> dev -> pin .cs_keep_active = 0 ;
268
+ SPI_MUTEX_UNLOCK ();
239
269
}
240
270
241
271
uint32_t spiGetClockDiv (spi_t * spi )
@@ -251,7 +281,9 @@ void spiSetClockDiv(spi_t * spi, uint32_t clockDiv)
251
281
if (!spi ) {
252
282
return ;
253
283
}
284
+ SPI_MUTEX_LOCK ();
254
285
spi -> dev -> clock .val = clockDiv ;
286
+ SPI_MUTEX_UNLOCK ();
255
287
}
256
288
257
289
uint8_t spiGetDataMode (spi_t * spi )
@@ -278,6 +310,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode)
278
310
if (!spi ) {
279
311
return ;
280
312
}
313
+ SPI_MUTEX_LOCK ();
281
314
switch (dataMode ) {
282
315
case SPI_MODE1 :
283
316
spi -> dev -> pin .ck_idle_edge = 0 ;
@@ -297,6 +330,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode)
297
330
spi -> dev -> user .ck_out_edge = 0 ;
298
331
break ;
299
332
}
333
+ SPI_MUTEX_UNLOCK ();
300
334
}
301
335
302
336
uint8_t spiGetBitOrder (spi_t * spi )
@@ -312,20 +346,23 @@ void spiSetBitOrder(spi_t * spi, uint8_t bitOrder)
312
346
if (!spi ) {
313
347
return ;
314
348
}
349
+ SPI_MUTEX_LOCK ();
315
350
if (SPI_MSBFIRST == bitOrder ) {
316
351
spi -> dev -> ctrl .wr_bit_order = 0 ;
317
352
spi -> dev -> ctrl .rd_bit_order = 0 ;
318
353
} else if (SPI_LSBFIRST == bitOrder ) {
319
354
spi -> dev -> ctrl .wr_bit_order = 1 ;
320
355
spi -> dev -> ctrl .rd_bit_order = 1 ;
321
356
}
357
+ SPI_MUTEX_UNLOCK ();
322
358
}
323
359
324
360
void spiStopBus (spi_t * spi )
325
361
{
326
362
if (!spi ) {
327
363
return ;
328
364
}
365
+ SPI_MUTEX_LOCK ();
329
366
spi -> dev -> slave .trans_done = 0 ;
330
367
spi -> dev -> slave .slave_mode = 0 ;
331
368
spi -> dev -> pin .val = 0 ;
@@ -335,18 +372,23 @@ void spiStopBus(spi_t * spi)
335
372
spi -> dev -> ctrl1 .val = 0 ;
336
373
spi -> dev -> ctrl2 .val = 0 ;
337
374
spi -> dev -> clock .val = 0 ;
375
+ SPI_MUTEX_UNLOCK ();
338
376
}
339
377
340
378
spi_t * spiStartBus (uint8_t spi_num , uint32_t clockDiv , uint8_t dataMode , uint8_t bitOrder )
341
379
{
342
-
343
- spi_t * spi = (spi_t * ) malloc (sizeof (spi_t ));
344
- if (spi == 0 ) {
380
+ if (spi_num > 3 ){
345
381
return NULL ;
346
382
}
347
383
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
+ }
350
392
351
393
if (spi_num == HSPI ) {
352
394
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_
364
406
spiSetBitOrder (spi , bitOrder );
365
407
spiSetClockDiv (spi , clockDiv );
366
408
409
+ SPI_MUTEX_LOCK ();
367
410
spi -> dev -> user .usr_mosi = 1 ;
368
411
spi -> dev -> user .usr_miso = 1 ;
369
412
spi -> dev -> user .doutdin = 1 ;
@@ -372,6 +415,7 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_
372
415
for (i = 0 ; i < 16 ; i ++ ) {
373
416
spi -> dev -> data_buf [i ] = 0x00000000 ;
374
417
}
418
+ SPI_MUTEX_UNLOCK ();
375
419
376
420
return spi ;
377
421
}
@@ -393,13 +437,15 @@ void spiWrite(spi_t * spi, uint32_t *data, uint8_t len)
393
437
if (len > 16 ) {
394
438
len = 16 ;
395
439
}
440
+ SPI_MUTEX_LOCK ();
396
441
while (spi -> dev -> cmd .usr );
397
442
spi -> dev -> mosi_dlen .usr_mosi_dbitlen = (len * 32 ) - 1 ;
398
443
spi -> dev -> miso_dlen .usr_miso_dbitlen = (len * 32 ) - 1 ;
399
444
for (i = 0 ; i < len ; i ++ ) {
400
445
spi -> dev -> data_buf [i ] = data [i ];
401
446
}
402
447
spi -> dev -> cmd .usr = 1 ;
448
+ SPI_MUTEX_UNLOCK ();
403
449
}
404
450
405
451
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)
411
457
if (len > 16 ) {
412
458
len = 16 ;
413
459
}
460
+ SPI_MUTEX_LOCK ();
414
461
while (spi -> dev -> cmd .usr );
415
462
for (i = 0 ; i < len ; i ++ ) {
416
463
data [i ] = spi -> dev -> data_buf [i ];
417
464
}
465
+ SPI_MUTEX_UNLOCK ();
418
466
}
419
467
420
468
void spiWriteByte (spi_t * spi , uint8_t data )
421
469
{
422
470
if (!spi ) {
423
471
return ;
424
472
}
473
+ SPI_MUTEX_LOCK ();
425
474
while (spi -> dev -> cmd .usr );
426
475
spi -> dev -> mosi_dlen .usr_mosi_dbitlen = 7 ;
427
476
spi -> dev -> miso_dlen .usr_miso_dbitlen = 7 ;
428
477
spi -> dev -> data_buf [0 ] = data ;
429
478
spi -> dev -> cmd .usr = 1 ;
479
+ SPI_MUTEX_UNLOCK ();
430
480
}
431
481
432
482
uint8_t spiReadByte (spi_t * spi )
433
483
{
434
484
if (!spi ) {
435
485
return 0 ;
436
486
}
487
+ uint8_t data ;
488
+ SPI_MUTEX_LOCK ();
437
489
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 ;
439
493
}
440
494
441
495
uint32_t __spiTranslate16 (uint16_t data , bool msb )
@@ -480,41 +534,53 @@ void spiWriteWord(spi_t * spi, uint16_t data)
480
534
if (!spi ) {
481
535
return ;
482
536
}
537
+ SPI_MUTEX_LOCK ();
483
538
while (spi -> dev -> cmd .usr );
484
539
spi -> dev -> mosi_dlen .usr_mosi_dbitlen = 15 ;
485
540
spi -> dev -> miso_dlen .usr_miso_dbitlen = 15 ;
486
541
spi -> dev -> data_buf [0 ] = __spiTranslate16 (data , !spi -> dev -> ctrl .wr_bit_order );
487
542
spi -> dev -> cmd .usr = 1 ;
543
+ SPI_MUTEX_UNLOCK ();
488
544
}
489
545
490
546
uint16_t spiReadWord (spi_t * spi )
491
547
{
492
548
if (!spi ) {
493
549
return 0 ;
494
550
}
551
+ uint16_t data ;
552
+ SPI_MUTEX_LOCK ();
495
553
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 ;
497
557
}
498
558
499
559
void spiWriteLong (spi_t * spi , uint32_t data )
500
560
{
501
561
if (!spi ) {
502
562
return ;
503
563
}
564
+ SPI_MUTEX_LOCK ();
504
565
while (spi -> dev -> cmd .usr );
505
566
spi -> dev -> mosi_dlen .usr_mosi_dbitlen = 31 ;
506
567
spi -> dev -> miso_dlen .usr_miso_dbitlen = 31 ;
507
568
spi -> dev -> data_buf [0 ] = __spiTranslate32 (data , !spi -> dev -> ctrl .wr_bit_order );
508
569
spi -> dev -> cmd .usr = 1 ;
570
+ SPI_MUTEX_UNLOCK ();
509
571
}
510
572
511
573
uint32_t spiReadLong (spi_t * spi )
512
574
{
513
575
if (!spi ) {
514
576
return 0 ;
515
577
}
578
+ uint32_t data ;
579
+ SPI_MUTEX_LOCK ();
516
580
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 ;
518
584
}
519
585
520
586
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)
529
595
uint32_t bytes = (bits + 7 ) / 8 ;//64 max
530
596
uint32_t mask = (((uint64_t )1 << bits ) - 1 ) & 0xFFFFFFFF ;
531
597
598
+ SPI_MUTEX_LOCK ();
532
599
while (spi -> dev -> cmd .usr );
533
600
spi -> dev -> mosi_dlen .usr_mosi_dbitlen = (bits - 1 );
534
601
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)
555
622
* out = __spiTranslate32 (spi -> dev -> data_buf [0 ] & mask , !spi -> dev -> ctrl .wr_bit_order );
556
623
}
557
624
}
625
+ SPI_MUTEX_UNLOCK ();
558
626
}
559
627
560
628
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)
605
673
if (!spi ) {
606
674
return ;
607
675
}
676
+ SPI_MUTEX_LOCK ();
608
677
while (size ) {
609
678
if (size > 64 ) {
610
679
__spiTransferBytes (spi , data , out , 64 );
@@ -620,6 +689,7 @@ void spiTransferBytes(spi_t * spi, uint8_t * data, uint8_t * out, uint32_t size)
620
689
size = 0 ;
621
690
}
622
691
}
692
+ SPI_MUTEX_UNLOCK ();
623
693
}
624
694
625
695
0 commit comments