Subversion Repositories f9daq

Rev

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