diff --git a/src/main/drivers/sdcard.c b/src/main/drivers/sdcard.c index 7707aa9cc1..c37947f365 100644 --- a/src/main/drivers/sdcard.c +++ b/src/main/drivers/sdcard.c @@ -119,31 +119,23 @@ void sdcardInsertionDetectInit(void) } /** - * @brief Detect if SD card is correctly plugged in the memory slot. - * @param None - * @retval Return if SD is detected or not + * Detect if a SD card is physically present in the memory slot. */ bool sdcard_isInserted(void) { + bool result = true; + #ifdef SDCARD_DETECT_PIN - /*!< Check GPIO to detect SD */ - if ((GPIO_ReadInputData(SDCARD_DETECT_GPIO_PORT) & SDCARD_DETECT_PIN) != 0) - { -#ifdef SD_DETECT_INVERTED - return false; -#else - return true; + + result = (GPIO_ReadInputData(SDCARD_DETECT_GPIO_PORT) & SDCARD_DETECT_PIN) != 0; + +#ifdef SDCARD_DETECT_INVERTED + result = !result; #endif - } else { -#ifdef SD_DETECT_INVERTED - return true; -#else - return false; -#endif - } -#else - return true; + #endif + + return result; } static void sdcard_select() @@ -247,7 +239,7 @@ static uint8_t sdcard_sendAppCommand(uint8_t commandCode, uint32_t commandArgume /** * Sends an IF_COND message to the card to check its version and validate its voltage requirements. Sets the global - * sdCardVersion with the detected version (0, 1, or 2) and returns true if the card is compatbile. + * sdCardVersion with the detected version (0, 1, or 2) and returns true if the card is compatible. */ static bool sdcard_validateInterfaceCondition() { diff --git a/src/main/io/asyncfatfs/asyncfatfs.c b/src/main/io/asyncfatfs/asyncfatfs.c index c5f0d9633c..c2ff1803fd 100644 --- a/src/main/io/asyncfatfs/asyncfatfs.c +++ b/src/main/io/asyncfatfs/asyncfatfs.c @@ -437,6 +437,8 @@ typedef struct afatfs_t { afatfsFile_t freeFile; #endif + afatfsError_e lastError; + bool filesystemFull; // The current working directory: @@ -500,6 +502,9 @@ static bool isPowerOfTwo(unsigned int x) static bool afatfs_assert(bool condition) { if (!condition) { + if (afatfs.lastError == AFATFS_ERROR_NONE) { + afatfs.lastError = AFATFS_ERROR_GENERIC; + } afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_FATAL; #ifdef AFATFS_DEBUG raise(SIGTRAP); @@ -942,6 +947,8 @@ static bool afatfs_parseVolumeID(const uint8_t *sector) { fatVolumeID_t *volume = (fatVolumeID_t *) sector; + afatfs.filesystemType = FAT_FILESYSTEM_TYPE_INVALID; + if (volume->bytesPerSector != AFATFS_SECTOR_SIZE || volume->numFATs != AFATFS_NUM_FATS || sector[510] != FAT_VOLUME_ID_SIGNATURE_1 || sector[511] != FAT_VOLUME_ID_SIGNATURE_2) { return false; @@ -967,7 +974,6 @@ static bool afatfs_parseVolumeID(const uint8_t *sector) if (afatfs.numClusters <= FAT12_MAX_CLUSTERS) { afatfs.filesystemType = FAT_FILESYSTEM_TYPE_FAT12; - afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_FATAL; return false; // FAT12 is not a supported filesystem } else if (afatfs.numClusters <= FAT16_MAX_CLUSTERS) { @@ -987,8 +993,6 @@ static bool afatfs_parseVolumeID(const uint8_t *sector) afatfs.clusterStartSector = endOfFATs + afatfs.rootDirectorySectors; - afatfs_chdir(NULL); - return true; } @@ -3245,6 +3249,7 @@ static void afatfs_freeFileCreated(afatfsFile_t *file) } } else { // Failed to allocate an entry + afatfs.lastError = AFATFS_ERROR_GENERIC; afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_FATAL; } } @@ -3268,6 +3273,7 @@ static void afatfs_initContinue() afatfs.initPhase = AFATFS_INITIALIZATION_READ_VOLUME_ID; goto doMore; } else { + afatfs.lastError = AFATFS_ERROR_BAD_MBR; afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_FATAL; } } @@ -3286,6 +3292,7 @@ static void afatfs_initContinue() afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_READY; #endif } else { + afatfs.lastError = AFATFS_ERROR_BAD_FILESYSTEM_HEADER; afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_FATAL; } } @@ -3339,6 +3346,7 @@ static void afatfs_initContinue() goto doMore; } else if (status == AFATFS_OPERATION_FAILURE) { + afatfs.lastError = AFATFS_ERROR_GENERIC; afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_FATAL; } break; @@ -3348,6 +3356,7 @@ static void afatfs_initContinue() if (status == AFATFS_OPERATION_SUCCESS) { afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_READY; } else if (status == AFATFS_OPERATION_FAILURE) { + afatfs.lastError = AFATFS_ERROR_GENERIC; afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_FATAL; } break; @@ -3382,6 +3391,11 @@ afatfsFilesystemState_e afatfs_getFilesystemState() return afatfs.filesystemState; } +afatfsError_e afatfs_getLastError() +{ + return afatfs.lastError; +} + void afatfs_init() { afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_INITIALIZATION; diff --git a/src/main/io/asyncfatfs/asyncfatfs.h b/src/main/io/asyncfatfs/asyncfatfs.h index e8ed508bc1..fd515694bb 100644 --- a/src/main/io/asyncfatfs/asyncfatfs.h +++ b/src/main/io/asyncfatfs/asyncfatfs.h @@ -37,6 +37,13 @@ typedef enum { AFATFS_OPERATION_FAILURE, } afatfsOperationStatus_e; +typedef enum { + AFATFS_ERROR_NONE = 0, + AFATFS_ERROR_GENERIC = 1, + AFATFS_ERROR_BAD_MBR = 2, + AFATFS_ERROR_BAD_FILESYSTEM_HEADER = 3 +} afatfsError_e; + typedef struct afatfsDirEntryPointer_t { uint32_t sectorNumberPhysical; int16_t entryIndex; @@ -82,3 +89,4 @@ uint32_t afatfs_getContiguousFreeSpace(); bool afatfs_isFull(); afatfsFilesystemState_e afatfs_getFilesystemState(); +afatfsError_e afatfs_getLastError(); diff --git a/src/main/io/serial_cli.c b/src/main/io/serial_cli.c index c0beb2f3c9..610b6aa92d 100644 --- a/src/main/io/serial_cli.c +++ b/src/main/io/serial_cli.c @@ -57,6 +57,7 @@ #include "io/ledstrip.h" #include "io/flashfs.h" #include "io/beeper.h" +#include "io/asyncfatfs/asyncfatfs.h" #include "rx/rx.h" #include "rx/spektrum.h" @@ -1508,14 +1509,21 @@ static void cliWriteBytes(const uint8_t *buffer, int count) static void cliSdInfo(char *cmdline) { UNUSED(cmdline); + cliPrint("SD card: "); + + if (!sdcard_isInserted()) { + cliPrint("None inserted\r\n"); + return; + } + if (!sdcard_isInitialized()) { - cliPrint("sd card not present\r\n"); + cliPrint("Startup failed\r\n"); return; } const sdcardMetadata_t *metadata = sdcard_getMetadata(); - cliPrintf("manufacturer 0x%x, capacity: %ukB, %02d/%04d, v%d.%d, '", + cliPrintf("Manufacturer 0x%x, %ukB, %02d/%04d, v%d.%d, '", metadata->manufacturerID, metadata->numBlocks / 2, /* One block is half a kB */ metadata->productionMonth, @@ -1526,7 +1534,35 @@ static void cliSdInfo(char *cmdline) { cliWriteBytes((uint8_t*)metadata->productName, sizeof(metadata->productName)); - cliPrint("'\r\n"); + cliPrint("'\r\n" "Filesystem: "); + + switch (afatfs_getFilesystemState()) { + case AFATFS_FILESYSTEM_STATE_READY: + cliPrint("Ready"); + break; + case AFATFS_FILESYSTEM_STATE_INITIALIZATION: + cliPrint("Initializing"); + break; + case AFATFS_FILESYSTEM_STATE_UNKNOWN: + case AFATFS_FILESYSTEM_STATE_FATAL: + cliPrint("Fatal"); + + switch (afatfs_getLastError()) { + case AFATFS_ERROR_BAD_MBR: + cliPrint(" - no FAT MBR partitions"); + break; + case AFATFS_ERROR_BAD_FILESYSTEM_HEADER: + cliPrint(" - bad FAT header"); + break; + case AFATFS_ERROR_GENERIC: + case AFATFS_ERROR_NONE: + ; // Nothing more detailed to print + break; + } + + cliPrint("\r\n"); + break; + } } #endif