From: Pat Thoyts Date: Thu, 5 Nov 2009 14:08:42 +0000 (+0000) Subject: Merged contributions for serial mode and bit-bang mode settings. X-Git-Url: http://privyetmir.co.uk/gitweb.cgi?a=commitdiff_plain;h=5255c17a955144a4ffa1794f3746698e94995f37;p=tclftd2xx Merged contributions for serial mode and bit-bang mode settings. Signed-off-by: Pat Thoyts --- 5255c17a955144a4ffa1794f3746698e94995f37 diff --cc makefile.vc index 984ade1,ceb32e9..fb6c839 --- a/makefile.vc +++ b/makefile.vc @@@ -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 a7efb39,8e244e7..ed592f4 --- a/tclftd2xx.c +++ b/tclftd2xx.c @@@ -1,7 -1,4 +1,8 @@@ -/* tclftd2xx.c - Copyright (C) 2008 Pat Thoyts +/* tclftd2xx.c - + * + * Copyright (C) 2008 Pat Thoyts + * 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) { @@@ -461,43 -349,17 +472,54 @@@ 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) {