Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
86 | f9daq | 1 | //**************************************************************************** |
2 | // Copyright (C) 2000-2004 ARW Elektronik Germany |
||
3 | // |
||
4 | // |
||
5 | // This program is free software; you can redistribute it and/or modify |
||
6 | // it under the terms of the GNU Lesser 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. |
||
9 | // |
||
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. |
||
14 | // |
||
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., 675 Mass Ave, Cambridge, MA 02139, USA. |
||
18 | // |
||
19 | // This product is not authorized for use as critical component in |
||
20 | // life support systems without the express written approval of |
||
21 | // ARW Elektronik Germany. |
||
22 | // |
||
23 | // Please announce changes and hints to ARW Elektronik |
||
24 | // |
||
25 | // Maintainer(s): Klaus Hitschler (klaus.hitschler@gmx.de) |
||
26 | // |
||
27 | //**************************************************************************** |
||
28 | |||
29 | //**************************************************************************** |
||
30 | // |
||
31 | // cc32lib.c -- a simple access library for the PCICC32 PCI to CAMAC Interface |
||
32 | // |
||
33 | // $Log: libcc32.c,v $ |
||
34 | // Revision 1.9 2004/11/29 20:45:36 klaus |
||
35 | // Bug remove. Still release libcc32.so.2. |
||
36 | // |
||
37 | // Revision 1.8 2004/11/29 20:43:12 klaus |
||
38 | // added _qx functions to get Q and X for every transfer. Release libcc32.so.2. |
||
39 | // |
||
40 | // Revision 1.7 2004/08/13 19:48:25 klaus |
||
41 | // changed license from GPL to LGPL |
||
42 | // |
||
43 | // Revision 1.6 2004/08/12 20:00:41 klaus |
||
44 | // conversion to kernel-version 2.6, released version 6.0 |
||
45 | // |
||
46 | // Revision 1.5 2002/05/20 21:24:19 klaus |
||
47 | // Small changes for kernel 2.4.18 |
||
48 | // |
||
49 | // Revision 1.4 2002/04/17 19:41:06 klaus |
||
50 | // added support for autoread |
||
51 | // |
||
52 | // Revision 1.3 2002/04/14 18:25:38 klaus |
||
53 | // added interrupt handling, driver 4.4. ...3.5.tar.gz |
||
54 | // |
||
55 | // Revision 1.2 2001/11/20 20:12:50 klaus |
||
56 | // included new header and CVS log |
||
57 | // |
||
58 | // |
||
59 | // first steps AR 25.02.2000 |
||
60 | // |
||
61 | //**************************************************************************** |
||
62 | |||
63 | /*--- INCLUDES -----------------------------------------------------------------------------------*/ |
||
64 | #include <stdio.h> |
||
65 | #include <stdlib.h> |
||
66 | #include <string.h> |
||
67 | #include <unistd.h> |
||
68 | #include <sys/mman.h> |
||
69 | #include <errno.h> |
||
70 | #include <ctype.h> |
||
71 | #include <sys/ioctl.h> |
||
72 | #include "../driver/pcicc32.h" /* PCI common ioctl commands and structures between driver and library */ |
||
73 | #include "libcc32.h" /* shared header bewteen application and library */ |
||
74 | |||
75 | /*--- DEFINES ------------------------------------------------------------------------------------*/ |
||
76 | #define pwCC32_ADR(adr, N, A, F) (__u16 *)((N << 10) + (A << 6) + ((F & 0xF) << 2) + adr) |
||
77 | #define plCC32_ADR(adr, N, A, F) (__u32 *)((N << 10) + (A << 6) + ((F & 0xF) << 2) + adr) |
||
78 | #define WINDOW_SIZE 32768 |
||
79 | |||
80 | /*--- EXTERNALS ----------------------------------------------------------------------------------*/ |
||
81 | |||
82 | /*--- TYPEDEFS -----------------------------------------------------------------------------------*/ |
||
83 | typedef struct |
||
84 | { |
||
85 | FILE *f; /* the handle of this device */ |
||
86 | int fileNo; /* equals fileno(f) */ |
||
87 | char *base; /* base of range, got with mmap */ |
||
88 | } CC32_DEVICE; |
||
89 | |||
90 | /*--- FUNCTIONS ----------------------------------------------------------------------------------*/ |
||
91 | static int cc32_interrupt_control(CC32_HANDLE handle, int enable) |
||
92 | { |
||
93 | CC32_DEVICE *dev = (CC32_DEVICE *)handle; |
||
94 | PCICC32_IRQ_CONTROL control; |
||
95 | |||
96 | control.bEnable = enable; |
||
97 | |||
98 | return ioctl(dev->fileNo, PCICC32_CONTROL_INTERRUPTS, &control); |
||
99 | } |
||
100 | |||
101 | static int cc32_xxxx_event(CC32_HANDLE handle, int *nTimeout, int *nLam, int nCode) |
||
102 | { |
||
103 | CC32_DEVICE *dev = (CC32_DEVICE *)handle; |
||
104 | PCICC32_STATUS state; |
||
105 | int error; |
||
106 | |||
107 | if ((error = ioctl(dev->fileNo, nCode, &state))) |
||
108 | return error; |
||
109 | |||
110 | *nTimeout = state.bFail; |
||
111 | *nLam = state.bIrq; |
||
112 | |||
113 | if (state.bFail) /* clear error */ |
||
114 | { |
||
115 | if ((error = ioctl(dev->fileNo, PCICC32_IOCNTRL, 0))) |
||
116 | return error; |
||
117 | } |
||
118 | |||
119 | return 0; |
||
120 | } |
||
121 | |||
122 | static int cc32_autoread_control(CC32_HANDLE handle, int nOn) |
||
123 | { |
||
124 | CC32_DEVICE *dev = (CC32_DEVICE *)handle; |
||
125 | PCICC32_AUTOREAD control; |
||
126 | |||
127 | control.bOn = nOn; |
||
128 | |||
129 | return ioctl(dev->fileNo, PCICC32_AUTOREAD_SWITCH, &control); |
||
130 | } |
||
131 | |||
132 | static void cc32_get_qx(CC32_DEVICE *dev, int *Q, int *X) |
||
133 | { |
||
134 | __u16 wstatus = *pwCC32_ADR(dev->base, 0, 0, 0); |
||
135 | |||
136 | *Q = (wstatus & 8) ? 1 : 0; |
||
137 | *X = (wstatus & 4) ? 1 : 0; |
||
138 | } |
||
139 | |||
140 | int cc32_open(char *cszPath, CC32_HANDLE *handle) |
||
141 | { |
||
142 | CC32_DEVICE *dev; |
||
143 | |||
144 | *handle = (CC32_HANDLE)0; |
||
145 | |||
146 | dev = (CC32_DEVICE *)malloc(sizeof(CC32_DEVICE)); |
||
147 | if (!dev) return errno; |
||
148 | |||
149 | dev->fileNo = 0; |
||
150 | dev->base = (char *)0; |
||
151 | |||
152 | if (!(dev->f = fopen(cszPath,"rw"))) |
||
153 | { |
||
154 | int error = errno; |
||
155 | |||
156 | free(dev); |
||
157 | printf("Cannot Open Device %s\n",cszPath); |
||
158 | return error; |
||
159 | } |
||
160 | |||
161 | dev->fileNo = fileno(dev->f); |
||
162 | |||
163 | dev->base = (char *)mmap(0, WINDOW_SIZE, PROT_READ, MAP_FILE | MAP_PRIVATE, dev->fileNo, 0); |
||
164 | if (dev->base == (char *)-1) |
||
165 | { |
||
166 | int error = errno; |
||
167 | |||
168 | fclose(dev->f); |
||
169 | free(dev); |
||
170 | printf("Cannot MMap Device %s\n",cszPath); |
||
171 | |||
172 | return error; |
||
173 | } |
||
174 | |||
175 | *handle = (CC32_HANDLE)dev; |
||
176 | |||
177 | return 0; |
||
178 | } |
||
179 | |||
180 | int cc32_close(CC32_HANDLE handle) |
||
181 | { |
||
182 | CC32_DEVICE *dev = (CC32_DEVICE *)handle; |
||
183 | int error = 0; |
||
184 | |||
185 | if (dev) |
||
186 | { |
||
187 | munmap(dev->base, WINDOW_SIZE); |
||
188 | |||
189 | if (dev->f) |
||
190 | fclose(dev->f); |
||
191 | else |
||
192 | error = -EINVAL; |
||
193 | |||
194 | free(dev); |
||
195 | } |
||
196 | else |
||
197 | error = -EINVAL; |
||
198 | |||
199 | return error; |
||
200 | } |
||
201 | |||
202 | __u16 cc32_read_word(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F) |
||
203 | { |
||
204 | CC32_DEVICE *dev = (CC32_DEVICE *)handle; |
||
205 | |||
206 | return *pwCC32_ADR(dev->base, N, A, F); |
||
207 | } |
||
208 | |||
209 | __u16 cc32_read_word_qx(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F, int *Q, int *X) |
||
210 | { |
||
211 | CC32_DEVICE *dev = (CC32_DEVICE *)handle; |
||
212 | __u32 erg = *plCC32_ADR(dev->base, N, A, F); |
||
213 | |||
214 | *Q = (erg & 0x80000000) ? 1 : 0; |
||
215 | *X = (erg & 0x40000000) ? 1 : 0; |
||
216 | |||
217 | return erg & 0x0000FFFF; // get only the lower 16 bits |
||
218 | } |
||
219 | |||
220 | __u32 cc32_read_long_all(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F) |
||
221 | { |
||
222 | CC32_DEVICE *dev = (CC32_DEVICE *)handle; |
||
223 | |||
224 | return *plCC32_ADR(dev->base, N, A, F);; |
||
225 | } |
||
226 | |||
227 | __u32 cc32_read_long(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F) |
||
228 | { |
||
229 | CC32_DEVICE *dev = (CC32_DEVICE *)handle; |
||
230 | __u32 erg = *plCC32_ADR(dev->base, N, A, F); |
||
231 | |||
232 | return erg & 0x00FFFFFF; |
||
233 | } |
||
234 | |||
235 | __u32 cc32_read_long_qx(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F, int *Q, int *X) |
||
236 | { |
||
237 | CC32_DEVICE *dev = (CC32_DEVICE *)handle; |
||
238 | __u32 erg = *plCC32_ADR(dev->base, N, A, F); |
||
239 | |||
240 | *Q = (erg & 0x80000000) ? 1 : 0; |
||
241 | *X = (erg & 0x40000000) ? 1 : 0; |
||
242 | |||
243 | return erg & 0x00FFFFFF; |
||
244 | } |
||
245 | |||
246 | void cc32_write_word(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F, __u16 uwData) |
||
247 | { |
||
248 | CC32_DEVICE *dev = (CC32_DEVICE *)handle; |
||
249 | |||
250 | *pwCC32_ADR(dev->base, N, A, F) = uwData; |
||
251 | } |
||
252 | |||
253 | void cc32_write_word_qx(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F, __u16 uwData, int *Q, int *X) |
||
254 | { |
||
255 | CC32_DEVICE *dev = (CC32_DEVICE *)handle; |
||
256 | |||
257 | *pwCC32_ADR(dev->base, N, A, F) = uwData; |
||
258 | |||
259 | cc32_get_qx(dev, Q, X); |
||
260 | } |
||
261 | |||
262 | void cc32_write_long(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F, __u32 ulData) |
||
263 | { |
||
264 | CC32_DEVICE *dev = (CC32_DEVICE *)handle; |
||
265 | |||
266 | *plCC32_ADR(dev->base, N, A, F) = ulData; |
||
267 | } |
||
268 | |||
269 | void cc32_write_long_qx(CC32_HANDLE handle, unsigned int N, unsigned int A, unsigned int F, __u32 ulData, int *Q, int *X) |
||
270 | { |
||
271 | CC32_DEVICE *dev = (CC32_DEVICE *)handle; |
||
272 | |||
273 | *plCC32_ADR(dev->base, N, A, F) = ulData; |
||
274 | |||
275 | cc32_get_qx(dev, Q, X); |
||
276 | } |
||
277 | |||
278 | int cc32_poll_event(CC32_HANDLE handle, int *nTimeout, int *nLam) |
||
279 | { |
||
280 | return cc32_xxxx_event(handle, nTimeout, nLam, PCICC32_IOSTATE); |
||
281 | } |
||
282 | |||
283 | int cc32_wait_event(CC32_HANDLE handle, int *nTimeout, int *nLam) |
||
284 | { |
||
285 | return cc32_xxxx_event(handle, nTimeout, nLam, PCICC32_IOSTATE_BLOCKING); |
||
286 | } |
||
287 | |||
288 | int cc32_interrupt_disable(CC32_HANDLE handle) |
||
289 | { |
||
290 | return cc32_interrupt_control(handle, 0); |
||
291 | } |
||
292 | |||
293 | int cc32_interrupt_enable(CC32_HANDLE handle) |
||
294 | { |
||
295 | return cc32_interrupt_control(handle, 1); |
||
296 | } |
||
297 | |||
298 | int cc32_autoread_on(CC32_HANDLE handle) |
||
299 | { |
||
300 | return cc32_autoread_control(handle, 1); |
||
301 | } |
||
302 | |||
303 | int cc32_autoread_off(CC32_HANDLE handle) |
||
304 | { |
||
305 | return cc32_autoread_control(handle, 0); |
||
306 | } |
||
307 |