Subversion Repositories f9daq

Rev

Rev 17 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
16 f9daq 1
//-------------------------------------------------------------------------------------------
2
// pcivme_ni_NT.c - a ni labview dll skeleton for the ARW pcivme interface, winNT
3
//
4
// (c) 1999-2004 ARW Elektronik, Germany
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
// $Log: pcivme_ni_NT.c,v $
15
// Revision 1.2  2004/07/24 07:47:00  klaus
16
// Update copyright to 2004
17
//
18
// Revision 1.1.1.1  2003/11/14 23:17:18  klaus
19
// First put into repository
20
//
21
// Revision 1.4  2002/10/27 21:32:35  klaus
22
// compatibility improved
23
//
24
// Revision 1.3  2002/10/27 19:22:58  klaus
25
// backward compatibilty problem for 2 Gbyte limit solved
26
//
27
// Revision 1.2  2002/10/27 17:05:33  klaus
28
// CVS log added, file addressing bug > 2 Gbtye circumvent
29
//
30
// what                                                              who    when
31
// first steps                                                       AR     07.11.1999
32
//
33
 
34
//-------------------------------------------------------------------------------------------
35
// INCLUDES
36
//
37
#include <windows.h>
38
#include <winioctl.h>
39
#include <pcivme.h>    // header for win-NT
40
#include <vic.h>
41
#include <vme.h>
42
#include <pcivme_ni_NT.h>
43
#include <Klist.h>
44
 
45
//-------------------------------------------------------------------------------------------
46
// DEFINES
47
//
48
#define DEFDEVICENAME "\\\\.\\PCIVME:\\VMEMMxx"
49
#define LIMIT_2GBYTE  0x80000000       // 2 GByte addressing limit of WINNT ...
50
 
51
//-------------------------------------------------------------------------------------------
52
// TYPEDEFS
53
//
54
typedef struct // a element associated to a open path (between VMEinit and VMEclose)
55
{
56
        HANDLE                                  nHandle;
57
        PCIVME_ACCESS_COMMAND   access;
58
} OPEN_PATH;
59
 
60
//-------------------------------------------------------------------------------------------
61
// LOCALS
62
//
63
// user initialisation table for pcivme
64
static PCIVME_INIT_COMMAND sUserInitStruct   = {2, {{STOP, WORD_ACCESS, 0,    0}}};            
65
// user deinitialisation table
66
static PCIVME_INIT_COMMAND sUserDeInitStruct = {2, {{STOP, WORD_ACCESS, 0,    0}}};
67
 
68
// the list of Path specific data (a element lives between VMEinit and VMEclose) 
69
static LIST liPathList          = (LIST)NULL;
70
 
71
//-------------------------------------------------------------------------------------------
72
// EXTERNALS
73
//
74
 
75
//-------------------------------------------------------------------------------------------
76
// GLOBALS
77
//
78
 
79
//-------------------------------------------------------------------------------------------
80
// FUNCTIONS
81
//
82
// not only delete a element - even remove the whole list if it is empty
83
static void removeListElement(OPEN_PATH *open_path)
84
{
85
        List_Delete((LPVOID)open_path);
86
 
87
        // remove the list if the last item was deleted ----
88
        if ((liPathList != NULL) && (List_IsEmpty(liPathList) == TRUE))
89
        {
90
                List_Destroy(&liPathList);
91
                liPathList = (LIST)NULL;
92
        }
93
}
94
 
95
//-------------------------------------------------------------------------
96
// create a DeviceName out of cszDeviceName and nIfcNum
97
static char *DeviceName(const char *cszDeviceName, int nIfcNum)
98
{
99
        static char buffer[255];
100
        char *ptr = buffer;
101
 
102
        if (cszDeviceName == NULL)
103
                strcpy(buffer, DEFDEVICENAME);
104
        else
105
                strcpy(buffer, cszDeviceName);
106
 
107
        while (*ptr) ptr++;
108
 
109
        do
110
        {
111
                ptr--;
112
        } while (*ptr != 'M');
113
 
114
        ptr++;
115
 
116
        if (nIfcNum >= 10)
117
        {
118
                *ptr++   = '1';
119
                nIfcNum -= 10;
120
        }
121
 
122
        *ptr++ = '0' + nIfcNum;
123
        *ptr = 0;
124
 
125
    return buffer;
126
}
127
 
