2019-02-20 14:31:46 +00:00
|
|
|
/*
|
2019-04-08 03:00:49 +01:00
|
|
|
* Copyright (c) 2018-2019 Atmosphère-NX
|
2019-02-20 14:31:46 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms and conditions of the GNU General Public License,
|
|
|
|
* version 2, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
|
|
* more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "fs_utils.h"
|
|
|
|
#include "mc.h"
|
|
|
|
#include "lib/fatfs/ff.h"
|
|
|
|
#include "lib/log.h"
|
|
|
|
|
|
|
|
FATFS sd_fs;
|
|
|
|
static bool g_sd_mounted = false;
|
|
|
|
static bool g_sd_initialized = false;
|
|
|
|
static bool g_ahb_redirect_enabled = false;
|
|
|
|
|
|
|
|
bool mount_sd(void)
|
|
|
|
{
|
|
|
|
/* Already mounted. */
|
|
|
|
if (g_sd_mounted)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
/* Enable AHB redirection if necessary. */
|
|
|
|
if (!g_ahb_redirect_enabled) {
|
|
|
|
mc_enable_ahb_redirect();
|
|
|
|
g_ahb_redirect_enabled = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!g_sd_initialized) {
|
|
|
|
/* Initialize SD. */
|
|
|
|
if (sdmmc_device_sd_init(&g_sd_device, &g_sd_sdmmc, SDMMC_BUS_WIDTH_4BIT, SDMMC_SPEED_SDR104))
|
|
|
|
{
|
|
|
|
g_sd_initialized = true;
|
|
|
|
|
|
|
|
/* Mount SD. */
|
|
|
|
if (f_mount(&sd_fs, "", 1) == FR_OK) {
|
|
|
|
print(SCREEN_LOG_LEVEL_INFO, "Mounted SD card!\n");
|
|
|
|
g_sd_mounted = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fatal_error("Failed to initialize the SD card!.\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
return g_sd_mounted;
|
|
|
|
}
|
|
|
|
|
|
|
|
void unmount_sd(void)
|
|
|
|
{
|
|
|
|
if (g_sd_mounted)
|
|
|
|
{
|
|
|
|
f_mount(NULL, "", 1);
|
|
|
|
sdmmc_device_finish(&g_sd_device);
|
|
|
|
g_sd_mounted = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Disable AHB redirection if necessary. */
|
|
|
|
if (g_ahb_redirect_enabled) {
|
|
|
|
mc_disable_ahb_redirect();
|
|
|
|
g_ahb_redirect_enabled = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t get_file_size(const char *filename)
|
|
|
|
{
|
|
|
|
/* SD card hasn't been mounted yet. */
|
|
|
|
if (!g_sd_mounted)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Open the file for reading. */
|
|
|
|
FIL f;
|
|
|
|
if (f_open(&f, filename, FA_READ) != FR_OK)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Get the file size. */
|
|
|
|
uint32_t file_size = f_size(&f);
|
|
|
|
|
|
|
|
/* Close the file. */
|
|
|
|
f_close(&f);
|
|
|
|
|
|
|
|
return file_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
int read_from_file(void *dst, uint32_t dst_size, const char *filename)
|
|
|
|
{
|
|
|
|
/* SD card hasn't been mounted yet. */
|
|
|
|
if (!g_sd_mounted)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Open the file for reading. */
|
|
|
|
FIL f;
|
|
|
|
if (f_open(&f, filename, FA_READ) != FR_OK)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Sync. */
|
|
|
|
f_sync(&f);
|
|
|
|
|
|
|
|
/* Read from file. */
|
|
|
|
UINT br = 0;
|
|
|
|
int res = f_read(&f, dst, dst_size, &br);
|
|
|
|
f_close(&f);
|
|
|
|
|
|
|
|
return (res == FR_OK) ? (int)br : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int write_to_file(void *src, uint32_t src_size, const char *filename)
|
|
|
|
{
|
|
|
|
/* SD card hasn't been mounted yet. */
|
|
|
|
if (!g_sd_mounted)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Open the file for writing. */
|
|
|
|
FIL f;
|
|
|
|
if (f_open(&f, filename, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Sync. */
|
|
|
|
f_sync(&f);
|
|
|
|
|
|
|
|
/* Write to file. */
|
|
|
|
UINT bw = 0;
|
|
|
|
int res = f_write(&f, src, src_size, &bw);
|
|
|
|
f_close(&f);
|
|
|
|
|
|
|
|
return (res == FR_OK) ? (int)bw : 0;
|
|
|
|
}
|