#include "ProjectControl.h"

//#define FILESYS_TEST_ENABLE



#ifdef FILESYS_MAIN


#ifdef PROVIDED_TEST

#include <stdint.h>
#include "OS_FileSys/diskio.h"
#include "OS_FileSys/ff.h"
#include "inc/tm4c123gh6pm.h"
#include "OS_Critical/HardwareManager/SystemOscillatorDriver/PLL.h"

// SDCFile.c
// Runs on TM4C123
// This program is a simple demonstration of the SD card,
// file system, and ST7735 LCD.  It will read from a file,
// print some of the contents to the LCD, and write to a
// file.
// Daniel Valvano
// January 13, 2015

/* This example accompanies the book
   "Embedded Systems: Introduction to ARM Cortex M Microcontrollers",
   ISBN: 978-1469998749, Jonathan Valvano, copyright (c) 2014
   Program 4.6, Section 4.3
   "Embedded Systems: Real Time Interfacing to ARM Cortex M Microcontrollers",
   ISBN: 978-1463590154, Jonathan Valvano, copyright (c) 2014
   Program 2.10, Figure 2.37

 Copyright 2014 by Jonathan W. Valvano, valvano@mail.utexas.edu
    You may use, edit, run or distribute this file
    as long as the above copyright notice remains
 THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
 OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
 VALVANO SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
 OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 For more information about my classes, my research, and my books, see
 http://users.ece.utexas.edu/~valvano/
 */

// hardware connections
// **********ST7735 TFT and SDC*******************
// ST7735
// 1  ground
// 2  Vcc +3.3V
// 3  PA7 TFT reset
// 4  PA6 TFT data/command
// 5  PD7 SDC_CS, active low to enable SDC
// 6  PA3 TFT_CS, active low to enable TFT
// 7  PA5 MOSI SPI data from microcontroller to TFT or SDC
// 8  PA2 Sclk SPI clock from microcontroller to TFT or SDC
// 9  PA4 MISO SPI data from SDC to microcontroller
// 10 Light, backlight connected to +3.3 V

// **********wide.hk ST7735R*******************
// Silkscreen Label (SDC side up; LCD side down) - Connection
// VCC  - +3.3 V
// GND  - Ground
// !SCL - PA2 Sclk SPI clock from microcontroller to TFT or SDC
// !SDA - PA5 MOSI SPI data from microcontroller to TFT or SDC
// DC   - PA6 TFT data/command
// RES  - PA7 TFT reset
// CS   - PA3 TFT_CS, active low to enable TFT
// *CS  - PD7 SDC_CS, active low to enable SDC
// MISO - PA4 MISO SPI data from SDC to microcontroller
// SDA  – (NC) I2C data for ADXL345 accelerometer
// SCL  – (NC) I2C clock for ADXL345 accelerometer
// SDO  – (NC) I2C alternate address for ADXL345 accelerometer
// Backlight + - Light, backlight connected to +3.3 V

void EnableInterrupts(void);

