moved tinitalk to device/examples/ds390
authorbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 18 Jan 2003 23:47:14 +0000 (23:47 +0000)
committerbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 18 Jan 2003 23:47:14 +0000 (23:47 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2158 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
device/examples/ds390/tinitalk/Makefile [new file with mode: 0644]
device/examples/ds390/tinitalk/Makefile.bcc [new file with mode: 0644]
device/examples/ds390/tinitalk/tinitalk.c [new file with mode: 0755]
device/examples/ds390/tinitalk/tinitalk.dsp [new file with mode: 0644]
device/examples/ds390/tinitalk/tinitalk.dsw [new file with mode: 0644]
device/examples/ds390/tinitalk/tinitalk.h [new file with mode: 0644]

index e018817555b0978caa86e0e9bf4e9718b771a0f0..922d9acd8b37c6c469f813f9e0ea2ca0b4fe157e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2003-01-19  Bernhard Held <bernhard@bernhardheld.de>
+
+        * moved tinitalk to device/examples/ds390
+
 2003-01-14  Bernhard Held <bernhard@bernhardheld.de>
 
        * as/mcs51/lkmem.c: rflag is for DS390
diff --git a/device/examples/ds390/tinitalk/Makefile b/device/examples/ds390/tinitalk/Makefile
new file mode 100644 (file)
index 0000000..d4bd41f
--- /dev/null
@@ -0,0 +1,8 @@
+CFLAGS=-Wall -g
+
+tinitalk: tinitalk.c tinitalk.h
+       cc -o $@ $(CFLAGS) $<
+       cp $@ /usr/local/bin
+
+clean:
+       rm -f core *~ *.o tinitalk \#*
diff --git a/device/examples/ds390/tinitalk/Makefile.bcc b/device/examples/ds390/tinitalk/Makefile.bcc
new file mode 100644 (file)
index 0000000..57dcf80
--- /dev/null
@@ -0,0 +1,18 @@
+PRJDIR         = ..
+
+OBJECTS         = tinitalk.obj
+
+TARGET          = tinitalk.exe
+
+# Compiling entire program or any subproject
+# ------------------------------------------
+all: $(TARGET)
+
+
+# My rules
+# --------
+$(TARGET): $(OBJECTS)
+        bcc32 -e$(TARGET) $(OBJECTS)
+
+!include ..\Bcc.inc
+
diff --git a/device/examples/ds390/tinitalk/tinitalk.c b/device/examples/ds390/tinitalk/tinitalk.c
new file mode 100755 (executable)
index 0000000..581a7dd
--- /dev/null
@@ -0,0 +1,848 @@
+/*-------------------------------------------------------------------------
+  tinitalk.c - A tini utility to download files to TINI and talk to it
+  
+  Written By - Johan Knol johan.knol@iduna.nl
+  
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+  
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+  
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  
+  In other words, you are welcome to use, share and improve this program.
+  You are forbidden to forbid anyone else to use, share and improve
+  what you give them.   Help stamp out software-hoarding!  
+  -------------------------------------------------------------------------*/
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+#define TINI_PORT "COM2"
+#else
+#ifdef linux
+// must be linux
+#define TINI_PORT "/dev/ttyS0"
+#else
+// could be solaris
+#define TINI_PORT "/dev/term/a"
+#endif
+#endif
+#define TINI_BAUD 115200
+#define TINI_ESCAPE_CHAR 0x1b
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <fcntl.h>
+
+#if !defined( _MSC_VER) && !defined(__BORLANDC__)
+#include <unistd.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#else
+#include <conio.h>
+#include <windows.h>
+#define sleep(ms) Sleep((ms*1000))
+#define usleep(us) Sleep((us/1000))
+#endif
+
+#include "tinitalk.h"
+
+char *programName;
+char escapeChar = 0;
+char *port = NULL;
+int baud = 0, appBaud = 0;
+
+void
+Usage ()
+{
+  fprintf (stderr, "usage: %s <options> command [args] \n", programName);
+  fprintf (stderr, "\nwhere options are:\n");
+  fprintf (stderr, "  <-p port> set the serial port, defaults to %s\n", TINI_PORT);
+  fprintf (stderr, "  <-b baud> set the baud rate, defaults to %d\n", TINI_BAUD);
+  fprintf (stderr, "  <-B baud> set the baud rate for the application\n");
+  fprintf (stderr, "  <-c> connect to tini after command (if any)\n");
+  fprintf (stderr, "  <-e #> to set the escape char\n");
+  fprintf (stderr, "  <-s> to see some examples.\n");
+  fprintf (stderr, "\nand commands are:\n");
+  fprintf (stderr, "  <load file> load a hex file and restart the bootloader\n");
+  fprintf (stderr, "  <execute [file]> load a hex file and/or start the program in bank 1\n");
+  exit (1);
+}
+
+void
+Examples ()
+{
+  printf ("\n");
+  printf ("%s -p /dev/ttyS1\n", programName);
+  printf ("    now you are talking to the bootloader through serial-1\n");
+  printf ("%s -b 19200\n", programName);
+  printf ("    now you are talking to the bootloader at 19200 baud\n");
+  printf ("%s load tini.hex\n", programName);
+  printf ("    load tini.hex\n");
+  printf ("%s -c load tini.hex\n", programName);
+  printf ("    after loading tini.hex you are talking to the bootloader\n");
+  printf ("%s execute tini.hex\n", programName);
+  printf ("    load tini.hex and start the program in bank 1\n");
+  printf ("%s -c execute tini.hex\n", programName);
+  printf ("    after loading the file you are talking to the (restarted)\n");
+  printf ("    program in bank 1\n");
+  printf ("%s execute\n", programName);
+  printf ("    now the program in bank 1 is restarted.\n");
+  printf ("%s -c execute\n", programName);
+  printf ("    now you are talking to the (restarted) program in bank 1\n");
+  printf ("%s -b 115200 -B 9600 -c execute tini.hex\n", programName);
+  printf ("    download tini.hex at 115200 baud, but talk the program at 9600 baud\n");
+  exit (0);
+}
+
+int
+main (int argc, char **argv)
+{
+  int connect = 0;
+  char command[64];
+
+  int arg = 1;
+
+  //programName=argv[0];
+  programName = "tinitalk";
+
+  // process options
+  while (arg < argc && argv[arg][0] == '-')
+    {
+
+      // no arguments required
+      if (argv[arg][1] == 'c')
+       {
+         connect = 1;
+         arg++;
+         continue;
+       }
+      else if (argv[arg][1] == 's')
+       {
+         Examples ();
+         // will not return
+       }
+      // argument required
+      if (arg >= (argc - 1))
+       {
+         Usage ();
+       }
+      switch (argv[arg][1])
+       {
+       case 'p':
+         port = argv[arg + 1];
+         break;
+       case 'b':
+         baud = atoi (argv[arg + 1]);
+         break;
+       case 'B':
+         appBaud = atoi (argv[arg + 1]);
+         break;
+       case 'e':
+         escapeChar = atoi (argv[arg + 1]);
+         break;
+       default:
+         Usage ();
+       }
+      arg += 2;
+    }
+
+  if (port == NULL)
+    {
+      if ((port = getenv ("TINI_PORT")) == NULL)
+       {
+         port = TINI_PORT;
+       }
+    }
+  if (baud == 0)
+    {
+      if (getenv ("TINI_BAUD"))
+       {
+         baud = atoi (getenv ("TINI_BAUD"));
+       }
+      else
+       {
+         baud = TINI_BAUD;
+       }
+    }
+  if (escapeChar == 0)
+    {
+      if (getenv ("TINI_ESCAPE_CHAR"))
+       {
+         escapeChar = atoi (getenv ("TINI_ESCAPE_CHAR"));
+       }
+      else
+       {
+         escapeChar = TINI_ESCAPE_CHAR;
+       }
+    }
+  if (appBaud == 0)
+    {
+      appBaud = baud;
+    }
+  if (!TiniOpen (port, baud))
+    {
+      exit (1);
+    }
+  // process commands
+  while (arg < argc)
+    {
+      if (strcmp (argv[arg], "load") == 0)
+       {
+         // argument required
+         if (arg >= (argc - 1))
+           {
+             Usage ();
+           }
+         if (LoadHexFile (argv[arg + 1]))
+           {
+             TiniReset (1);
+             if (connect)
+               {
+                 TiniConnect (baud);
+               }
+           }
+         exit (0);
+       }
+      if (strcmp (argv[arg], "execute") == 0)
+       {
+         // argument supplied?
+         if (arg < (argc - 1))
+           {
+             if (!LoadHexFile (argv[arg + 1]))
+               {
+                 exit (0);
+               }
+           }
+         TiniReset (0);
+         if (connect)
+           {
+             TiniConnect (appBaud);
+           }
+         exit (0);
+       }
+      // unsupported command
+      Usage ();
+    }
+
+  // no commands, just connect
+
+  // on my linux box, DTR is always set after opening the port, so:
+  // reset the bootloader
+
+  strcpy (command, "r");
+
+  while (1)
+    {
+      switch (tolower (command[0]))
+       {
+       case '?':
+       case '\n':
+       case 'h':
+         printf ("\n");
+         printf ("r - reset, start bootloader and connect to TINI\n");
+         printf ("e - reset, start program in bank 1 and connect to TINI\n");
+         printf ("c - connect to TINI.\n");
+         printf ("l - load file.\n");
+         printf ("s - save file.\n");
+         printf ("q - quit.\n");
+         break;
+       case 'e':
+         TiniReset (0);
+         TiniConnect (appBaud);
+         break;
+       case 'r':
+         TiniReset (1);
+         TiniConnect (baud);
+         break;
+       case 'c':
+         // leave it as it was
+         TiniConnect (0);
+         break;
+       case 'l':
+         {
+           char fileName[FILENAME_MAX] = "";
+           printf ("Enter filename: ");
+           fflush (stdout);
+           fgets (fileName, FILENAME_MAX, stdin);
+           // remove the EOL character
+           fileName[strlen (fileName) - 1] = 0;
+           LoadHexFile (fileName);
+         }
+         break;
+       case 's':
+         printf ("Command \"%c\" not implemented yet.\n", command[0]);
+         break;
+       case 'q':
+         return 0;
+         break;
+       default:
+         printf ("Unknown command: \"%c\".\n", command[0]);
+         break;
+       }
+      printf ("\n<%s> ", programName);
+      fflush (stdout);
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+      // don't know why
+      getch ();
+#endif
+      fgets (command, 64, stdin);
+    }
+  return 0;
+}
+
+int
+LoadHexFile (char *path)
+{
+  FILE *hexFile;
+  char hexLine[256];
+  int bank = 0;
+  int line = 0, type;
+  char tempString[16];
+  char c, ctrlC = 0x03;
+  int bytesLoaded = 0, progress = 0;
+  char banksZapped[8] =
+  {0, 0, 0, 0, 0, 0, 0, 0};
+  unsigned int address, bytes, i;
+  unsigned int checksum, chk;
+
+  if ((hexFile = fopen (path, "r")) == NULL)
+    {
+      perror (path);
+      return 0;
+    }
+  TiniFlush ();
+
+  while (fgets (hexLine, 256, hexFile))
+    {
+
+      if (TiniRead (&c, 1) == 1)
+       {
+         // show error messages from TINI
+         printf ("\n");
+         do
+           {
+             putchar (c);
+           }
+         while (TiniRead (&c, 1) == 1);
+
+         printf ("\nInterrupted by loader.\n");
+         return 0;
+       }
+      line++;
+
+      if (hexLine[0] != ':' ||
+         sscanf (&hexLine[1], "%02x", &bytes) != 1 ||
+         sscanf (&hexLine[3], "%04x", &address) != 1 ||
+         sscanf (&hexLine[7], "%02x", &type) != 1)
+       {
+         printf ("Invalid ihx record: \"%s\"\n", hexLine);
+         TiniReset (1);
+         return 0;
+       }
+      // make sure line ends with '\r' or TINI won't swallow it
+      hexLine[strlen (hexLine) - 1] = '\r';
+
+      address += bank << 16;
+
+      // test checksum
+      checksum = 0;
+      for (i = 0; i < bytes + 5; i++)
+       {
+         sscanf (&hexLine[i * 2 + 1], "%02x", &chk);
+         checksum += chk;
+       }
+      if (checksum & 0xff)
+       {
+         printf ("\nChecksum error at %06x (0x%02x!=0) in line: %d\n",
+                 address, checksum&0xff, line);
+         TiniReset (1);
+         return 0;
+       }
+      if (type == 4)
+       {
+         // new Hex386 record
+         sscanf (&hexLine[9], "%04x", &bank);
+         address = (address & 0xffff) + (bank << 16);
+         // just for safety
+         if (bank == 0)
+           {
+             printf ("==> No overwrite of bank 0 <==\n");
+             return 0;
+           }
+         if (0)
+           {
+             // interupt loader
+             TiniWriteAndWait (&ctrlC, 1, '>');
+           }
+         else
+           {
+             // reset TINI
+             TiniReset (1);
+           }
+         if (!banksZapped[bank])
+           {
+             // zap bank
+             sprintf (tempString, "z%d\r", bank);
+             TiniWriteAndWait (tempString, 3, '?');
+             TiniWriteAndWait ("y", 1, '\n');
+             printf ("[Zapping bank %d]\n", bank);
+             TiniWait ('>');
+             banksZapped[bank] = 1;
+             // start loader
+             //printf ("[Starting loader]\n");
+           }
+         TiniWriteAndWait ("l\r", 2, '\n');
+         printf ("[Loading bank %d]\n", bank);
+       }
+      if (bank > 0)
+       {
+         if ((type == 0) && (1 || ((bytesLoaded / 1024) > progress)))
+           {
+             progress = bytesLoaded / 1024;
+             printf ("[%06x: sent %d bytes]\r", address, bytesLoaded);
+             fflush (stdout);
+           }
+         bytesLoaded += bytes;
+
+         //printf ("data: %s\n", hexLine);
+         TiniWrite ("            ", 12);
+         TiniWrite (hexLine, strlen (hexLine));
+         TiniDrain ();
+       }
+      else
+       {
+         //printf ("skip: %s\n", hexLine);
+       }
+    }
+  TiniWriteAndWait ("\r", 1, '>');
+  printf ("\n[Load succesfull]\n");
+  fclose (hexFile);
+  return 1;
+}
+
+int
+SaveFile (char *path)
+{
+  printf ("Saving file: %s\n", path);
+  return 1;
+}
+
+/*
+   this is the io part 
+ */
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+HANDLE tiniHandle;
+DCB tiniDcb;
+#else
+static int tini_fd;
+static int tini_status;
+static struct termios tini_options;
+#endif
+
+static int initflag = 0;
+
+int
+TiniOpen (char *port, int baud)
+{
+
+  if (initflag)
+    {
+      return 1;
+    }
+  printf ("[Opening \"%s\" at \"%d\" baud, escape is 0x%02x]\n",
+         port, baud, escapeChar);
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+  if ((tiniHandle = CreateFile (port, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+                            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) ==
+      INVALID_HANDLE_VALUE)
+#else
+  if ((tini_fd = open (port, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0)
+#endif
+    {
+      fprintf (stderr, "%s: unable to open port %s - ",
+              "TiniOpen", port);
+      perror("");
+      return 0;
+    }
+  // configure the serial port
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+  tiniDcb.DCBlength = sizeof (DCB);
+  if (GetCommState (tiniHandle, &tiniDcb) != TRUE)
+    {
+      fprintf (stderr, "%s: unable to query port %s\n",
+              "TiniOpen", port);
+      TiniClose ();
+      return 0;
+    }
+  tiniDcb.StopBits = 0;
+  tiniDcb.ByteSize = 8;
+  tiniDcb.Parity = 0;
+  tiniDcb.fDtrControl = DTR_CONTROL_DISABLE;
+  tiniDcb.fRtsControl = RTS_CONTROL_DISABLE;
+  tiniDcb.fOutxCtsFlow = FALSE;
+  tiniDcb.fOutX = FALSE;
+  tiniDcb.fInX = FALSE;
+  if (SetCommState (tiniHandle, &tiniDcb) != TRUE)
+    {
+      fprintf (stderr, "%s: unable to configure port %s\n",
+              "TiniOpen", port);
+      TiniClose ();
+      return 0;
+    }
+  // reset DTR
+  EscapeCommFunction (tiniHandle, CLRDTR);
+#else
+  if (ioctl (tini_fd, TIOCMGET, &tini_status))
+    {
+      perror ("0: ioctl(tini_fd, TIOCMGET, &tini_status) - ");
+      TiniClose ();
+      return 0;
+    }
+  // reset DTR
+  tini_status &= ~TIOCM_DTR;
+  if (ioctl (tini_fd, TIOCMSET, &tini_status))
+    {
+      perror ("2: ioctl(tini_fd, TIOCMSET, &tini_status) - ");
+      TiniClose ();
+      return 0;
+    }
+  tcgetattr (tini_fd, &tini_options);
+  tini_options.c_cflag |= (CLOCAL | CREAD);
+  tini_options.c_lflag &= ~(ISIG | ICANON | ECHO);
+  tini_options.c_iflag |= (IGNCR);
+  tini_options.c_cc[VMIN] = 0;
+  tini_options.c_cc[VTIME] = 0;
+  tcsetattr (tini_fd, TCSANOW, &tini_options);
+#endif
+
+  if (!TiniBaudRate (baud))
+    {
+      TiniClose ();
+      return 0;
+    }
+  initflag = 1;
+  return 1;
+}
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+#define B9600 CBR_9600
+#define B19200 CBR_19200
+#define B38400 CBR_38400
+#define B57600 CBR_57600
+#define B115200 CBR_115200
+#endif
+
+int
+TiniBaudRate (int baud)
+{
+  int baudB;
+
+  switch (baud)
+    {
+    case 9600:
+      baudB = B9600;
+      break;
+    case 19200:
+      baudB = B19200;
+      break;
+    case 38400:
+      baudB = B38400;
+      break;
+    case 57600:
+      baudB = B57600;
+      break;
+    case 115200:
+      baudB = B115200;
+      break;
+    default:
+      fprintf (stderr, "%s: illegal baudrate: \"%d\"\n", programName, baud);
+      return 0;
+    }
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+  tiniDcb.BaudRate = baudB;
+  SetCommState (tiniHandle, &tiniDcb);
+#else
+  cfsetispeed (&tini_options, baudB);
+  cfsetospeed (&tini_options, baudB);
+  tcsetattr (tini_fd, TCSANOW, &tini_options);
+#endif
+
+  return 1;
+}
+
+int
+TiniReset (int toBootLoader)
+{
+
+  // set DTR
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+  EscapeCommFunction (tiniHandle, SETDTR);
+#else
+  tini_status |= TIOCM_DTR;
+  if (ioctl (tini_fd, TIOCMSET, &tini_status))
+    {
+      perror ("1: ioctl(tini_fd, TIOCMSET, &tini_status) - ");
+      return 0;
+    }
+#endif
+
+  // wait for 100ms
+  usleep (100000);
+
+  // drain input and output buffers
+  TiniDrain ();
+
+  // reset DTR
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+  EscapeCommFunction (tiniHandle, CLRDTR);
+#else
+  tini_status &= ~TIOCM_DTR;
+  if (ioctl (tini_fd, TIOCMSET, &tini_status))
+    {
+      perror ("2: ioctl(tini_fd, TIOCMSET, &tini_status) - ");
+      return 0;
+    }
+#endif
+
+  // wait for 100ms
+  usleep (100000);
+
+  if (TiniWrite ("\r", 1) != 1)
+    {
+      fprintf (stderr, "TiniReset: couldn't write to tini\n");
+      return 0;
+    }
+  // wait for the bootloader prompt
+  // we should build a timeout here
+  TiniWait ('>');
+
+  if (toBootLoader)
+    {
+      return 1;
+    }
+  TiniWriteAndWait ("E\r", 2, 'E');
+  return 1;
+}
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+// read as much character as available, at most n
+int
+TiniRead (char *buffer, int n)
+{
+  int count;
+  int status;
+  COMSTAT tiniComStat;
+
+  ClearCommError (tiniHandle, &status, &tiniComStat);
+  if (tiniComStat.cbInQue < (unsigned int) n)
+    {
+      n = tiniComStat.cbInQue;
+    }
+  ReadFile (tiniHandle, buffer, n, &count, NULL);
+
+  return count;
+}
+
+int
+TiniWrite (char *buffer, int n)
+{
+  int count;
+  WriteFile (tiniHandle, buffer, n, &count, NULL);
+  return count;
+}
+#else
+int
+TiniRead (char *buffer, int n)
+{
+  return read (tini_fd, buffer, n);
+}
+
+int
+TiniWrite (char *buffer, int n)
+{
+  return write (tini_fd, buffer, n);
+}
+#endif
+
+// wait for the prompChar
+int
+TiniWait (char promptChar)
+{
+  char c;
+  while (1)
+    {
+      switch (TiniRead (&c, 1))
+       {
+       case 0:         // no char available
+         // give up our time slice
+
+         sleep (0);
+         break;
+       case 1:         // one char read
+
+         putchar (c);
+         fflush (stdout);
+         if (c == promptChar)
+           {
+             return 1;
+           }
+         break;
+       default:                // some error
+
+         perror ("TiniWait: ");
+         return 0;
+         break;
+       }
+    }
+}
+
+// send the buffer and wait for the promptChar
+int
+TiniWriteAndWait (char *buffer, int n, char promptChar)
+{
+  char bytes = TiniWrite (buffer, n);
+  TiniWait (promptChar);
+  return bytes;
+}
+
+// flush input and output buffers (wait for it)
+void
+TiniFlush ()
+{
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+  FlushFileBuffers (tiniHandle);
+#else
+  // flush the buffers, isn't there a simpler way?
+  tcsetattr (tini_fd, TCSAFLUSH, &tini_options);
+#endif
+}
+
+// drain input and output buffers (forget it)
+void
+TiniDrain ()
+{
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+  PurgeComm (tiniHandle, PURGE_TXCLEAR | PURGE_RXCLEAR);
+#else
+  // drain the buffers, isn't there a simpler way?
+  tcsetattr (tini_fd, TCSADRAIN, &tini_options);
+#endif
+}
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+void
+TiniConnect (int baud)
+{
+  char c;
+
+  if (baud)
+    {
+      TiniBaudRate (baud);
+    }
+
+  while (1)
+    {
+      if (TiniRead (&c, 1))
+       {
+         // char from TINI, high priority
+         putchar (c);
+         fflush (stdout);
+       }
+      else if (kbhit ())
+       {
+         // char from console, low priotity
+         if ((c = getch ()) == escapeChar)
+           {
+             // escape from connect?
+             printf ("<ESC>");
+             break;
+           }
+         TiniWrite (&c, 1);
+       }
+      else
+       {
+         // nothing to do, so give up our timeslice
+         sleep (0);
+       }
+    }
+}
+#else
+void
+TiniConnect (int baud)
+{
+  struct termios options, consoleOptions;
+  int consoleFlags;
+  char c;
+  int fno;
+
+  if (baud)
+    {
+      TiniBaudRate (baud);
+    }
+
+  // set stdin to nonblocking IO, noecho
+  fno = fileno (stdin);
+  consoleFlags = fcntl (fno, F_GETFL);
+  fcntl (fno, F_SETFL, consoleFlags | O_NONBLOCK);
+
+  tcgetattr (fno, &consoleOptions);
+  options = consoleOptions;
+  options.c_lflag &= ~(ISIG | ICANON | ECHO);
+  tcsetattr (fno, TCSANOW, &options);
+
+  while (1)
+    {
+      if (TiniRead (&c, 1) == 1)
+       {
+         // char from TINI, high priority
+         putchar (c);
+       }
+      else if ((c = getchar ()) != EOF)
+       {
+         // char from console, low priority
+         if (c == escapeChar)
+           {
+             // escape from connect?
+             break;
+           }
+         if (c == '\n')
+           {
+             c = '\r';
+           }
+         TiniWrite (&c, 1);
+       }
+      else
+       {
+         // nothing to do, so give up our timeslice
+         sleep (0);
+       }
+    }
+
+  // reset stdin
+  fcntl (fno, F_SETFL, consoleFlags);
+  tcsetattr (fno, TCSANOW, &consoleOptions);
+}
+#endif
+
+void
+TiniClose (void)
+{
+  initflag = 0;
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+  CloseHandle (tiniHandle);
+#else
+  close (tini_fd);
+#endif
+}
diff --git a/device/examples/ds390/tinitalk/tinitalk.dsp b/device/examples/ds390/tinitalk/tinitalk.dsp
new file mode 100644 (file)
index 0000000..c9f38f9
--- /dev/null
@@ -0,0 +1,88 @@
+# Microsoft Developer Studio Project File - Name="tinitalk" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=tinitalk - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "tinitalk.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "tinitalk.mak" CFG="tinitalk - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "tinitalk - Win32 Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "tinitalk - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "tinitalk - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x413 /d "NDEBUG"
+# ADD RSC /l 0x413 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "tinitalk - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x413 /d "_DEBUG"
+# ADD RSC /l 0x413 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "tinitalk - Win32 Release"
+# Name "tinitalk - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\tinitalk.c
+# End Source File
+# End Target
+# End Project
diff --git a/device/examples/ds390/tinitalk/tinitalk.dsw b/device/examples/ds390/tinitalk/tinitalk.dsw
new file mode 100644 (file)
index 0000000..67b9216
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "tinitalk"=.\tinitalk.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/device/examples/ds390/tinitalk/tinitalk.h b/device/examples/ds390/tinitalk/tinitalk.h
new file mode 100644 (file)
index 0000000..9f8b0db
--- /dev/null
@@ -0,0 +1,16 @@
+extern char *globalStringSpace;
+
+extern int TiniOpen(char *argPort, int argBaud);
+extern int TiniBaudRate(int baud);
+extern int TiniReset(int toBootLoader);
+extern int TiniRead(char*, int);
+extern int TiniWrite(char*, int);
+extern int TiniWait(char promptChar);
+extern int TiniWriteAndWait(char *buffer, int n, char promptChar);
+extern void TiniFlush(void);
+extern void TiniDrain(void);
+extern void TiniConnect(int baud);
+extern void TiniClose(void);
+
+extern int LoadHexFile(char *path);
+extern int SaveHexFile(char *path);