215 lines
3.6 KiB
C
215 lines
3.6 KiB
C
/**
|
|
* @file storage_sd.c
|
|
* @brief Narrow SD-card storage wrapper built directly on FatFs.
|
|
*/
|
|
|
|
#include "storage_sd.h"
|
|
|
|
#include "fatfs.h"
|
|
|
|
#include "board_io.h"
|
|
|
|
static uint8_t g_storage_mounted = 0u;
|
|
static uint16_t g_storage_mount_depth = 0u;
|
|
|
|
bool storage_sd_is_available(void)
|
|
{
|
|
return board_io_is_sd_card_present();
|
|
}
|
|
|
|
FRESULT storage_sd_begin(void)
|
|
{
|
|
FRESULT result;
|
|
|
|
if (!storage_sd_is_available())
|
|
{
|
|
return FR_NOT_READY;
|
|
}
|
|
|
|
if (g_storage_mount_depth > 0u)
|
|
{
|
|
++g_storage_mount_depth;
|
|
return FR_OK;
|
|
}
|
|
|
|
result = f_mount(&SDFatFS, SDPath, 1u);
|
|
if (result == FR_OK)
|
|
{
|
|
g_storage_mounted = 1u;
|
|
g_storage_mount_depth = 1u;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
FRESULT storage_sd_end(void)
|
|
{
|
|
FRESULT result;
|
|
|
|
if (g_storage_mount_depth == 0u)
|
|
{
|
|
return FR_OK;
|
|
}
|
|
|
|
--g_storage_mount_depth;
|
|
if (g_storage_mount_depth > 0u)
|
|
{
|
|
return FR_OK;
|
|
}
|
|
|
|
result = f_mount(NULL, SDPath, 1u);
|
|
if (result == FR_OK)
|
|
{
|
|
g_storage_mounted = 0u;
|
|
}
|
|
else
|
|
{
|
|
g_storage_mount_depth = 1u;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
FRESULT storage_sd_open_file(FIL *file, const char *path, BYTE mode)
|
|
{
|
|
FRESULT result;
|
|
|
|
if ((file == NULL) || (path == NULL))
|
|
{
|
|
return FR_INVALID_PARAMETER;
|
|
}
|
|
|
|
result = storage_sd_begin();
|
|
if (result != FR_OK)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
result = f_open(file, path, mode);
|
|
if (result != FR_OK)
|
|
{
|
|
(void)storage_sd_end();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
FRESULT storage_sd_close_file(FIL *file)
|
|
{
|
|
FRESULT close_result = FR_OK;
|
|
FRESULT end_result;
|
|
|
|
if (file != NULL)
|
|
{
|
|
close_result = f_close(file);
|
|
}
|
|
|
|
end_result = storage_sd_end();
|
|
if (close_result != FR_OK)
|
|
{
|
|
return close_result;
|
|
}
|
|
|
|
return end_result;
|
|
}
|
|
|
|
FRESULT storage_sd_read_bytes(const char *path, FSIZE_t offset, void *data, UINT size, UINT *bytes_read)
|
|
{
|
|
FIL file;
|
|
UINT local_bytes_read = 0u;
|
|
FRESULT result = storage_sd_open_file(&file, path, FA_READ);
|
|
|
|
if (result != FR_OK)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
result = f_lseek(&file, offset);
|
|
if (result == FR_OK)
|
|
{
|
|
result = f_read(&file, data, size, &local_bytes_read);
|
|
}
|
|
(void)storage_sd_close_file(&file);
|
|
|
|
if (bytes_read != NULL)
|
|
{
|
|
*bytes_read = local_bytes_read;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
FRESULT storage_sd_stat(const char *path, FILINFO *out_info)
|
|
{
|
|
FRESULT result;
|
|
|
|
if (path == NULL)
|
|
{
|
|
return FR_INVALID_PARAMETER;
|
|
}
|
|
|
|
result = storage_sd_begin();
|
|
if (result != FR_OK)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
result = f_stat(path, out_info);
|
|
(void)storage_sd_end();
|
|
return result;
|
|
}
|
|
|
|
bool storage_sd_file_exists(const char *path)
|
|
{
|
|
FILINFO info;
|
|
return storage_sd_stat(path, &info) == FR_OK;
|
|
}
|
|
|
|
FRESULT storage_sd_make_directory(const char *path)
|
|
{
|
|
FRESULT result;
|
|
|
|
if (path == NULL)
|
|
{
|
|
return FR_INVALID_PARAMETER;
|
|
}
|
|
|
|
result = storage_sd_begin();
|
|
if (result != FR_OK)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
result = f_mkdir(path);
|
|
if (result == FR_EXIST)
|
|
{
|
|
result = FR_OK;
|
|
}
|
|
(void)storage_sd_end();
|
|
return result;
|
|
}
|
|
|
|
FRESULT storage_sd_remove_file(const char *path)
|
|
{
|
|
FRESULT result;
|
|
|
|
if (path == NULL)
|
|
{
|
|
return FR_INVALID_PARAMETER;
|
|
}
|
|
|
|
result = storage_sd_begin();
|
|
if (result != FR_OK)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
result = f_unlink(path);
|
|
if ((result == FR_NO_FILE) || (result == FR_NO_PATH))
|
|
{
|
|
result = FR_OK;
|
|
}
|
|
(void)storage_sd_end();
|
|
return result;
|
|
}
|