static FATFS g_sFatFs;
FIL Handle,Handle2;
FRESULT MountFresult;
FRESULT Fresult;
unsigned char buffer[512];
#define MAXBLOCKS 100
// Describe the error with text on the LCD and then stall.  If
// the error was caused by a mistake in configuring SSI0, then
// the LCD will probably not work.
void diskError(char *errtype, int32_t code, int32_t block){
  while(1){};
}
// The simple unformatted test will destroy the formatting and
// erase everything on the SD card.
void SimpleUnformattedTest(void){ DSTATUS result; uint16_t block; int i; uint32_t n; uint32_t errors = 0;
  // simple test of eDisk
  result = disk_initialize(0);  // initialize disk
  if(result) diskError("disk_initialize", result, 0);
  n = 1;    // seed
  for(block = 0; block < MAXBLOCKS; block++){
    for(i=0; i<512; i++){
      n = (16807*n)%2147483647; // pseudo random sequence
      buffer[i] = 0xFF&n;
    }
    result = disk_write (0,buffer, block, 1);
    if(result) diskError("disk_write", result, block); // save to disk
  }
  n = 1;  // reseed, start over to get the same sequence
  for(block = 0; block < MAXBLOCKS; block++){
    result = disk_read (0,buffer, block,1);
    if(result) diskError("disk_read ", result, block); // read from disk
    for(i=0; i<512; i++){
      n = (16807*n)%2147483647; // pseudo random sequence
      if(buffer[i] != (0xFF&n)){
        errors = errors + 1;
      }
    }
  }
}
#define FILETESTSIZE 10000
void FileSystemTest(void){
  UINT successfulreads, successfulwrites;
  char c, d;
  int16_t x, y; int i; uint32_t n;
  c = 0;
  x = 0;
  y = 10;
  n = 1;    // seed
  Fresult = f_open(&Handle2, "testFile.txt", FA_CREATE_ALWAYS|FA_WRITE);
  if(Fresult){
    while(1){};
  } else{
    for(i=0; i<FILETESTSIZE; i++){
      n = (16807*n)%2147483647; // pseudo random sequence
      c = ((n>>24)%10)+'0'; // random digit 0 to 9
      Fresult = f_write(&Handle2, &c, 1, &successfulwrites);
      if((successfulwrites != 1) || (Fresult != FR_OK)){
        while(1){};
      }
    }
    Fresult = f_close(&Handle2);
    if(Fresult){
      while(1){};
    }
  }
  n = 1;  // reseed, start over to get the same sequence
  Fresult = f_open(&Handle, "testFile.txt", FA_READ);
  if(Fresult == FR_OK){
    for(i=0; i<FILETESTSIZE; i++){
      n = (16807*n)%2147483647; // pseudo random sequence
      d = ((n>>24)%10)+'0'; // expected random digit 0 to 9
      Fresult = f_read(&Handle, &c, 1, &successfulreads);
      if((successfulreads == 1) && (Fresult == FR_OK) && (c == d)){
        x = x + 6;
        if(x > 122){
          x = 0;                          // start over on the next line
          y = y + 10;
        }
        if(y > 150){
          y = 10;                         // the screen is full
        }
      } else{

        while(1){};
      }

    }
  } else{
    while(1){};
  }
  Fresult = f_close(&Handle);
/*  Fresult = f_open(&Handle,"out.txt", FA_CREATE_ALWAYS|FA_WRITE);
  if(Fresult == FR_OK){
    ST7735_DrawString(0, 0, "Opened out.txt", ST7735_Color565(0, 0, 255));
    c = 'A';
    x = 0;
    y = 10;
    Fresult = f_write(&Handle, &c, 1, &successfulreads);
    ST7735_DrawChar(x, y, c, ST7735_Color565(255, 255, 0), 0, 1);
    while((c <= 'Z') && (Fresult == FR_OK)){
      x = x + 6;
      c = c + 1;
      if(x > 122){
        x = 0;                          // start over on the next line
        y = y + 10;
      }
      if(y > 150){
        break;                          // the screen is full
      }
      Fresult = f_write(&Handle, &c, 1, &successfulreads);
      ST7735_DrawChar(x, y, c, ST7735_Color565(255, 255, 0), 0, 1);
    }
  } else{
    ST7735_DrawString(0, 0, "Error out.txt (  )", ST7735_Color565(255, 0, 0));
    ST7735_SetCursor(15, 0);
    ST7735_SetTextColor(ST7735_Color565(255, 0, 0));
    ST7735_OutUDec((uint32_t)Fresult);
  }*/
}

const char inFilename[] = "test.txt";   // 8 characters or fewer
const char outFilename[] = "out.txt";   // 8 characters or fewer

