Skip to content

Commit b3fdfda

Browse files
APokornyme-no-dev
authored andcommitted
Bugfix: Put every SPI access between begin / end Transaction (espressif#509)
The change intrdocues a local RAII helper to simplify maintaining begin/end scopes Signed-off-by: Andreas Pokorny <andreas.pokorny@siemens.com>
1 parent d8330cc commit b3fdfda

File tree

1 file changed

+34
-15
lines changed

1 file changed

+34
-15
lines changed

libraries/SD/src/sd_diskio.cpp

+34-15
Original file line numberDiff line numberDiff line change
@@ -417,10 +417,32 @@ unsigned long sdGetSectorsCount(uint8_t pdrv)
417417
}
418418

419419

420+
namespace
421+
{
420422

423+
struct AcquireSPI
424+
{
425+
ardu_sdcard_t *card;
426+
explicit AcquireSPI(ardu_sdcard_t* card)
427+
: card(card)
428+
{
429+
card->spi->beginTransaction(SPISettings(card->frequency, MSBFIRST, SPI_MODE0));
430+
}
431+
AcquireSPI(ardu_sdcard_t* card, int frequency)
432+
: card(card)
433+
{
434+
card->spi->beginTransaction(SPISettings(frequency, MSBFIRST, SPI_MODE0));
435+
}
436+
~AcquireSPI()
437+
{
438+
card->spi->endTransaction();
439+
}
440+
private:
441+
AcquireSPI(AcquireSPI const&);
442+
AcquireSPI& operator=(AcquireSPI const&);
443+
};
421444

422-
423-
445+
}
424446

425447

426448
/*
@@ -438,7 +460,7 @@ DSTATUS ff_sd_initialize(uint8_t pdrv)
438460
return card->status;
439461
}
440462

441-
card->spi->beginTransaction(SPISettings(400000, MSBFIRST, SPI_MODE0));
463+
AcquireSPI card_locked(card, 400000);
442464

443465
digitalWrite(card->ssPin, HIGH);
444466
for (uint8_t i = 0; i < 20; i++) {
@@ -538,13 +560,10 @@ DSTATUS ff_sd_initialize(uint8_t pdrv)
538560
card->frequency = 25000000;
539561
}
540562

541-
card->spi->endTransaction();
542-
543563
card->status &= ~STA_NOINIT;
544564
return card->status;
545565

546566
unknown_card:
547-
card->spi->endTransaction();
548567
card->type = CARD_UNKNOWN;
549568
return card->status;
550569
}
@@ -562,15 +581,13 @@ DRESULT ff_sd_read(uint8_t pdrv, uint8_t* buffer, DWORD sector, UINT count)
562581
}
563582
DRESULT res = RES_OK;
564583

565-
card->spi->beginTransaction(SPISettings(card->frequency, MSBFIRST, SPI_MODE0));
584+
AcquireSPI lock(card);
566585

567586
if (count > 1) {
568587
res = sdReadSectors(pdrv, (char*)buffer, sector, count) ? RES_OK : RES_ERROR;
569588
} else {
570589
res = sdReadSector(pdrv, (char*)buffer, sector) ? RES_OK : RES_ERROR;
571590
}
572-
573-
card->spi->endTransaction();
574591
return res;
575592
}
576593

@@ -586,24 +603,25 @@ DRESULT ff_sd_write(uint8_t pdrv, const uint8_t* buffer, DWORD sector, UINT coun
586603
}
587604
DRESULT res = RES_OK;
588605

589-
card->spi->beginTransaction(SPISettings(card->frequency, MSBFIRST, SPI_MODE0));
606+
AcquireSPI lock(card);
590607

591608
if (count > 1) {
592609
res = sdWriteSectors(pdrv, (const char*)buffer, sector, count) ? RES_OK : RES_ERROR;
593610
}
594611
res = sdWriteSector(pdrv, (const char*)buffer, sector) ? RES_OK : RES_ERROR;
595-
596-
card->spi->endTransaction();
597612
return res;
598613
}
599614

600615
DRESULT ff_sd_ioctl(uint8_t pdrv, uint8_t cmd, void* buff)
601616
{
602617
switch(cmd) {
603618
case CTRL_SYNC:
604-
if (sdSelectCard(pdrv)) {
605-
sdDeselectCard(pdrv);
606-
return RES_OK;
619+
{
620+
AcquireSPI lock(s_cards[pdrv]);
621+
if (sdSelectCard(pdrv)) {
622+
sdDeselectCard(pdrv);
623+
return RES_OK;
624+
}
607625
}
608626
return RES_ERROR;
609627
case GET_SECTOR_COUNT:
@@ -722,6 +740,7 @@ bool sdcard_mount(uint8_t pdrv, const char* path)
722740
esp_vfs_fat_unregister_path(path);
723741
return false;
724742
}
743+
AcquireSPI lock(card);
725744
card->sectors = sdGetSectorsCount(pdrv);
726745
return true;
727746
}

0 commit comments

Comments
 (0)