2 EIBD eib bus access and management daemon
3 Copyright (C) 2005-2011 Martin Koegler <mkoegler@auto.tuwien.ac.at>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include <sys/ioctl.h>
25 #include "bcu1serial.h"
28 BCU1SerialLowLevelDriver::SendReset ()
33 BCU1SerialLowLevelDriver::Connection_Lost ()
39 BCU1SerialLowLevelDriver::Send_Packet (CArray l
)
42 t
->TracePacket (1, this, "Send", l
);
44 pth_sem_set_value (&send_empty
, 0);
45 pth_sem_inc (&in_signal
, TRUE
);
49 BCU1SerialLowLevelDriver::Send_Queue_Empty ()
51 return inqueue
.isempty ();
55 BCU1SerialLowLevelDriver::Send_Queue_Empty_Cond ()
61 BCU1SerialLowLevelDriver::Get_Packet (pth_event_t stop
)
64 pth_event_concat (getwait
, stop
, NULL
);
69 pth_event_isolate (getwait
);
71 if (pth_event_status (getwait
) == PTH_STATUS_OCCURRED
)
73 pth_sem_dec (&out_signal
);
74 CArray
*c
= outqueue
.get ();
75 t
->TracePacket (1, this, "Recv", *c
);
82 BCU1SerialLowLevelDriver::BCU1SerialLowLevelDriver (const char *dev
,
88 pth_sem_init (&in_signal
);
89 pth_sem_init (&out_signal
);
90 pth_sem_init (&send_empty
);
91 pth_sem_set_value (&send_empty
, 1);
92 getwait
= pth_event (PTH_EVENT_SEM
, &out_signal
);
94 TRACEPRINTF (t
, 1, this, "Open");
95 fd
= open (dev
, O_RDWR
| O_NOCTTY
| O_NDELAY
| O_SYNC
);
98 set_low_latency (fd
, &sold
);
101 fd
= open (dev
, O_RDWR
| O_NOCTTY
| O_NDELAY
| O_SYNC
);
105 if (tcgetattr (fd
, &told
))
107 restore_low_latency (fd
, &sold
);
113 if (tcgetattr (fd
, &ti
))
115 restore_low_latency (fd
, &sold
);
120 ti
.c_cflag
= CS8
| CLOCAL
| CREAD
;
121 ti
.c_iflag
= IGNBRK
| INPCK
| ISIG
;
126 cfsetospeed (&ti
, B9600
);
127 cfsetispeed (&ti
, 0);
129 if (tcsetattr (fd
, TCSAFLUSH
, &ti
))
131 restore_low_latency (fd
, &sold
);
137 setstat (getstat () & ~(TIOCM_RTS
| TIOCM_CTS
));
138 while ((getstat () & TIOCM_CTS
));
141 TRACEPRINTF (t
, 1, this, "Opened");
144 BCU1SerialLowLevelDriver::~BCU1SerialLowLevelDriver ()
146 TRACEPRINTF (t
, 1, this, "Close");
148 pth_event_free (getwait
, PTH_FREE_THIS
);
152 restore_low_latency (fd
, &sold
);
153 tcsetattr (fd
, TCSAFLUSH
, &told
);
159 BCU1SerialLowLevelDriver::init ()
165 BCU1SerialLowLevelDriver::getstat ()
168 ioctl (fd
, TIOCMGET
, &s
);
173 BCU1SerialLowLevelDriver::setstat (int s
)
175 ioctl (fd
, TIOCMSET
, &s
);
178 /** counts to number of set bits in x */
180 bitcount (unsigned char x
)
183 for (i
= j
= 0; i
< 8; i
++)
190 BCU1SerialLowLevelDriver::startsync ()
194 setstat (s
| TIOCM_RTS
);
195 while (!(getstat () & TIOCM_CTS
))
201 TRACEPRINTF (t
, 0, this, "Startsync");
206 BCU1SerialLowLevelDriver::endsync ()
211 setstat (s
& ~TIOCM_RTS
);
212 while ((getstat () & TIOCM_CTS
))
218 TRACEPRINTF (t
, 0, this, "Endsync");
223 BCU1SerialLowLevelDriver::exchange (uchar c
, uchar
& result
,
231 while ((i
= read (fd
, &s
, 1)) == -1)
237 TRACEPRINTF (t
, 0, this, "exchange %02X <->%02X", c
, s
);
243 BCU1SerialLowLevelDriver::Run (pth_sem_t
* stop1
)
245 pth_event_t stop
= pth_event (PTH_EVENT_SEM
, stop1
);
246 pth_event_t input
= pth_event (PTH_EVENT_SEM
, &in_signal
);
247 pth_event_t timeout
= pth_event (PTH_EVENT_RTIME
, pth_time (0, 10));
248 while (pth_event_status (stop
) != PTH_STATUS_OCCURRED
)
252 pth_event (PTH_EVENT_RTIME
| PTH_MODE_REUSE
, timeout
,
254 pth_event_concat (stop
, input
, timeout
, NULL
);
256 pth_event_isolate (stop
);
257 pth_event_isolate (input
);
259 pth_event (PTH_EVENT_RTIME
| PTH_MODE_REUSE
, timeout
,
261 pth_event_concat (stop
, timeout
, NULL
);
263 struct timeval v1
, v2
;
264 gettimeofday (&v1
, 0);
269 if (!inqueue
.isempty ())
271 const CArray
& c
= inqueue
.top ();
275 s
|= 0x80 * bitcount (s
);
289 if (!exchange (e
[0], s
, stop
))
299 if (s
== 0xff && e
[0] != 0xff)
301 for (unsigned i
= 1; i
< e (); i
++)
308 if (!exchange (e
[i
], s
, stop
))
325 TRACEPRINTF (t
, 0, this, "Sent");
326 pth_sem_dec (&in_signal
);
327 if (inqueue
.isempty ())
328 pth_sem_set_value (&send_empty
, 1);
332 r
.resize ((s
& 0x1f));
333 for (unsigned i
= 0; i
< (s
& 0x1f); i
++)
340 if (!exchange (0, r
[i
], stop
))
351 TRACEPRINTF (t
, 0, this, "Recv");
352 outqueue
.put (new CArray (r
));
353 pth_sem_inc (&out_signal
, 1);
355 gettimeofday (&v2
, 0);
356 TRACEPRINTF (t
, 1, this, "Recvtime: %d",
357 v2
.tv_sec
* 1000000L + v2
.tv_usec
-
358 (v1
.tv_sec
* 1000000L + v1
.tv_usec
));
363 gettimeofday (&v2
, 0);
364 TRACEPRINTF (t
, 1, this, "ERecvtime: %d",
365 v2
.tv_sec
* 1000000L + v2
.tv_usec
-
366 (v1
.tv_sec
* 1000000L + v1
.tv_usec
));
367 setstat (getstat () & ~(TIOCM_RTS
| TIOCM_CTS
));
369 while ((getstat () & TIOCM_CTS
));
370 TRACEPRINTF (t
, 0, this, "Restart %d", error
);
373 pth_event_isolate (timeout
);
375 pth_event_free (timeout
, PTH_FREE_THIS
);
376 pth_event_free (stop
, PTH_FREE_THIS
);
377 pth_event_free (input
, PTH_FREE_THIS
);
380 LowLevelDriverInterface::EMIVer
BCU1SerialLowLevelDriver::getEMIVer ()