/*
    FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
    All rights reserved

    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

    This file is part of the FreeRTOS distribution.

    FreeRTOS is free software; you can redistribute it and/or modify it under
    the terms of the GNU General Public License (version 2) as published by the
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.

    ***************************************************************************
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
    >>!   obliged to provide the source code for proprietary components     !<<
    >>!   outside of the FreeRTOS kernel.                                   !<<
    ***************************************************************************

    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
    link: http://www.freertos.org/a00114.html

    ***************************************************************************
     *                                                                       *
     *    FreeRTOS provides completely free yet professionally developed,    *
     *    robust, strictly quality controlled, supported, and cross          *
     *    platform software that is more than just the market leader, it     *
     *    is the industry's de facto standard.                               *
     *                                                                       *
     *    Help yourself get started quickly while simultaneously helping     *
     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
     *    tutorial book, reference manual, or both:                          *
     *    http://www.FreeRTOS.org/Documentation                              *
     *                                                                       *
    ***************************************************************************

    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
    the FAQ page "My application does not run, what could be wrong?".  Have you
    defined configASSERT()?

    http://www.FreeRTOS.org/support - In return for receiving this top quality
    embedded software for free we request you assist our global community by
    participating in the support forum.

    http://www.FreeRTOS.org/training - Investing in training allows your team to
    be as productive as possible as early as possible.  Now you can receive
    FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
    Ltd, and the world's leading authority on the world's leading RTOS.

    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
    compatible FAT file system, and our tiny thread aware UDP/IP stack.

    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.

    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
    licenses offer ticketed support, indemnification and commercial middleware.

    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
    engineered and independently SIL3 certified version for use in safety and
    mission critical applications that require provable dependability.

    1 tab == 4 spaces!
*/

/*******************************************************************************
 * See the URL in the comments within main.c for the location of the online
 * documentation.
 ******************************************************************************/

/* Standard includes. */
#include <stdio.h>
#include <string.h>

/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"

/* File system includes. */
#include "fat_sl.h"
#include "api_mdriver_ram.h"

/* 8.3 format, plus null terminator. */
#define fsMAX_FILE_NAME_LEN				13

/* The number of bytes read/written to the example files at a time. */
#define fsRAM_BUFFER_SIZE 				200

/* The number of bytes written to the file that uses f_putc() and f_getc(). */
#define fsPUTC_FILE_SIZE				100

/* The number of files created in root. */
#define fsROOT_FILES					3

/*-----------------------------------------------------------*/

/*
 * Creates and verifies different files on the volume, demonstrating the use of
 * various different API functions.
 */
void vCreateAndVerifySampleFiles( void );

/*
 * Create a set of example files in the root directory of the volume using
 * f_write().
 */
static void prvCreateDemoFilesUsing_f_write( void );

/*
 * Use f_read() to read back and verify the files that were created by
 * prvCreateDemoFilesUsing_f_write().
 */
static void prvVerifyDemoFileUsing_f_read( void );

/*
 * Create an example file in a sub-directory using f_putc().
 */
static void prvCreateDemoFileUsing_f_putc( void );

/*
 * Use f_getc() to read back and verify the file that was created by
 * prvCreateDemoFileUsing_f_putc().
 */
static void prvVerifyDemoFileUsing_f_getc( void );

/*-----------------------------------------------------------*/

/* A buffer used to both create content to write to disk, and read content back
from a disk.  Note there is no mutual exclusion on this buffer. */
static char cRAMBuffer[ fsRAM_BUFFER_SIZE ];

/* Names of directories that are created. */
static const char *pcRoot = "/", *pcDirectory1 = "SUB1", *pcDirectory2 = "SUB2", *pcFullPath = "/SUB1/SUB2";

/*-----------------------------------------------------------*/

