Subversion Repositories f9daq

Rev

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