SD Cache: moved to diskio layer, invalidation in case of error (#2428)
Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
12c1ec37a2
commit
9bda3e62ee
@ -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;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#define __IO volatile
|
||||
|
||||
#define SD_TIMEOUT_MS (1000)
|
||||
#define SD_BLOCK_SIZE 512
|
||||
|
||||
typedef enum {
|
||||
SdSpiStatusOK,
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user