/* ---------------------------------------------------------------------------
 * dosfs_test.c                                       (c) 2008 Micro-key bv
 * ---------------------------------------------------------------------------
 * Micro-key bv
 * Industrieweg 28, 9804 TG Noordhorn
 * Postbus 92, 9800 AB Zuidhorn
 * The Netherlands
 * Tel: +31 594 503020
 * Fax: +31 594 505825
 * Email: support@microkey.nl  
 * Web: www.microkey.nl
 * ---------------------------------------------------------------------------
 * Description: 
 * ---------------------------------------------------------------------------
 * Version(s):  0.1, Jul 29, 2008, MMi
 *                   Creation.
 * ---------------------------------------------------------------------------
 */

/* ---------------------------------------------------------------------------
 * System include files
 * ---------------------------------------------------------------------------
 */
/* Compiler includes */
#include <string.h>
#include <stdlib.h>

#include "LPC23xx.h"
#include "types.h"

/* FreeRTOS includes */
#include "FreeRTOS.h"
#include "task.h"
/* ---------------------------------------------------------------------------
 * Application include files
 * ---------------------------------------------------------------------------
 */ 
#include "fat_test.h"
#include "fat_intern.h"
#include "fat_public.h"
#include "fat_diskio.h"
#include "mmc.h"
#include "SerOut.h"
#include "serial.h"

/* ---------------------------------------------------------------------------
 * Local constant and macro definitions
 * ---------------------------------------------------------------------------
 */

/* ---------------------------------------------------------------------------
 * Global variable definitions
 * ---------------------------------------------------------------------------
 */

/* ---------------------------------------------------------------------------
 * Local variable definitions
 * ---------------------------------------------------------------------------
 */
UINT8 ff_Write[0x200];                  /* used with MMC Write Function     */
UINT8 ff_Read[0x200];
UINT8 test_Write[0x200];
UINT8 test_Read1[0x200];
UINT8 test_Read2[0x200];
/* ---------------------------------------------------------------------------
 * Local function definitions
 * ---------------------------------------------------------------------------
 */

