Files
RadioPhotonic_PCB_software/App/Services/storage_sd.c
2026-04-24 16:51:15 +03:00

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;
}