]>
Commit | Line | Data |
---|---|---|
a8827307 | 1 | // constants |
2 | static const int fgkEmCalRows = 24; // number of rows per module for EMCAL | |
3 | static const int fgkEmCalCols = 48; // number of columns per module for EMCAL | |
4 | ||
5 | const int NRCU = 2; // per SM | |
6 | const int NBranch = 2; // per RCU | |
7 | const int NFEC = 9; // per branch, labelled 1..9 | |
8 | const int NCSP = 32; // per FEC | |
9 | ||
cdb5074a | 10 | // conversion between DAC (0-0x3ff) and HV values (V): |
11 | // hv = hvmin + prop*DAC; values from PHOS manual, and used in Houston/Catania | |
12 | const float hvmin = 209.9; | |
13 | const float prop = 0.2022; | |
14 | ||
a8827307 | 15 | // some global variables |
cdb5074a | 16 | Float_t biasVoltage[NRCU][NBranch][NFEC][NCSP]; |
a8827307 | 17 | int towerCol[NRCU][NBranch][NFEC][NCSP]; |
18 | int towerRow[NRCU][NBranch][NFEC][NCSP]; | |
19 | ||
20 | //__________________________________________________________ | |
21 | void Tower2FEEBiasInfo(const char *inputFileName) | |
22 | { | |
23 | ifstream inputFile(inputFileName); | |
cdb5074a | 24 | int ic, ir; |
25 | Float_t ival; | |
a8827307 | 26 | int ircu, ibranch, card, icsp; |
27 | for (int icol=0; icol<fgkEmCalCols; icol++) { | |
28 | for (int irow=0; irow<fgkEmCalRows; irow++) { | |
29 | inputFile >> ic >> ir >> ival; | |
30 | ||
31 | // could check here that ic && ir match with icol && irow, but should not be needed | |
32 | ||
33 | // translate to FEE type indices | |
34 | Tower2FEEMap(ic, ir, | |
35 | &ircu, &ibranch, &card, &icsp); | |
36 | ||
37 | // debug | |
38 | /* | |
39 | printf("ic %d ir %d ircu %d ibranch %d card %d icsp %d\n", | |
40 | ic, ir, ircu, ibranch, card, icsp); | |
41 | */ | |
42 | ||
43 | // store value | |
44 | biasVoltage[ircu][ibranch][card][icsp] = ival; | |
45 | towerCol[ircu][ibranch][card][icsp] = ic; | |
46 | towerRow[ircu][ibranch][card][icsp] = ir; | |
47 | } | |
48 | } | |
49 | ||
50 | inputFile.close(); | |
51 | ||
52 | return; | |
53 | } | |
54 | ||
55 | //__________________________________________________________ | |
56 | void Tower2FEEMap(const int icol, const int irow, | |
57 | int *ircu, int *ibranch, int *card, int *icsp) | |
58 | { /* | |
59 | If you are interested in where these magic numbers come from - | |
60 | See mapping info on | |
61 | http://dsilverm.web.cern.ch/dsilverm/mapping/emcal_mapping.html | |
62 | http://dsilverm.web.cern.ch/dsilverm/mapping/ppt/Coordinates_and_Mapping.pdf | |
63 | */ | |
64 | ||
65 | // each FEC covers a 4x8 tower area | |
66 | int C = irow/8; // Cable bundle | |
67 | int FEC = C*12 + icol/4; // FEC in 0..35 range | |
68 | ||
69 | *ircu = FEC / 18; // 18 FEC per RCU | |
70 | *ibranch = (FEC%18) / 9; | |
71 | *card = FEC % 9; | |
72 | ||
73 | // columns and rows within an FEC area | |
74 | int tCol = icol%4; | |
75 | int tRow = irow%8; | |
76 | ||
77 | // The mapping to CSP is a bit complicated so I also define two more help variables here.. | |
78 | // which T-card? | |
79 | int TCard = tCol/2; // 0=Top (even StripModules), 1=Bottom (odd StripModules) | |
80 | int locCol = tCol%2; // local column inside T-card | |
81 | ||
82 | *icsp = (7 - tRow) + locCol*16 + TCard*8; | |
83 | } | |
84 | ||
85 | /* Main method.. */ | |
86 | //__________________________________________________________ | |
87 | void DCSGenerateAPD(const char *inputFileName, | |
88 | const char *outputDir, | |
f49a14fe | 89 | const int readBack=0, |
90 | const int RCUFWVersion=1, // default as of May 2009 is RCU FWv2 | |
91 | const int FEEBCVersion=1) // default as of May 2009 is PCM4 | |
a8827307 | 92 | { |
93 | ||
94 | // set up which bias voltage should be applicable for which CSP.. | |
95 | Tower2FEEBiasInfo(inputFileName); | |
96 | ||
f49a14fe | 97 | // general setup block: try to keep magic numbers/registers collected here |
a8827307 | 98 | const char *branch_str[] = { "A", "B"}; |
f49a14fe | 99 | const int nRCUFW = 2; |
100 | const char *rcufw_str[] = { "v1", "v2"}; | |
101 | const int rcu_addr_start[nRCUFW] = {0x7000, 0x0000}; | |
102 | const int read_header[nRCUFW] = {0x520000, 0x020000}; | |
103 | const int write_header[nRCUFW] = {0x620000, 0x220000}; | |
104 | const int voltage_value_start[nRCUFW] = {0x700000, 0x200000}; | |
105 | const int rcu_endmem[nRCUFW] = {0x390000, 0x3F0000}; | |
106 | const int rcu_exeseq[nRCUFW] = {0x0, 0x5304}; | |
107 | const int rcu_result_reg[nRCUFW] = {0x6000, 0x2000}; | |
108 | ||
109 | const int nFEEBC = 2; | |
110 | const char *feebc_str[] = { "PCM3", "PCM4"}; | |
111 | const int trailer_offset[nFEEBC] = {0x48, 0x68}; | |
112 | const int update_voltage_register = 0x1E; | |
113 | const int max_dac_value = 0x3FF; | |
114 | ||
115 | printf("DCSGenerateAPD: RCU FW %s, FEE BC %s\n", | |
116 | rcufw_str[RCUFWVersion], feebc_str[FEEBCVersion]); | |
117 | ||
a8827307 | 118 | // resulting voltage settings should be good within a few volts |
119 | cout << " HV-DAC prop. constant = " << prop << endl; | |
120 | char iv_dac_setting[100]; | |
121 | ||
122 | char cfile[200]; | |
123 | ||
124 | FILE* fout_setbias_card[NRCU][NBranch][NFEC]; | |
125 | FILE* fout_readbias_card[NRCU][NBranch][NFEC]; | |
126 | ||
127 | // end of setup, let's go.. | |
128 | ||
f49a14fe | 129 | int rcu_addr_card = rcu_addr_start[RCUFWVersion]; |
0c5cf7f0 | 130 | int csp_addr = trailer_offset[FEEBCVersion]; |
a8827307 | 131 | int word = 0; |
132 | char comment[400]; | |
133 | ||
f49a14fe | 134 | int rcu_addr_read = rcu_addr_start[RCUFWVersion]; // we'll also write the readbias file in the same loop, so |
a8827307 | 135 | // need a separate index also |
136 | ||
137 | for (int rcu=0; rcu<NRCU; rcu++) { | |
138 | for (int branch=0; branch<NBranch; branch++) { | |
139 | for (int ifec=0; ifec<NFEC; ifec++) { | |
140 | int card = ifec; | |
141 | int icard = ifec+1; | |
142 | ||
143 | sprintf(cfile,"%s/set_rcu_%d_bias_branch_%s_FEC_%d.scr", | |
144 | outputDir, rcu, | |
145 | branch_str[branch], icard); | |
146 | fout_setbias_card[rcu][branch][card] = fopen(cfile, "w"); | |
147 | ||
148 | sprintf(cfile,"%s/read_rcu_%d_bias_branch_%s_FEC_%d.scr", | |
149 | outputDir, rcu, | |
150 | branch_str[branch], icard); | |
151 | fout_readbias_card[rcu][branch][card] = fopen(cfile, "w"); | |
152 | ||
f49a14fe | 153 | rcu_addr_card = rcu_addr_start[RCUFWVersion]; |
154 | rcu_addr_read = rcu_addr_start[RCUFWVersion]; | |
a8827307 | 155 | |
156 | for (int icsp = 0; icsp<NCSP; icsp++) { | |
157 | ||
158 | /* | |
159 | some funkiness to address the CSPs correctly follows here. | |
160 | DS verified this with section 16.1 "Bias voltage programming", table 8 | |
161 | of H. Muller's PHOS manual (version from Jan 2007) | |
162 | */ | |
0c5cf7f0 | 163 | if (icsp<16) { csp_addr = trailer_offset[FEEBCVersion] + icsp; } |
164 | else { csp_addr = trailer_offset[FEEBCVersion] - 1 - (icsp%16); } | |
a8827307 | 165 | if (icsp >= 24) csp_addr += 0x20; |
166 | ||
167 | // what does the desired voltage (in V) correspond to in DAC? | |
cdb5074a | 168 | int iv_dac = (int)( (biasVoltage[rcu][branch][card][icsp] - hvmin)/prop + 0.5); // round-off |
f49a14fe | 169 | if (iv_dac > max_dac_value) iv_dac = max_dac_value; |
170 | sprintf(iv_dac_setting,"%06X", voltage_value_start[RCUFWVersion] + iv_dac); | |
a8827307 | 171 | |
172 | // set up instructions that should be written | |
f49a14fe | 173 | word = write_header[RCUFWVersion] | (branch << 16) | (icard << 12) | (csp_addr); |
a8827307 | 174 | |
175 | // write a long comment with all info for this CSP | |
cdb5074a | 176 | sprintf(comment, "# RCU %d, Branch %s, FEC %d, CSP %02d - Tower Col %02d, Row %02d ", |
a8827307 | 177 | rcu, branch_str[branch], icard, icsp, |
178 | towerCol[rcu][branch][card][icsp], | |
179 | towerRow[rcu][branch][card][icsp] | |
180 | ); | |
181 | ||
f49a14fe | 182 | fprintf(fout_setbias_card[rcu][branch][card], "w 0x%04X 0x%6X %s\n", |
a8827307 | 183 | rcu_addr_card, word, comment); |
184 | rcu_addr_card++; | |
185 | ||
f49a14fe | 186 | fprintf(fout_setbias_card[rcu][branch][card], "w 0x%04X 0x%s # Set Voltage: %4.1f V, DAC %d (hex: %03X)\n", |
a8827307 | 187 | rcu_addr_card, iv_dac_setting, |
188 | biasVoltage[rcu][branch][card][icsp], | |
189 | iv_dac, iv_dac | |
190 | ); | |
191 | rcu_addr_card++; | |
192 | ||
193 | // slighly modified comment for read command - include voltage info | |
cdb5074a | 194 | sprintf(comment, "# RCU %d, Branch %s, FEC %d, CSP %02d - Tower Col %02d, Row %02d : %4.1f V, DAC %d (hex: %03X)", |
a8827307 | 195 | rcu, branch_str[branch], icard, icsp, |
196 | towerCol[rcu][branch][card][icsp], | |
197 | towerRow[rcu][branch][card][icsp], | |
198 | biasVoltage[rcu][branch][card][icsp], | |
199 | iv_dac, iv_dac | |
200 | ); | |
201 | ||
f49a14fe | 202 | word = read_header[RCUFWVersion] | (branch << 16) | (icard << 12) | (csp_addr); |
203 | fprintf(fout_readbias_card[rcu][branch][card], "w 0x%04X 0x%06X %s\n", rcu_addr_read, word, comment); | |
a8827307 | 204 | rcu_addr_read++; |
205 | } // csp loop | |
206 | ||
207 | // after CSP per card; send update command | |
f49a14fe | 208 | word = write_header[RCUFWVersion] | (branch << 16) | (icard << 12) | update_voltage_register; |
209 | fprintf(fout_setbias_card[rcu][branch][card],"w 0x%04X 0x%06X # Update Voltages\n", | |
a8827307 | 210 | rcu_addr_card, word); |
211 | rcu_addr_card++; | |
f49a14fe | 212 | fprintf(fout_setbias_card[rcu][branch][card],"w 0x%04X 0x%06X \n", |
213 | rcu_addr_card, voltage_value_start[RCUFWVersion]); | |
214 | rcu_addr_card++; | |
a8827307 | 215 | |
216 | // also put ending for the individual card files: | |
f49a14fe | 217 | fprintf(fout_setbias_card[rcu][branch][card],"w 0x%04X 0x%06X # End of the instruction memory\n", |
218 | rcu_addr_card, rcu_endmem[RCUFWVersion]); | |
a8827307 | 219 | rcu_addr_card++; |
220 | ||
f49a14fe | 221 | fprintf(fout_setbias_card[rcu][branch][card],"wait 100 us\n"); |
222 | fprintf(fout_setbias_card[rcu][branch][card],"w 0x%X 0x0 # execute and update registers\n", | |
223 | rcu_exeseq[RCUFWVersion]); | |
224 | if (RCUFWVersion == 0) { // specialty for old FW version | |
225 | fprintf(fout_setbias_card[rcu][branch][card],"wait 100 us\n"); | |
226 | fprintf(fout_setbias_card[rcu][branch][card],"r 0x7800 # error checking\n"); | |
227 | fprintf(fout_setbias_card[rcu][branch][card],"w 0x6c01 0x 0 # clear registers\n"); | |
228 | } | |
a8827307 | 229 | |
230 | // in case we want to check what was written | |
231 | if (readBack) { | |
f49a14fe | 232 | fprintf(fout_setbias_card[rcu][branch][card],"wait 100 us\n"); |
a8827307 | 233 | fprintf(fout_setbias_card[rcu][branch][card],"b %s # read-back the values also\n", cfile); |
f49a14fe | 234 | fprintf(fout_setbias_card[rcu][branch][card],"wait 100 us\n"); |
a8827307 | 235 | } |
236 | ||
a8827307 | 237 | // close down output files (set) |
238 | fclose(fout_setbias_card[rcu][branch][card]); | |
239 | ||
240 | // readbias ending | |
f49a14fe | 241 | fprintf(fout_readbias_card[rcu][branch][card],"w 0x%04X 0x%06X \n", |
242 | rcu_addr_read, rcu_endmem[RCUFWVersion]); | |
a8827307 | 243 | rcu_addr_read++; |
244 | ||
245 | fprintf(fout_readbias_card[rcu][branch][card],"wait 1 us\n"); | |
f49a14fe | 246 | fprintf(fout_readbias_card[rcu][branch][card],"w 0x%X 0x0 # execute and update registers\n", |
247 | rcu_exeseq[RCUFWVersion]); | |
a8827307 | 248 | |
249 | fprintf(fout_readbias_card[rcu][branch][card],"wait 1 us\n"); | |
f49a14fe | 250 | int nRead = NCSP*2; // new FW reads back i/o |
251 | if (RCUFWVersion == 0) { // specialty for old FW version | |
252 | fprintf(fout_readbias_card[rcu][branch][card],"r 0x7800 # error checking\n"); | |
253 | fprintf(fout_readbias_card[rcu][branch][card],"wait 1 us\n"); | |
254 | nRead = NCSP; | |
255 | } | |
256 | fprintf(fout_readbias_card[rcu][branch][card],"r 0x%04X %d( \n", rcu_result_reg[RCUFWVersion], nRead); | |
257 | if (RCUFWVersion == 0) { // specialty for old FW version | |
258 | fprintf(fout_readbias_card[rcu][branch][card],"wait 1 us\n"); | |
259 | fprintf(fout_readbias_card[rcu][branch][card],"r 0x7800 # error checking\n"); | |
260 | fprintf(fout_readbias_card[rcu][branch][card],"w 0x6c01 0x 0 # clear registers\n"); | |
261 | } | |
262 | ||
a8827307 | 263 | // close down output files (read) |
264 | fclose(fout_readbias_card[rcu][branch][card]); | |
265 | ||
266 | } // card=FEC | |
267 | } // branch | |
268 | } // rcu | |
269 | ||
270 | } |