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))))
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+
4258void 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
7896void 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
199219void 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
207229void 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
216240void 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
225251void 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
233261void 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
241271uint32_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
257289uint8_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
302336uint8_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
324360void 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
340378spi_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
405451void 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
420468void 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
432482uint8_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
441495uint32_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
490546uint16_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
499559void 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
511573uint32_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
520586void 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
560628void __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
0 commit comments