|
1 /** @brief device support adcPi |
|
2 * |
|
3 */ |
|
4 #include <stdio.h> |
|
5 #include <stdlib.h> |
|
6 #include <devSup.h> |
|
7 #include <recGbl.h> |
|
8 #include <alarm.h> |
|
9 #include <errlog.h> |
|
10 #include <aiRecord.h> |
|
11 #include <epicsExport.h> |
|
12 #include "drvAdcPi.h" |
|
13 |
|
14 typedef struct { |
|
15 adcPiCard* card; |
|
16 int signal; |
|
17 } adcPiAiPrivate; |
|
18 |
|
19 long adcPiInitRecordAi (aiRecord *record); |
|
20 long adcPiReadAi (aiRecord *record); |
|
21 long adcPiSpecialLinconvAi (aiRecord *record, int after); |
|
22 |
|
23 struct { |
|
24 long number; |
|
25 DEVSUPFUN report; |
|
26 DEVSUPFUN init; |
|
27 DEVSUPFUN init_record; |
|
28 DEVSUPFUN get_ioint_info; |
|
29 DEVSUPFUN read_ai; |
|
30 DEVSUPFUN special_linconv; |
|
31 } adcPiAi = { |
|
32 6, |
|
33 NULL, |
|
34 NULL, |
|
35 adcPiInitRecordAi, |
|
36 NULL, |
|
37 adcPiReadAi, |
|
38 adcPiSpecialLinconvAi |
|
39 }; |
|
40 epicsExportAddress (dset, adcPiAi); |
|
41 |
|
42 /** @brief init record |
|
43 * |
|
44 */ |
|
45 long adcPiInitRecordAi (aiRecord *record) |
|
46 { |
|
47 adcPiAiPrivate *priv; |
|
48 epicsUInt16 initval; |
|
49 adcPiCard* card; |
|
50 int signal; |
|
51 |
|
52 if (record->inp.type != VME_IO) { |
|
53 errlogSevPrintf (errlogFatal, "adcPiInitRecordAi %s: illegal INP link type\n", record->name); |
|
54 return -1; |
|
55 } |
|
56 |
|
57 card = adcPiOpen (record->inp.value.vmeio.card); |
|
58 if (!card) { |
|
59 errlogSevPrintf (errlogFatal, "adcPiInitRecordAi %s: invalid card number %d\n", record->name, record->inp.value.vmeio.card); |
|
60 return S_dev_noDevice; |
|
61 } |
|
62 |
|
63 signal = record->inp.value.vmeio.signal; |
|
64 if (signal < 0 || signal >= ADC_PI_MAX_CHANNEL) { |
|
65 errlogSevPrintf (errlogFatal, "adcPiInitRecordAi %s: invalid signal number %d\n", record->name, signal); |
|
66 return S_dev_badSignalNumber; |
|
67 } |
|
68 |
|
69 priv = (adcPiAiPrivate*) malloc (sizeof (adcPiAiPrivate)); |
|
70 if (!priv) { |
|
71 errlogSevPrintf (errlogFatal, "adcPiInitRecordAi %s: out of memory\n", record->name); |
|
72 return S_dev_noMemory; |
|
73 } |
|
74 |
|
75 priv->card = card; |
|
76 priv->signal = signal; |
|
77 record->dpvt = priv; |
|
78 |
|
79 // printf(" priv at @%p [%d]\n", priv, sizeof (adcPiAiPrivate) ); |
|
80 |
|
81 adcPiSpecialLinconvAi (record, TRUE); |
|
82 adcPiGet (card, signal, &initval); |
|
83 |
|
84 record->rval = initval; |
|
85 return 0; |
|
86 } |
|
87 |
|
88 long adcPiReadAi (aiRecord *record) |
|
89 { |
|
90 adcPiAiPrivate *priv = (adcPiAiPrivate*) record->dpvt; |
|
91 int status; |
|
92 |
|
93 // printf("ReadAi: priv at @%p [%d]\n", priv, sizeof (adcPiAiPrivate) ); |
|
94 |
|
95 if (!priv) { |
|
96 recGblSetSevr (record, UDF_ALARM, INVALID_ALARM); |
|
97 errlogSevPrintf (errlogFatal, "adcPiReadAi %s: record not initialized correctly\n", record->name); |
|
98 return -1; |
|
99 } |
|
100 unsigned short value; |
|
101 status = adcPiGet (priv->card, priv->signal, &value); |
|
102 if (status) { |
|
103 errlogSevPrintf (errlogFatal, "adcPiReadAi %s: adcPiGet failes: error code 0x%x\n", record->name, status); |
|
104 recGblSetSevr (record, READ_ALARM, INVALID_ALARM); |
|
105 } |
|
106 record->rval = value; |
|
107 return status; // 2 do not convert |
|
108 } |
|
109 |
|
110 long adcPiSpecialLinconvAi (aiRecord *record, int after) |
|
111 { |
|
112 if (after) { |
|
113 // printf(" In convert ....\n"); |
|
114 // Check/Check ... |
|
115 // MAX_CODE_12BIT / 2048 Volt |
|
116 //record->eoff = ( 8191 * record->egul - -8192 * record->eguf) / (8191 - 8192); |
|
117 record->eoff = 0; |
|
118 record->eslo = 0.000250; // 205 uV (record->eguf - record->egul)/ (8191 - 8192); |
|
119 } |
|
120 return 0; |
|
121 } |
|
122 |
|
123 |
|
124 |