Bugfix: Put every SPI access between begin / end Transaction (#509)

The change intrdocues a local RAII helper to simplify maintaining begin/end scopes

Signed-off-by: Andreas Pokorny <andreas.pokorny@siemens.com>
This commit is contained in:
Andreas Pokorny 2017-07-31 21:46:15 +02:00 committed by Me No Dev
parent d8330cceec
commit b3fdfda914

View File

@ -417,10 +417,32 @@ unsigned long sdGetSectorsCount(uint8_t pdrv)
} }
namespace
{
struct AcquireSPI
{
ardu_sdcard_t *card;
explicit AcquireSPI(ardu_sdcard_t* card)
: card(card)
{
card->spi->beginTransaction(SPISettings(card->frequency, MSBFIRST, SPI_MODE0));
}
AcquireSPI(ardu_sdcard_t* card, int frequency)
: card(card)
{
card->spi->beginTransaction(SPISettings(frequency, MSBFIRST, SPI_MODE0));
}
~AcquireSPI()
{
card->spi->endTransaction();
}
private:
AcquireSPI(AcquireSPI const&);
AcquireSPI& operator=(AcquireSPI const&);
};
}
/* /*
@ -438,7 +460,7 @@ DSTATUS ff_sd_initialize(uint8_t pdrv)
return card->status; return card->status;
} }
card->spi->beginTransaction(SPISettings(400000, MSBFIRST, SPI_MODE0)); AcquireSPI card_locked(card, 400000);
digitalWrite(card->ssPin, HIGH); digitalWrite(card->ssPin, HIGH);
for (uint8_t i = 0; i < 20; i++) { for (uint8_t i = 0; i < 20; i++) {
@ -538,13 +560,10 @@ DSTATUS ff_sd_initialize(uint8_t pdrv)
card->frequency = 25000000; card->frequency = 25000000;
} }
card->spi->endTransaction();
card->status &= ~STA_NOINIT; card->status &= ~STA_NOINIT;
return card->status; return card->status;
unknown_card: unknown_card:
card->spi->endTransaction();
card->type = CARD_UNKNOWN; card->type = CARD_UNKNOWN;
return card->status; return card->status;
} }
@ -562,15 +581,13 @@ DRESULT ff_sd_read(uint8_t pdrv, uint8_t* buffer, DWORD sector, UINT count)
} }
DRESULT res = RES_OK; DRESULT res = RES_OK;
card->spi->beginTransaction(SPISettings(card->frequency, MSBFIRST, SPI_MODE0)); AcquireSPI lock(card);
if (count > 1) { if (count > 1) {
res = sdReadSectors(pdrv, (char*)buffer, sector, count) ? RES_OK : RES_ERROR; res = sdReadSectors(pdrv, (char*)buffer, sector, count) ? RES_OK : RES_ERROR;
} else { } else {
res = sdReadSector(pdrv, (char*)buffer, sector) ? RES_OK : RES_ERROR; res = sdReadSector(pdrv, (char*)buffer, sector) ? RES_OK : RES_ERROR;
} }
card->spi->endTransaction();
return res; return res;
} }
@ -586,14 +603,12 @@ DRESULT ff_sd_write(uint8_t pdrv, const uint8_t* buffer, DWORD sector, UINT coun
} }
DRESULT res = RES_OK; DRESULT res = RES_OK;
card->spi->beginTransaction(SPISettings(card->frequency, MSBFIRST, SPI_MODE0)); AcquireSPI lock(card);
if (count > 1) { if (count > 1) {
res = sdWriteSectors(pdrv, (const char*)buffer, sector, count) ? RES_OK : RES_ERROR; res = sdWriteSectors(pdrv, (const char*)buffer, sector, count) ? RES_OK : RES_ERROR;
} }
res = sdWriteSector(pdrv, (const char*)buffer, sector) ? RES_OK : RES_ERROR; res = sdWriteSector(pdrv, (const char*)buffer, sector) ? RES_OK : RES_ERROR;
card->spi->endTransaction();
return res; return res;
} }
@ -601,9 +616,12 @@ DRESULT ff_sd_ioctl(uint8_t pdrv, uint8_t cmd, void* buff)
{ {
switch(cmd) { switch(cmd) {
case CTRL_SYNC: case CTRL_SYNC:
if (sdSelectCard(pdrv)) { {
sdDeselectCard(pdrv); AcquireSPI lock(s_cards[pdrv]);
return RES_OK; if (sdSelectCard(pdrv)) {
sdDeselectCard(pdrv);
return RES_OK;
}
} }
return RES_ERROR; return RES_ERROR;
case GET_SECTOR_COUNT: case GET_SECTOR_COUNT:
@ -722,6 +740,7 @@ bool sdcard_mount(uint8_t pdrv, const char* path)
esp_vfs_fat_unregister_path(path); esp_vfs_fat_unregister_path(path);
return false; return false;
} }
AcquireSPI lock(card);
card->sectors = sdGetSectorsCount(pdrv); card->sectors = sdGetSectorsCount(pdrv);
return true; return true;
} }