/*
   A4TEST.C - Testing the functionality ASIC4 Example
              Interface Board device driver A4Exif.ldd
              A comprehensive test program which checks
              I/O request functionality of A4Exif.ldd

              Written by Mal, January 31, 1995
*/

#include <plib.h>
#include <p_keyb.h>

#define BUFLEN             1
#define MAXBUF             8
#define SERREAD_TIMEOUT    20L
#define FLASH_TIME         1L

GLREF_D TEXT *DatCommandPtr;
GLREF_D VOID *winHandle;
LOCAL_D VOID *serH;                    /* serial channel handle */
LOCAL_D VOID *timH;                    /* timer channel handle */
LOCAL_D WORD serReadStat;              /* serial channel status word */
LOCAL_D WORD timStat;                  /* timer channel status word */
LOCAL_D WORD keyStat;                  /* console channel status word */
LOCAL_D P_CON_KBREC kbrec;
LOCAL_D TEXT buf[40];
LOCAL_D UBYTE wowbuf[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
LOCAL_D TEXT *head="LED: ";


LOCAL_C VOID PrintHeader(VOID)
/* Prints the title at the start of the program */
   {
   p_printf("*********************");
   p_printf("Welcome to the ASIC 4");
   p_printf("Example IF board test");
   p_printf("program");
   p_printf("*********************");
   p_printf(".....\n");
   p_getch();
   }

LOCAL_C VOID PrintInstructions(VOID)
   {
   p_printf("Type in the test number");
   p_printf("  0 => Alternate flash");
   p_printf("  1 => Asynchronous read");
   p_printf("  2 => Sense");
   p_printf("  3 => Set");
   p_printf("  4 => Memory");
   p_printf("  q => Quit");
   p_printf("  .....");
   }

LOCAL_C VOID LoadLdd(VOID)
/* Loads the LDD A4Exif.ldd from anywhere and exits on failure */
   {
   TEXT filename[128];
   INT ret;

   p_printf("\nLOADLDD=>");
   p_fparse("A4EXIF.LDD",DatCommandPtr,&filename[0],NULL);
   if ((ret=p_loadldd(&filename[0]))<0)
      {
      p_printf("A4Exif.ldd failed to load");
      if (ret==E_FILE_NXIST)
            {
         p_printf("Device does not exist");
         p_getch();
         p_exit(0);
         }
      else if (ret==E_FILE_EXIST)
         {
         p_printf("Device is already loaded");
         p_getch();
         }
      else if (ret==E_GEN_NOMEMORY)
         {
         p_printf("Not enough memory available");
         p_getch();
         p_exit(0);
         }
      else
         {
         p_printf("Unknown error %d on p_loadldd",ret);
         p_getch();
         p_exit(0);
         }
      }
   else
      {
      p_printf("Successfully loaded A4Exif.ldd\n");
      p_getch();
      }
   }

LOCAL_C VOID UnloadLdd(VOID)
/* Removes the LDD A4Exif.ldd */
   {
   INT ret;

   p_printf("\nUNLOADLDD=>");
   if ((ret=p_devdel("LED",E_LDD))!=0)
      {
      p_printf("A4Exif.ldd failed to unload");
      if (ret==E_FILE_DEVICE)
         p_printf("The device driver is not loaded");
      else if (ret==E_GEN_INUSE)
         p_printf("Driver is open and cannot be deleted");
      else
         p_printf("Unknown error %d on p_devdel",ret);
      p_getch();
      }
   else
      {
      p_printf("Successfully deleted A4Exif.ldd");
      p_getch();
      }
   }

LOCAL_C VOID OpenPort(VOID)
/*Opens a serial port of the A4Example IF on the host machine*/
   {
   INT ret, seropen;

   p_printf("\nOPENPORT=>");
DoAgain:
   p_printf("Type in the serial\r\nport to open");
   p_printf("eg A => port A");
   p_printf(".....\n");
   ret=p_toupper(p_getch());
   *(head+4)=ret;
   p_printf("%s",head);
   p_sleep(5L);
   if ((seropen=p_open(&serH,head,-1))<0)
      {/* Failed to open */
      p_atos(&buf[0],"p_open on port %c has failed",ret);
      p_printf("%s\n<p_open ret=%d>",&buf[0],seropen);
      p_errs(buf,seropen);
      p_printf("%s\n",&buf[0]);
      p_getch();
      goto DoAgain;
      }
   else
      {/* Succeeded in opening */
      p_atos(&buf[0],"Successfully opened port %c",ret);
      p_printf("%s",&buf[0]);
      p_printf(".....\n");
      p_getch();
      }
   }

LOCAL_C VOID ClosePort(VOID)
   {
   INT ret;

   p_printf("\nCLOSEPORT=>");
   if ((ret=p_close(serH))!=0)
      p_printf("Error in closing port");
   else
      p_printf("Successfully closed port");
   p_getch();
   }

LOCAL_C VOID SensePort(VOID)
   {
   UBYTE A1,A2;

   p_printf("\nSENSEPORT=>");
   p_iow(serH,P_FSENSE,&A1,&A2);
   p_printf("Status byte: 0x%x",A1);
   p_printf("LED byte: 0x%x",A2);
   p_getch();
   }

LOCAL_C INT SetPort(VOID)
   {
   UBYTE key;

   p_printf("\nSETPORT=>");
   p_printf("Type a key");
   p_printf("ESCAPE to exit\r\n");
   if ((key=p_getch())==E_KEY_ESCAPE)
      {
      key=0x00;
      p_iow(serH,P_FSET,&key);
      return(-1);
      }
   else
      {
      p_printf("Output byte is 0x%x",key);
      p_iow(serH,P_FSET,&key);
      return(0);
      }
   }

LOCAL_C VOID OpenTimer(VOID)
   {
   if (p_open(&timH,"TIM:",-1)<0)
      {/* Error in opening timer */
      p_printf("Cannot open timer channel\n");
      p_getch();
      }
   }

LOCAL_C VOID QueueTimer(ULONG timeouttime)
   {
   p_ioc4(timH,P_FRELATIVE,&timStat,&timeouttime);
   }

LOCAL_C VOID CancelTimer(VOID)
   {
   p_iow(timH,P_FCANCEL);
   p_waitstat(&timStat);
   }

LOCAL_C VOID QueueSerRead(UBYTE *statusptr,UBYTE *ledptr)
   {
   p_ioc5(serH,P_FREAD,&serReadStat,statusptr,ledptr);
   }

LOCAL_C VOID CancelSerRead(VOID)
   {
   p_iow(serH,P_FCANCEL);
   p_waitstat(&serReadStat);
   }

LOCAL_C VOID QueueKeypress(P_CON_KBREC *keybrec)
   {
   p_ioc4(winHandle,P_FREAD,&keyStat,keybrec);
   }

LOCAL_C VOID AsynchRead(VOID)
   {
   UBYTE b_led;
   UBYTE b_status;

   p_printf("ASYNCH READ\r\n");
   OpenTimer();
   QueueTimer(SERREAD_TIMEOUT);
   QueueSerRead(&b_status,&b_led);
   QueueKeypress(&kbrec);
   FOREVER
      {
      p_iowait();
      if (keyStat!=E_FILE_PENDING)
         {/* Keypress received */
         p_printf("KEYPRESS");
         if (kbrec.keycode==E_KEY_ESCAPE)
            {
            CancelSerRead();
            CancelTimer();
            b_led=0x00;
            p_iow(serH,P_FWRITE,&b_led);
            break;
            }
         else
            {
            /* Do nothing - requeue keypress */
            QueueKeypress(&kbrec);
            continue;
            }
         }
      else if (serReadStat!=E_FILE_PENDING)
         {
         p_printf("SERIAL READ COMPLETED");
         CancelTimer();
         p_printf("Status byte is => 0x%x",b_status);
         p_printf("LED byte is => 0x%x",b_led);
         QueueTimer(SERREAD_TIMEOUT);
         QueueSerRead(&b_status,&b_led);
         continue;
         }
      else if (timStat!=E_FILE_PENDING)
         {
         p_printf("TIMEOUT");
         CancelSerRead();
         QueueSerRead(&b_status,&b_led);
         QueueTimer(SERREAD_TIMEOUT);
         continue;
         }
      else
         {/* Error - missing status word so fatal error */
         p_printf("***Stray status word***");
         break;
         }
      }
   p_close(timH);
   }

LOCAL_C VOID AlternateFlash(VOID)
   {
   UBYTE b_led;
   INT i=0;

   p_printf("ALTERNATE FLASH\r\n");
   p_printf("Hit ESCAPE to exit");
   OpenTimer();
   QueueTimer(FLASH_TIME);
   QueueKeypress(&kbrec);
   FOREVER
      {
      p_iowait();
      if (keyStat!=E_FILE_PENDING)
         {/* Keypress received */
         if (kbrec.keycode==E_KEY_ESCAPE)
            {
            CancelTimer();
            b_led=0x00;
            p_iow(serH,P_FWRITE,&b_led);
            break;
            }
         else
            {
            /* Do nothing - requeue keypress */
            QueueKeypress(&kbrec);
            continue;
            }
         }
      else if (timStat!=E_FILE_PENDING)
         {/* Timer finished */
         if (i<MAXBUF)
            {
            p_iow(serH,P_FSET,&wowbuf[i]);
            i++;
            }
         else
            {
            i=0;
            p_iow(serH,P_FSET,&wowbuf[i]);
            }
         QueueTimer(FLASH_TIME);
         continue;
         }
      else
         {/* Missing status word so fatal error */
         p_printf("***Stray status error***");
         break;
         }
      }
   p_close(timH);
   }

LOCAL_C VOID CheckMemory(TEXT *str)
   {
   VOID *Heap;
   INT fbytes;

   fbytes=p_allspc(&Heap);
   p_print("\n\t%s\r\n",str);
   p_print("Free Heap Memory =>\r\n\t%x bytes\r\n",fbytes);
   p_print("Free Segments =>\r\n\t%d\r\n",p_sgfree());
   p_getch();
   }

LOCAL_C VOID MemoryTest(VOID)
   {
   CheckMemory("OpenPort");
   ClosePort();
   CheckMemory("ClosedPort");
   UnloadLdd();
   CheckMemory("UnoadedLdd");
   LoadLdd();
   CheckMemory("LoadLdd");
   OpenPort();
   CheckMemory("OpenPort");
   p_printf("End of Memory Test");
   }

GLDEF_C VOID main(VOID)
/*
*/
   {
   INT ret,set=0;

   PrintHeader();
   LoadLdd();
   OpenPort();
Start:
   PrintInstructions();
   if ((ret=p_getch())=='0')
      AlternateFlash();
   else if (ret=='1')
      AsynchRead();
   else if (ret=='2')
      SensePort();
   else if (ret=='3')
      {
      while (set>=0)
         set=SetPort();
      set=0;
      }
   else if (ret=='4')
      MemoryTest();
   else if (ret=='q')
      {
      ClosePort();
      UnloadLdd();
      p_exit(0);
      }
   else
      goto Start;
   goto Start;
   }






                    
