Subversion Repositories f9daq

Rev

Rev 21 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
21 f9daq 1
/*
2
   cc32lib.c -- a simple access library for the PCICC32 PCI to CAMAC Interface from ARW Elektronik
3
 
4
   (c) 2000 ARW Elektronik
5
 
6
   this source code is published under GPL (Open Source). You can use, redistrubute and
7
   modify it unless this header   is not modified or deleted. No warranty is given that
8
   this software will work like expected.
9
   This product is not authorized for use as critical component in life support systems
10
   wihout the express written approval of ARW Elektronik Germany.
11
 
12
   Please announce changes and hints to ARW Elektronik
13
 
14
   first steps derived from the LINUX pcicc32 library                   AR   16.03.2000
15
   added buffer, UNTIL_NOT_Q and AUTOREAD functionality                 AR   17.03.2001
16
   corrected fault in setAccessParameter()                              AR   21.05.2002
17
   added framework only fro future interrupt handling                   AR   08.06.2002
18
*/
19
 
20
/*--- INCLUDES -----------------------------------------------------------------------------------*/
21
#include <windows.h>
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
#include <errno.h>
26
#include "Vpcic32D.h"     /* PCI common ioctl commands and structures between driver and library  */
27
#include "libcc32_95.h"   /* shared header bewteen applictaion and library                        */
28
 
29
/*--- DEFINES ------------------------------------------------------------------------------------*/
30
#define pwCC32_ADR(adr, N, A, F) (unsigned short *)((N << 10) + (A << 6) + ((F & 0xF) << 2) + adr)
31
#define plCC32_ADR(adr, N, A, F) (unsigned long *)((N << 10) + (A << 6) + ((F & 0xF) << 2) + adr)
32
#define WINDOW_SIZE 32768
33
 
34
/*--- EXTERNALS ----------------------------------------------------------------------------------*/
35
 
36
/*--- TYPEDEFS -----------------------------------------------------------------------------------*/
37
typedef struct
38
{
39
        HANDLE nHandle;       /* the handle of this device */
40
        int    nModuleNumber; /* the number of the module */
41
        char   *base;             /* base of range             */
42
        unsigned short wLastAttributes; /* switched attributes like UNTIL_NOT_Q or AUTOREAD */
43
} CC32_DEVICE;
44
 
45
/*--- FUNCTIONS -----------------------------------------------------------------------*/
46
 
47
//--------------------------------------------------------------------------------------
48
// a function to get the base address of the CAMAC range
49
//
50
static int attachWindow(HANDLE nHandle, DWORD dwInterface, void **base)
51
{
52
        VPCIC32D_WINDOW window;
53
        DWORD DIOC_count;             // count of returned bytes of DeviceIoControl
54
        DWORD result;
55
 
56
    *base = NULL;
57
        if (nHandle == (HANDLE)-1) return ERROR_INVALID_HANDLE;
58
 
59
        // attach a window into the CC32 space ----------------
60
        result = DeviceIoControl(nHandle, VPCIC32_ATTACH_CC32,
61
                                                &dwInterface, sizeof(dwInterface),
62
                                                &window,      sizeof(window),
63
                                                                 &DIOC_count, NULL);
64
 
65
    if (!result)
66
                return GetLastError();
67
        else
68
        {
69
                *base = window.pvWindowBase;
70
                return 0;
71
        }
72
}
73
 
74
//--------------------------------------------------------------------------------------
75
// a function to release a attached range
76
//
77
static int detachWindow(HANDLE nHandle, DWORD dwInterface)
78
{
79
        DWORD DIOC_count;             // count of returned bytes of DeviceIoControl
80
        DWORD result;
81
 
82
        if (nHandle == (HANDLE)-1) return ERROR_INVALID_HANDLE;
83
 
84
        // attach a window into the CC32 space ----------------
85
        result = DeviceIoControl(nHandle, VPCIC32_DETACH_CC32,
86
                                                &dwInterface, sizeof(dwInterface),
87
                                                NULL,      0, &DIOC_count, NULL);
88
    if (!result)
89
                return GetLastError();
90
        else
91
                return 0;
92
}
93
 
