source: trigger/v812.c@ 4350

Last change on this file since 4350 was 115, checked in by daqct3, 15 years ago
New Functions
File size: 10.5 KB
Line 
1
2
3//******************************************************************************
4//Constants
5//******************************************************************************
6
7#define NMAX_V812_MODULES 10 //maximum 65535, probably more than enough...
8#define V812_CHANNELS 16
9#include "v812.h"
10//******************************************************************************
11//Type definitions
12//******************************************************************************
13
14
15//******************************************************************************
16//Global Variables
17//******************************************************************************
18
19v812_module_t v812_modules[NMAX_V812_MODULES];
20
21//******************************************************************************
22//Function Definitions
23//******************************************************************************
24
25VME_ErrorCode_t V812_Open(void)
26{
27 u_int tmp_virtual_address, tmp_base_address;
28 u_short i=0;
29 VME_ErrorCode_t error_code;
30 VME_MasterMap_t master_map;
31
32 master_map.vmebus_address = 0x00010000;
33 master_map.window_size = 0x1000;
34 master_map.address_modifier = VME_A24;
35 master_map.options = 0;
36
37 for(i=0; i<NMAX_V812_MODULES; i++) {
38 v812_modules[i].present = 0;
39 }
40
41 //opening the file containing the base addresses
42 FILE *datfile = fopen("v812_base.dat","r");
43 char line[256];
44
45 i=0;
46 if (datfile!=NULL) {
47 while(fgets(line,255,datfile)) {
48
49 //excluding comment lines
50 if(line[0] == '%') {
51 continue;
52 }
53
54 //reading the hex address
55 if(!sscanf(&line[2],"%8x",&tmp_base_address)) {
56 printf("Reading input file v812_base.dat: non-comment line without address found. Please delete or comment this line.\n");
57 }
58
59 //check address, assign to the master map
60 if(tmp_base_address & 0x0000FFFF) {
61 printf("Reading input file v812_base.dat: 0x%08x is no valid base address (0xXXXX0000)\n",tmp_base_address);
62 continue;
63 }
64 if(i>=NMAX_V812_MODULES) {
65 printf("Reading input file v812_base.dat: More addresses found than memory space provided.\nIncrease NMAX_V812_MODULES in v812.h and v812.c.\n");
66 break;
67 }
68 master_map.vmebus_address = tmp_base_address;
69
70 if(error_code = VME_MasterMap(&master_map,&v812_modules[i].master_mapping)) {
71 VME_ErrorPrint(error_code);
72 return error_code;
73 }
74
75 if(error_code = VME_MasterMapVirtualAddress(v812_modules[i].master_mapping,&tmp_virtual_address)) {
76 VME_ErrorPrint(error_code);
77 return error_code;
78 }
79
80 v812_modules[i].registers = (v812_registers_t *) tmp_virtual_address;
81
82 if(v812_modules[i].registers->manufacturer_type==0x0851) {
83 //printf("v812-module %i found at address 0x%08x:\n\tMaster mapping: %i\n\tVirtual address: 0x%08x\n\n",i+1,tmp_base_address,v812_modules[i].master_mapping,v812_modules[i].registers);
84 v812_modules[i].present = 1;
85 }
86 else {
87 printf("Module %i at address 0x%08x is not of type v812, or module not found. Please check the v812_base.dat-file.\n\n",i+1,tmp_base_address);
88 v812_modules[i].present = 0;
89 if(error_code = VME_MasterUnmap(v812_modules[i].master_mapping)) {
90 VME_ErrorPrint(error_code);
91 return error_code;
92 }
93 }
94
95 i++;
96 }
97 fclose(datfile);
98 }
99 else { printf("File v812_base.dat containing the base addresses of the v812-modules not found.\n"); error_code = VME_FILE; return error_code; }
100
101 return VME_SUCCESS;
102}
103
104//******************************************************************************
105
106int V812_Set_Threshold(short module, short channel, short threshold)
107{
108 //return values
109 //0: threshold set successful
110 //1: module out of range or not present
111 //2: channel number out of range
112 //3: threshold out of range (threshold in mV between -1 mV and -255 mV)
113
114 if((module>NMAX_V812_MODULES) || (v812_modules[module-1].present != 1)) { return 1; }
115 if(!((channel>=0) && (channel<=15))) { return 2; }
116 if(!((threshold>=1) && (channel<=255))) { return 3; }
117 v812_modules[module-1].registers->threshold_ch[channel] = threshold;
118 return 0;
119
120 /* comment on little/big endian: the Intel architecture uses little Endian coding,
121 whereas the VME-Standard uses big Endian (to my knowledge). Nonetheless the thresholds
122 can be written directly to the module memory since the thresholds are saved as 8 bit
123 words located at the adress of the short integer (according to the Technical Information
124 Manual MOD. V 812 Series, p 16). */
125}
126
127//******************************************************************************
128
129int V812_Set_Pattern_Inhibit(short module, char channels[16])
130{
131 //return values
132 //0: pattern of inhibit written successfully
133 //1: module out of range or not present
134 if((module>NMAX_V812_MODULES) || (v812_modules[module-1].present != 1)) { return 1; }
135
136 //create the pattern of inhibit
137 u_short pattern = 0;
138 int i;
139 for(i=0; i<16; i++) {
140 if(channels[i]!=0) {
141 switch(i) {
142 case 0: pattern |= 0x0001; break;
143 case 1: pattern |= 0x0002; break;
144 case 2: pattern |= 0x0004; break;
145 case 3: pattern |= 0x0008; break;
146 case 4: pattern |= 0x0010; break;
147 case 5: pattern |= 0x0020; break;
148 case 6: pattern |= 0x0040; break;
149 case 7: pattern |= 0x0080; break;
150 case 8: pattern |= 0x0100; break;
151 case 9: pattern |= 0x0200; break;
152 case 10: pattern |= 0x0400; break;
153 case 11: pattern |= 0x0800; break;
154 case 12: pattern |= 0x1000; break;
155 case 13: pattern |= 0x2000; break;
156 case 14: pattern |= 0x4000; break;
157 case 15: pattern |= 0x8000; break;
158 }
159 }
160 }
161 v812_modules[module-1].registers->pattern_inhibit = pattern;
162 return 0;
163}
164int V812_Set_Pattern_Inhibit_Hex(short module, int pattern)
165{
166 //return values
167 //0: pattern of inhibit written successfully
168 //1: module out of range or not present
169 if((module>NMAX_V812_MODULES) || (v812_modules[module-1].present != 1)) { return 1; }
170
171 v812_modules[module-1].registers->pattern_inhibit = pattern;
172 return 0;
173}
174//******************************************************************************
175
176int V812_Set_Output_Width(short module, short channel_block, short width)
177{
178 //channel_block: 0 for ch0-ch7, 1 for ch8-ch15
179
180 //return values
181 //0: width set successful
182 //1: module out of range or not present
183 //2: channel_block out of range
184 //3: width out of range (width between 0 (15 ns) and 255 (250 ns), non-linear relation)
185
186 if((module>NMAX_V812_MODULES) || (v812_modules[module-1].present != 1)) { return 1; }
187 if(!((channel_block>=0) && (channel_block<=1))) { return 2; }
188 if(!((width>=0) && (width<=255))) { return 3; }
189 v812_modules[module-1].registers->output_width[channel_block] = width;
190 return 0;
191}
192
193//******************************************************************************
194
195int V812_Set_Dead_Time(short module, short channel_block, short dead_time)
196{
197 //channel_block: 0 for ch0-ch7, 1 for ch8-ch15
198
199 //return values
200 //0: dead time set successful
201 //1: module out of range or not present
202 //2: channel_block out of range
203 //3: dead time out of range (dead time between 0 (150 ns) and 255 (2 us))
204
205 if((module>NMAX_V812_MODULES) || (v812_modules[module-1].present != 1)) { return 1; }
206 if(!((channel_block>=0) && (channel_block<=1))) { return 2; }
207 if(!((dead_time>=0) && (dead_time<=255))) { return 3; }
208 v812_modules[module-1].registers->dead_time[channel_block] = dead_time;
209 return 0;
210}
211
212//******************************************************************************
213
214int V812_Set_Majority_Level(short module, short majority_level)
215{
216 //majority_level according to Technical Information Manual, p. 17
217
218 //return values
219 //0: majority level set succesful
220 //1: module out of range or not present
221 //2: majority level out of range (1 to 20)
222
223 u_short majority_threshold;
224
225 if((module>NMAX_V812_MODULES) || (v812_modules[module-1].present != 1)) { return 1; }
226 if(!((majority_level>=1) && (majority_level<=20))) { return 2; }
227
228 majority_threshold = (double) (majority_level*50-25)/4 + 0.5;
229 //Why + 0.5? This is necessary for the correct calculation of the nearest integer since double-variables are truncated when converted to integer
230
231 v812_modules[module-1].registers->majority_threshold = majority_threshold;
232 return 0;
233}
234int V812_Set_Majority_Threshold(short module, short majority_threshold)
235{
236 //majority_threshold according to Technical Information Manual, p. 17
237
238 //return values
239 //0: majority threshold set succesful
240 //1: module out of range or not present
241 //2: majority threshold out of range (1 to 255)
242
243 if((module>NMAX_V812_MODULES) || (v812_modules[module-1].present != 1)) { return 1; }
244 if(!((majority_threshold>=1) && (majority_threshold<=255))) { return 2; }
245 v812_modules[module-1].registers->majority_threshold = majority_threshold;
246 return 0;
247}
248
249//******************************************************************************
250
251int V812_Test_Pulse(short module)
252{
253 //return values
254 //0: test pulse generated successfully
255 //1: module out of range or not present
256
257 if((module>NMAX_V812_MODULES) || (v812_modules[module-1].present != 1)) { return 1; }
258 v812_modules[module-1].registers->test_pulse = 0xFFFF;
259 return 0;
260}
261
262//******************************************************************************
263
264int V812_Print_Info(void)
265{
266 //return values
267 //0: print to stdio successful
268
269 u_short manufacturer, type, version, sn, i;
270
271 for(i=0; i<NMAX_V812_MODULES; i++) {
272 if(v812_modules[i].present != 1) {
273 printf("Module %i is not present.\n",i+1);
274 continue;
275 }
276
277 printf("v812-module %i (master mapping %i) found:\n",i+1,v812_modules[i].master_mapping);
278 manufacturer = v812_modules[i].registers->manufacturer_type; manufacturer &= 0xFC00; // 0b1111 1100 0000 0000
279 type = v812_modules[i].registers->manufacturer_type; type &= 0x03FF; // 0b0000 0011 1111 1111
280 version = v812_modules[i].registers->version_serialnumber; version &= 0xF000; // 0b1111 0000 0000 0000
281 sn = v812_modules[i].registers->version_serialnumber; sn &= 0x0FFF; // 0b0000 1111 1111 1111
282 printf("Manufacturer: 0x%04x\nType: 0x%04x\nVersion: 0x%04x\nSerial Number:0x%04x\n\n", manufacturer, type, version, sn);
283 }
284 return 0;
285}
286
287//******************************************************************************
288
289
290VME_ErrorCode_t V812_Close(void)
291{
292 VME_ErrorCode_t error_code;
293 u_short i;
294
295 for(i=0; i<NMAX_V812_MODULES; i++) {
296 if(v812_modules[i].present != 1) continue;
297
298 printf("Closing v812-module %i with master mapping %i...",i+1,v812_modules[i].master_mapping);
299 if(error_code = VME_MasterUnmap(v812_modules[i].master_mapping)) {
300 VME_ErrorPrint(error_code);
301 return error_code;
302 }
303 printf("closed.\n");
304 }
305
306 return VME_SUCCESS;
307}
308
309//******************************************************************************
Note: See TracBrowser for help on using the repository browser.