Ver código fonte

SD Cache: moved to diskio layer, invalidation in case of error (#2428)

Co-authored-by: あく <alleteam@gmail.com>
Sergey Gavrilov 3 anos atrás
pai
commit
9bda3e62ee

+ 1 - 37
firmware/targets/f7/fatfs/sd_spi_io.c

@@ -17,7 +17,6 @@
 #define SD_DUMMY_BYTE 0xFF
 #define SD_ANSWER_RETRY_COUNT 8
 #define SD_IDLE_RETRY_COUNT 100
-#define SD_BLOCK_SIZE 512
 
 #define FLAG_SET(x, y) (((x) & (y)) == (y))
 
@@ -598,23 +597,6 @@ static SdSpiStatus sd_spi_get_cid(SD_CID* Cid) {
     return ret;
 }
 
-static inline bool sd_cache_get(uint32_t address, uint32_t* data) {
-    uint8_t* cached_data = sector_cache_get(address);
-    if(cached_data) {
-        memcpy(data, cached_data, SD_BLOCK_SIZE);
-        return true;
-    }
-    return false;
-}
-
-static inline void sd_cache_put(uint32_t address, uint32_t* data) {
-    sector_cache_put(address, (uint8_t*)data);
-}
-
-static inline void sd_cache_invalidate_range(uint32_t start_sector, uint32_t end_sector) {
-    sector_cache_invalidate_range(start_sector, end_sector);
-}
-
 static SdSpiStatus
     sd_spi_cmd_read_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms) {
     uint32_t block_address = address;
@@ -833,30 +815,12 @@ SdSpiStatus sd_get_card_info(SD_CardInfo* card_info) {
 
 SdSpiStatus
     sd_read_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms) {
-    SdSpiStatus status = SdSpiStatusError;
-
-    bool single_sector_read = (blocks == 1);
-
-    if(single_sector_read) {
-        if(sd_cache_get(address, data)) {
-            return SdSpiStatusOK;
-        }
-
-        status = sd_spi_cmd_read_blocks(data, address, blocks, timeout_ms);
-
-        if(status == SdSpiStatusOK) {
-            sd_cache_put(address, data);
-        }
-    } else {
-        status = sd_spi_cmd_read_blocks(data, address, blocks, timeout_ms);
-    }
-
+    SdSpiStatus status = sd_spi_cmd_read_blocks(data, address, blocks, timeout_ms);
     return status;
 }
 
 SdSpiStatus
     sd_write_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms) {
-    sd_cache_invalidate_range(address, address + blocks);
     SdSpiStatus status = sd_spi_cmd_write_blocks(data, address, blocks, timeout_ms);
     return status;
 }

+ 1 - 0
firmware/targets/f7/fatfs/sd_spi_io.h

@@ -5,6 +5,7 @@
 #define __IO volatile
 
 #define SD_TIMEOUT_MS (1000)
+#define SD_BLOCK_SIZE 512
 
 typedef enum {
     SdSpiStatusOK,

+ 37 - 0
firmware/targets/f7/fatfs/user_diskio.c

@@ -36,6 +36,7 @@
 /* Includes ------------------------------------------------------------------*/
 #include "user_diskio.h"
 #include <furi_hal.h>
+#include "sector_cache.h"
 /* Private typedef -----------------------------------------------------------*/
 /* Private define ------------------------------------------------------------*/
 
@@ -79,6 +80,26 @@ Diskio_drvTypeDef USER_Driver = {
 };
 
 /* Private functions ---------------------------------------------------------*/
+static inline bool sd_cache_get(uint32_t address, uint32_t* data) {
+    uint8_t* cached_data = sector_cache_get(address);
+    if(cached_data) {
+        memcpy(data, cached_data, SD_BLOCK_SIZE);
+        return true;
+    }
+    return false;
+}
+
+static inline void sd_cache_put(uint32_t address, uint32_t* data) {
+    sector_cache_put(address, (uint8_t*)data);
+}
+
+static inline void sd_cache_invalidate_range(uint32_t start_sector, uint32_t end_sector) {
+    sector_cache_invalidate_range(start_sector, end_sector);
+}
+
+static inline void sd_cache_invalidate_all() {
+    sector_cache_init();
+}
 
 /**
   * @brief  Initializes a Drive
@@ -125,6 +146,14 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) {
     UNUSED(pdrv);
     DRESULT res = RES_ERROR;
 
+    bool single_sector = count == 1;
+
+    if(single_sector) {
+        if(sd_cache_get(sector, (uint32_t*)buff)) {
+            return RES_OK;
+        }
+    }
+
     furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast);
     furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast;
 
@@ -145,6 +174,10 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) {
     furi_hal_sd_spi_handle = NULL;
     furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast);
 
+    if(single_sector && res == RES_OK) {
+        sd_cache_put(sector, (uint32_t*)buff);
+    }
+
     return res;
     /* USER CODE END READ */
 }
@@ -164,6 +197,8 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) {
     UNUSED(pdrv);
     DRESULT res = RES_ERROR;
 
+    sd_cache_invalidate_range(sector, sector + count);
+
     furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast);
     furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast;
 
@@ -175,6 +210,8 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) {
         res = RES_OK;
         while(sd_get_card_state() != SdSpiStatusOK) {
             if(furi_hal_cortex_timer_is_expired(timer)) {
+                sd_cache_invalidate_all();
+
                 res = RES_ERROR;
                 break;
             }