94
//--------------------------------------------------------------------------------------
95
// get the PCIADA status from the PCI side of the interface
96
//
97
static int getStatus(HANDLE nHandle, DWORD dwInterface, char *nTimeout, char *nLAM)
98
{
99
        VPCIC32D_STATUS status;
100
        DWORD DIOC_count;             // count of returned bytes of DeviceIoControl
101
        DWORD result;
102
 
103
        if (nHandle == (HANDLE)-1) return ERROR_INVALID_HANDLE;
104
 
105
        *nTimeout = *nLAM = 0;
106
 
107
        // attach a window into the CC32 space ----------------
108
        result = DeviceIoControl(nHandle, VPCIC32_GET_STATUS,
109
                                                &dwInterface, sizeof(dwInterface),
110
                                                &status,      sizeof(status), &DIOC_count, NULL);
111
 
112
    if (!result)
113
                return GetLastError();
114
        else
115
        {
116
                *nTimeout = (char)status.bTimeout;
117
                *nLAM     = (char)status.bInterrupt;
118
 
119
                return 0;
120
        }
121
}
122
 
123
//--------------------------------------------------------------------------------------
124
// clear the PCIADA status
125
//
126
static int clearStatus(HANDLE nHandle, DWORD dwInterface)
127
{
128
        DWORD DIOC_count;             // count of returned bytes of DeviceIoControl
129
        DWORD result;
130
 
131
        if (nHandle == (HANDLE)-1) return ERROR_INVALID_HANDLE;
132
 
133
        // attach a window into the CC32 space ----------------
134
        result = DeviceIoControl(nHandle, VPCIC32_CLEAR_STATUS,
135
                                                &dwInterface, sizeof(dwInterface),
136
                                                NULL,      0, &DIOC_count, NULL);
137
 
138
    if (!result)
139
                return GetLastError();
140
        else
141
                return 0;
142
}
143
 
144
//-------------------------------------------------------------------------
145
// set the future access parameters - override the current
146
//
147
static int setAccessParameter(HANDLE hHandle, DWORD dwInterface, USHORT wBlockTransfer)
148
{
149
        DWORD result;
150
        DWORD   DIOC_count;     // count of returned bytes of DeviceIoControl
151
    VPCIC32D_ACCESS_COMMAND access_parameter;
152
 
153
        if (hHandle == (HANDLE)-1) return ERROR_INVALID_HANDLE;
154
 
155
        access_parameter.dwInterface        = dwInterface;
156
        access_parameter.wBlockTransfer         = wBlockTransfer;
157
 
158
        result = DeviceIoControl(hHandle, VPCIC32_SET_ACCESS_PARA,
159
                                        &access_parameter, (DWORD)sizeof(access_parameter), NULL,
160
                                                   0, &DIOC_count, NULL);        
161
        if (!result)
162
                return GetLastError();
163
        else
164
                return 0;
165
}
166
 
167
//--------------------------------------------------------------------------------------
168
// open the device
169
//
170
int cc32_open_95(char *cszPath, int nModuleNumber, void **handle)
171
{
172
        CC32_DEVICE *dev;
173
        int error;
174
 
175
        *handle = (void *)-1;
176
 
177
        dev = (CC32_DEVICE *)malloc(sizeof(CC32_DEVICE));
178
        if (!dev) return errno;
179
 
180
        dev->base   = (char *)0;
181
        dev->nModuleNumber = nModuleNumber;
182
        dev->wLastAttributes = 0;
183
 
184
        dev->nHandle = CreateFile(cszPath,
185
                                                0,
186
                                                0,
187
                                                NULL,
188
                                                0,
189
                                                FILE_FLAG_DELETE_ON_CLOSE,
190
                                                NULL);
191
 
192
        if (dev->nHandle != INVALID_HANDLE_VALUE)
193
        error = attachWindow(dev->nHandle, nModuleNumber, &dev->base);
194
        else
195
                error = GetLastError();
196
 
197
        if (error)
198
        {
199
                free(dev);
200
                return error;
201
        }
202
 
203
        *handle = (void *)dev;
204
 
205
        return NO_ERROR;
206
}
207
 