128
int VMEinitNT(const char *cszDeviceName, unsigned short nVMEMM, unsigned char ubAddressModifier, int *pnHandle)
129
{
130
        OPEN_PATH *open_path;
131
        DWORD   DIOC_count;                     // count of returned bytes of DeviceIoControl
132
        DWORD   result;
133
 
134
        if (liPathList == NULL)         // create a list to hold the paths and its variables
135
        {
136
                liPathList = List_Create();
137
                if (liPathList == (LIST)NULL)
138
                        return GetLastError();
139
        }
140
 
141
        open_path = (OPEN_PATH *)List_NewFirst(liPathList, sizeof(OPEN_PATH));
142
 
143
        *pnHandle = -1;
144
 
145
    if ((open_path->nHandle = CreateFile(
146
                                                DeviceName(cszDeviceName, nVMEMM),
147
                                                GENERIC_READ | GENERIC_WRITE,
148
                                                0,
149
                                                NULL,
150
                                                OPEN_EXISTING,
151
                                                FILE_ATTRIBUTE_NORMAL,
152
                                                NULL)) != ((HANDLE)-1))
153
        {
154
                // init hardware (only one time after the first init it works OK)
155
                result = DeviceIoControl(open_path->nHandle,
156
                                                PCIVME_INIT_HARDWARE,
157
                                                &sUserInitStruct,
158
                                                (DWORD)sizeof(sUserInitStruct),
159
                                                NULL,
160
                                                (DWORD)0,
161
                                                &DIOC_count,
162
                                                NULL);
163
 
164
                // set the current access parameters ------------------
165
                open_path->access.bAddressModifier      = ubAddressModifier;
166
                open_path->access.bAccessType           =
167
                open_path->access.bIncrement            = BYTE_ACCESS;
168
                open_path->access.dwAccessBase  = 0;
169
 
170
                result = DeviceIoControl(open_path->nHandle,
171
                                                PCIVME_SET_ACCESS_PARA,
172
                                                &open_path->access,
173
                                                (DWORD)sizeof(open_path->access),
174
                                                NULL,
175
                                                0,
176
                                                &DIOC_count,
177
                                                NULL);   
178
 
179
                if (!result)
180
                {
181
                        result = GetLastError();
182
                        CloseHandle(open_path->nHandle);
183
                        removeListElement(open_path);
184
                        return result;
185
                }
186
 
187
                *pnHandle    = (int)open_path;
188
 
189
                return 0;
190
        }
191
        else
192
        {
193
                result = GetLastError();
194
                removeListElement(open_path);
195
                return result;
196
        }
197
}
198
 
199
int VMEreadNT(int nHandle, unsigned long ulAddress, unsigned char ubAccessWidth, unsigned long ulElementCount, void *pvBuffer)
200
{
201
        DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
202
        unsigned long ulNumberOfBytes = ulElementCount * ubAccessWidth;
203
        unsigned long bytesRead;
204
        OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
205
 
206
        if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
207
 
208
        // set the current access parameters ------------------
209
        open_path->access.bAccessType                   =
210
        open_path->access.bIncrement                    = ubAccessWidth;
211
 
212
        // take care of only 2 Gbyte addressing capabilities of WINNT ...
213
        if (ulAddress >= LIMIT_2GBYTE)
214
        {
215
                ulAddress -= LIMIT_2GBYTE;
216
                open_path->access.dwAccessBase = LIMIT_2GBYTE;
217
        }
218
        else
219
                open_path->access.dwAccessBase = 0;
220
 
221
        if (!DeviceIoControl(open_path->nHandle,
222
                                                PCIVME_SET_ACCESS_PARA,
223
                                                &open_path->access,
224
                                                (DWORD)sizeof(open_path->access),
225
                                                NULL,
226
                                                0,
227
                                                &DIOC_count,
228
                                                NULL))   
229
                return GetLastError();
230
 
231
        SetFilePointer(open_path->nHandle, ulAddress, NULL, FILE_BEGIN);
232
 
233
        if (!ReadFile(open_path->nHandle, pvBuffer, ulNumberOfBytes, &bytesRead, NULL))
234
                return GetLastError();
235
 
236
        return 0;
237
}
238
 
