/*******************************************************************************
 * (c) Copyright 2008 Actel Corporation.  All rights reserved.
 *
 */
#include "main.h"
#include "mss_uart.h"
#include "DirectC/dpuser.h"
#include "DirectC/dpalg.h"
#include "mss_watchdog.h"
#include "mss_iap.h"
#include "ff.h"
#include "diskio.h"

FATFS     fatfs;    /* File system object */
FILINFO   Finfo;
FIL       file1, file2;  /* File object */

extern int xatoi 
(  /* 0:Failed, 1:Successful */
   char **str,  /* Pointer to pointer to the string */
   long *res  /* Pointer to the variable to store the value */
);
void Init_FS()
{
   /* File System  on SPI Flash Init */
   if(disk_initialize(0))
   {
      iprintf("Disk Initialization Failed: SPI interface Error \n\r");
   }
   else
   {
      f_mount(0, &fatfs);
   }
}

static
void put_rc (FRESULT rc)
{
   const char *str = "OK\0" "DISK_ERR\0" "INT_ERR\0" "NOT_READY\0" "NO_FILE\0" "NO_PATH\0"
                     "INVALID_NAME\0" "DENIED\0" "EXIST\0" "INVALID_OBJECT\0" "WRITE_PROTECTED\0"
                     "INVALID_DRIVE\0" "NOT_ENABLED\0" "NO_FILE_SYSTEM\0" "MKFS_ABORTED\0" "TIMEOUT\0"
                     "LOCKED\0" "NOT_ENOUGH_CORE\0" "TOO_MANY_OPEN_FILES\0";
   FRESULT i;

   for (i = 0; i != rc && *str; i++) 
   {
      while (*str++) ;
   }
   iprintf("rc=%u FR_%s\n\r", (UINT)rc, str);
}

void show_file_stats()
{
   BYTE res;
   long p1;
   UINT s1, s2;
   DIR dir;    /* Directory object */
   res = f_opendir(&dir, NULL);
   if (res)
   { 
      put_rc(res);
      iprintf("Cann't Read File System !!!\n\r");
      return;
   }
   p1 = s1 = s2 = 0;
   for(;;) 
   {
     res = f_readdir(&dir, &Finfo);
     if ((res != FR_OK) || !Finfo.fname[0]) 
        break;
     if (Finfo.fattrib & AM_DIR) 
     {
        s2++;
     } 
     else 
     {
        s1++; p1 += Finfo.fsize;
     }
     iprintf("%s  %9lu\n\r", &(Finfo.fname[0]), Finfo.fsize);
   }
   iprintf("%4u File(s),%10lu bytes\n\r%4u Dir(s)\n\r", s1, p1, s2);
}
void action_menu(void)
{
   uint8_t tx_data[24][40] = {
                                {"\r\n\r\n   Action:                    "},
                                {"\r\n01 DEVICE_INFO                    "},
                                {"\r\n02 READ_IDCODE                    "},
                                {"\r\n03 ERASE                          "},
                                {"\r\n04 ERASE_ALL                      "},
                                {"\r\n05 PROGRAM                        "},
                                {"\r\n06 VERIFY                         "},
                                {"\r\n07 ENC_DATA_AUTHENTICATION        "},
                                {"\r\n08 ERASE_ARRAY                    "},
                                {"\r\n09 PROGRAM_ARRAY                  "},
                                {"\r\n10 VERIFY_ARRAY                   "},
                                {"\r\n11 ERASE_FROM                     "},
                                {"\r\n12 PROGRAM_FROM                   "},
                                {"\r\n13 VERIFY_FROM                    "},
                                {"\r\n14 ERASE_SECURITY                 "},
                                {"\r\n15 PROGRAM_SECURITY               "},
                                {"\r\n16 PROGRAM_NVM                    "},
                                {"\r\n17 VERIFY_NVM                     "},
                                {"\r\n18 VERIFY_DEVICE_INFO             "},
                                {"\r\n19 READ_USERCODE                  "},
                                {"\r\n20 PROGRAM_NVM_ACTIVE             "},
                                {"\r\n21 VERIFY_NVM_ACTIVE              "},
                                {"\r\n22 IS_CORE_CONFIGURED             "},
                                {"\r\n Enter 1,2,3,4 .. 22, accordingly "}
                             };
   uint8_t rx_data[20];
   uint8_t rx_size =0;
   uint8_t valid_entry = 0;

   MSS_UART_polled_tx (&g_mss_uart0, tx_data[0],sizeof(tx_data));
   while (!valid_entry)
   {
      do 
      {
         rx_size = MSS_UART_get_rx(&g_mss_uart0, &rx_data[1],1);
      }while(rx_size == 0);
      do
      {
         rx_size = MSS_UART_get_rx(&g_mss_uart0, &rx_data[0],1);
      }while(rx_size == 0);
      Action_code = (rx_data[1] - 48) * 10 + (rx_data[0] - 48);
      if ((Action_code > 0 ) && (Action_code < 23))
      {
         valid_entry = 1;
      }
      else
      {
         dp_display_text((signed char *)"\n\rInvalid entry.  Try again. ");
      }
   }
   return;
}

int main(void)
{
   uint8_t rx_data[20];
   int res;
   /*--------------------------------------------------------------------------
    * Disable watch dog.
   */
   MSS_WD_disable();
   MSS_UART_init(&g_mss_uart0, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT );

   Init_FS();
   hardware_interface = IAP_SEL;
   while( 1 )
   {
      action_menu();
      #ifdef ENABLE_DEBUG          
        dp_display_text((signed char *)"\r\nPerforming IAP actions...\n\r");
      #endif
      iprintf((signed char *)"Files available in SPI flash: \n\r");
      show_file_stats();
      iprintf("\n\rTo Program Fabric Please enter the file name (in Small letters)\n\r");
      get_line((char *)rx_data, sizeof(rx_data));
      res = f_open(&file1, (char *)rx_data, FA_OPEN_EXISTING | FA_READ);
      if(res)
      {
         iprintf("Cann't Open file Please check the file details\n\r");
         continue;
      }
      enable_IAP();
      dp_top();
      #ifdef ENABLE_DEBUG        
        dp_display_text((signed char *)"\r\nExit code = ");
        dp_display_value(error_code,DEC);
        dp_display_text((signed char *)"\r\n-------------------------------------------------------------------\r\n\r\n ");
      #endif
      disable_IAP();
      f_close(&file1);
   }
   return 0;
}
