Merged contributions for serial mode and bit-bang mode settings.
authorPat Thoyts <patthoyts@users.sourceforge.net>
Thu, 5 Nov 2009 14:08:42 +0000 (14:08 +0000)
committerPat Thoyts <patthoyts@users.sourceforge.net>
Thu, 5 Nov 2009 14:08:42 +0000 (14:08 +0000)
Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
1  2 
makefile.vc
tclftd2xx.c

diff --cc makefile.vc
index 984ade194d741ea86654abd82cb1c610fa8fc501,ceb32e971249487570873be4080178f72ca7ff02..fb6c839689f3d2f7359e327644a40048dc380fa7
@@@ -164,7 -164,7 +164,7 @@@ PROJECT = tclftd2x
  #PROJECT_REQUIRES_TK=1
  !include "rules.vc"
  
- DOTVERSION      = 1.1.0
 -DOTVERSION      = 1.0.2
++DOTVERSION      = 1.2.0
  VERSION         = $(DOTVERSION:.=)
  STUBPREFIX      = $(PROJECT)stub
  
diff --cc tclftd2xx.c
index a7efb39a66c84fb2193399bf6f365314b97633de,8e244e7c7694e9926de47beb4acc7c0855d7231a..ed592f44f5f5f5cdfddde6dc14f576001a46d55c
@@@ -1,7 -1,4 +1,8 @@@
 -/* tclftd2xx.c - Copyright (C) 2008 Pat Thoyts <patthoyts@users.sourceforge.net>
 +/* tclftd2xx.c - 
 + *
 + *   Copyright (C) 2008 Pat Thoyts <patthoyts@users.sourceforge.net>
 + *   Copyright (C) 2008 Leopold Gerlinger
++ *   Copyright (C) 2009 Lars Unger
   *
   *    FTDI D2XX USB Device driver Tcl interface.
   *
@@@ -293,110 -280,12 +298,116 @@@ ChannelSetOption(ClientData instance, T
        if (r == TCL_OK) {
            fts = procs.FT_SetLatencyTimer(instPtr->handle, (UCHAR)tmp);
        }
+     } else if (!strcmp("-bitmode", optionName)) {
+       int tmp = 1;
+       r = Tcl_GetInt(interp, newValue, &tmp);
+       if (r == TCL_OK) {
+           fts = procs.FT_SetBitMode(instPtr->handle, (UCHAR)(tmp >> 8), (UCHAR)(tmp & 0xff));
+       }
 +    } else if (!strcmp("-mode", optionName)) {
 +      int baudrate = 19200, databits = 8, stop = 1;
 +      char parity = 'n';
 +      unsigned char wordlen = FT_BITS_8, stopbits = FT_STOP_BITS_1;
 +
 +      sscanf(newValue, "%d,%c,%d,%d", &baudrate, &parity, &databits, &stop);
 +
 +      switch (databits) {
 +          case 8: wordlen = FT_BITS_8; break;
 +          case 7: wordlen = FT_BITS_7; break;
 +          case 6: wordlen = FT_BITS_6; break;
 +          case 5: wordlen = FT_BITS_5; break;
 +          default:
 +              Tcl_AppendResult(interp, "bad data value \"", newValue, 
 +                  "\": must be 5, 6, 7 or 8.", NULL);
 +              return TCL_ERROR;
 +      }
 +
 +      switch (stop) {
 +          case 1: stopbits = FT_STOP_BITS_1; break;
 +          case 2: stopbits = FT_STOP_BITS_2; break;
 +          default:
 +              Tcl_AppendResult(interp, "bad stop value \"", newValue,
 +                  "\"must be either 1 or 2.", NULL);
 +              return TCL_ERROR;
 +      }
 +
 +      switch (parity) {
 +          case 'n': parity = FT_PARITY_NONE; break;
 +          case 'o': parity = FT_PARITY_ODD; break;
 +          case 'e': parity = FT_PARITY_EVEN; break;
 +          case 'm': parity = FT_PARITY_MARK; break;
 +          case 's': parity = FT_PARITY_SPACE; break;
 +          default:
 +              Tcl_AppendResult(interp, "bad parity value \"", newValue,
 +                  "\": must be one of n, o, e, m, or s.", NULL);
 +              return TCL_ERROR;
 +      }
 +
 +      fts = procs.FT_SetBaudRate(instPtr->handle, baudrate);
 +      if (fts != FT_OK) {
 +          Tcl_AppendResult(interp, "failed set baudrate: \"",
 +                           ConvertError(fts), NULL);
 +          return TCL_ERROR;
 +      }
 +
 +      fts = procs.FT_SetDataCharacteristics(instPtr->handle, wordlen, stopbits, parity);
 +      if (fts == FT_OK) {
 +          instPtr->baudrate = baudrate;
 +          instPtr->databits = wordlen;
 +          instPtr->stopbits = stopbits;
 +          instPtr->parity = parity;
 +      }
 +    } else if (!strcmp("-handshake", optionName)) {
 +      unsigned short handshake = 0xFFFF;
 +      if (!strcmp(newValue,"none")) {
 +          handshake = FT_FLOW_NONE;
 +      } else if (!strcmp(newValue,"rtscts")) {
 +          handshake = FT_FLOW_RTS_CTS;
 +      } else if (!strcmp(newValue,"dtrdsr")) {
 +          handshake = FT_FLOW_DTR_DSR;
 +      } else if (!strcmp(newValue,"xonxoff")) {
 +          handshake = FT_FLOW_XON_XOFF;
 +      } else {
 +          Tcl_AppendResult(interp, "bad value \"", newValue, "\" for ", optionName,
 +              ": must be one of none, rtscts, dtrdsr or xonxoff", NULL);
 +          return TCL_ERROR;
 +      }
 +      fts = procs.FT_SetFlowControl(instPtr->handle, handshake, instPtr->xonchar, instPtr->xoffchar);
 +      if (fts == FT_OK) {
 +          instPtr->handshake = handshake;
 +      }
 +    } else if (!strcmp("-xchar", optionName)) {
 +      int xrgc, n;
 +      char xonxoff[2];
 +      const char **xrgv;
 +      if (Tcl_SplitList(interp, newValue, &xrgc, &xrgv) != TCL_OK) {
 +          return TCL_ERROR;
 +      }
 +      if (xrgc != 2) {
 +      badxchar:
 +          Tcl_AppendResult(interp, "bad value for -xchar: must be a list of two elements", NULL);
 +          return TCL_ERROR;
 +      }
 +      for (n = 0; n < 2; ++n) {
 +          /* check for extended utf-8 and handle like tcl serial channel */
 +          if (xrgv[n][0] & 0x80) {
 +              Tcl_UniChar c;
 +              int len;
 +              len = Tcl_UtfToUniChar(xrgv[n], &c);
 +              if (xrgv[n][len]) {
 +                  goto badxchar;
 +              }
 +              xonxoff[n] = (char)c;
 +          } else {
 +              xonxoff[n] = xrgv[n][0];
 +          }
 +      }
 +
 +      fts = procs.FT_SetFlowControl(instPtr->handle, instPtr->handshake, xonxoff[0], xonxoff[1]);
 +      if (fts == FT_OK) {
 +          instPtr->xonchar = xonxoff[0];
 +          instPtr->xoffchar = xonxoff[1];
 +      }
      }
  
      if (fts != FT_OK) {
@@@ -419,8 -308,7 +430,8 @@@ ChannelGetOption(ClientData instance, T
                 const char *optionName, Tcl_DString *optionValue)
  {
      Channel *instPtr = instance;
 -    const char *options[] = {"readtimeout", "writetimeout", "latency", "bitmode", NULL};
 +    const char *options[] = {"readtimeout", "writetimeout", "latency",
-                            "mode", "handshake", "xchar", NULL};
++                           "bitmode", "mode", "handshake", "xchar", NULL};
      int r = TCL_OK;
  
      if (optionName == NULL) {
                                 ConvertError(fts), NULL);
                r = TCL_ERROR;
            }