239
int VMEwriteNT(int nHandle, unsigned long ulAddress, unsigned char ubAccessWidth, unsigned long ulElementCount, void *pvBuffer)
240
{
241
        DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
242
        unsigned long ulNumberOfBytes = ulElementCount * ubAccessWidth;
243
        unsigned long bytesRead;
244
        OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
245
 
246
        if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
247
 
248
        // set the current access parameters ------------------
249
        open_path->access.bAccessType    =
250
        open_path->access.bIncrement     = ubAccessWidth;
251
 
252
        // take care of only 2 Gbyte addressing capabilities of WINNT ...
253
        if (ulAddress >= LIMIT_2GBYTE)
254
        {
255
                ulAddress -= LIMIT_2GBYTE;
256
                open_path->access.dwAccessBase = LIMIT_2GBYTE;
257
        }
258
        else
259
                open_path->access.dwAccessBase = 0;
260
 
261
        if (!DeviceIoControl(open_path->nHandle,
262
                                                        PCIVME_SET_ACCESS_PARA,
263
                                                        &open_path->access,
264
                                                        (DWORD)sizeof(open_path->access),
265
                                                        NULL,
266
                                                        0,
267
                                                        &DIOC_count,
268
                                                        NULL))   
269
                return GetLastError();
270
 
271
        SetFilePointer(open_path->nHandle, ulAddress, NULL, FILE_BEGIN);
272
 
273
        if (!WriteFile(open_path->nHandle, pvBuffer, ulNumberOfBytes, &bytesRead, NULL))
274
                return GetLastError();
275
 
276
        return 0;
277
}
278
 
279
int VMEaccessVICNT(int nHandle, unsigned char ubAccessMode, unsigned short uwAddress, unsigned char *ubContent)
280
{
281
        DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
282
        OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
283
        PCIVME_VIC68A_ACTION   sAction;    // structure to access vic chip
284
        DWORD                  result;
285
 
286
        if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
287
 
288
        sAction.wRegisterAddress = uwAddress;
289
        sAction.wAccessMode      = ubAccessMode;
290
        sAction.bContent         = *ubContent;
291
 
292
        result = DeviceIoControl(open_path->nHandle, PCIVME_ACCESS_VIC68A,
293
                                         &sAction, sizeof(sAction), &sAction,
294
                                                        sizeof(sAction), &DIOC_count, NULL);     
295
 
296
        *ubContent = sAction.bContent;
297
 
298
        if (!result)
299
                return GetLastError();
300
        else
301
                return 0;
302
}
303
 
304
int VMEresetNT(int nHandle)
305
{
306
        DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
307
        OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
308
        DWORD   result;
309
        PCIVME_RESET_COMMAND reset_command;
310
        PCIVME_RESET_RESULT  reset_result;
311
 
312
        if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
313
 
314
        reset_command.wCommand = VME_RESET_CMD;
315
        reset_result.wResult   = 0;
316
        result = DeviceIoControl(open_path->nHandle, PCIVME_RESET,
317
                &reset_command, sizeof(reset_command),
318
                                &reset_result,  sizeof(reset_result),
319
                                   &DIOC_count, NULL);   
320
 
321
        if (!result)
322
                return GetLastError();
323
        else
324
        {
325
                result = 1;
326
 
327
                while (reset_result.wResult && result)
328
                {
329
                        reset_command.wCommand = POLL_RESET_CMD;
330
                        result = DeviceIoControl(open_path->nHandle, PCIVME_RESET,
331
                                                &reset_command, sizeof(reset_command),
332
                                                &reset_result,  sizeof(reset_result),
333
                                                        &DIOC_count, NULL);      
334
                        Sleep(10);
335
                }
336
        }
337
 
338
        if (!result)
339
                return GetLastError();
340
        else
341
                return 0;
342
}
343
 
