In an ongoing effort to get TzMax working, I've been fighting to get it to talk to the device through the COM port. The problem is that the device (a wrist-watch...the program is used to download heart-rate data from said watch) is very difficult to comunicate with. In theory it is quite simple: send a 'ping' command, wait for a response, then send the 'receive' command, and read the data. In practice, getting the watch to acknowledge the initial ping is challenging. You need to repetitively send the 'ping' at odd intervals until the watch responds. Once it does, it will respond to commands readily.
In any case, it turns out that one of the many requirements to get the watch to respond is to have DTR disabled (done by setting fDtrControl = DTR_CONTROL_DISABLE). But apparently the default for linux is DTR_CONTROL_ENABLE, and Wine will ignore any requests to change it (DTR_CONTROL_HANDSHAKE being unimplemented as well)
I assume that driving the DTR line low is the trigger that tells the watch to listen to the Rx line.
I am not sure if this is a Wine or Linux limitation, (as I have very limited knowledge of serial protocols), so I was wondering if anyone had any ideas for a suibtable workaround?
Thanks, .Geoff
On Sun, 11 Apr 2004 23:15:14 -0500, you wrote:
In any case, it turns out that one of the many requirements to get the watch to respond is to have DTR disabled (done by setting fDtrControl = DTR_CONTROL_DISABLE). But apparently the default for linux is DTR_CONTROL_ENABLE, and Wine will ignore any requests to change it (DTR_CONTROL_HANDSHAKE being unimplemented as well)
I assume that driving the DTR line low is the trigger that tells the watch to listen to the Rx line.
I am not sure if this is a Wine or Linux limitation, (as I have very limited knowledge of serial protocols), so I was wondering if anyone had any ideas for a suibtable workaround?
Geoffrey,
Please try my patch, submitted two days ago, that is just doing that - obeying DTR_CONTROL_DISABLE.
http://www.winehq.org/hypermail/wine-patches/2004/04/att-0145/01-comm-DTR-RT...
Rein.
Hey Rein,
Your patch looks a little more complete than mine :) I was writing an improved one, and then saw your patch... Two comments:
1) it might be better to call COMM_WhackModem() after tcsetattr() so previous flow control settings don't interfere with setting the RTS/DTS lines.
2) #ifdef guards around TIOCM_DTR and TIOCM_RTS?
Mike
Rein Klazes wrote:
Geoffrey,
Please try my patch, submitted two days ago, that is just doing that - obeying DTR_CONTROL_DISABLE.
http://www.winehq.org/hypermail/wine-patches/2004/04/att-0145/01-comm-DTR-RT...
Rein.
Index: dlls/kernel/comm.c =================================================================== RCS file: /home/wine/wine/dlls/kernel/comm.c,v retrieving revision 1.77 diff -u -r1.77 comm.c --- dlls/kernel/comm.c 16 Jan 2004 02:21:01 -0000 1.77 +++ dlls/kernel/comm.c 12 Apr 2004 06:47:01 -0000 @@ -1084,6 +1084,7 @@ { struct termios port; int fd, bytesize, stopbits; + BOOL r = FALSE;
TRACE("handle %p, ptr %p\n", handle, lpdcb); TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n", @@ -1384,12 +1385,6 @@ TRACE("CRTSCTS\n"); } #endif - - if (lpdcb->fDtrControl == DTR_CONTROL_HANDSHAKE) - { - WARN("DSR/DTR flow control not supported\n"); - } - if (lpdcb->fInX) port.c_iflag |= IXON; else @@ -1400,16 +1395,42 @@ port.c_iflag &= ~IXOFF;
if (tcsetattr(fd,TCSANOW,&port)==-1) { /* otherwise it hangs with pending input*/ - int save_error=errno; + ERR("tcsetattr error '%s'\n", strerror(errno)); COMM_SetCommError(handle,CE_IOE); - release_comm_fd( handle, fd ); - ERR("tcsetattr error '%s'\n", strerror(save_error)); - return FALSE; } else { COMM_SetCommError(handle,0); - release_comm_fd( handle, fd ); - return TRUE; + r = TRUE; } + + /* do after we set the com properties, so flow control doesn't interfere */ +#ifdef TIOCM_RTS + if (lpdcb->fRtsControl == RTS_CONTROL_DISABLE) + { + COMM_WhackModem(fd, ~TIOCM_RTS, 0); + } + else if (lpdcb->fRtsControl == RTS_CONTROL_ENABLE) + { + COMM_WhackModem(fd, TIOCM_RTS, 0); + } +#endif + + if (lpdcb->fDtrControl == DTR_CONTROL_HANDSHAKE) + { + WARN("DSR/DTR flow control not supported\n"); + } +#ifdef TIOCM_DTR + else if (lpdcb->fDtrControl == DTR_CONTROL_DISABLE) + { + COMM_WhackModem(fd, ~TIOCM_DTR, 0); + } + else if (lpdcb->fDtrControl == DTR_CONTROL_ENABLE) + { + COMM_WhackModem(fd, TIOCM_DTR, 0); + } +#endif + + release_comm_fd( handle, fd ); + return r; }
On Mon, 12 Apr 2004 16:46:56 +0900, you wrote:
Hey Rein,
Your patch looks a little more complete than mine :) I was writing an improved one, and then saw your patch... Two comments:
- it might be better to call COMM_WhackModem() after tcsetattr() so
previous flow control settings don't interfere with setting the RTS/DTS lines.
- #ifdef guards around TIOCM_DTR and TIOCM_RTS?
Agreed, I will fix this in a moment.
Rein.
Geoffrey Hausheer wrote:
In any case, it turns out that one of the many requirements to get the watch to respond is to have DTR disabled (done by setting fDtrControl = DTR_CONTROL_DISABLE). But apparently the default for linux is DTR_CONTROL_ENABLE, and Wine will ignore any requests to change it (DTR_CONTROL_HANDSHAKE being unimplemented as well)
Does this help?
Mike
Index: dlls/kernel/comm.c =================================================================== RCS file: /home/wine/wine/dlls/kernel/comm.c,v retrieving revision 1.77 diff -u -r1.77 comm.c --- dlls/kernel/comm.c 16 Jan 2004 02:21:01 -0000 1.77 +++ dlls/kernel/comm.c 12 Apr 2004 06:32:36 -0000 @@ -1389,6 +1389,14 @@ { WARN("DSR/DTR flow control not supported\n"); } + else if (lpdcb->fDtrControl == DTR_CONTROL_DISABLE) + { + EscapeCommFunction( handle, CLRDTR ); + } + else if (lpdcb->fDtrControl == DTR_CONTROL_ENABLE) + { + EscapeCommFunction( handle, SETDTR ); + }
if (lpdcb->fInX) port.c_iflag |= IXON;