Skip to content
Snippets Groups Projects
fatfs.c 3.64 KiB
/*
 * support routines for FatFs
 */

#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

#include <ff.h>

#include <FreeRTOS.h>
#include <semphr.h>

#include "modules.h"
#include "epicardium.h"

#ifndef EPIC_FAT_STATIC_SEMAPHORE
#define EPIC_FAT_STATIC_SEMAPHORE 0
#endif

static const TCHAR *rcstrings =
	_T("OK\0DISK_ERR\0INT_ERR\0NOT_READY\0NO_FILE\0NO_PATH\0INVALID_NAME\0")
	_T("DENIED\0EXIST\0INVALID_OBJECT\0WRITE_PROTECTED\0INVALID_DRIVE\0")
	_T("NOT_ENABLED\0NO_FILESYSTEM\0MKFS_ABORTED\0TIMEOUT\0LOCKED\0")
	_T("NOT_ENOUGH_CORE\0TOO_MANY_OPEN_FILES\0INVALID_PARAMETER\0");

static bool mount(void);

DIR dir;
FATFS FatFs;

#if (EPIC_FAT_STATIC_SEMAPHORE == 1)
StaticSemaphore_t xSemaphoreBuffer;
#endif

static volatile bool s_fatfs_initiaized = false;

void fatfs_init()
{
	if (mount()) {
		s_fatfs_initiaized = true;
		printf("FatFs mounted\n");
	}
}

const char *f_get_rc_string(FRESULT rc)
{
	FRESULT i;
	const char *p = rcstrings;

	for (i = 0; i != rc && *p; i++) {
		while (*p++)
			;
	}
	return p;
}

static bool mount()
{
	FRESULT res;
	res = f_mount(&FatFs, "/", 0);
	if (res != FR_OK) {
		printf("f_mount error %s\n", f_get_rc_string(res));
		return false;
	}

	res = f_opendir(&dir, "0:");
	if (res != FR_OK) {
		printf("f_opendir error %s\n", f_get_rc_string(res));
		return false;
	}

	return true;
}

/*------------------------------------------------------------------------*/
/* Create a Synchronization Object */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to create a new
/  synchronization object for the volume, such as semaphore and mutex.
/  When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
*/

/*
 * Return value:
 *   - 1: Function succeeded
 *   - 0: Could not create the sync object
 */
int ff_cre_syncobj(BYTE vol, FF_SYNC_t *sobj)
{
#if (EPIC_FAT_STATIC_SEMAPHORE == 1)
	*sobj = xSemaphoreCreateMutexStatic(&xSemaphoreBuffer);
#else
	*sobj = xSemaphoreCreateMutex();
#endif //EPIC_FAT_STATIC_SEMAPHORE

	return (int)(*sobj != NULL);
}

/*------------------------------------------------------------------------*/
/* 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.
*/

/*
 * Return value:
 *   - 1: Function succeeded
 *   - 0: Could not delete due to an error
 */
int ff_del_syncobj(FF_SYNC_t sobj)
{
	/* FreeRTOS */
	vSemaphoreDelete(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.
*/

/*
 * Return value:
 *   - 1: Got a grant to access the volume
 *   - 0: Could not get a grant
 */
int ff_req_grant(FF_SYNC_t sobj)
{
	/* FreeRTOS */
	return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
}

/*------------------------------------------------------------------------*/
/* Release Grant to Access the Volume                                     */
/*------------------------------------------------------------------------*/
/* This function is called on leaving file functions to unlock the volume.
*/

void ff_rel_grant(FF_SYNC_t sobj)
{
	/* FreeRTOS */
	xSemaphoreGive(sobj);
}