344
int VMETASNT(int nHandle, unsigned long ulAddress, unsigned char *ubResult)
345
{
346
        DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
347
        OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
348
        PCIVME_TAS_STRUCT      sTAS;       // structure to do a Test and Set
349
        DWORD                  result;
350
 
351
        if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
352
 
353
        sTAS.wModifier        = open_path->access.bAddressModifier;
354
        sTAS.dwAddress        = ulAddress;
355
        sTAS.bContent         = 0x80;
356
 
357
        result = DeviceIoControl(open_path->nHandle, PCIVME_TAS,
358
                                         &sTAS, (DWORD)sizeof(sTAS), &sTAS,
359
                                                        (DWORD)sizeof(sTAS), &DIOC_count, NULL);
360
 
361
        *ubResult = sTAS.bContent;
362
 
363
        if (!result)
364
                return GetLastError();
365
        else
366
                return 0;
367
}
368
 
369
int VMEinterruptNT(int nHandle, unsigned char *ubVector)
370
{
371
//      DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
372
        OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
373
 
374
        if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
375
 
376
        return 0;
377
}
378
 
379
int VMEsysfailGetNT(int nHandle, BOOLEAN *bResult)
380
{
381
        DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
382
        OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
383
        PCIVME_VIC68A_ACTION   sAction;    // structure to access vic chip
384
        DWORD result;
385
 
386
        if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
387
 
388
        sAction.wRegisterAddress = EGICR;
389
        sAction.wAccessMode      = VIC68A_READ;
390
        sAction.bContent         = 0;
391
 
392
        result = DeviceIoControl(open_path->nHandle, PCIVME_ACCESS_VIC68A,
393
                                         &sAction, sizeof(sAction), &sAction,
394
                                                        sizeof(sAction), &DIOC_count, NULL);     
395
 
396
 
397
        *bResult = (sAction.bContent & 0x08) ? FALSE : TRUE;
398
 
399
        if (!result)
400
                return GetLastError();
401
        else
402
                return 0;
403
}
404
 
405
int VMEsysfailSetNT(int nHandle, BOOLEAN bForce)
406
{
407
        DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
408
        OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
409
        PCIVME_VIC68A_ACTION   sAction;    // structure to access vic chip
410
        DWORD result;
411
 
412
        if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
413
 
414
        sAction.wRegisterAddress = ICR7;
415
        sAction.wAccessMode      = (bForce == TRUE) ? VIC68A_AND : VIC68A_OR;
416
        sAction.bContent         = (bForce == TRUE) ? 0x3F               : 0x80;
417
 
418
        result = DeviceIoControl(open_path->nHandle, PCIVME_ACCESS_VIC68A,
419
                                         &sAction, (DWORD)sizeof(sAction), &sAction,
420
                                                        (DWORD)sizeof(sAction), &DIOC_count, NULL);
421
        if (!result)
422
                return GetLastError();
423
        else
424
                return 0;
425
}
426
 
427
int VMEcloseNT(int nHandle)
428
{
429
        DWORD    DIOC_count;     // count of returned bytes of DeviceIoControl
430
        OPEN_PATH *open_path = (OPEN_PATH *)nHandle;
431
 
432
        if (nHandle == -1) return ERROR_PATH_NOT_FOUND;
433
 
434
        DeviceIoControl(open_path->nHandle,
435
                                                PCIVME_DEINIT_HARDWARE,
436
                                                &sUserDeInitStruct,
437
                                                (DWORD)sizeof(sUserDeInitStruct),
438
                                                NULL,
439
                                                0,
440
                                                &DIOC_count,
441
                                                NULL);   
442
 
443
        CloseHandle(open_path->nHandle);
444
        removeListElement(open_path);
445
 
446
        return 0;
447
}
448