208
//--------------------------------------------------------------------------------------
209
// close the device
210
//
211
int cc32_close_95(void *handle)
212
{
213
        CC32_DEVICE *dev = (CC32_DEVICE *)handle;
214
        int error = NO_ERROR;
215
 
216
        if (dev)
217
        {
218
                if (dev->nHandle != INVALID_HANDLE_VALUE)
219
                {
220
                        detachWindow(dev->nHandle, dev->nModuleNumber);
221
                        CloseHandle(dev->nHandle);
222
                }
223
 
224
                free(dev);
225
        }
226
        else
227
                error = ERROR_INVALID_FUNCTION;
228
 
229
        return error;
230
}
231
 
232
//--------------------------------------------------------------------------------------
233
// read a word
234
//
235
unsigned short cc32_read_word_95(void *handle, unsigned int N, unsigned int A, unsigned int F)
236
{
237
        CC32_DEVICE *dev = (CC32_DEVICE *)handle;
238
 
239
        return *pwCC32_ADR(dev->base, N, A, F);
240
}
241
 
242
//--------------------------------------------------------------------------------------
243
// read a long
244
//
245
unsigned long cc32_read_long_all_95(void *handle, unsigned int N, unsigned int A, unsigned int F)
246
{
247
        CC32_DEVICE *dev = (CC32_DEVICE *)handle;
248
 
249
        return *plCC32_ADR(dev->base, N, A, F);
250
}
251
 
252
//--------------------------------------------------------------------------------------
253
// read a long and get Q and X
254
//
255
unsigned long cc32_read_long_95(void *handle, unsigned int N, unsigned int A, unsigned int F, char *Q, char *X)
256
{
257
        CC32_DEVICE *dev = (CC32_DEVICE *)handle;
258
        unsigned long erg = *plCC32_ADR(dev->base, N, A, F);
259
 
260
        *Q = (erg & 0x80000000) ? 1 : 0;
261
        *X = (erg & 0x40000000) ? 1 : 0;
262
 
263
        return erg & 0x00FFFFFF;
264
}
265
 
266
//--------------------------------------------------------------------------------------
267
// write a word
268
//
269
void cc32_write_word_95(void *handle, unsigned int N, unsigned int A, unsigned int F, unsigned short uwData)
270
{
271
        CC32_DEVICE *dev = (CC32_DEVICE *)handle;
272
 
273
        dev->wLastAttributes = 0;
274
        *pwCC32_ADR(dev->base, N, A, F) = uwData;
275
}
276
 
277
//--------------------------------------------------------------------------------------
278
// write a long
279
//
280
void cc32_write_long_95(void *handle, unsigned int N, unsigned int A, unsigned int F, unsigned long ulData)
281
{
282
        CC32_DEVICE *dev = (CC32_DEVICE *)handle;
283
 
284
        dev->wLastAttributes = 0;
285
        *plCC32_ADR(dev->base, N, A, F) = ulData;
286
}
287
 
288
//--------------------------------------------------------------------------------------
289
// clear the PCIADA status
290
//
291
int cc32_poll_error_95(void *handle, char *nTimeout, char *nLam)
292
{
293
        CC32_DEVICE *dev = (CC32_DEVICE *)handle;
294
        int error;
295
 
296
    if ((error = getStatus(dev->nHandle, dev->nModuleNumber, nTimeout, nLam)))
297
                return error;
298
 
299
        if (*nTimeout)  /* clear error */
300
        {
301
                if ((error = clearStatus(dev->nHandle, dev->nModuleNumber)))
302
                        return error;  
303
        }
304
 
305
        return NO_ERROR;
306
}
307
 
308
//--------------------------------------------------------------------------------------
309
// read 'len' words or 'UNTIL_NOT_Q' from a address made out of N,A,F 
310
//
311
int cc32_read_word_buffer_95(void * handle, unsigned int N, unsigned int A, unsigned int F,
312
                                                                                                                                unsigned short *pwBuffer, unsigned long *pdwLen)
313
{
314
        CC32_DEVICE *dev = (CC32_DEVICE *)handle;
315
        register unsigned long i = 0;
316
        unsigned long dwLen = *pdwLen;
317
        unsigned long *pdwAddress = plCC32_ADR(dev->base, N, A, F);
318
        register unsigned long dwTempBuffer;
319
 
320
        if (dev->wLastAttributes & UNTIL_NOT_Q)
321
        {
322
                do
323
                {
324
                        dwTempBuffer = *pdwAddress;
325
                        *pwBuffer++ = (unsigned short)dwTempBuffer;
326
                } while ((dwTempBuffer & 0x80000000) && (i++ < dwLen));
327
        }
328
        else
329
        {
330
                while (i++ < dwLen)
331
                        *pwBuffer++ = (unsigned short)*pdwAddress;
332
        }
333
 
334
        *pdwLen = --i;
335
        return 0;
336
}
337
 