void ffTestStart (void)
{
    UINT32 loopcnt;
    MmcState_t CardStatus;
    
    /* Clear Terminal Screen with VT100 Command                             */
    serWrite(SerOutPort, sizeof("\x1B[2J"), "\x1B[2J"); /*WARNING don't care*/
    
    MmcInitMedia();                     /* Init Card and give Status        */
 
    
    /* Test that write and Read work                                        */
    CardStatus = disk_write (0, (pUINT8)ff_Write, 3, 1);
    
    CardStatus = disk_read (0, (pUINT8)ff_Read, 3, 1);
    
    for (loopcnt = 0; loopcnt < 0x200; loopcnt++)
        {
        if (ff_Write[loopcnt] != ff_Read[loopcnt])
            {
            debugPrint ("\n\rCompare ERROR");
            break;
            }
        ff_Write[loopcnt] = 0;
        ff_Read[loopcnt] = 0;
        }
    vTaskDelay(1000);
    

/* ---------------------------------------------------------------------------
 * BEGINN FAT TEST SEQUENCE
 * ---------------------------------------------------------------------------
 */

    
    /* Mount SD-Card as virtual drive 0                                     */
    FATFS volume_object;
    debugPrint ("\n\r-----");
    debugPrint ("\n\rMount Volume as Drive 0");
    FAT_StatusOut (f_mount (0, &volume_object));

    
    vTaskDelay (100);
    /* FILE ACCESS TESTS
     * Open a File. If file does not exist, create it
     * Close File
     * Delete File
     */
    FIL file_1;                      /* create a blank File structure    */
    debugPrint ("\n\r-----");
    debugPrint ("\n\rOpen, Close and Delete a File");
    FAT_StatusOut (f_open (&file_1, "test.fil", (FA_CREATE_ALWAYS)));
    FAT_StatusOut (f_close (&file_1));
    FAT_StatusOut (f_unlink ("test.fil"));
    
    vTaskDelay (100);
    /* DIRECTORY ACCESS TESTS
     * Create a subdirectory
     * Open a File in the subdirectory. If file does not exist, create it
     * Sync File
     * Leave file opened
     */
    debugPrint ("\n\r-----");
    debugPrint ("\n\rCreate subdirs, create file in subdir, sync file, delete subdir");
    FAT_StatusOut (f_mkdir ("subdir"));
    FAT_StatusOut (f_mkdir ("deleteme"));
    FAT_StatusOut (f_open (&file_1, "subdir/test.dat", (FA_READ | FA_WRITE | FA_CREATE_ALWAYS)));
    FAT_StatusOut (f_sync (&file_1));
    FAT_StatusOut (f_unlink ("deleteme"));
    
    
    vTaskDelay (100);
    /* FILE READ/WRITE TESTS
     * Read MBR from Disc into an Array
     * Open a file. If file does not exist, create it with read and write access
     * Write MBR from Array in opened/created file
     * Write MBR in already opened file from above (test.dat)
     * Sync both files
     * Set File Pointer for both files to offset 0x00
     * Read both files and compare content with original MBR
     * Close both files
     * 
     * Shown with this is that the file system is capable of multifile access 
     * by usage of the fil information structure.
     */
    UINT32 bytes_written;
    UINT32 bytes_read;
    FIL file_2;                     /* create a blank File structure    */
    debugPrint ("\n\r-----");
    debugPrint ("\n\rOpen, write and read to files");
    disk_read (0, (pUINT8)test_Write, 0, 1);
    FAT_StatusOut (f_open (&file_2, "write.txt", (FA_WRITE | FA_READ | FA_CREATE_ALWAYS)));
    FAT_StatusOut (f_write (&file_2, &test_Write, 0x200, &bytes_written));
    FAT_StatusOut (f_write (&file_1, &test_Write, 0x200, &bytes_written));
    FAT_StatusOut (f_sync (&file_2));
    FAT_StatusOut (f_sync (&file_1));
    FAT_StatusOut (f_lseek (&file_2, 0x00));
    FAT_StatusOut (f_lseek (&file_1, 0x00));
    FAT_StatusOut (f_read (&file_2, &test_Read1, 0x200, &bytes_read));
    FAT_StatusOut (f_read (&file_1, &test_Read2, 0x200, &bytes_read));
    for (loopcnt = 0; loopcnt < 0x200; loopcnt++)
        {
        if ((test_Write[loopcnt] != test_Read1[loopcnt])
         || (test_Write[loopcnt] != test_Read2[loopcnt]))
            {
            /* Strings are not equal                                        */
            debugPrint ("\n\rCompare Error");
            break;
            }
        }
    FAT_StatusOut (f_close (&file_2));
    FAT_StatusOut (f_close (&file_1));
    
    vTaskDelay (100);
    /* RENAMING FILE AND DIRECTORY
     * Create two files and two Directories
     * Rename a File
     * Rename a Directory
     * Move a File
     * Move a Directory
     * Combine moving with renaming
     * Close both files
     */
    debugPrint ("\n\r-----");
    debugPrint ("\n\rCreate, Rename and Move each a file and a directory");
    FAT_StatusOut (f_open (&file_1, "rename1.old", (FA_CREATE_ALWAYS)));
    FAT_StatusOut (f_open (&file_2, "rename2.old", (FA_CREATE_ALWAYS)));
    FAT_StatusOut (f_mkdir ("renameme"));
    FAT_StatusOut (f_mkdir ("movehere"));
    FAT_StatusOut (f_rename ("rename1.old", "renamed1.new"));
    FAT_StatusOut (f_rename ("renameme", "renamed"));
    FAT_StatusOut (f_rename ("renamed1.new", "movehere/renamed1.new"));
    FAT_StatusOut (f_rename ("renamed", "movehere/renamed"));
    FAT_StatusOut (f_rename ("rename2.old", "movehere/renamed2.new"));
    FAT_StatusOut (f_close (&file_1));
    FAT_StatusOut (f_close (&file_2));
    
    
    vTaskDelay (100);
    /* CHANGING FILES
     * Open a file. If not available, create it
     * change Attributes (SET HIDDEN, set READ ONLY, clear ARCHIVE)
     */
    debugPrint ("\n\r-----");
    debugPrint ("\n\rChange Attributes");
    FAT_StatusOut (f_open (&file_1, "attr.dat", (FA_READ | FA_WRITE | FA_CREATE_ALWAYS)));
    FAT_StatusOut (f_chmod ("attr.dat", (AR_HID | AR_RDO), (AR_HID | AR_RDO | AR_ARC)));
    FAT_StatusOut (f_close (&file_1));

    
    vTaskDelay (100);
    /* DO A SPEED TEST
     * Fill write array with signs
     * Open "speed.txt. If file does not exist, create it with write access
     * Write Buffer x-Times to the speed.txt
     */
    UINT8 character = 48;
    debugPrint ("\n\r-----");
    debugPrint ("\n\rSpeed Test");
    for (loopcnt = 0; loopcnt < 0x200; loopcnt++)
        {
        ff_Write[loopcnt] = character;
        }
    FAT_StatusOut (f_open (&file_1, "speed.txt", (FA_WRITE | FA_OPEN_ALWAYS)));
    
    for (loopcnt = 0; loopcnt < 20000; loopcnt++)
        {
        f_write (&file_1, &ff_Write, 0x200, &bytes_written);
        }
    FAT_StatusOut (f_close (&file_1));

    
    debugPrint ("\n\rREADY!!!");    
}