int main(void){
  UINT successfulreads, successfulwrites;
  uint8_t c, x, y;
  PLL_Init(Bus80MHz);    // 80 MHz
  EnableInterrupts();
  //SimpleUnformattedTest();              // comment this out if continuing to the advanced file system tests
  //FileSystemTest();                     // comment this out if file system works
  MountFresult = f_mount(&g_sFatFs, "", 0);
  if(MountFresult){
    while(1){};
  }
  // open the file to be read
  Fresult = f_open(&Handle, inFilename, FA_READ);
  if(Fresult == FR_OK){

    // get a character in 'c' and the number of successful reads in 'successfulreads'
    Fresult = f_read(&Handle, &c, 1, &successfulreads);
    x = 0;                              // start in the first column
    y = 10;                             // start in the second row
    while((Fresult == FR_OK) && (successfulreads == 1) && (y <= 130)){
      if(c == '\n'){
        x = 0;                          // go to the first column (this seems implied)
        y = y + 10;                     // go to the next row
      } else if(c == '\r'){
        x = 0;                          // go to the first column
      } else{                           // the character is printable, so print it
        x = x + 6;                      // go to the next column
        if(x > 122){                    // reached the right edge of the screen
          x = 0;                        // go to the first column
          y = y + 10;                   // go to the next row
        }
      }
      // get the next character in 'c'
      Fresult = f_read(&Handle, &c, 1, &successfulreads);
    }
    // close the file
    Fresult = f_close(&Handle);
  } else{
    // print the error code
  }

  // open the file to be written
  // Options:
  // FA_CREATE_NEW    - Creates a new file, only if it does not already exist.  If file already exists, the function fails.
  // FA_CREATE_ALWAYS - Creates a new file, always.  If file already exists, it is over-written.
  // FA_OPEN_ALWAYS   - Opens a file, always.  If file does not exist, the function creates a file.
  // FA_OPEN_EXISTING - Opens a file, only if it exists.  If the file does not exist, the function fails.
  Fresult = f_open(&Handle, outFilename, FA_WRITE|FA_OPEN_ALWAYS);
  if(Fresult == FR_OK){
    // jump to the end of the file
    Fresult = f_lseek(&Handle, Handle.fsize);
    // write a message and get the number of successful writes in 'successfulwrites'
    Fresult = f_write(&Handle, "Another successful write.\r\n", 27, &successfulwrites);
    if(Fresult == FR_OK){
      // print the number of successful writes
      // expect: third parameter of f_write()
      // print the byte offset from the start of the file where the writes started
      // expect: (third parameter of f_write())*(number of times this program has been run before)

    } else{
      // print the error code
    }
    // close the file
    Fresult = f_close(&Handle);
  } else{
    // print the error code
  }
  while(1){};

  uint32_t successfulreads, successfulwrites;
  uint8_t c, x, y;

  OS_Init();
  MountFresult = f_mount(&g_sFatFs, "", 0);
  Fresult = f_open(&Handle, "lab5.txt", FA_READ);
  if(Fresult == FR_OK)
  {
	    Fresult = f_read(&Handle, &c, 1, &successfulreads);
	    while((Fresult == FR_OK) && (successfulreads == 1)){
	      if(c == '\n')
	      {
	    	  	  OS_SerialOutString("\n");
	      } else
	      {
	    	  	  OS_SerialOutChar(c);
	      }
	      // get the next character in 'c'
	      Fresult = f_read(&Handle, &c, 1, &successfulreads);
	    }
	    // close the file
	    Fresult = f_close(&Handle);
  }

  Fresult = f_open(&Handle, "govinda.txt", FA_WRITE|FA_OPEN_ALWAYS);
  Fresult = f_write(&Handle, string, strlen(string), &successfulwrites);
  Fresult = f_close(&Handle);

}
#else
#include <stdint.h>
#include "OS_Critical/OS.h"
#include "Shell/Shell.h"
#include "OS_Critical/HardwareManager/OS_Hardware.h"
#include "OS_Critical/BackgroundThreadManager/OS_BackgroundThread.h"
#include "OS_Critical/CommunicationManager/OS_Communication.h"
#include "OS_Critical/MutualExclusionManager/OS_Semaphore.h"
#include "OS_FileSys/OS_FileSystemScheme.h"

uint32_t line = 0;
void LCDTask()
{
	while(1)
	{
		OS_Sleep(2000);
		OS_DisplayMessage(0, line++, "hari hari", 1);
	}
}

void LCDTask2()
{
	while(1)
	{
		OS_Sleep(2000);
		OS_DisplayMessage(0, line++, "hari hari", 2);
	}
}

FIL Handle;
FRESULT Fresult;
UINT succ;
char c;
int main()
{
	  OS_Init();

	  Fresult = f_open(&Handle, "lab5.txt", FA_READ);
	  if(Fresult == FR_OK)
	  {
		    Fresult = f_read(&Handle, &c, 1, &succ);
		    while((Fresult == FR_OK) && (succ == 1)){
		      if(c == '\n')
		      {
		    	  	  OS_SerialOutString("\n");
		      } else
		      {
		    	  	  OS_SerialOutChar(c);
		      }
		      // get the next character in 'c'
		      Fresult = f_read(&Handle, &c, 1, &succ);
		    }
		    // close the file
		    Fresult = f_close(&Handle);
	  }

	  OS_SerialOutString("\n");
	  OS_AddThread(LCDTask, 100, 2);
	  OS_AddThread(LCDTask2, 100, 2);

	  OS_AddThread(IdleTask, 100, 5);
	  OS_Launch(TIME_1MS);

}
#endif
#endif
