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_DUMMY_BYTE 0xFF
|
||||||
#define SD_ANSWER_RETRY_COUNT 8
|
#define SD_ANSWER_RETRY_COUNT 8
|
||||||
#define SD_IDLE_RETRY_COUNT 100
|
#define SD_IDLE_RETRY_COUNT 100
|
||||||
#define SD_BLOCK_SIZE 512
|
|
||||||
|
|
||||||
#define FLAG_SET(x, y) (((x) & (y)) == (y))
|
#define FLAG_SET(x, y) (((x) & (y)) == (y))
|
||||||
|
|
||||||
@ -598,23 +597,6 @@ static SdSpiStatus sd_spi_get_cid(SD_CID* Cid) {
|
|||||||
return ret;
|
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
|
static SdSpiStatus
|
||||||
sd_spi_cmd_read_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms) {
|
sd_spi_cmd_read_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms) {
|
||||||
uint32_t block_address = address;
|
uint32_t block_address = address;
|
||||||
@ -833,30 +815,12 @@ SdSpiStatus sd_get_card_info(SD_CardInfo* card_info) {
|
|||||||
|
|
||||||
SdSpiStatus
|
SdSpiStatus
|
||||||
sd_read_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms) {
|
sd_read_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms) {
|
||||||
SdSpiStatus status = SdSpiStatusError;
|
SdSpiStatus status = sd_spi_cmd_read_blocks(data, address, blocks, timeout_ms);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
SdSpiStatus
|
SdSpiStatus
|
||||||
sd_write_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms) {
|
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);
|
SdSpiStatus status = sd_spi_cmd_write_blocks(data, address, blocks, timeout_ms);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#define __IO volatile
|
#define __IO volatile
|
||||||
|
|
||||||
#define SD_TIMEOUT_MS (1000)
|
#define SD_TIMEOUT_MS (1000)
|
||||||
|
#define SD_BLOCK_SIZE 512
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SdSpiStatusOK,
|
SdSpiStatusOK,
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "user_diskio.h"
|
#include "user_diskio.h"
|
||||||
#include <furi_hal.h>
|
#include <furi_hal.h>
|
||||||
|
#include "sector_cache.h"
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
/* Private define ------------------------------------------------------------*/
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -79,6 +80,26 @@ Diskio_drvTypeDef USER_Driver = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
/* 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
|
* @brief Initializes a Drive
|
||||||
@ -125,6 +146,14 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) {
|
|||||||
UNUSED(pdrv);
|
UNUSED(pdrv);
|
||||||
DRESULT res = RES_ERROR;
|
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_spi_acquire(&furi_hal_spi_bus_handle_sd_fast);
|
||||||
furi_hal_sd_spi_handle = &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_sd_spi_handle = NULL;
|
||||||
furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast);
|
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;
|
return res;
|
||||||
/* USER CODE END READ */
|
/* USER CODE END READ */
|
||||||
}
|
}
|
||||||
@ -164,6 +197,8 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) {
|
|||||||
UNUSED(pdrv);
|
UNUSED(pdrv);
|
||||||
DRESULT res = RES_ERROR;
|
DRESULT res = RES_ERROR;
|
||||||
|
|
||||||
|
sd_cache_invalidate_range(sector, sector + count);
|
||||||
|
|
||||||
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast);
|
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast);
|
||||||
furi_hal_sd_spi_handle = &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;
|
res = RES_OK;
|
||||||
while(sd_get_card_state() != SdSpiStatusOK) {
|
while(sd_get_card_state() != SdSpiStatusOK) {
|
||||||
if(furi_hal_cortex_timer_is_expired(timer)) {
|
if(furi_hal_cortex_timer_is_expired(timer)) {
|
||||||
|
sd_cache_invalidate_all();
|
||||||
|
|
||||||
res = RES_ERROR;
|
res = RES_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user