338
//--------------------------------------------------------------------------------------
339
// read 'len' longs or 'UNTIL_NOT_Q' from a address made out of N,A,F, mask 24 bits out
340
//
341
int cc32_read_long_buffer_95(void * handle, unsigned int N, unsigned int A, unsigned int F,
342
                                                                                                                                unsigned long *pdwBuffer, unsigned long *pdwLen)
343
{
344
        CC32_DEVICE *dev = (CC32_DEVICE *)handle;
345
        register unsigned long i = 0;
346
        unsigned long dwLen = *pdwLen;
347
        unsigned long *pdwAddress = plCC32_ADR(dev->base, N, A, F);
348
        register unsigned long dwTempBuffer;
349
 
350
        if (dev->wLastAttributes & UNTIL_NOT_Q)
351
        {
352
                do
353
                {
354
                        dwTempBuffer = *pdwAddress;
355
                        *pdwBuffer++ = dwTempBuffer & 0x00FFFFFF;
356
                } while ((dwTempBuffer & 0x80000000) && (i++ < dwLen));
357
        }
358
        else
359
        {
360
                while (i++ < dwLen)
361
                        *pdwBuffer++ = *pdwAddress & 0x00FFFFFF;
362
        }
363
 
364
        *pdwLen = --i;
365
        return 0;
366
}
367
 
368
//--------------------------------------------------------------------------------------
369
// read 'len' longs or 'UNTIL_NOT_Q' from a address made out of N,A,F, without interpretation 
370
//
371
int cc32_read_long_all_buffer_95(void * handle, unsigned int N, unsigned int A, unsigned int F,
372
                                                                                                                                unsigned long *pdwBuffer, unsigned long *pdwLen)
373
{
374
        CC32_DEVICE *dev = (CC32_DEVICE *)handle;
375
        register unsigned long i = 0;
376
        unsigned long dwLen = *pdwLen;
377
        unsigned long *pdwAddress = plCC32_ADR(dev->base, N, A, F);
378
        register unsigned long dwTempBuffer;
379
 
380
        if (dev->wLastAttributes & UNTIL_NOT_Q)
381
        {
382
                do
383
                {
384
                        dwTempBuffer = *pdwAddress;
385
                        *pdwBuffer++ = dwTempBuffer;
386
                } while ((dwTempBuffer & 0x80000000) && (i++ < dwLen));
387
        }
388
        else
389
        {
390
                while (i++ < dwLen)
391
                        *pdwBuffer++ = *pdwAddress;
392
        }
393
 
394
        *pdwLen = --i;
395
        return 0;
396
}
397
 
398
//--------------------------------------------------------------------------------------
399
// switch UNTIL_NOT_Q or AUTOREAD on or off 
400
//
401
int cc32_access_switch_95(void *handle, unsigned short uwSwitch)
402
{
403
        CC32_DEVICE *dev = (CC32_DEVICE *)handle;
404
 
405
        dev->wLastAttributes = uwSwitch;
406
        return setAccessParameter(dev->nHandle, dev->nModuleNumber, dev->wLastAttributes);
407
}
408
 
409
//--------------------------------------------------------------------------------------
410
// switch interrupts on
411
//
412
int cc32_enable_interrupt_95(void *handle)
413
{
414
        return ERROR_INVALID_FUNCTION;
415
}
416
 
417
//--------------------------------------------------------------------------------------
418
// switch interrupts off
419
//
420
int cc32_disable_interrupt_95(void *handle)
421
{
422
        return ERROR_INVALID_FUNCTION;
423
}
424
 
425
//--------------------------------------------------------------------------------------
426
// wait blocking for the next interrupt
427
//
428
int cc32_get_interrupt_95(void *handle, unsigned long *dwStatus)
429
{
430
        return ERROR_INVALID_FUNCTION;
431
}