+       } else if (!strcmp("-bitmode", optionName)) {
+           UCHAR bmode = 0;
+           fts = procs.FT_GetBitMode(instPtr->handle, &bmode);
+           if (fts == FT_OK) {
+               Tcl_DStringSetLength(&ds, TCL_INTEGER_SPACE);
+               sprintf(Tcl_DStringValue(&ds), "%d", bmode);
+           } else {
+               Tcl_AppendResult(interp, "failed to read ", optionName, ": ",
+                                ConvertError(fts), NULL);
+               r = TCL_ERROR;
+           }
 +      } else if (!strcmp("-mode", optionName)) {
 +          char parity = 0;
 +          switch (instPtr->parity) {
 +              case FT_PARITY_NONE:  parity = 'n'; break;
 +              case FT_PARITY_ODD:   parity = 'o'; break;
 +              case FT_PARITY_EVEN:  parity = 'e'; break;
 +              case FT_PARITY_MARK:  parity = 'm'; break;
 +              case FT_PARITY_SPACE: parity = 's'; break;
 +              default:              parity = '?';
 +          }
 +          Tcl_DStringSetLength(&ds, TCL_INTEGER_SPACE * 3 + 6);
 +          sprintf(Tcl_DStringValue(&ds), "%d,%c,%d,%d",
 +                  instPtr->baudrate, parity, instPtr->databits,
 +                  (instPtr->stopbits == FT_STOP_BITS_1) ? 1 : 2);
 +      } else if (!strcmp("-handshake", optionName)) {
 +          switch (instPtr->handshake) {
 +              case FT_FLOW_NONE:
 +                  Tcl_DStringAppend(&ds, "none", 4);
 +                  break;
 +              case FT_FLOW_RTS_CTS:
 +                  Tcl_DStringAppend(&ds, "rtscts", 6);
 +                  break;
 +              case FT_FLOW_DTR_DSR:
 +                  Tcl_DStringAppend(&ds, "dtrdsr", 6);
 +                  break;
 +              case FT_FLOW_XON_XOFF:
 +                  Tcl_DStringAppend(&ds, "xonxoff", 7);
 +                  break;
 +              default:
 +                  Tcl_DStringAppend(&ds, "unknown", 7);
 +          }
 +      } else if (!strcmp("-xchar", optionName)) {
 +          char cbuf[2] = {0, 0};
 +          cbuf[0] = instPtr->xonchar;
 +          Tcl_DStringAppendElement(&ds, cbuf);
 +          cbuf[0] = instPtr->xoffchar;
 +          Tcl_DStringAppendElement(&ds, cbuf);
        } else {
            const char **p;
            for (p = options; *p != NULL; ++p) {