void vCreateAndVerifySampleFiles( void )
{
unsigned char ucStatus;

	/* First create the volume. */
	ucStatus = f_initvolume( ram_initfunc );

	/* It is expected that the volume is not formatted. */
	if( ucStatus == F_ERR_NOTFORMATTED )
	{
		/* Format the created volume. */
		ucStatus = f_format( F_FAT12_MEDIA );
	}

	if( ucStatus == F_NO_ERROR )
	{
		/* Create a set of files using f_write(). */
		prvCreateDemoFilesUsing_f_write();

		/* Read back and verify the files that were created using f_write(). */
		prvVerifyDemoFileUsing_f_read();

		/* Create sub directories two deep then create a file using putc. */
		prvCreateDemoFileUsing_f_putc();

		/* Read back and verify the file created by
		prvCreateDemoFileUsing_f_putc(). */
		prvVerifyDemoFileUsing_f_getc();
	}
}
/*-----------------------------------------------------------*/

static void prvCreateDemoFilesUsing_f_write( void )
{
portBASE_TYPE xFileNumber, xWriteNumber;
char cFileName[ fsMAX_FILE_NAME_LEN ];
long lItemsWritten;
F_FILE *pxFile;

	/* Create fsROOT_FILES files.  Each created file will be
	( xFileNumber * fsRAM_BUFFER_SIZE ) bytes in length, and filled
	with a different repeating character. */
	for( xFileNumber = 1; xFileNumber <= fsROOT_FILES; xFileNumber++ )
	{
		/* Generate a file name. */
		sprintf( cFileName, "root%03d.txt", ( int ) xFileNumber );

		/* Obtain the current working directory and print out the file name and
		the	directory into which the file is being written. */
		f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
		printf( "Creating file %s in %s\r\n", cFileName, cRAMBuffer );

		/* Open the file, creating the file if it does not already exist. */
		pxFile = f_open( cFileName, "w" );
		configASSERT( pxFile );

		/* Fill the RAM buffer with data that will be written to the file.  This
		is just a repeating ascii character that indicates the file number. */
		memset( cRAMBuffer, ( int ) ( '0' + xFileNumber ), fsRAM_BUFFER_SIZE );

		/* Write the RAM buffer to the opened file a number of times.  The
		number of times the RAM buffer is written to the file depends on the
		file number, so the length of each created file will be different. */
		for( xWriteNumber = 0; xWriteNumber < xFileNumber; xWriteNumber++ )
		{
			lItemsWritten = f_write( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile );
			configASSERT( lItemsWritten == 1 );
		}

		/* Close the file so another file can be created. */
		f_close( pxFile );
	}
}
/*-----------------------------------------------------------*/

static void prvVerifyDemoFileUsing_f_read( void )
{
portBASE_TYPE xFileNumber, xReadNumber;
char cFileName[ fsMAX_FILE_NAME_LEN ];
long lItemsRead, lChar;
F_FILE *pxFile;

	/* Read back the files that were created by
	prvCreateDemoFilesUsing_f_write(). */
	for( xFileNumber = 1; xFileNumber <= fsROOT_FILES; xFileNumber++ )
	{
		/* Generate the file name. */
		sprintf( cFileName, "root%03d.txt", ( int ) xFileNumber );

		/* Obtain the current working directory and print out the file name and
		the	directory from which the file is being read. */
		f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
		printf( "Reading file %s from %s\r\n", cFileName, cRAMBuffer );

		/* Open the file for reading. */
		pxFile = f_open( cFileName, "r" );
		configASSERT( pxFile );

		/* Read the file into the RAM buffer, checking the file contents are as
		expected.  The size of the file depends on the file number. */
		for( xReadNumber = 0; xReadNumber < xFileNumber; xReadNumber++ )
		{
			/* Start with the RAM buffer clear. */
			memset( cRAMBuffer, 0x00, fsRAM_BUFFER_SIZE );

			lItemsRead = f_read( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile );
			configASSERT( lItemsRead == 1 );

			/* Check the RAM buffer is filled with the expected data.  Each
			file contains a different repeating ascii character that indicates
			the number of the file. */
			for( lChar = 0; lChar < fsRAM_BUFFER_SIZE; lChar++ )
			{
				configASSERT( cRAMBuffer[ lChar ] == ( '0' + ( char ) xFileNumber ) );
			}
		}

		/* Close the file. */
		f_close( pxFile );
	}
}
/*-----------------------------------------------------------*/

