public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* Serial programming patch
@ 2001-05-22  5:33 Jacek Trzcinski
  2001-05-22 13:09 ` Corinna Vinschen
  0 siblings, 1 reply; 10+ messages in thread
From: Jacek Trzcinski @ 2001-05-22  5:33 UTC (permalink / raw)
  To: cygwin

Hi !,
Here is my patch to serial device. I implemented ioctl function which
makes possible
to get modem lines state (CTS,DSR,RI,CD) and set(get) modem control
lines (RTS and DTR)
It does not get(set) other signals from MCR register(there is no need).
It will be usefull for people (like me) who have to connect devices
requiring mentioned signals f.e. chip card readers.
I made changes in fhandler_serial.cc, fhandler.h and in termios.h where
I placed
proper constants taken directly from linux headers. I tested it in NT
and W2K environment
where there is nice way to get RTS and DTR state by DeviceIoControl
function. In
Windows 9x it is no possible and so far I do not know how to do it
without big gimnastics.
In consequence for 9x I keep mirror of this signals set by functions
which influence on state
of this signals (open, ioctl,tcsetattr) and in my ioctl simply return
it.
This patch was created on base of cygwin sources version 1.3.1-1
I have to send it as attachment because my post client is netscape and
inserted patch looks
horrible
Jacek
--- fhandler_serial.old.cc	Tue Apr 24 03:19:15 2001
+++ fhandler_serial.cc	Tue May 22 11:01:29 2001
@@ -32,6 +32,9 @@ fhandler_serial::fhandler_serial (const 
   vtime_ = 0;
   pgrp_ = myself->pgid;
   set_need_fork_fixup ();
+  osVersion=GetVersion();
+  dtr=0;
+  rts=0;
 }
 
 void
@@ -275,7 +278,8 @@ fhandler_serial::open (const char *name,
       if (!SetCommState (get_handle (), &state))
 	system_printf ("couldn't set initial state for %s, %E", get_name ());
     }
-
+  rts=TIOCM_RTS;
+  dtr=TIOCM_DTR;
   SetCommMask (get_handle (), EV_RXCHAR);
   set_open_status ();
   syscall_printf ("%p = fhandler_serial::open (%s, %p, %p)",
@@ -366,6 +370,93 @@ fhandler_serial::tcflow (int action)
   return 0;
 }
 
+
+/* ioctl: POSIX  */
+int
+fhandler_serial::ioctl (unsigned int cmd,void * buffer)
+{
+ 
+  DCB dcb;
+  DWORD ev;
+  COMSTAT st;
+  DWORD action;
+  DWORD modemLines;
+  DWORD mcr;
+  DWORD cbReturned;
+  bool  result;
+  int   modemStatus;
+  int request;
+
+  request=*(int*)buffer;
+  action=0;
+  modemStatus=0;
+  if (!ClearCommError (get_handle (), &ev, &st)) return -1;
+  switch (cmd)
+    {
+      case TIOCMGET:
+        if(GetCommModemStatus(get_handle(),&modemLines)==0) return -1;
+	if(modemLines&MS_CTS_ON) modemStatus|=TIOCM_CTS;
+	if(modemLines&MS_DSR_ON) modemStatus|=TIOCM_DSR;
+	if(modemLines&MS_RING_ON) modemStatus|=TIOCM_RNG | TIOCM_RI;
+	if(modemLines&MS_RLSD_ON) modemStatus|=TIOCM_CAR | TIOCM_CD;
+	if(!(osVersion&0x80000000))
+	{
+	// here is Windows NT or Windows 2000
+	  result=DeviceIoControl(
+	                          get_handle(),
+				  0x001B0078,
+				  NULL,
+				  0,
+				  &mcr,
+				  4,
+				  &cbReturned,
+				  0
+				  );
+	  if(!result) return -1;
+	  if(cbReturned!=4) return -1;
+	  if(mcr&2) modemStatus|=TIOCM_RTS;
+	  if(mcr&1) modemStatus|=TIOCM_DTR;
+	  
+	} else
+	{
+	
+	// here is Windows 9x
+	  modemStatus|=rts|dtr;
+	  
+	}
+	*(int*)buffer=modemStatus;
+	return 0;
+      case TIOCMSET:
+        //if(request & ~(TIOCM_RTS | TIOCM_DTR)) return -1;
+	if (request&TIOCM_RTS)
+	{
+	    if(EscapeCommFunction(get_handle(),SETRTS)==0) return -1; else
+	    rts=TIOCM_RTS;
+	} else
+	{
+	    if(EscapeCommFunction(get_handle(),CLRRTS)==0) return -1;else
+	    rts=0;
+	}
+	if (request&TIOCM_DTR)
+	{
+	    if(EscapeCommFunction(get_handle(),SETDTR)==0) return -1;else
+	    dtr=TIOCM_DTR;
+	} else
+	{
+	    if(EscapeCommFunction(get_handle(),CLRDTR)==0) return -1;else
+	    dtr=0;
+	}
+	return 0;
+      case TIOCINQ:
+        if(ev&CE_FRAME | ev&CE_IOE | ev&CE_OVERRUN | \
+	ev&CE_RXOVER | ev&CE_RXPARITY) return -1;
+	*(int*)buffer=st.cbInQue;
+	return 0;
+      default:
+	return -1;
+    }
+}
+
 /* tcflush: POSIX 7.2.2.1 */
 int
 fhandler_serial::tcflush (int queue)
@@ -373,7 +464,7 @@ fhandler_serial::tcflush (int queue)
   if (queue == TCOFLUSH || queue == TCIOFLUSH)
     PurgeComm (get_handle (), PURGE_TXABORT | PURGE_TXCLEAR);
 
-  if (queue == TCIFLUSH | queue == TCIOFLUSH)
+  if (queue == TCIFLUSH || queue == TCIOFLUSH)
     /* Input flushing by polling until nothing turns up
        (we stop after 1000 chars anyway) */
     for (int max = 1000; max > 0; max--)
@@ -404,6 +495,8 @@ fhandler_serial::tcsetattr (int action, 
   COMMTIMEOUTS to;
   DCB ostate, state;
   unsigned int ovtime = vtime_, ovmin = vmin_;
+  int tmpDtr,tmpRts;
+  tmpDtr=tmpRts=0;
 
   termios_printf ("action %d", action);
   if ((action == TCSADRAIN) || (action == TCSAFLUSH))
@@ -569,6 +662,7 @@ fhandler_serial::tcsetattr (int action, 
     {							/* disable */
       state.fRtsControl = RTS_CONTROL_ENABLE;
       state.fOutxCtsFlow = FALSE;
+      tmpRts=TIOCM_RTS;
     }
 
   if (t->c_cflag & CRTSXOFF)
@@ -601,7 +695,10 @@ fhandler_serial::tcsetattr (int action, 
   set_w_binary ((t->c_oflag & ONLCR) ? 0 : 1);
 
   if (dropDTR == TRUE)
+  {
     EscapeCommFunction (get_handle (), CLRDTR);
+    tmpDtr=0;
+  }
   else
     {
       /* FIXME: Sometimes when CLRDTR is set, setting
@@ -610,7 +707,11 @@ fhandler_serial::tcsetattr (int action, 
       parameters while DTR is still down. */
 
       EscapeCommFunction (get_handle (), SETDTR);
+      tmpDtr=TIOCM_DTR;
     }
+    
+  rts=tmpRts;
+  dtr=tmpDtr;
 
   /*
   The following documentation on was taken from "Linux Serial Programming
--- fhandler.old.h	Tue Apr 24 03:19:14 2001
+++ fhandler.h	Tue May 22 10:34:58 2001
@@ -529,6 +529,9 @@ private:
   unsigned int vmin_;			/* from termios */
   unsigned int vtime_;			/* from termios */
   pid_t pgrp_;
+  unsigned int osVersion;
+  int	rts;
+  int	dtr;
 
 public:
   int overlapped_armed;
@@ -547,6 +550,7 @@ public:
   int tcsendbreak (int);
   int tcdrain ();
   int tcflow (int);
+  int ioctl (unsigned int cmd, void *);
   int tcsetattr (int a, const struct termios *t);
   int tcgetattr (struct termios *t);
   off_t lseek (off_t, int) { return 0; }
--- ./include/sys/termios.old.h	Sun Mar 25 21:09:52 2001
+++ ./include/sys/termios.h	Tue May 22 12:03:16 2001
@@ -13,6 +13,22 @@ details. */
 #ifndef	_SYS_TERMIOS_H
 #define _SYS_TERMIOS_H
 
+
+#define	TIOCMGET	0x5415
+#define TIOCMSET	0x5418
+#define TIOCINQ		0x541B
+
+#define	TIOCM_LE	0x001
+#define	TIOCM_DTR	0x002
+#define	TIOCM_RTS	0x004
+#define	TIOCM_CTS	0x020
+#define	TIOCM_CAR	0x040
+#define	TIOCM_RNG	0x080
+#define	TIOCM_DSR	0x100
+#define	TIOCM_CD	TIOCM_CAR
+#define	TIOCM_RI	TIOCM_RNG
+
+
 #define TCOOFF		0
 #define TCOON		1
 #define TCIOFF		2

^ permalink raw reply	[flat|nested] 10+ messages in thread
* Re: Serial programming patch
@ 2001-05-22 18:21 J. J. Farrell
  0 siblings, 0 replies; 10+ messages in thread
From: J. J. Farrell @ 2001-05-22 18:21 UTC (permalink / raw)
  To: cygwin

From: Jacek Trzcinski <jacek@certum.pl>
>
> Here is my patch to serial device. I implemented ioctl function which
> makes possible
> to get modem lines state (CTS,DSR,RI,CD) and set(get) modem control
> lines (RTS and DTR)
>
> ...
>
> +
> +/* ioctl: POSIX  */
> +int
> +fhandler_serial::ioctl (unsigned int cmd,void * buffer)

Just a very minor nit-pick: it might reduce future confusion if the word
"POSIX" were removed from that comment. POSIX doesn't specify an ioctl()
function or any means to access the modem control signals on serial lines.




--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 10+ messages in thread
* Serial programming patch
@ 2002-04-11  9:51 briseida deyanira maytorena sanchez
  2002-04-11 10:04 ` Christopher Faylor
  0 siblings, 1 reply; 10+ messages in thread
