1: /*
2: * Cary 118c Spectrophotometer Driver
3: *
4: * WFJ 19-AUG-78
5: * wfj 8 mar 80 (rewritten for version 7)
6: */
7:
8: /*
9: * SCCS id @(#)cary.c 2.1 (Berkeley) 8/5/83
10: */
11:
12: /* #define debug */
13:
14: #include "param.h"
15: #include <sys/conf.h>
16: #include <sys/dir.h>
17: #include <sys/user.h>
18: #include <sys/tty.h>
19:
20: #define PRI (PZERO+1) /*user's wait priority */
21: #define NELEMENTS 32 /* depth of internal buffer q */
22:
23: /* states */
24: #define OPEN 1
25: #define DATAQ 2
26: #define DATAZ 4
27: #define OVERRUN 010
28:
29: /* device bits */
30: #define DATAINTS 1
31: #define SWINTS 2
32: #define LITE 4
33: #define MODE_MSK 0400
34: #define TENK_MSK 0200
35: #define START_MSK 01000
36: #define OVERANGE 02000
37: #define READY 04000
38: #define SIGN_MSK 0100000
39:
40: #define DEFAULT 200L /* default sample freq. */
41:
42: struct cary118
43: {
44: int state;
45: union {
46: long freq;
47: int w[2];
48: } frun;
49: long count;
50: int head,tail; /* ring buffer pointers */
51: int buffer[NELEMENTS];
52: #ifdef debug
53: unsigned notready;
54: unsigned ovflow;
55: #endif
56: } cary;
57:
58: struct device
59: {
60: int data; /* read-only */
61: int csr; /* no read-modify-write instructions (rmw)*/
62: };
63:
64: struct device *CARYADDR = ((struct device*)0160040);
65: /* note: the carlock board has data & switch interrupts at 270 & 274 */
66:
67: caryattach(addr, unit)
68: struct device *addr;
69: {
70: if (unit != 0)
71: return(0);
72: CARYADDR = addr;
73: return(1);
74: }
75:
76: caryopen()
77: {
78: if ((CARYADDR == (struct device *) NULL) || cary.state)
79: {
80: u.u_error = ENXIO;
81: return;
82: }
83: cary.state = OPEN;
84: CARYADDR->csr = SWINTS;
85: cary.count = 0L;
86: cary.frun.freq = DEFAULT;
87: cary.head = cary.tail = 0;
88: }
89:
90: caryclose()
91: {
92: CARYADDR->csr = 0;
93: cary.state = 0;
94: }
95:
96: caryioctl(dev,cmd,addr,flag)
97: dev_t dev;
98: int cmd;
99: register caddr_t addr;
100: int flag;
101: {
102: register x,y;
103:
104: switch(cmd)
105: {
106:
107: /* get status */
108: case ('c'<<8)+0:
109: suword(addr, CARYADDR->csr);
110: addr += 2;
111: suword(addr,cary.frun.w[0]);
112: addr += 2;
113: suword(addr,cary.frun.w[1]);
114: addr += 2;
115: suword(addr,cary.state);
116: return;
117:
118: /* set sample frequency/rate */
119: case ('c'<<8)+1:
120: addr += 2;
121: x = fuword(addr);
122: addr += 2;
123: y = fuword(addr);
124: if (x == -1 || y == -1)
125: {
126: u.u_error = EFAULT;
127: return;
128: }
129: cary.frun.w[0] = x; cary.frun.w[1] = y;
130: return;
131:
132: default:
133: u.u_error = ENOTTY;
134: return;
135: }
136: }
137:
138: caryread()
139: {
140: union
141: {
142: int w;
143: char b[2];
144: } w;
145:
146: do
147: {
148: while (cary.head == cary.tail)
149: {
150: if ((cary.state & OPEN) == 0)
151: return;
152: sleep((caddr_t)&cary, PRI);
153: }
154: w.w = cary.buffer[cary.tail];
155: cary.tail = ++cary.tail % NELEMENTS;
156: } while ( (passc(w.b[0])>=0) && (passc(w.b[1])>=0));
157:
158: }
159:
160: caryswint()
161: {
162: register m;
163:
164: if(!cary.state)
165: {
166: CARYADDR->csr = 0;
167: return;
168: }
169: m = CARYADDR->csr & START_MSK;
170: if( m && (cary.state & DATAQ) == 0)
171: { /* allow data accquisition (interrupts) */
172: cary.state |= DATAQ;
173: CARYADDR->csr = DATAINTS | SWINTS | LITE;
174: return;
175: }
176: if( m == 0 && (cary.state & DATAQ))
177: { /* disable accquisition */
178: cary.state &= ~OPEN;
179: CARYADDR->csr = 0;
180: wakeup((caddr_t)&cary);
181: return;
182: }
183: }
184:
185: carydataint()
186: {
187: register int data, val, x;
188: if(--cary.count <= 0)
189: { /* take data */
190: if( (cary.state & OPEN) == 0)
191: {
192: CARYADDR->csr = 0;
193: return;
194: }
195: cary.count = cary.frun.freq;
196: data = CARYADDR->data;
197: val = 0;
198: /*
199: * Convert bcd to binary
200: */
201:
202: for(x = 12;x >= 0; x -= 4)
203: val = 10 * val + (017 & (data >> x));
204: data = CARYADDR->csr;
205: #ifdef debug
206: if (!data&READY)
207: cary.notready++;
208: #endif
209: if (data & TENK_MSK)
210: val += 10000;
211: if(!(data & SIGN_MSK))val = -val;
212: cary.buffer[cary.head] = val;
213: cary.head = ++cary.head % NELEMENTS;
214: if (cary.head == cary.tail) {
215: printf("Ring buffer overflow!\n");
216: cary.state |= OVERRUN;
217: #ifdef debug
218: cary.ovflow++;
219: #endif
220: }
221:
222: /*
223: * This blinks the indicator lamp at the data rate.
224: * (its this complicated cause csr can't do rmw cycles.
225: * thus no csr ^= LITE...)
226: */
227:
228: if (cary.state & DATAZ)
229: CARYADDR->csr = SWINTS|DATAINTS|LITE;
230: else
231: CARYADDR->csr = SWINTS|DATAINTS;
232: cary.state ^= DATAZ;
233: wakeup((caddr_t)&cary);
234: }
235: }
Defined functions
Defined variables
cary
defined in line
56; used 42 times
Defined struct's
Defined macros
DATAQ
defined in line
25; used 3 times
DATAZ
defined in line
26; used 2 times
LITE
defined in line
32; used 2 times
OPEN
defined in line
24; used 4 times
PRI
defined in line
20; used 1 times
READY
defined in line
37; used 1 times