/**************************************************************
  FAT_UCOS.C
  Z-World, 2005

  Demonstrate using FAT with uC/OS-II.

  Versions of the Dynamic C FAT prior to 2.10 did not support
  FAT unless all FAT API calls are done in one task.

  FAT_USE_UCOS_MUTEX must be #defined before #use'ing FAT.LIB

  fat_InitUCOSMutex(priority)  MUST be called after calling
  OSInit() and before calling FAT APIs or begining multitasking.
  'priority' MUST be higher than all tasks using FAT APIs.

  Only high level fat APIs with names that begin with 'fat_'
  should be called from uC/OS-II tasks.

**************************************************************/
#memmap xmem

#define OS_MUTEX_EN		       1	 	// Enable mutexes
#define OS_TIME_DLY_HMSM_EN	 1    // Enable hour, min, sec, ms delays
#define OS_TASK_SUSPEND_EN     1    // Enable task ssuspension

// Must use mutexes to multitask with FAT,
//  and must use blocking mode
#define FAT_USE_UCOS_MUTEX
#define FAT_BLOCK

// Create 1024 task stacks for FAT tasks just to be safe
#define STACK_CNT_1K 2

// Bring in libraries
#use "ucos2.lib"
#use "fat.lib"
#ifndef FAT_VERSION
  #error "This program requires FAT version 2.10 or greater"
#endif

int taskcount;

#define  FILESIZE 4096
char fbuff1[FILESIZE];
char fbuff2[FILESIZE];

void File1Task(void* pdata);
void File2Task(void* pdata);

void main()
{
   int rc;

   OSInit();
   taskcount = 0;

   // MUST Initialize FAT mutex at higher priority than other tasks
   fat_InitUCOSMutex(4);

   rc = fat_AutoMount(FDDF_MOUNT_PART_0    | FDDF_MOUNT_DEV_0     |
                      FDDF_COND_DEV_FORMAT | FDDF_COND_PART_FORMAT );
   if(rc)
   {
      printf("ERROR: fat_AutoMount() returned  %d, aborting\n");
   }

   OSTaskCreate(File1Task, NULL, 1024, 5);
   OSTaskCreate(File2Task, NULL, 1024, 6);
   OSStart();  // Start multi-tasking
}

void File1Task(void* pdata)
{
   auto FATfile my_file;
   auto char ch;
   auto int i, rc;

   while(1){
      OSTimeDlyHMSM(0,0,0,100);  // Allow lower priority taskes to run

      // PARTITION_A = partition 0  on device 0
      fat_Open(PARTITION_A, "file1.txt",FAT_FILE, FAT_CREATE, &my_file, NULL);

      // Fill file with whatever is in the low byte of MS_TIMER
      ch = (char)MS_TIMER;
      memset(fbuff1, ch, FILESIZE);
      fat_Write(&my_file, fbuff1, FILESIZE);

      // Make sure it reads back correctly
      memset(fbuff1, 0, FILESIZE);             // clear buffer
      fat_Seek(&my_file, 0L, SEEK_SET);
      fat_Read(&my_file, fbuff1, FILESIZE);

      for(i=0;i<FILESIZE;i++){
         if( fbuff1[i] != ch){
             printf("ERROR:fat_Read() bad value\n");
             break;
         }
      }
      if (i==FILESIZE){
         if(fat_Delete(PARTITION_A, FAT_FILE, "file1.txt" ))
         {
             printf("Task1 successful\n");
         }
         else{
             printf("ERROR:fat_Delete() bad value\n");
         }
      }
      fat_Close(&my_file);

      // quit after 4 passes so we don't wear out flash if left running
      if(taskcount++ > 4){
         fat_UnmountDevice(PARTITION_A->dev);
         printf("Test done: Hit any key to end program");
         OSTaskSuspend(6);
         while(!kbhit());
         exit(0);
      }
   }
}

void File2Task(void* pdata)
{
   auto FATfile my_file;
   auto char ch;
   auto int i, rc;

   while(1){
     fat_Open(PARTITION_A, "file2.txt",
                 FAT_FILE, FAT_CREATE, &my_file, NULL);

      // Fill file with whatever is in the low byte of MS_TIMER
      ch = (char)MS_TIMER;
      memset(fbuff2, ch, FILESIZE);
      fat_Write(&my_file, fbuff2, FILESIZE);

      // Make sure it reads back correctly
      memset(fbuff2, 0, FILESIZE);         // clear buffer
      fat_Seek(&my_file, 0L, SEEK_SET);
      fat_Read(&my_file, fbuff2, FILESIZE);

      for(i=0;i<FILESIZE;i++){
         if( fbuff2[i] != ch){
             printf("ERROR:fat_Read() bad value\n");
             break;
         }
      }
      if (i==FILESIZE){
         if(fat_Delete( PARTITION_A, FAT_FILE, "file2.txt" )){
             printf("Task2 successful\n");
         }
         else{
             printf("ERROR:fat_Delete() bad value\n");
         }
      }
      fat_Close(&my_file);
   }
}

