From f7024cff786751309f67ca3cdbf6d527b9eb5214 Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Mon, 20 Mar 2023 06:09:10 -0700 Subject: [PATCH] SD Driver: reinit sd card on error (#2493) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SD Driver: reinit sd card on error * SD Driver: cleanup fatfs bindings * Storage: optimized glue * Storage: move fatfs initialization to appropriate subsystems, minor code cleanup * SD Driver: minor code cleanup Co-authored-by: あく --- applications/services/storage/storage_glue.c | 61 ++--- applications/services/storage/storage_glue.h | 2 +- .../services/storage/storage_processing.c | 8 +- .../services/storage/storages/storage_ext.c | 4 +- firmware/targets/f18/furi_hal/furi_hal.c | 6 - firmware/targets/f7/fatfs/fatfs.c | 47 +--- firmware/targets/f7/fatfs/fatfs.h | 50 +--- firmware/targets/f7/fatfs/ffconf.h | 2 +- firmware/targets/f7/fatfs/syscall.c | 116 --------- firmware/targets/f7/fatfs/user_diskio.c | 228 ++++++++---------- firmware/targets/f7/fatfs/user_diskio.h | 40 +-- firmware/targets/f7/furi_hal/furi_hal.c | 6 - firmware/targets/f7/src/update.c | 2 +- 13 files changed, 154 insertions(+), 418 deletions(-) delete mode 100644 firmware/targets/f7/fatfs/syscall.c diff --git a/applications/services/storage/storage_glue.c b/applications/services/storage/storage_glue.c index 5dabfa38..63e44c9d 100644 --- a/applications/services/storage/storage_glue.c +++ b/applications/services/storage/storage_glue.c @@ -73,29 +73,34 @@ uint32_t storage_data_get_timestamp(StorageData* storage) { /****************** storage glue ******************/ -bool storage_has_file(const File* file, StorageData* storage_data) { - bool result = false; +static StorageFile* storage_get_file(const File* file, StorageData* storage) { + StorageFile* storage_file_ref = NULL; StorageFileList_it_t it; - for(StorageFileList_it(it, storage_data->files); !StorageFileList_end_p(it); + for(StorageFileList_it(it, storage->files); !StorageFileList_end_p(it); StorageFileList_next(it)) { - const StorageFile* storage_file = StorageFileList_cref(it); + StorageFile* storage_file = StorageFileList_ref(it); if(storage_file->file->file_id == file->file_id) { - result = true; + storage_file_ref = storage_file; break; } } - return result; + return storage_file_ref; } -bool storage_path_already_open(FuriString* path, StorageFileList_t array) { +bool storage_has_file(const File* file, StorageData* storage) { + return storage_get_file(file, storage) != NULL; +} + +bool storage_path_already_open(FuriString* path, StorageData* storage) { bool open = false; StorageFileList_it_t it; - for(StorageFileList_it(it, array); !StorageFileList_end_p(it); StorageFileList_next(it)) { + for(StorageFileList_it(it, storage->files); !StorageFileList_end_p(it); + StorageFileList_next(it)) { const StorageFile* storage_file = StorageFileList_cref(it); if(furi_string_cmp(storage_file->path, path) == 0) { @@ -108,43 +113,15 @@ bool storage_path_already_open(FuriString* path, StorageFileList_t array) { } void storage_set_storage_file_data(const File* file, void* file_data, StorageData* storage) { - StorageFile* founded_file = NULL; - - StorageFileList_it_t it; - - for(StorageFileList_it(it, storage->files); !StorageFileList_end_p(it); - StorageFileList_next(it)) { - StorageFile* storage_file = StorageFileList_ref(it); - - if(storage_file->file->file_id == file->file_id) { - founded_file = storage_file; - break; - } - } - - furi_check(founded_file != NULL); - - founded_file->file_data = file_data; + StorageFile* storage_file_ref = storage_get_file(file, storage); + furi_check(storage_file_ref != NULL); + storage_file_ref->file_data = file_data; } void* storage_get_storage_file_data(const File* file, StorageData* storage) { - const StorageFile* founded_file = NULL; - - StorageFileList_it_t it; - - for(StorageFileList_it(it, storage->files); !StorageFileList_end_p(it); - StorageFileList_next(it)) { - const StorageFile* storage_file = StorageFileList_cref(it); - - if(storage_file->file->file_id == file->file_id) { - founded_file = storage_file; - break; - } - } - - furi_check(founded_file != NULL); - - return founded_file->file_data; + StorageFile* storage_file_ref = storage_get_file(file, storage); + furi_check(storage_file_ref != NULL); + return storage_file_ref->file_data; } void storage_push_storage_file(File* file, FuriString* path, StorageData* storage) { diff --git a/applications/services/storage/storage_glue.h b/applications/services/storage/storage_glue.h index bf0a1c69..f1064034 100644 --- a/applications/services/storage/storage_glue.h +++ b/applications/services/storage/storage_glue.h @@ -60,7 +60,7 @@ struct StorageData { }; bool storage_has_file(const File* file, StorageData* storage_data); -bool storage_path_already_open(FuriString* path, StorageFileList_t files); +bool storage_path_already_open(FuriString* path, StorageData* storage_data); void storage_set_storage_file_data(const File* file, void* file_data, StorageData* storage); void* storage_get_storage_file_data(const File* file, StorageData* storage); diff --git a/applications/services/storage/storage_processing.c b/applications/services/storage/storage_processing.c index a3076f27..e6b42696 100644 --- a/applications/services/storage/storage_processing.c +++ b/applications/services/storage/storage_processing.c @@ -77,7 +77,7 @@ static void storage_path_change_to_real_storage(FuriString* path, StorageType re } } -FS_Error storage_get_data(Storage* app, FuriString* path, StorageData** storage) { +static FS_Error storage_get_data(Storage* app, FuriString* path, StorageData** storage) { StorageType type = storage_get_type_by_path(path); if(storage_type_is_valid(type)) { @@ -111,7 +111,7 @@ bool storage_process_file_open( file->error_id = storage_get_data(app, path, &storage); if(file->error_id == FSE_OK) { - if(storage_path_already_open(path, storage->files)) { + if(storage_path_already_open(path, storage)) { file->error_id = FSE_ALREADY_OPEN; } else { if(access_mode & FSAM_WRITE) { @@ -268,7 +268,7 @@ bool storage_process_dir_open(Storage* app, File* file, FuriString* path) { file->error_id = storage_get_data(app, path, &storage); if(file->error_id == FSE_OK) { - if(storage_path_already_open(path, storage->files)) { + if(storage_path_already_open(path, storage)) { file->error_id = FSE_ALREADY_OPEN; } else { storage_push_storage_file(file, path, storage); @@ -357,7 +357,7 @@ static FS_Error storage_process_common_remove(Storage* app, FuriString* path) { FS_Error ret = storage_get_data(app, path, &storage); do { - if(storage_path_already_open(path, storage->files)) { + if(storage_path_already_open(path, storage)) { ret = FSE_ALREADY_OPEN; break; } diff --git a/applications/services/storage/storages/storage_ext.c b/applications/services/storage/storages/storage_ext.c index 530c88f8..d802d6e9 100644 --- a/applications/services/storage/storages/storage_ext.c +++ b/applications/services/storage/storages/storage_ext.c @@ -618,8 +618,10 @@ static const FS_Api fs_api = { }; void storage_ext_init(StorageData* storage) { + fatfs_init(); + SDData* sd_data = malloc(sizeof(SDData)); - sd_data->fs = &USERFatFS; + sd_data->fs = &fatfs_object; sd_data->path = "0:/"; sd_data->sd_was_present = true; diff --git a/firmware/targets/f18/furi_hal/furi_hal.c b/firmware/targets/f18/furi_hal/furi_hal.c index 0a68fdb6..2c255fa0 100644 --- a/firmware/targets/f18/furi_hal/furi_hal.c +++ b/firmware/targets/f18/furi_hal/furi_hal.c @@ -3,8 +3,6 @@ #include -#include - #define TAG "FuriHal" void furi_hal_init_early() { @@ -74,10 +72,6 @@ void furi_hal_init() { #endif furi_hal_bt_init(); furi_hal_compress_icon_init(); - - // FatFS driver initialization - MX_FATFS_Init(); - FURI_LOG_I(TAG, "FATFS OK"); } void furi_hal_switch(void* address) { diff --git a/firmware/targets/f7/fatfs/fatfs.c b/firmware/targets/f7/fatfs/fatfs.c index 1aa5fe44..2c0e77fe 100644 --- a/firmware/targets/f7/fatfs/fatfs.c +++ b/firmware/targets/f7/fatfs/fatfs.c @@ -1,39 +1,12 @@ -/** - ****************************************************************************** - * @file fatfs.c - * @brief Code for fatfs applications - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - #include "fatfs.h" -uint8_t retUSER; /* Return value for USER */ -char USERPath[4]; /* USER logical drive path */ -FATFS USERFatFS; /* File system object for USER logical drive */ -FIL USERFile; /* File object for USER */ +/** logical drive path */ +char fatfs_path[4]; +/** File system object */ +FATFS fatfs_object; -/* USER CODE BEGIN Variables */ - -/* USER CODE END Variables */ - -void MX_FATFS_Init(void) { - /*## FatFS: Link the USER driver ###########################*/ - retUSER = FATFS_LinkDriver(&USER_Driver, USERPath); - - /* USER CODE BEGIN Init */ - /* additional user code for init */ - /* USER CODE END Init */ +void fatfs_init(void) { + FATFS_LinkDriver(&sd_fatfs_driver, fatfs_path); } /** @@ -42,13 +15,5 @@ void MX_FATFS_Init(void) { * @retval Time in DWORD */ DWORD get_fattime(void) { - /* USER CODE BEGIN get_fattime */ return 0; - /* USER CODE END get_fattime */ } - -/* USER CODE BEGIN Application */ - -/* USER CODE END Application */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/fatfs/fatfs.h b/firmware/targets/f7/fatfs/fatfs.h index a0775d88..8376bf6c 100644 --- a/firmware/targets/f7/fatfs/fatfs.h +++ b/firmware/targets/f7/fatfs/fatfs.h @@ -1,49 +1,19 @@ -/** - ****************************************************************************** - * @file fatfs.h - * @brief Header for fatfs applications - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ +#pragma once + +#include "fatfs/ff.h" +#include "fatfs/ff_gen_drv.h" +#include "user_diskio.h" -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __fatfs_H -#define __fatfs_H #ifdef __cplusplus extern "C" { #endif -#include "fatfs/ff.h" -#include "fatfs/ff_gen_drv.h" -#include "user_diskio.h" /* defines USER_Driver as external */ +/** File system object */ +extern FATFS fatfs_object; -/* USER CODE BEGIN Includes */ +/** Init file system driver */ +void fatfs_init(void); -/* USER CODE END Includes */ - -extern uint8_t retUSER; /* Return value for USER */ -extern char USERPath[4]; /* USER logical drive path */ -extern FATFS USERFatFS; /* File system object for USER logical drive */ -extern FIL USERFile; /* File object for USER */ - -void MX_FATFS_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ #ifdef __cplusplus } -#endif -#endif /*__fatfs_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +#endif \ No newline at end of file diff --git a/firmware/targets/f7/fatfs/ffconf.h b/firmware/targets/f7/fatfs/ffconf.h index 9410cedc..a4452155 100644 --- a/firmware/targets/f7/fatfs/ffconf.h +++ b/firmware/targets/f7/fatfs/ffconf.h @@ -164,7 +164,7 @@ /* USER CODE BEGIN Volumes */ #define _STR_VOLUME_ID 0 /* 0:Use only 0-9 for drive ID, 1:Use strings for drive ID */ -#define _VOLUME_STRS "RAM", "NAND", "CF", "SD1", "SD2", "USB1", "USB2", "USB3" +#define _VOLUME_STRS "SD" /* _STR_VOLUME_ID switches string support of volume ID. / When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive / number in the path name. _VOLUME_STRS defines the drive ID strings for each diff --git a/firmware/targets/f7/fatfs/syscall.c b/firmware/targets/f7/fatfs/syscall.c deleted file mode 100644 index 00eb8aed..00000000 --- a/firmware/targets/f7/fatfs/syscall.c +++ /dev/null @@ -1,116 +0,0 @@ -/*------------------------------------------------------------------------*/ -/* Sample code of OS dependent controls for FatFs */ -/* (C)ChaN, 2014 */ -/* Portions COPYRIGHT 2017 STMicroelectronics */ -/* Portions Copyright (C) 2014, ChaN, all right reserved */ -/*------------------------------------------------------------------------*/ - -/** - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. All rights reserved. - * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** -**/ - -#include "fatfs/ff.h" - -#if _FS_REENTRANT -/*------------------------------------------------------------------------*/ -/* Create a Synchronization Object */ -/*------------------------------------------------------------------------*/ -/* This function is called in f_mount() function to create a new -/ synchronization object, such as semaphore and mutex. When a 0 is returned, -/ the f_mount() function fails with FR_INT_ERR. -*/ - -int ff_cre_syncobj(/* 1:Function succeeded, 0:Could not create the sync object */ - BYTE vol, /* Corresponding volume (logical drive number) */ - _SYNC_t* sobj /* Pointer to return the created sync object */ -) { - int ret; - - //osSemaphoreDef(SEM); - //*sobj = osSemaphoreCreate(osSemaphore(SEM), 1); - *sobj = furi_mutex_alloc(FuriMutexTypeNormal); - ret = (*sobj != NULL); - - return ret; -} - -/*------------------------------------------------------------------------*/ -/* Delete a Synchronization Object */ -/*------------------------------------------------------------------------*/ -/* This function is called in f_mount() function to delete a synchronization -/ object that created with ff_cre_syncobj() function. When a 0 is returned, -/ the f_mount() function fails with FR_INT_ERR. -*/ - -int ff_del_syncobj(/* 1:Function succeeded, 0:Could not delete due to any error */ - _SYNC_t sobj /* Sync object tied to the logical drive to be deleted */ -) { - furi_mutex_free(sobj); - return 1; -} - -/*------------------------------------------------------------------------*/ -/* Request Grant to Access the Volume */ -/*------------------------------------------------------------------------*/ -/* This function is called on entering file functions to lock the volume. -/ When a 0 is returned, the file function fails with FR_TIMEOUT. -*/ - -int ff_req_grant(/* 1:Got a grant to access the volume, 0:Could not get a grant */ - _SYNC_t sobj /* Sync object to wait */ -) { - int ret = 0; - - if(furi_mutex_acquire(sobj, _FS_TIMEOUT) == FuriStatusOk) { - ret = 1; - } - - return ret; -} - -/*------------------------------------------------------------------------*/ -/* Release Grant to Access the Volume */ -/*------------------------------------------------------------------------*/ -/* This function is called on leaving file functions to unlock the volume. -*/ - -void ff_rel_grant(_SYNC_t sobj /* Sync object to be signaled */ -) { - furi_mutex_release(sobj); -} - -#endif - -#if _USE_LFN == 3 /* LFN with a working buffer on the heap */ -/*------------------------------------------------------------------------*/ -/* Allocate a memory block */ -/*------------------------------------------------------------------------*/ -/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE. -*/ - -void* ff_memalloc(/* Returns pointer to the allocated memory block */ - UINT msize /* Number of bytes to allocate */ -) { - return ff_malloc(msize); /* Allocate a new memory block with POSIX API */ -} - -/*------------------------------------------------------------------------*/ -/* Free a memory block */ -/*------------------------------------------------------------------------*/ - -void ff_memfree(void* mblock /* Pointer to the memory block to free */ -) { - ff_free(mblock); /* Discard the memory block with POSIX API */ -} - -#endif diff --git a/firmware/targets/f7/fatfs/user_diskio.c b/firmware/targets/f7/fatfs/user_diskio.c index d7be09c5..74bf26f6 100644 --- a/firmware/targets/f7/fatfs/user_diskio.c +++ b/firmware/targets/f7/fatfs/user_diskio.c @@ -1,50 +1,10 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file user_diskio.c - * @brief This file includes a diskio driver skeleton to be completed by the user. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -#ifdef USE_OBSOLETE_USER_CODE_SECTION_0 -/* - * Warning: the user section 0 is no more in use (starting from CubeMx version 4.16.0) - * To be suppressed in the future. - * Kept to ensure backward compatibility with previous CubeMx versions when - * migrating projects. - * User code previously added there should be copied in the new user sections before - * the section contents can be deleted. - */ -/* USER CODE BEGIN 0 */ -/* USER CODE END 0 */ -#endif - -/* USER CODE BEGIN DECL */ - -/* Includes ------------------------------------------------------------------*/ #include "user_diskio.h" #include #include "sector_cache.h" -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Disk status */ static volatile DSTATUS Stat = STA_NOINIT; -static DSTATUS User_CheckStatus(BYTE lun) { +static DSTATUS driver_check_status(BYTE lun) { UNUSED(lun); Stat = STA_NOINIT; if(sd_get_card_state() == SdSpiStatusOK) { @@ -54,32 +14,20 @@ static DSTATUS User_CheckStatus(BYTE lun) { return Stat; } -/* USER CODE END DECL */ +static DSTATUS driver_initialize(BYTE pdrv); +static DSTATUS driver_status(BYTE pdrv); +static DRESULT driver_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count); +static DRESULT driver_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); +static DRESULT driver_ioctl(BYTE pdrv, BYTE cmd, void* buff); -/* Private function prototypes -----------------------------------------------*/ -DSTATUS USER_initialize(BYTE pdrv); -DSTATUS USER_status(BYTE pdrv); -DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count); -#if _USE_WRITE == 1 -DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); -#endif /* _USE_WRITE == 1 */ -#if _USE_IOCTL == 1 -DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff); -#endif /* _USE_IOCTL == 1 */ - -Diskio_drvTypeDef USER_Driver = { - USER_initialize, - USER_status, - USER_read, -#if _USE_WRITE - USER_write, -#endif /* _USE_WRITE == 1 */ -#if _USE_IOCTL == 1 - USER_ioctl, -#endif /* _USE_IOCTL == 1 */ +Diskio_drvTypeDef sd_fatfs_driver = { + driver_initialize, + driver_status, + driver_read, + driver_write, + driver_ioctl, }; -/* 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) { @@ -101,24 +49,73 @@ static inline void sd_cache_invalidate_all() { sector_cache_init(); } +static bool sd_device_read(uint32_t* buff, uint32_t sector, uint32_t count) { + bool result = false; + + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; + + if(sd_read_blocks(buff, sector, count, SD_TIMEOUT_MS) == SdSpiStatusOK) { + FuriHalCortexTimer timer = furi_hal_cortex_timer_get(SD_TIMEOUT_MS * 1000); + + /* wait until the read operation is finished */ + result = true; + while(sd_get_card_state() != SdSpiStatusOK) { + if(furi_hal_cortex_timer_is_expired(timer)) { + result = false; + break; + } + } + } + + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); + + return result; +} + +static bool sd_device_write(uint32_t* buff, uint32_t sector, uint32_t count) { + bool result = false; + + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; + + if(sd_write_blocks(buff, sector, count, SD_TIMEOUT_MS) == SdSpiStatusOK) { + FuriHalCortexTimer timer = furi_hal_cortex_timer_get(SD_TIMEOUT_MS * 1000); + + /* wait until the Write operation is finished */ + result = true; + while(sd_get_card_state() != SdSpiStatusOK) { + if(furi_hal_cortex_timer_is_expired(timer)) { + sd_cache_invalidate_all(); + + result = false; + break; + } + } + } + + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); + + return result; +} + /** * @brief Initializes a Drive * @param pdrv: Physical drive number (0..) * @retval DSTATUS: Operation status */ -DSTATUS USER_initialize(BYTE pdrv) { - /* USER CODE BEGIN INIT */ - +static DSTATUS driver_initialize(BYTE pdrv) { furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; - DSTATUS status = User_CheckStatus(pdrv); + DSTATUS status = driver_check_status(pdrv); furi_hal_sd_spi_handle = NULL; furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return status; - /* USER CODE END INIT */ } /** @@ -126,11 +123,9 @@ DSTATUS USER_initialize(BYTE pdrv) { * @param pdrv: Physical drive number (0..) * @retval DSTATUS: Operation status */ -DSTATUS USER_status(BYTE pdrv) { - /* USER CODE BEGIN STATUS */ +static DSTATUS driver_status(BYTE pdrv) { UNUSED(pdrv); return Stat; - /* USER CODE END STATUS */ } /** @@ -141,11 +136,10 @@ DSTATUS USER_status(BYTE pdrv) { * @param count: Number of sectors to read (1..128) * @retval DRESULT: Operation result */ -DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { - /* USER CODE BEGIN READ */ +static DRESULT driver_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { UNUSED(pdrv); - DRESULT res = RES_ERROR; + bool result; bool single_sector = count == 1; if(single_sector) { @@ -154,32 +148,33 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { } } - furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); - furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; + result = sd_device_read((uint32_t*)buff, (uint32_t)(sector), count); - if(sd_read_blocks((uint32_t*)buff, (uint32_t)(sector), count, SD_TIMEOUT_MS) == - SdSpiStatusOK) { - FuriHalCortexTimer timer = furi_hal_cortex_timer_get(SD_TIMEOUT_MS * 1000); + if(!result) { + uint8_t counter = sd_max_mount_retry_count(); - /* wait until the read operation is finished */ - res = RES_OK; - while(sd_get_card_state() != SdSpiStatusOK) { - if(furi_hal_cortex_timer_is_expired(timer)) { - res = RES_ERROR; - break; + while(result == false && counter > 0 && hal_sd_detect()) { + SdSpiStatus status; + + if((counter % 2) == 0) { + // power reset sd card + status = sd_init(true); + } else { + status = sd_init(false); } + + if(status == SdSpiStatusOK) { + result = sd_device_read((uint32_t*)buff, (uint32_t)(sector), count); + } + counter--; } } - furi_hal_sd_spi_handle = NULL; - furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); - - if(single_sector && res == RES_OK) { + if(single_sector && result == true) { sd_cache_put(sector, (uint32_t*)buff); } - return res; - /* USER CODE END READ */ + return result ? RES_OK : RES_ERROR; } /** @@ -190,41 +185,36 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { * @param count: Number of sectors to write (1..128) * @retval DRESULT: Operation result */ -#if _USE_WRITE == 1 -DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { - /* USER CODE BEGIN WRITE */ - /* USER CODE HERE */ +static DRESULT driver_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { UNUSED(pdrv); - DRESULT res = RES_ERROR; + bool result; 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; + result = sd_device_write((uint32_t*)buff, (uint32_t)(sector), count); - if(sd_write_blocks((uint32_t*)buff, (uint32_t)(sector), count, SD_TIMEOUT_MS) == - SdSpiStatusOK) { - FuriHalCortexTimer timer = furi_hal_cortex_timer_get(SD_TIMEOUT_MS * 1000); + if(!result) { + uint8_t counter = sd_max_mount_retry_count(); - /* wait until the Write operation is finished */ - res = RES_OK; - while(sd_get_card_state() != SdSpiStatusOK) { - if(furi_hal_cortex_timer_is_expired(timer)) { - sd_cache_invalidate_all(); + while(result == false && counter > 0 && hal_sd_detect()) { + SdSpiStatus status; - res = RES_ERROR; - break; + if((counter % 2) == 0) { + // power reset sd card + status = sd_init(true); + } else { + status = sd_init(false); } + + if(status == SdSpiStatusOK) { + result = sd_device_write((uint32_t*)buff, (uint32_t)(sector), count); + } + counter--; } } - furi_hal_sd_spi_handle = NULL; - furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); - - return res; - /* USER CODE END WRITE */ + return result ? RES_OK : RES_ERROR; } -#endif /* _USE_WRITE == 1 */ /** * @brief I/O control operation @@ -233,9 +223,7 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { * @param *buff: Buffer to send/receive control data * @retval DRESULT: Operation result */ -#if _USE_IOCTL == 1 -DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { - /* USER CODE BEGIN IOCTL */ +static DRESULT driver_ioctl(BYTE pdrv, BYTE cmd, void* buff) { UNUSED(pdrv); DRESULT res = RES_ERROR; SD_CardInfo CardInfo; @@ -280,8 +268,4 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return res; - /* USER CODE END IOCTL */ } -#endif /* _USE_IOCTL == 1 */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/fatfs/user_diskio.h b/firmware/targets/f7/fatfs/user_diskio.h index 12e0f27d..7b3f2bb9 100644 --- a/firmware/targets/f7/fatfs/user_diskio.h +++ b/firmware/targets/f7/fatfs/user_diskio.h @@ -1,48 +1,14 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file user_diskio.h - * @brief This file contains the common defines and functions prototypes for - * the user_diskio driver. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USER_DISKIO_H -#define __USER_DISKIO_H +#pragma once #ifdef __cplusplus extern "C" { #endif -/* USER CODE BEGIN 0 */ - -/* Includes ------------------------------------------------------------------*/ #include "sd_spi_io.h" #include "fatfs/ff_gen_drv.h" -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -extern Diskio_drvTypeDef USER_Driver; -/* USER CODE END 0 */ +extern Diskio_drvTypeDef sd_fatfs_driver; #ifdef __cplusplus } -#endif - -#endif /* __USER_DISKIO_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +#endif \ No newline at end of file diff --git a/firmware/targets/f7/furi_hal/furi_hal.c b/firmware/targets/f7/furi_hal/furi_hal.c index afe46c4e..5840a697 100644 --- a/firmware/targets/f7/furi_hal/furi_hal.c +++ b/firmware/targets/f7/furi_hal/furi_hal.c @@ -4,8 +4,6 @@ #include -#include - #define TAG "FuriHal" void furi_hal_init_early() { @@ -81,10 +79,6 @@ void furi_hal_init() { furi_hal_nfc_init(); furi_hal_rfid_init(); #endif - - // FatFS driver initialization - MX_FATFS_Init(); - FURI_LOG_I(TAG, "FATFS OK"); } void furi_hal_switch(void* address) { diff --git a/firmware/targets/f7/src/update.c b/firmware/targets/f7/src/update.c index d8d26eb7..c1e1084c 100644 --- a/firmware/targets/f7/src/update.c +++ b/firmware/targets/f7/src/update.c @@ -44,7 +44,7 @@ static bool flipper_update_init() { furi_hal_spi_config_init(); - MX_FATFS_Init(); + fatfs_init(); if(!hal_sd_detect()) { return false; }