diff --git a/src/main/drivers/sdcard.c b/src/main/drivers/sdcard.c index 45f2b27f2..fb7fe020a 100644 --- a/src/main/drivers/sdcard.c +++ b/src/main/drivers/sdcard.c @@ -32,6 +32,8 @@ #include "drivers/bus_spi.h" #include "drivers/time.h" +#include "pg/sdcard.h" + #include "sdcard.h" #include "sdcard_impl.h" #include "sdcard_standard.h" @@ -93,4 +95,76 @@ bool sdcard_isInserted(void) } return result; } + +/** + * Dispatch + */ +sdcardVTable_t *sdcardVTable; + +void sdcard_init(const sdcardConfig_t *config) +{ + switch (config->mode) { +#ifdef USE_SDCARD_SPI + case SDCARD_MODE_SPI: + sdcardVTable = &sdcardSpiVTable; + break; +#endif +#ifdef USE_SDCARD_SDIO + case SDCARD_MODE_SDIO: + sdcardVTable = &sdcardSdioVTable; + break; +#endif + default: + break; + } + + if (sdcardVTable) { + sdcardVTable->sdcard_init(config); + } +} + +bool sdcard_readBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData) +{ + return sdcardVTable->sdcard_readBlock(blockIndex, buffer, callback, callbackData); +} + +sdcardOperationStatus_e sdcard_beginWriteBlocks(uint32_t blockIndex, uint32_t blockCount) +{ + return sdcardVTable->sdcard_beginWriteBlocks(blockIndex, blockCount); +} + +sdcardOperationStatus_e sdcard_writeBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData) +{ + return sdcardVTable->sdcard_writeBlock(blockIndex, buffer, callback, callbackData); +} + +bool sdcard_poll(void) +{ + // sdcard_poll is called from taskMain() via afatfs_poll() and for USE_SDCARD. + if (sdcardVTable) { + return sdcardVTable->sdcard_poll(); + } else { + return false; + } +} + +bool sdcard_isFunctional(void) +{ + // sdcard_isFunctional is called from multiple places + if (sdcardVTable) { + return sdcardVTable->sdcard_isFunctional(); + } else { + return false; + } +} + +bool sdcard_isInitialized(void) +{ + return sdcardVTable->sdcard_isInitialized(); +} + +const sdcardMetadata_t* sdcard_getMetadata(void) +{ + return sdcardVTable->sdcard_getMetadata(); +} #endif diff --git a/src/main/drivers/sdcard_impl.h b/src/main/drivers/sdcard_impl.h index 5a8374dd5..b3d140fe6 100644 --- a/src/main/drivers/sdcard_impl.h +++ b/src/main/drivers/sdcard_impl.h @@ -111,3 +111,24 @@ STATIC_ASSERT(sizeof(sdcardCSD_t) == 16, sdcard_csd_bitfields_didnt_pack_properl void sdcardInsertionDetectInit(void); void sdcardInsertionDetectDeinit(void); bool sdcard_isInserted(void); + +typedef struct sdcardVTable_s { + void (*sdcard_init)(const sdcardConfig_t *config); + bool (*sdcard_readBlock)(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData); + sdcardOperationStatus_e (*sdcard_beginWriteBlocks)(uint32_t blockIndex, uint32_t blockCount); + sdcardOperationStatus_e (*sdcard_writeBlock)(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData); + bool (*sdcard_poll)(void); + bool (*sdcard_isFunctional)(void); + bool (*sdcard_isInitialized)(void); + const sdcardMetadata_t* (*sdcard_getMetadata)(void); +#ifdef SDCARD_PROFILING + void (*sdcardSdio_setProfilerCallback)(sdcard_profilerCallback_c callback); +#endif +} sdcardVTable_t; + +#ifdef USE_SDCARD_SPI +extern sdcardVTable_t sdcardSpiVTable; +#endif +#ifdef USE_SDCARD_SDIO +extern sdcardVTable_t sdcardSdioVTable; +#endif diff --git a/src/main/drivers/sdcard_sdio_baremetal.c b/src/main/drivers/sdcard_sdio_baremetal.c index 33d616c5d..99493e584 100644 --- a/src/main/drivers/sdcard_sdio_baremetal.c +++ b/src/main/drivers/sdcard_sdio_baremetal.c @@ -72,7 +72,7 @@ void cache_reset(void) * Returns true if the card has already been, or is currently, initializing and hasn't encountered enough errors to * trip our error threshold and be disabled (i.e. our card is in and working!) */ -bool sdcard_isFunctional(void) +static bool sdcardSdio_isFunctional(void) { return sdcard.state != SDCARD_STATE_NOT_PRESENT; } @@ -187,7 +187,7 @@ static bool sdcard_checkInitDone(void) /** * Begin the initialization process for the SD card. This must be called first before any other sdcard_ routine. */ -void sdcard_init(const sdcardConfig_t *config) +static void sdcardSdio_init(const sdcardConfig_t *config) { sdcard.enabled = config->enabled; if (!sdcard.enabled) { @@ -273,7 +273,7 @@ static sdcardOperationStatus_e sdcard_endWriteBlocks() * * Returns true if the card is ready to accept commands. */ -bool sdcard_poll(void) +static bool sdcardSdio_poll(void) { if (!sdcard.enabled) { sdcard.state = SDCARD_STATE_NOT_PRESENT; @@ -448,7 +448,7 @@ bool sdcard_poll(void) * SDCARD_OPERATION_BUSY - The card is already busy and cannot accept your write * SDCARD_OPERATION_FAILURE - Your write was rejected by the card, card will be reset */ -sdcardOperationStatus_e sdcard_writeBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData) +static sdcardOperationStatus_e sdcardSdio_writeBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData) { #ifdef SDCARD_PROFILING @@ -531,7 +531,7 @@ sdcardOperationStatus_e sdcard_writeBlock(uint32_t blockIndex, uint8_t *buffer, * SDCARD_OPERATION_BUSY - The card is already busy and cannot accept your write * SDCARD_OPERATION_FAILURE - A fatal error occured, card will be reset */ -sdcardOperationStatus_e sdcard_beginWriteBlocks(uint32_t blockIndex, uint32_t blockCount) +static sdcardOperationStatus_e sdcardSdio_beginWriteBlocks(uint32_t blockIndex, uint32_t blockCount) { if (sdcard.state != SDCARD_STATE_READY) { if (sdcard.state == SDCARD_STATE_WRITING_MULTIPLE_BLOCKS) { @@ -564,7 +564,7 @@ sdcardOperationStatus_e sdcard_beginWriteBlocks(uint32_t blockIndex, uint32_t bl * true - The operation was successfully queued for later completion, your callback will be called later * false - The operation could not be started due to the card being busy (try again later). */ -bool sdcard_readBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData) +static bool sdcardSdio_readBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData) { if (sdcard.state != SDCARD_STATE_READY) { if (sdcard.state == SDCARD_STATE_WRITING_MULTIPLE_BLOCKS) { @@ -611,23 +611,36 @@ bool sdcard_readBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationComp /** * Returns true if the SD card has successfully completed its startup procedures. */ -bool sdcard_isInitialized(void) +static bool sdcardSdio_isInitialized(void) { return sdcard.state >= SDCARD_STATE_READY; } -const sdcardMetadata_t* sdcard_getMetadata(void) +static const sdcardMetadata_t* sdcardSdio_getMetadata(void) { return &sdcard.metadata; } #ifdef SDCARD_PROFILING -void sdcard_setProfilerCallback(sdcard_profilerCallback_c callback) +static void sdcardSdio_setProfilerCallback(sdcard_profilerCallback_c callback) { sdcard.profiler = callback; } #endif +sdcardVTable_t sdcardSdioVTable = { + sdcardSdio_init, + sdcardSdio_readBlock, + sdcardSdio_beginWriteBlocks, + sdcardSdio_writeBlock, + sdcardSdio_poll, + sdcardSdio_isFunctional, + sdcardSdio_isInitialized, + sdcardSdio_getMetadata, +#ifdef SDCARD_PROFILING + sdcardSdio_setProfilerCallback, +#endif +}; #endif diff --git a/src/main/drivers/sdcard_spi.c b/src/main/drivers/sdcard_spi.c index c2a851337..28ec61bf9 100644 --- a/src/main/drivers/sdcard_spi.c +++ b/src/main/drivers/sdcard_spi.c @@ -63,7 +63,7 @@ * Returns true if the card has already been, or is currently, initializing and hasn't encountered enough errors to * trip our error threshold and be disabled (i.e. our card is in and working!) */ -bool sdcard_isFunctional(void) +static bool sdcardSpi_isFunctional(void) { return sdcard.state != SDCARD_STATE_NOT_PRESENT; } @@ -471,7 +471,7 @@ static bool sdcard_checkInitDone(void) /** * Begin the initialization process for the SD card. This must be called first before any other sdcard_ routine. */ -void sdcard_init(const sdcardConfig_t *config) +static void sdcardSpi_init(const sdcardConfig_t *config) { sdcard.enabled = config->enabled; if (!sdcard.enabled) { @@ -587,7 +587,7 @@ static sdcardOperationStatus_e sdcard_endWriteBlocks(void) * * Returns true if the card is ready to accept commands. */ -bool sdcard_poll(void) +static bool sdcardSpi_poll(void) { if (!sdcard.enabled) { sdcard.state = SDCARD_STATE_NOT_PRESENT; @@ -897,7 +897,7 @@ bool sdcard_poll(void) * SDCARD_OPERATION_BUSY - The card is already busy and cannot accept your write * SDCARD_OPERATION_FAILURE - Your write was rejected by the card, card will be reset */ -sdcardOperationStatus_e sdcard_writeBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData) +static sdcardOperationStatus_e sdcardSpi_writeBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData) { uint8_t status; @@ -964,7 +964,7 @@ sdcardOperationStatus_e sdcard_writeBlock(uint32_t blockIndex, uint8_t *buffer, * SDCARD_OPERATION_BUSY - The card is already busy and cannot accept your write * SDCARD_OPERATION_FAILURE - A fatal error occured, card will be reset */ -sdcardOperationStatus_e sdcard_beginWriteBlocks(uint32_t blockIndex, uint32_t blockCount) +static sdcardOperationStatus_e sdcardSpi_beginWriteBlocks(uint32_t blockIndex, uint32_t blockCount) { if (sdcard.state != SDCARD_STATE_READY) { if (sdcard.state == SDCARD_STATE_WRITING_MULTIPLE_BLOCKS) { @@ -1012,7 +1012,7 @@ sdcardOperationStatus_e sdcard_beginWriteBlocks(uint32_t blockIndex, uint32_t bl * true - The operation was successfully queued for later completion, your callback will be called later * false - The operation could not be started due to the card being busy (try again later). */ -bool sdcard_readBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData) +static bool sdcardSpi_readBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData) { if (sdcard.state != SDCARD_STATE_READY) { if (sdcard.state == SDCARD_STATE_WRITING_MULTIPLE_BLOCKS) { @@ -1056,23 +1056,37 @@ bool sdcard_readBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationComp /** * Returns true if the SD card has successfully completed its startup procedures. */ -bool sdcard_isInitialized(void) +static bool sdcardSpi_isInitialized(void) { return sdcard.state >= SDCARD_STATE_READY; } -const sdcardMetadata_t* sdcard_getMetadata(void) +static const sdcardMetadata_t* sdcardSpi_getMetadata(void) { return &sdcard.metadata; } #ifdef SDCARD_PROFILING -void sdcard_setProfilerCallback(sdcard_profilerCallback_c callback) +static void sdcardSpi_setProfilerCallback(sdcard_profilerCallback_c callback) { sdcard.profiler = callback; } #endif +sdcardVTable_t sdcardSpiVTable = { + sdcardSpi_init, + sdcardSpi_readBlock, + sdcardSpi_beginWriteBlocks, + sdcardSpi_writeBlock, + sdcardSpi_poll, + sdcardSpi_isFunctional, + sdcardSpi_isInitialized, + sdcardSpi_getMetadata, +#ifdef SDCARD_PROFILING + sdcardSpi_setProfilerCallback, +#endif +}; + #endif