From: briseida deyanira maytorena sanchez @ 2002-04-11  9:51 UTC (permalink / raw)
  To: cygwin

Hello,

I've been searching through the mailing lists trying to find a painless
way of toggling DTR/RTS lines for some test code which I am writing. I was
trying to use ioctl() but TIOCMSET, TIOCM_DTR and all the other
definitions needed are currently unsupported. 

I also found in the archive a patch written by Jacek Trzcinski 
(see http://sources.redhat.com/ml/cygwin/2001-05/msg01163.html) and
wondered what the current status of this is, i.e. is it still under
development?  If the patch has been abandoned what can one do to help, how
would I go about testing it? Not knowing anything about tweaking cygwin
packages could you point me to appropriate documentation. Forgive my
ignorance but all I'm doing at the moment is a bit of C so looking at the
Trzcinski's posting of the patch is a bit like reading Arabic.

All I really want is to be able to toggle those lines so if there is an
easier way that you know of, sharing your knowledge would be much
appreciated.

Thanks in advance,

Deya



--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2002-04-11 16:57 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-05-22  5:33 Serial programming patch Jacek Trzcinski
2001-05-22 13:09 ` Corinna Vinschen
2001-05-23  1:03   ` Jacek Trzcinski
2001-05-23  1:33     ` Corinna Vinschen
2001-05-23  5:21       ` Jacek Trzcinski
2001-05-23  7:29         ` Corinna Vinschen
2001-05-23 13:00           ` Christopher Faylor
2001-05-22 18:21 J. J. Farrell
2002-04-11  9:51 briseida deyanira maytorena sanchez
2002-04-11 10:04 ` Christopher Faylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).