static void prvCreateDemoFileUsing_f_putc( void )
{
unsigned char ucReturn;
int iByte, iReturned;
F_FILE *pxFile;
char cFileName[ fsMAX_FILE_NAME_LEN ];

	/* Obtain and print out the working directory. */
	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
	printf( "In directory %s\r\n", cRAMBuffer );

	/* Create a sub directory. */
	ucReturn = f_mkdir( pcDirectory1 );
	configASSERT( ucReturn == F_NO_ERROR );

	/* Move into the created sub-directory. */
	ucReturn = f_chdir( pcDirectory1 );
	configASSERT( ucReturn == F_NO_ERROR );

	/* Obtain and print out the working directory. */
	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
	printf( "In directory %s\r\n", cRAMBuffer );

	/* Create a subdirectory in the new directory. */
	ucReturn = f_mkdir( pcDirectory2 );
	configASSERT( ucReturn == F_NO_ERROR );

	/* Move into the directory just created - now two directories down from
	the root. */
	ucReturn = f_chdir( pcDirectory2 );
	configASSERT( ucReturn == F_NO_ERROR );

	/* Obtain and print out the working directory. */
	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
	printf( "In directory %s\r\n", cRAMBuffer );
	configASSERT( strcmp( cRAMBuffer, pcFullPath ) == 0 );

	/* Generate the file name. */
	sprintf( cFileName, "%s.txt", pcDirectory2 );

	/* Print out the file name and the directory into which the file is being
	written. */
	printf( "Writing file %s in %s\r\n", cFileName, cRAMBuffer );

	pxFile = f_open( cFileName, "w" );

	/* Create a file 1 byte at a time.  The file is filled with incrementing
	ascii characters starting from '0'. */
	for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ )
	{
		iReturned = f_putc( ( ( int ) '0' + iByte ), pxFile );
		configASSERT( iReturned ==  ( ( int ) '0' + iByte ) );
	}

	/* Finished so close the file. */
	f_close( pxFile );

	/* Move back to the root directory. */
	ucReturn = f_chdir( "../.." );
	configASSERT( ucReturn == F_NO_ERROR );

	/* Obtain and print out the working directory. */
	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
	printf( "Back in root directory %s\r\n", cRAMBuffer );
	configASSERT( strcmp( cRAMBuffer, pcRoot ) == 0 );
}
/*-----------------------------------------------------------*/

static void prvVerifyDemoFileUsing_f_getc( void )
{
unsigned char ucReturn;
int iByte, iReturned;
F_FILE *pxFile;
char cFileName[ fsMAX_FILE_NAME_LEN ];

	/* Move into the directory in which the file was created. */
	ucReturn = f_chdir( pcFullPath );
	configASSERT( ucReturn == F_NO_ERROR );

	/* Obtain and print out the working directory. */
	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
	printf( "Back in directory %s\r\n", cRAMBuffer );
	configASSERT( strcmp( cRAMBuffer, pcFullPath ) == 0 );

	/* Generate the file name. */
	sprintf( cFileName, "%s.txt", pcDirectory2 );

	/* Print out the file name and the directory from which the file is being
	read. */
	printf( "Reading file %s in %s\r\n", cFileName, cRAMBuffer );

	/* This time the file is opened for reading. */
	pxFile = f_open( cFileName, "r" );

	/* Read the file 1 byte at a time. */
	for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ )
	{
		iReturned = f_getc( pxFile );
		configASSERT( iReturned ==  ( ( int ) '0' + iByte ) );
	}

	/* Finished so close the file. */
	f_close( pxFile );

	/* Move back to the root directory. */
	ucReturn = f_chdir( "../.." );
	configASSERT( ucReturn == F_NO_ERROR );

	/* Obtain and print out the working directory. */
	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
	printf( "Back in root directory %s\r\n", cRAMBuffer );
}




