FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/tw.c
1 /*-
2 * Copyright (c) 1992, 1993, 1995 Eugene W. Stark
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Eugene W. Stark.
16 * 4. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY EUGENE W. STARK (THE AUTHOR) ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #include "tw.h"
33 #if NTW > 0
34
35 /*
36 * Driver configuration parameters
37 */
38
39 /*
40 * Time for 1/2 of a power line cycle, in microseconds.
41 * Change this to 10000 for 50Hz power. Phil Sampson
42 * (vk2jnt@gw.vk2jnt.ampr.org OR sampson@gidday.enet.dec.com)
43 * reports that this works (at least in Australia) using a
44 * TW7223 module (a local version of the TW523).
45 */
46 #define HALFCYCLE 8333 /* 1/2 cycle = 8333us at 60Hz */
47
48 /*
49 * Undefine the following if you don't have the high-resolution "microtime"
50 * routines (leave defined for FreeBSD, which has them).
51 */
52 #define HIRESTIME
53
54 /*
55 * End of driver configuration parameters
56 */
57
58 /*
59 * FreeBSD Device Driver for X-10 POWERHOUSE (tm)
60 * Two-Way Power Line Interface, Model #TW523
61 *
62 * written by Eugene W. Stark (stark@cs.sunysb.edu)
63 * December 2, 1992
64 *
65 * NOTES:
66 *
67 * The TW523 is a carrier-current modem for home control/automation purposes.
68 * It is made by:
69 *
70 * X-10 Inc.
71 * 185A LeGrand Ave.
72 * Northvale, NJ 07647
73 * USA
74 * (201) 784-9700 or 1-800-526-0027
75 *
76 * X-10 Home Controls Inc.
77 * 1200 Aerowood Drive, Unit 20
78 * Mississauga, Ontario
79 * (416) 624-4446 or 1-800-387-3346
80 *
81 * The TW523 is designed for communications using the X-10 protocol,
82 * which is compatible with a number of home control systems, including
83 * Radio Shack "Plug 'n Power(tm)" and Stanley "Lightmaker(tm)."
84 * I bought my TW523 from:
85 *
86 * Home Control Concepts
87 * 9353-C Activity Road
88 * San Diego, CA 92126
89 * (619) 693-8887
90 *
91 * They supplied me with the TW523 (which has an RJ-11 four-wire modular
92 * telephone connector), a modular cable, an RJ-11 to DB-25 connector with
93 * internal wiring, documentation from X-10 on the TW523 (very good),
94 * an instruction manual by Home Control Concepts (not very informative),
95 * and a floppy disk containing binary object code of some demonstration/test
96 * programs and of a C function library suitable for controlling the TW523
97 * by an IBM PC under MS-DOS (not useful to me other than to verify that
98 * the unit worked). I suggest saving money and buying the bare TW523
99 * rather than the TW523 development kit (what I bought), because if you
100 * are running FreeBSD you don't really care about the DOS binaries.
101 *
102 * The interface to the TW-523 consists of four wires on the RJ-11 connector,
103 * which are jumpered to somewhat more wires on the DB-25 connector, which
104 * in turn is intended to plug into the PC parallel printer port. I dismantled
105 * the DB-25 connector to find out what they had done:
106 *
107 * Signal RJ-11 pin DB-25 pin(s) Parallel Port
108 * Transmit TX 4 (Y) 2, 4, 6, 8 Data out
109 * Receive RX 3 (G) 10, 14 -ACK, -AutoFeed
110 * Common 2 (R) 25 Common
111 * Zero crossing 1 (B) 17 or 12 -Select or +PaperEnd
112 *
113 * NOTE: In the original cable I have (which I am still using, May, 1997)
114 * the Zero crossing signal goes to pin 17 (-Select) on the parallel port.
115 * In retrospect, this doesn't make a whole lot of sense, given that the
116 * -Select signal propagates the other direction. Indeed, some people have
117 * reported problems with this, and have had success using pin 12 (+PaperEnd)
118 * instead. This driver searches for the zero crossing signal on either
119 * pin 17 or pin 12, so it should work with either cable configuration.
120 * My suggestion would be to start by making the cable so that the zero
121 * crossing signal goes to pin 12 on the parallel port.
122 *
123 * The zero crossing signal is used to synchronize transmission to the
124 * zero crossings of the AC line, as detailed in the X-10 documentation.
125 * It would be nice if one could generate interrupts with this signal,
126 * however one needs interrupts on both the rising and falling edges,
127 * and the -ACK signal to the parallel port interrupts only on the falling
128 * edge, so it can't be done without additional hardware.
129 *
130 * In this driver, the transmit function is performed in a non-interrupt-driven
131 * fashion, by polling the zero crossing signal to determine when a transition
132 * has occurred. This wastes CPU time during transmission, but it seems like
133 * the best that can be done without additional hardware. One problem with
134 * the scheme is that preemption of the CPU during transmission can cause loss
135 * of sync. The driver tries to catch this, by noticing that a long delay
136 * loop has somehow become foreshortened, and the transmission is aborted with
137 * an error return. It is up to the user level software to handle this
138 * situation (most likely by retrying the transmission).
139 */
140
141 #include <sys/param.h>
142 #include <sys/systm.h>
143 #include <sys/proc.h>
144 #include <sys/conf.h>
145 #include <sys/buf.h>
146 #include <sys/kernel.h>
147 #include <sys/ioctl.h>
148 #include <sys/uio.h>
149 #include <sys/syslog.h>
150 #include <sys/select.h>
151 #ifdef DEVFS
152 #include <sys/devfsext.h>
153 #endif /*DEVFS*/
154
155 #define MIN(a,b) ((a)<(b)?(a):(b))
156
157 #ifdef HIRESTIME
158 #include <sys/time.h>
159 #endif /* HIRESTIME */
160
161 #include <i386/isa/isa_device.h>
162
163 /*
164 * Transmission is done by calling write() to send three byte packets of data.
165 * The first byte contains a four bit house code (0=A to 15=P).
166 * The second byte contains five bit unit/key code (0=unit 1 to 15=unit 16,
167 * 16=All Units Off to 31 = Status Request). The third byte specifies
168 * the number of times the packet is to be transmitted without any
169 * gaps between successive transmissions. Normally this is 2, as per
170 * the X-10 documentation, but sometimes (e.g. for bright and dim codes)
171 * it can be another value. Each call to write can specify an arbitrary
172 * number of data bytes. An incomplete packet is buffered until a subsequent
173 * call to write() provides data to complete it. At most one packet will
174 * actually be processed in any call to write(). Successive calls to write()
175 * leave a three-cycle gap between transmissions, per the X-10 documentation.
176 *
177 * Reception is done using read().
178 * The driver produces a series of three-character packets.
179 * In each packet, the first character consists of flags,
180 * the second character is a four bit house code (0-15),
181 * and the third character is a five bit key/function code (0-31).
182 * The flags are the following:
183 */
184
185 #define TW_RCV_LOCAL 1 /* The packet arrived during a local transmission */
186 #define TW_RCV_ERROR 2 /* An invalid/corrupted packet was received */
187
188 /*
189 * IBM PC parallel port definitions relevant to TW523
190 */
191
192 #define tw_data 0 /* Data to tw523 (R/W) */
193
194 #define tw_status 1 /* Status of tw523 (R) */
195 #define TWS_RDATA 0x40 /* tw523 receive data */
196 #define TWS_OUT 0x20 /* pin 12, out of paper */
197
198 #define tw_control 2 /* Control tw523 (R/W) */
199 #define TWC_SYNC 0x08 /* tw523 sync (pin 17) */
200 #define TWC_ENA 0x10 /* tw523 interrupt enable */
201
202 /*
203 * Miscellaneous defines
204 */
205
206 #define TWUNIT(dev) (minor(dev)) /* Extract unit number from device */
207 #define TWPRI (PZERO+8) /* I don't know any better, so let's */
208 /* use the same as the line printer */
209
210 static int twprobe(struct isa_device *idp);
211 static int twattach(struct isa_device *idp);
212
213 struct isa_driver twdriver = {
214 twprobe, twattach, "tw"
215 };
216
217 static d_open_t twopen;
218 static d_close_t twclose;
219 static d_read_t twread;
220 static d_write_t twwrite;
221 static d_select_t twselect;
222
223 #define CDEV_MAJOR 19
224 static struct cdevsw tw_cdevsw =
225 { twopen, twclose, twread, twwrite, /*19*/
226 noioc, nullstop, nullreset, nodevtotty, /* tw */
227 twselect, nommap, nostrat, "tw", NULL, -1 };
228
229 /*
230 * Software control structure for TW523
231 */
232
233 #define TWS_XMITTING 1 /* Transmission in progress */
234 #define TWS_RCVING 2 /* Reception in progress */
235 #define TWS_WANT 4 /* A process wants received data */
236 #define TWS_OPEN 8 /* Is it currently open? */
237
238 #define TW_SIZE 3*60 /* Enough for about 10 sec. of input */
239 #define TW_MIN_DELAY 1500 /* Ignore interrupts of lesser latency */
240
241 static struct tw_sc {
242 u_int sc_port; /* I/O Port */
243 u_int sc_state; /* Current software control state */
244 struct selinfo sc_selp; /* Information for select() */
245 u_char sc_xphase; /* Current state of sync (for transmitter) */
246 u_char sc_rphase; /* Current state of sync (for receiver) */
247 u_char sc_flags; /* Flags for current reception */
248 short sc_rcount; /* Number of bits received so far */
249 int sc_bits; /* Bits received so far */
250 u_char sc_pkt[3]; /* Packet not yet transmitted */
251 short sc_pktsize; /* How many bytes in the packet? */
252 u_char sc_buf[TW_SIZE]; /* We buffer our own input */
253 int sc_nextin; /* Next free slot in circular buffer */
254 int sc_nextout; /* First used slot in circular buffer */
255 #ifdef HIRESTIME
256 int sc_xtimes[22]; /* Times for bits in current xmit packet */
257 int sc_rtimes[22]; /* Times for bits in current rcv packet */
258 int sc_no_rcv; /* number of interrupts received */
259 #define SC_RCV_TIME_LEN 128
260 int sc_rcv_time[SC_RCV_TIME_LEN]; /* usec time stamp on interrupt */
261 #endif /* HIRESTIME */
262 #ifdef DEVFS
263 void *devfs_token; /* store the devfs handle */
264 #endif
265 } tw_sc[NTW];
266
267 static int tw_zcport; /* offset of port for zero crossing signal */
268 static int tw_zcmask; /* mask for the zero crossing signal */
269
270 static void twdelay25(void);
271 static void twdelayn(int n);
272 static void twsetuptimes(int *a);
273 static int wait_for_zero(struct tw_sc *sc);
274 static int twputpkt(struct tw_sc *sc, u_char *p);
275 static int twgetbytes(struct tw_sc *sc, u_char *p, int cnt);
276 static void twabortrcv(struct tw_sc *sc);
277 static int twsend(struct tw_sc *sc, int h, int k, int cnt);
278 static int next_zero(struct tw_sc *sc);
279 static int twchecktime(int target, int tol);
280 static void twdebugtimes(struct tw_sc *sc);
281
282 /*
283 * Counter value for delay loop.
284 * It is adjusted by twprobe so that the delay loop takes about 25us.
285 */
286
287 #define TWDELAYCOUNT 161 /* Works on my 486DX/33 */
288 static int twdelaycount;
289
290 /*
291 * Twdelay25 is used for very short delays of about 25us.
292 * It is implemented with a calibrated delay loop, and should be
293 * fairly accurate ... unless we are preempted by an interrupt.
294 *
295 * We use this to wait for zero crossings because the X-10 specs say we
296 * are supposed to assert carrier within 25us when one happens.
297 * I don't really believe we can do this, but the X-10 devices seem to be
298 * fairly forgiving.
299 */
300
301 static void twdelay25(void)
302 {
303 int cnt;
304 for(cnt = twdelaycount; cnt; cnt--); /* Should take about 25us */
305 }
306
307 /*
308 * Twdelayn is used to time the length of the 1ms carrier pulse.
309 * This is not very critical, but if we have high-resolution time-of-day
310 * we check it every apparent 200us to make sure we don't get too far off
311 * if we happen to be interrupted during the delay.
312 */
313
314 static void twdelayn(int n)
315 {
316 #ifdef HIRESTIME
317 int t, d;
318 struct timeval tv;
319 microtime(&tv);
320 t = tv.tv_usec;
321 t += n;
322 #endif /* HIRESTIME */
323 while(n > 0) {
324 twdelay25();
325 n -= 25;
326 #ifdef HIRESTIME
327 if((n & 0x7) == 0) {
328 microtime(&tv);
329 d = tv.tv_usec - t;
330 if(d >= 0 && d < 1000000) return;
331 }
332 #endif /* HIRESTIME */
333 }
334 }
335
336 static int twprobe(idp)
337 struct isa_device *idp;
338 {
339 struct tw_sc sc;
340 int d;
341 int tries;
342
343 sc.sc_port = idp->id_iobase;
344 /* Search for the zero crossing signal at ports, bit combinations. */
345 tw_zcport = tw_control;
346 tw_zcmask = TWC_SYNC;
347 sc.sc_xphase = inb(idp->id_iobase + tw_zcport) & tw_zcmask;
348 if(wait_for_zero(&sc) < 0) {
349 tw_zcport = tw_status;
350 tw_zcmask = TWS_OUT;
351 sc.sc_xphase = inb(idp->id_iobase + tw_zcport) & tw_zcmask;
352 }
353 if(wait_for_zero(&sc) < 0)
354 return(0);
355 /*
356 * Iteratively check the timing of a few sync transitions, and adjust
357 * the loop delay counter, if necessary, to bring the timing reported
358 * by wait_for_zero() close to HALFCYCLE. Give up if anything
359 * ridiculous happens.
360 */
361 if(twdelaycount == 0) { /* Only adjust timing for first unit */
362 twdelaycount = TWDELAYCOUNT;
363 for(tries = 0; tries < 10; tries++) {
364 sc.sc_xphase = inb(idp->id_iobase + tw_zcport) & tw_zcmask;
365 if(wait_for_zero(&sc) >= 0) {
366 d = wait_for_zero(&sc);
367 if(d <= HALFCYCLE/100 || d >= HALFCYCLE*100) {
368 twdelaycount = 0;
369 return(0);
370 }
371 twdelaycount = (twdelaycount * d)/HALFCYCLE;
372 }
373 }
374 }
375 /*
376 * Now do a final check, just to make sure
377 */
378 sc.sc_xphase = inb(idp->id_iobase + tw_zcport) & tw_zcmask;
379 if(wait_for_zero(&sc) >= 0) {
380 d = wait_for_zero(&sc);
381 if(d <= (HALFCYCLE * 110)/100 && d >= (HALFCYCLE * 90)/100) return(8);
382 }
383 return(0);
384 }
385
386 static int twattach(idp)
387 struct isa_device *idp;
388 {
389 struct tw_sc *sc;
390 int unit;
391
392 sc = &tw_sc[unit = idp->id_unit];
393 sc->sc_port = idp->id_iobase;
394 sc->sc_state = 0;
395 sc->sc_rcount = 0;
396
397 #ifdef DEVFS
398 sc->devfs_token =
399 devfs_add_devswf(&tw_cdevsw, unit, DV_CHR, 0, 0,
400 0600, "tw%d", unit);
401 #endif
402
403 return (1);
404 }
405
406 int twopen(dev, flag, mode, p)
407 dev_t dev;
408 int flag;
409 int mode;
410 struct proc *p;
411 {
412 struct tw_sc *sc = &tw_sc[TWUNIT(dev)];
413 int s;
414 int port;
415
416 s = spltty();
417 if(sc->sc_state == 0) {
418 sc->sc_state = TWS_OPEN;
419 sc->sc_nextin = sc->sc_nextout = 0;
420 sc->sc_pktsize = 0;
421 outb(sc->sc_port+tw_control, TWC_ENA);
422 }
423 splx(s);
424 return(0);
425 }
426
427 int twclose(dev, flag, mode, p)
428 dev_t dev;
429 int flag;
430 int mode;
431 struct proc *p;
432 {
433 struct tw_sc *sc = &tw_sc[TWUNIT(dev)];
434 int s;
435 int port = sc->sc_port;
436
437 s = spltty();
438 sc->sc_state = 0;
439 outb(sc->sc_port+tw_control, 0);
440 splx(s);
441 return(0);
442 }
443
444 int twread(dev, uio, ioflag)
445 dev_t dev;
446 struct uio *uio;
447 int ioflag;
448 {
449 u_char buf[3];
450 struct tw_sc *sc = &tw_sc[TWUNIT(dev)];
451 int error, cnt, s;
452
453 s = spltty();
454 cnt = MIN(uio->uio_resid, 3);
455 if((error = twgetbytes(sc, buf, cnt)) == 0) {
456 error = uiomove(buf, cnt, uio);
457 }
458 splx(s);
459 return(error);
460 }
461
462 int twwrite(dev, uio, ioflag)
463 dev_t dev;
464 struct uio *uio;
465 int ioflag;
466 {
467 struct tw_sc *sc;
468 int house, key, reps;
469 int s, error;
470 int cnt;
471
472 sc = &tw_sc[TWUNIT(dev)];
473 /*
474 * Note: Although I had intended to allow concurrent transmitters,
475 * there is a potential problem here if two processes both write
476 * into the sc_pkt buffer at the same time. The following code
477 * is an additional critical section that needs to be synchronized.
478 */
479 s = spltty();
480 cnt = MIN(3 - sc->sc_pktsize, uio->uio_resid);
481 if(error = uiomove(&(sc->sc_pkt[sc->sc_pktsize]), cnt, uio)) {
482 splx(s);
483 return(error);
484 }
485 sc->sc_pktsize += cnt;
486 if(sc->sc_pktsize < 3) { /* Only transmit 3-byte packets */
487 splx(s);
488 return(0);
489 }
490 sc->sc_pktsize = 0;
491 /*
492 * Collect house code, key code, and rep count, and check for sanity.
493 */
494 house = sc->sc_pkt[0];
495 key = sc->sc_pkt[1];
496 reps = sc->sc_pkt[2];
497 if(house >= 16 || key >= 32) {
498 splx(s);
499 return(ENODEV);
500 }
501 /*
502 * Synchronize with the receiver operating in the bottom half, and
503 * also with concurrent transmitters.
504 * We don't want to interfere with a packet currently being received,
505 * and we would like the receiver to recognize when a packet has
506 * originated locally.
507 */
508 while(sc->sc_state & (TWS_RCVING | TWS_XMITTING)) {
509 if(error = tsleep((caddr_t)sc, TWPRI|PCATCH, "twwrite", 0)) {
510 splx(s);
511 return(error);
512 }
513 }
514 sc->sc_state |= TWS_XMITTING;
515 /*
516 * Everything looks OK, let's do the transmission.
517 */
518 splx(s); /* Enable interrupts because this takes a LONG time */
519 error = twsend(sc, house, key, reps);
520 s = spltty();
521 sc->sc_state &= ~TWS_XMITTING;
522 wakeup((caddr_t)sc);
523 splx(s);
524 if(error) return(EIO);
525 else return(0);
526 }
527
528 /*
529 * Determine if there is data available for reading
530 */
531
532 int twselect(dev, rw, p)
533 dev_t dev;
534 int rw;
535 struct proc *p;
536 {
537 struct tw_sc *sc;
538 struct proc *pp;
539 int s, i;
540
541 sc = &tw_sc[TWUNIT(dev)];
542 s = spltty();
543 if(sc->sc_nextin != sc->sc_nextout) {
544 splx(s);
545 return(1);
546 }
547 selrecord(p, &sc->sc_selp);
548 splx(s);
549 return(0);
550 }
551
552 /*
553 * X-10 Protocol
554 */
555
556 #define X10_START_LENGTH 4
557 static char X10_START[] = { 1, 1, 1, 0 };
558
559 /*
560 * Each bit of the 4-bit house code and 5-bit key code
561 * is transmitted twice, once in true form, and then in
562 * complemented form. This is already taken into account
563 * in the following tables.
564 */
565
566 #define X10_HOUSE_LENGTH 8
567 static char X10_HOUSE[16][8] = {
568 0, 1, 1, 0, 1, 0, 0, 1, /* A = 0110 */
569 1, 0, 1, 0, 1, 0, 0, 1, /* B = 1110 */
570 0, 1, 0, 1, 1, 0, 0, 1, /* C = 0010 */
571 1, 0, 0, 1, 1, 0, 0, 1, /* D = 1010 */
572 0, 1, 0, 1, 0, 1, 1, 0, /* E = 0001 */
573 1, 0, 0, 1, 0, 1, 1, 0, /* F = 1001 */
574 0, 1, 1, 0, 0, 1, 1, 0, /* G = 0101 */
575 1, 0, 1, 0, 0, 1, 1, 0, /* H = 1101 */
576 0, 1, 1, 0, 1, 0, 1, 0, /* I = 0111 */
577 1, 0, 1, 0, 1, 0, 1, 0, /* J = 1111 */
578 0, 1, 0, 1, 1, 0, 1, 0, /* K = 0011 */
579 1, 0, 0, 1, 1, 0, 1, 0, /* L = 1011 */
580 0, 1, 0, 1, 0, 1, 0, 1, /* M = 0000 */
581 1, 0, 0, 1, 0, 1, 0, 1, /* N = 1000 */
582 0, 1, 1, 0, 0, 1, 0, 1, /* O = 0100 */
583 1, 0, 1, 0, 0, 1, 0, 1 /* P = 1100 */
584 };
585
586 #define X10_KEY_LENGTH 10
587 static char X10_KEY[32][10] = {
588 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, /* 01100 => 1 */
589 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, /* 11100 => 2 */
590 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, /* 00100 => 3 */
591 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, /* 10100 => 4 */
592 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, /* 00010 => 5 */
593 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, /* 10010 => 6 */
594 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, /* 01010 => 7 */
595 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, /* 11010 => 8 */
596 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, /* 01110 => 9 */
597 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, /* 11110 => 10 */
598 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, /* 00110 => 11 */
599 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, /* 10110 => 12 */
600 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, /* 00000 => 13 */
601 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, /* 10000 => 14 */
602 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, /* 01000 => 15 */
603 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, /* 11000 => 16 */
604 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, /* 00001 => All Units Off */
605 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, /* 00011 => All Units On */
606 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, /* 00101 => On */
607 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, /* 00111 => Off */
608 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, /* 01001 => Dim */
609 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, /* 01011 => Bright */
610 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, /* 01101 => All LIGHTS Off */
611 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, /* 01111 => Extended Code */
612 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, /* 10001 => Hail Request */
613 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, /* 10011 => Hail Acknowledge */
614 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, /* 10101 => Preset Dim 0 */
615 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, /* 10111 => Preset Dim 1 */
616 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, /* 11000 => Extended Data (analog) */
617 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, /* 11011 => Status = on */
618 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, /* 11101 => Status = off */
619 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 /* 11111 => Status request */
620 };
621
622 /*
623 * Tables for mapping received X-10 code back to house/key number.
624 */
625
626 static short X10_HOUSE_INV[16] = {
627 12, 4, 2, 10, 14, 6, 0, 8,
628 13, 5, 3, 11, 15, 7, 1, 9
629 };
630
631 static short X10_KEY_INV[32] = {
632 12, 16, 4, 17, 2, 18, 10, 19,
633 14, 20, 6, 21, 0, 22, 8, 23,
634 13, 24, 5, 25, 3, 26, 11, 27,
635 15, 28, 7, 29, 1, 30, 9, 31
636 };
637
638 static char *X10_KEY_LABEL[32] = {
639 "1",
640 "2",
641 "3",
642 "4",
643 "5",
644 "6",
645 "7",
646 "8",
647 "9",
648 "10",
649 "11",
650 "12",
651 "13",
652 "14",
653 "15",
654 "16",
655 "All Units Off",
656 "All Units On",
657 "On",
658 "Off",
659 "Dim",
660 "Bright",
661 "All LIGHTS Off",
662 "Extended Code",
663 "Hail Request",
664 "Hail Acknowledge",
665 "Preset Dim 0",
666 "Preset Dim 1",
667 "Extended Data (analog)",
668 "Status = on",
669 "Status = off",
670 "Status request"
671 };
672 /*
673 * Transmit a packet containing house code h and key code k
674 */
675
676 #define TWRETRY 10 /* Try 10 times to sync with AC line */
677
678 static int twsend(sc, h, k, cnt)
679 struct tw_sc *sc;
680 int h, k, cnt;
681 {
682 int i;
683 int port = sc->sc_port;
684
685 /*
686 * Make sure we get a reliable sync with a power line zero crossing
687 */
688 for(i = 0; i < TWRETRY; i++) {
689 if(wait_for_zero(sc) > 100) goto insync;
690 }
691 log(LOG_ERR, "TWXMIT: failed to sync.\n");
692 return(-1);
693
694 insync:
695 /*
696 * Be sure to leave 3 cycles space between transmissions
697 */
698 for(i = 6; i > 0; i--)
699 if(next_zero(sc) < 0) return(-1);
700 /*
701 * The packet is transmitted cnt times, with no gaps.
702 */
703 while(cnt--) {
704 /*
705 * Transmit the start code
706 */
707 for(i = 0; i < X10_START_LENGTH; i++) {
708 outb(port+tw_data, X10_START[i] ? 0xff : 0x00); /* Waste no time! */
709 #ifdef HIRESTIME
710 if(i == 0) twsetuptimes(sc->sc_xtimes);
711 if(twchecktime(sc->sc_xtimes[i], HALFCYCLE/20) == 0) {
712 outb(port+tw_data, 0);
713 return(-1);
714 }
715 #endif /* HIRESTIME */
716 twdelayn(1000); /* 1ms pulse width */
717 outb(port+tw_data, 0);
718 if(next_zero(sc) < 0) return(-1);
719 }
720 /*
721 * Transmit the house code
722 */
723 for(i = 0; i < X10_HOUSE_LENGTH; i++) {
724 outb(port+tw_data, X10_HOUSE[h][i] ? 0xff : 0x00); /* Waste no time! */
725 #ifdef HIRESTIME
726 if(twchecktime(sc->sc_xtimes[i+X10_START_LENGTH], HALFCYCLE/20) == 0) {
727 outb(port+tw_data, 0);
728 return(-1);
729 }
730 #endif /* HIRESTIME */
731 twdelayn(1000); /* 1ms pulse width */
732 outb(port+tw_data, 0);
733 if(next_zero(sc) < 0) return(-1);
734 }
735 /*
736 * Transmit the unit/key code
737 */
738 for(i = 0; i < X10_KEY_LENGTH; i++) {
739 outb(port+tw_data, X10_KEY[k][i] ? 0xff : 0x00);
740 #ifdef HIRESTIME
741 if(twchecktime(sc->sc_xtimes[i+X10_START_LENGTH+X10_HOUSE_LENGTH],
742 HALFCYCLE/20) == 0) {
743 outb(port+tw_data, 0);
744 return(-1);
745 }
746 #endif /* HIRESTIME */
747 twdelayn(1000); /* 1ms pulse width */
748 outb(port+tw_data, 0);
749 if(next_zero(sc) < 0) return(-1);
750 }
751 }
752 return(0);
753 }
754
755 /*
756 * Waste CPU cycles to get in sync with a power line zero crossing.
757 * The value returned is roughly how many microseconds we wasted before
758 * seeing the transition. To avoid wasting time forever, we give up after
759 * waiting patiently for 1/4 sec (15 power line cycles at 60 Hz),
760 * which is more than the 11 cycles it takes to transmit a full
761 * X-10 packet.
762 */
763
764 static int wait_for_zero(sc)
765 struct tw_sc *sc;
766 {
767 int i, old, new, max;
768 int port = sc->sc_port + tw_zcport;
769
770 old = sc->sc_xphase;
771 max = 10000; /* 10000 * 25us = 0.25 sec */
772 i = 0;
773 while(max--) {
774 new = inb(port) & tw_zcmask;
775 if(new != old) {
776 sc->sc_xphase = new;
777 return(i*25);
778 }
779 i++;
780 twdelay25();
781 }
782 return(-1);
783 }
784
785 /*
786 * Wait for the next zero crossing transition, and if we don't have
787 * high-resolution time-of-day, check to see that the zero crossing
788 * appears to be arriving on schedule.
789 * We expect to be waiting almost a full half-cycle (8.333ms-1ms = 7.333ms).
790 * If we don't seem to wait very long, something is wrong (like we got
791 * preempted!) and we should abort the transmission because
792 * there's no telling how long it's really been since the
793 * last bit was transmitted.
794 */
795
796 static int next_zero(sc)
797 struct tw_sc *sc;
798 {
799 int d;
800 #ifdef HIRESTIME
801 if((d = wait_for_zero(sc)) < 0) {
802 #else
803 if((d = wait_for_zero(sc)) < 6000 || d > 8500) {
804 /* No less than 6.0ms, no more than 8.5ms */
805 #endif /* HIRESTIME */
806 log(LOG_ERR, "TWXMIT framing error: %d\n", d);
807 return(-1);
808 }
809 return(0);
810 }
811
812 /*
813 * Put a three-byte packet into the circular buffer
814 * Should be called at priority spltty()
815 */
816
817 static int twputpkt(sc, p)
818 struct tw_sc *sc;
819 u_char *p;
820 {
821 int i, next;
822
823 for(i = 0; i < 3; i++) {
824 next = sc->sc_nextin+1;
825 if(next >= TW_SIZE) next = 0;
826 if(next == sc->sc_nextout) { /* Buffer full */
827 /*
828 log(LOG_ERR, "TWRCV: Buffer overrun\n");
829 */
830 return(1);
831 }
832 sc->sc_buf[sc->sc_nextin] = *p++;
833 sc->sc_nextin = next;
834 }
835 if(sc->sc_state & TWS_WANT) {
836 sc->sc_state &= ~TWS_WANT;
837 wakeup((caddr_t)(&sc->sc_buf));
838 }
839 selwakeup(&sc->sc_selp);
840 return(0);
841 }
842
843 /*
844 * Get bytes from the circular buffer
845 * Should be called at priority spltty()
846 */
847
848 static int twgetbytes(sc, p, cnt)
849 struct tw_sc *sc;
850 u_char *p;
851 int cnt;
852 {
853 int error;
854
855 while(cnt--) {
856 while(sc->sc_nextin == sc->sc_nextout) { /* Buffer empty */
857 sc->sc_state |= TWS_WANT;
858 if(error = tsleep((caddr_t)(&sc->sc_buf), TWPRI|PCATCH, "twread", 0)) {
859 return(error);
860 }
861 }
862 *p++ = sc->sc_buf[sc->sc_nextout++];
863 if(sc->sc_nextout >= TW_SIZE) sc->sc_nextout = 0;
864 }
865 return(0);
866 }
867
868 /*
869 * Abort reception that has failed to complete in the required time.
870 */
871
872 static void twabortrcv(sc)
873 struct tw_sc *sc;
874 {
875 int s;
876 u_char pkt[3];
877
878 s = spltty();
879 sc->sc_state &= ~TWS_RCVING;
880 /* simply ignore single isolated interrupts. */
881 if (sc->sc_no_rcv > 1) {
882 sc->sc_flags |= TW_RCV_ERROR;
883 pkt[0] = sc->sc_flags;
884 pkt[1] = pkt[2] = 0;
885 twputpkt(sc, pkt);
886 log(LOG_ERR, "TWRCV: aborting (%x, %d)\n", sc->sc_bits, sc->sc_rcount);
887 twdebugtimes(sc);
888 }
889 wakeup((caddr_t)sc);
890 splx(s);
891 }
892
893 static int
894 tw_is_within(int value, int expected, int tolerance)
895 {
896 int diff;
897 diff = value - expected;
898 if (diff < 0)
899 diff *= -1;
900 if (diff < tolerance)
901 return 1;
902 return 0;
903 }
904
905 /*
906 * This routine handles interrupts that occur when there is a falling
907 * transition on the RX input. There isn't going to be a transition
908 * on every bit (some are zero), but if we are smart and keep track of
909 * how long it's been since the last interrupt (via the zero crossing
910 * detect line and/or high-resolution time-of-day routine), we can
911 * reconstruct the transmission without having to poll.
912 */
913
914 void twintr(unit)
915 int unit;
916 {
917 struct tw_sc *sc = &tw_sc[unit];
918 int port;
919 int newphase;
920 u_char pkt[3];
921 int delay = 0;
922 struct timeval tv;
923
924 port = sc->sc_port;
925 /*
926 * Ignore any interrupts that occur if the device is not open.
927 */
928 if(sc->sc_state == 0) return;
929 newphase = inb(port + tw_zcport) & tw_zcmask;
930 microtime(&tv);
931
932 /*
933 * NEW PACKET:
934 * If we aren't currently receiving a packet, set up a new packet
935 * and put in the first "1" bit that has just arrived.
936 * Arrange for the reception to be aborted if too much time goes by.
937 */
938 if((sc->sc_state & TWS_RCVING) == 0) {
939 #ifdef HIRESTIME
940 twsetuptimes(sc->sc_rtimes);
941 #endif /* HIRESTIME */
942 sc->sc_state |= TWS_RCVING;
943 sc->sc_rcount = 1;
944 if(sc->sc_state & TWS_XMITTING) sc->sc_flags = TW_RCV_LOCAL;
945 else sc->sc_flags = 0;
946 sc->sc_bits = 0;
947 sc->sc_rphase = newphase;
948 /* 3 cycles of silence = 3/60 = 1/20 = 50 msec */
949 timeout((timeout_func_t)twabortrcv, (caddr_t)sc, hz/20);
950 sc->sc_rcv_time[0] = tv.tv_usec;
951 sc->sc_no_rcv = 1;
952 return;
953 }
954 untimeout((timeout_func_t)twabortrcv, (caddr_t)sc);
955 timeout((timeout_func_t)twabortrcv, (caddr_t)sc, hz/20);
956 newphase = inb(port + tw_zcport) & tw_zcmask;
957
958 /* enforce a minimum delay since the last interrupt */
959 delay = tv.tv_usec - sc->sc_rcv_time[sc->sc_no_rcv - 1];
960 if (delay < 0)
961 delay += 1000000;
962 if (delay < TW_MIN_DELAY)
963 return;
964
965 sc->sc_rcv_time[sc->sc_no_rcv] = tv.tv_usec;
966 if (sc->sc_rcv_time[sc->sc_no_rcv] < sc->sc_rcv_time[0])
967 sc->sc_rcv_time[sc->sc_no_rcv] += 1000000;
968 sc->sc_no_rcv++;
969
970 /*
971 * START CODE:
972 * The second and third bits are a special case.
973 */
974 if (sc->sc_rcount < 3) {
975 if (
976 #ifdef HIRESTIME
977 tw_is_within(delay, HALFCYCLE, HALFCYCLE / 6)
978 #else
979 newphase != sc->sc_rphase
980 #endif
981 ) {
982 sc->sc_rcount++;
983 } else {
984 /*
985 * Invalid start code -- abort reception.
986 */
987 sc->sc_state &= ~TWS_RCVING;
988 sc->sc_flags |= TW_RCV_ERROR;
989 untimeout((timeout_func_t)twabortrcv, (caddr_t)sc);
990 log(LOG_ERR, "TWRCV: Invalid start code\n");
991 twdebugtimes(sc);
992 sc->sc_no_rcv = 0;
993 return;
994 }
995 if(sc->sc_rcount == 3) {
996 /*
997 * We've gotten three "1" bits in a row. The start code
998 * is really 1110, but this might be followed by a zero
999 * bit from the house code, so if we wait any longer we
1000 * might be confused about the first house code bit.
1001 * So, we guess that the start code is correct and insert
1002 * the trailing zero without actually having seen it.
1003 * We don't change sc_rphase in this case, because two
1004 * bit arrivals in a row preserve parity.
1005 */
1006 sc->sc_rcount++;
1007 return;
1008 }
1009 /*
1010 * Update sc_rphase to the current phase before returning.
1011 */
1012 sc->sc_rphase = newphase;
1013 return;
1014 }
1015 /*
1016 * GENERAL CASE:
1017 * Now figure out what the current bit is that just arrived.
1018 * The X-10 protocol transmits each data bit twice: once in
1019 * true form and once in complemented form on the next half
1020 * cycle. So, there will be at least one interrupt per bit.
1021 * By comparing the phase we see at the time of the interrupt
1022 * with the saved sc_rphase, we can tell on which half cycle
1023 * the interrupt occrred. This assumes, of course, that the
1024 * packet is well-formed. We do the best we can at trying to
1025 * catch errors by aborting if too much time has gone by, and
1026 * by tossing out a packet if too many bits arrive, but the
1027 * whole scheme is probably not as robust as if we had a nice
1028 * interrupt on every half cycle of the power line.
1029 * If we have high-resolution time-of-day routines, then we
1030 * can do a bit more sanity checking.
1031 */
1032
1033 /*
1034 * A complete packet is 22 half cycles.
1035 */
1036 if(sc->sc_rcount <= 20) {
1037 #ifdef HIRESTIME
1038 int bit = 0, last_bit;
1039 if (sc->sc_rcount == 4)
1040 last_bit = 1; /* Start (1110) ends in 10, a 'one' code. */
1041 else
1042 last_bit = sc->sc_bits & 0x1;
1043 if ( ( (last_bit == 1)
1044 && (tw_is_within(delay, HALFCYCLE * 2, HALFCYCLE / 6)))
1045 || ( (last_bit == 0)
1046 && (tw_is_within(delay, HALFCYCLE * 1, HALFCYCLE / 6))))
1047 bit = 1;
1048 else if ( ( (last_bit == 1)
1049 && (tw_is_within(delay, HALFCYCLE * 3, HALFCYCLE / 6)))
1050 || ( (last_bit == 0)
1051 && (tw_is_within(delay, HALFCYCLE * 2, HALFCYCLE / 6))))
1052 bit = 0;
1053 else {
1054 sc->sc_flags |= TW_RCV_ERROR;
1055 log(LOG_ERR, "TWRCV: %d cycle after %d bit, delay %d%%\n",
1056 sc->sc_rcount, last_bit, 100 * delay / HALFCYCLE);
1057 }
1058 sc->sc_bits = (sc->sc_bits << 1) | bit;
1059 #else
1060 sc->sc_bits = (sc->sc_bits << 1)
1061 | ((newphase == sc->sc_rphase) ? 0x0 : 0x1);
1062 #endif /* HIRESTIME */
1063 sc->sc_rcount += 2;
1064 }
1065 if(sc->sc_rcount >= 22 || sc->sc_flags & TW_RCV_ERROR) {
1066 if(sc->sc_rcount != 22) {
1067 sc->sc_flags |= TW_RCV_ERROR;
1068 pkt[0] = sc->sc_flags;
1069 pkt[1] = pkt[2] = 0;
1070 } else {
1071 pkt[0] = sc->sc_flags;
1072 pkt[1] = X10_HOUSE_INV[(sc->sc_bits & 0x1e0) >> 5];
1073 pkt[2] = X10_KEY_INV[sc->sc_bits & 0x1f];
1074 }
1075 sc->sc_state &= ~TWS_RCVING;
1076 twputpkt(sc, pkt);
1077 untimeout((timeout_func_t)twabortrcv, (caddr_t)sc);
1078 if(sc->sc_flags & TW_RCV_ERROR) {
1079 log(LOG_ERR, "TWRCV: invalid packet: (%d, %x) %c %d\n",
1080 sc->sc_rcount, sc->sc_bits, 'A' + pkt[1], X10_KEY_LABEL[pkt[2]]);
1081 twdebugtimes(sc);
1082 } else {
1083 /* log(LOG_ERR, "TWRCV: valid packet: (%d, %x) %c %s\n",
1084 sc->sc_rcount, sc->sc_bits, 'A' + pkt[1], X10_KEY_LABEL[pkt[2]]); */
1085 }
1086 sc->sc_rcount = 0;
1087 wakeup((caddr_t)sc);
1088 }
1089 }
1090
1091 static void twdebugtimes(struct tw_sc *sc)
1092 {
1093 int i;
1094 for (i = 0; (i < sc->sc_no_rcv) && (i < SC_RCV_TIME_LEN); i++)
1095 log(LOG_ERR, "TWRCV: interrupt %2d: %d\t%d%%\n", i, sc->sc_rcv_time[i],
1096 (sc->sc_rcv_time[i] - sc->sc_rcv_time[(i?i-1:0)])*100/HALFCYCLE);
1097 }
1098
1099 #ifdef HIRESTIME
1100 /*
1101 * Initialize an array of 22 times, starting from the current
1102 * microtime and continuing for the next 21 half cycles.
1103 * We use the times as a reference to make sure transmission
1104 * or reception is on schedule.
1105 */
1106
1107 static void twsetuptimes(int *a)
1108 {
1109 struct timeval tv;
1110 int i, t;
1111
1112 microtime(&tv);
1113 t = tv.tv_usec;
1114 for(i = 0; i < 22; i++) {
1115 *a++ = t;
1116 t += HALFCYCLE;
1117 if(t >= 1000000) t -= 1000000;
1118 }
1119 }
1120
1121 /*
1122 * Check the current time against a slot in a previously set up
1123 * timing array, and make sure that it looks like we are still
1124 * on schedule.
1125 */
1126
1127 static int twchecktime(int target, int tol)
1128 {
1129 struct timeval tv;
1130 int t, d;
1131
1132 microtime(&tv);
1133 t = tv.tv_usec;
1134 d = (target - t) >= 0 ? (target - t) : (t - target);
1135 if(d > 500000) d = 1000000-d;
1136 if(d <= tol && d >= -tol) {
1137 return(1);
1138 } else {
1139 return(0);
1140 }
1141 }
1142 #endif /* HIRESTIME */
1143
1144
1145 static tw_devsw_installed = 0;
1146
1147 static void tw_drvinit(void *unused)
1148 {
1149 dev_t dev;
1150
1151 if( ! tw_devsw_installed ) {
1152 dev = makedev(CDEV_MAJOR, 0);
1153 cdevsw_add(&dev,&tw_cdevsw, NULL);
1154 tw_devsw_installed = 1;
1155 }
1156 }
1157
1158 SYSINIT(twdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,tw_drvinit,NULL)
1159
1160
1161 #endif NTW
Cache object: a2a980f6e80ba0ba3023efbf203411bf
|