Skip to content

Commit 6d4f1aa

Browse files
committed
Added automated baseline adjustment routine.
1 parent a90bc0d commit 6d4f1aa

3 files changed

Lines changed: 155 additions & 39 deletions

File tree

DAQController.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ int DAQController::InitializeElectronics(std::string opts, std::vector<int>&keys
7777
// Load registers into digitizers
7878
for( auto const& link : fDigitizers ) {
7979
for(auto digi : link.second){
80+
81+
// Load DAC. n.b.: if you set the DAC value in your ini file you'll overwrite
82+
// the fancy stuff done here!
83+
vector<u_int32_t>dac_values(8, 0x1000);
84+
int nominal_dac = fOptions->GetInt("baseline_value", 16000);
85+
digi->ConfigureBaselines(dac_values, nominal_dac, 100);
86+
8087
int success=0;
8188
for(auto regi : fOptions->GetRegisters(digi->bid())){
8289
unsigned int reg = fHelper->StringToHex(regi.reg);

V1724.cc

Lines changed: 143 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ unsigned int V1724::ReadRegister(unsigned int reg){
117117
std::stringstream err;
118118
err<<"Failed to read register 0x"<<hex<<reg<<dec<<" on board "<<fBID<<endl;
119119
fLog->Entry(err.str(), MongoLog::Warning);
120-
return -1;
120+
return 0xFFFFFFFF;
121121
}
122122
return temp;
123123
}
@@ -175,10 +175,8 @@ u_int32_t V1724::ReadMBLT(unsigned int *&buffer){
175175

176176
}
177177

178-
int V1724::ConfigureBaselines(int nominal_value,
179-
int ntries,
180-
vector <unsigned int> start_values,
181-
vector <unsigned int> &end_values){
178+
int V1724::ConfigureBaselines(vector <unsigned int> &end_values,
179+
int nominal_value, int ntries){
182180

183181
// Baseline configuration routine. The V1724 has a DAC offset setting that
184182
// biases the ADC, allowing you to effectively move the 'zero level' of the
@@ -188,8 +186,8 @@ int V1724::ConfigureBaselines(int nominal_value,
188186
// suited to your acquisition (positive, negative, bipolar logic)
189187

190188
// n.b. hard-coding guess to 16000 for testing
191-
u_int32_t target_value = 16000;
192-
int max_deviation = 5;
189+
u_int32_t target_value = nominal_value;
190+
int adjustment_threshold = 2;
193191

194192
// We can adjust a DAC offset register, which is 0xffff in range, is inversely
195193
// proportional to the baseline position, and has ~5% overshoot on either end.
@@ -202,7 +200,7 @@ int V1724::ConfigureBaselines(int nominal_value,
202200
// Now we need to load a simple configuration to the board in order to read
203201
// some data. try/catch cause CAENVMElib fails poorly (segfault) sometimes
204202
// in case the hardware has an issue.
205-
write_success = 0;
203+
int write_success = 0;
206204
try{
207205
write_success += WriteRegister(0x8000, 0x10); // Channel configuration
208206
write_success += WriteRegister(0x8080, 0x800000); // DPP
@@ -211,7 +209,9 @@ int V1724::ConfigureBaselines(int nominal_value,
211209
write_success += WriteRegister(0xEF24, 0x1); // Global reset
212210
write_success += WriteRegister(0xEF1C, 0x1); // BERR
213211
write_success += WriteRegister(0xEF00, 0x10); // Channel memory
214-
write_success += WriteRegister(0x8120, 0xFF); // Channel mask
212+
write_success += WriteRegister(0x8034, 0x0); // Delay to zero
213+
write_success += WriteRegister(0x8038, 0x0); // Pre trig to zero
214+
write_success += WriteRegister(0x8120, 0xFF); // Channel mask
215215
}
216216
catch(const std::exception &e){
217217
std::stringstream error;
@@ -232,26 +232,26 @@ int V1724::ConfigureBaselines(int nominal_value,
232232
// Now we'll iterate for a while. It should be pretty quick since starting values
233233
// should be quite close to true.
234234
int currentIteration = 0;
235-
int maxIterations = 100;
235+
int maxIterations = ntries;
236236
while(currentIteration < maxIterations){
237237
currentIteration++;
238238
bool breakout = true;
239+
240+
// Load DAC for this channel
241+
if(LoadDAC(dac_values)!=0){
242+
std::stringstream error;
243+
error<<"Digitizer "<<fBID<<" failed to load DAC in baseline routine.";
244+
fLog->Entry(error.str(), MongoLog::Error);
245+
return -1;
246+
}
239247

240-
for(unsigned int channel=0; channel<nChannels; channel++){
248+
for(int channel=0; channel<nChannels; channel++){
241249
if(channel_finished[channel])
242250
continue;
243-
breakout = false;
244-
245-
// Load DAC for this channel
246-
if(LoadDAC(channel, dac_values[channel])!=0){
247-
std::stringstream error;
248-
error<<"Digitizer "<<fBID<<" channel "<<channel<<" failed to load DAC in baseline routine.";
249-
fLog->Entry(error.str(), MongoLog::Error);
250-
return -1;
251-
}
251+
breakout = false;
252252

253253
// Tell board to read out this channel only
254-
unsigned short channel_mask = 1 << channel;
254+
unsigned short channel_mask = 0x80000000+(1 << channel);
255255
if(WriteRegister(0x8120, channel_mask)!=0){
256256
stringstream error;
257257
error<<"Digitizer "<<fBID<<" channel "<<channel<<" failed to set channel mask in baseline.";
@@ -260,28 +260,136 @@ int V1724::ConfigureBaselines(int nominal_value,
260260
}
261261

262262
// Trigger the board with software trigger
263-
WriteRegister(CBV1724_AcquisitionControlReg,0x24);
264-
WriteRegister(CBV1724_SoftwareTriggerReg,0x1);
265-
usleep(50); // paranoia. Like, you need some time to acquire right?
266-
WriteRegister(CBV1724_AcquisitionControlReg,0x0);
263+
//usleep(10000);
264+
WriteRegister(0x8100,0x4);//x24 // Acq control reg
265+
//usleep(1000); // Prevent zeroes in data stream
266+
WriteRegister(0x8108,0x1); // Software trig reg
267+
usleep(1000); // paranoia. Like, you need some time to acquire right?
268+
WriteRegister(0x8100,0x0); // Acq off
267269

270+
// Now read the data. Don't forget to delete buff later.
271+
u_int32_t *buff=NULL;
272+
u_int32_t size = ReadMBLT(buff);
273+
int baseline = -1;
268274

269-
// Sample Samples
270-
// Good? then finish
271-
// Else twiddle DAC offset
272-
// Repeat
273-
}
275+
// Parse it up. Remember we masked every channel except the one
276+
// we want so should be just that one in the data.
277+
unsigned int idx = 0;
278+
while(idx < size/sizeof(u_int32_t)){
279+
if(buff[idx]>>20==0xA00){ // header
274280

281+
// Sanity check. Is this your channel?
282+
u_int32_t cmask = buff[idx+1]&0xFF;
283+
if(!((cmask>>channel)&1)){
284+
// wtf?
285+
std::cout<<"Got wrong channel in baselines."<<std::endl;
286+
break;
287+
}
288+
289+
idx += 4;
290+
u_int32_t csize = buff[idx];
291+
idx+=2;
292+
int tbase = 0;
293+
u_int32_t minval=0x3fff, maxval=0;
294+
295+
for(unsigned int i=0; i<csize-2; i++){
296+
tbase += buff[idx+i]&0xFFFF;
297+
tbase += (buff[idx+i]>>16)&0xFFFF;
298+
if((buff[idx+i]&0xFFFF)<minval)
299+
minval = buff[idx+i]&0xFFFF;
300+
if((buff[idx+i]&0xFFFF)>maxval)
301+
maxval = buff[idx+i]&0xFFFF;
302+
if(((buff[idx+i]>>16)&0xFFFF)<minval)
303+
minval=(buff[idx+i]>>16)&0xFFFF;
304+
if(((buff[idx+i]>>16)&0xFFFF)>maxval)
305+
maxval=(buff[idx+i]>>16)&0xFFFF;
306+
}
307+
if(abs(maxval-minval>1000)){
308+
std::cout<<"Signal in baseline, channel "<<channel
309+
<<" min: "<<minval<<" max: "<<maxval<<std::endl;
310+
}
311+
else
312+
baseline = int(tbase / ((csize-2)*2));
313+
break;
314+
}
315+
idx++;
316+
}
317+
318+
if(baseline>0){
319+
// Time for the **magic**. We want to see how far we are off from nominal and
320+
// adjust up and down accordingly. We will always adjust just a tiny bit
321+
// less than we think we need to to avoid getting into some overshoot
322+
// see-saw type loop where we never hit the target.
323+
float absolute_unit = float(0xffff)/float(0x3fff);
324+
int adjustment = int(0.5*absolute_unit*((int(baseline)-int(target_value))));
325+
if(abs(adjustment) < adjustment_threshold)
326+
channel_finished[channel]=true;
327+
else{
328+
if(adjustment<0 && (u_int32_t(abs(adjustment)))>dac_values[channel])
329+
dac_values[channel]=0;
330+
else if(adjustment>0 &&dac_values[channel]+adjustment>0xffff)
331+
dac_values[channel]=0xffff;
332+
else
333+
dac_values[channel]+=adjustment;
334+
}
335+
}
336+
337+
} // end channel loop
338+
339+
// If all channels finished we can break out
275340
if(breakout)
341+
break;
342+
343+
}// end iteration loop
344+
LoadDAC(dac_values);
345+
end_values = dac_values;
346+
return 0;
347+
}
348+
349+
int V1724::LoadDAC(vector<u_int32_t>dac_values){
350+
// Loads DAC values into registers
351+
352+
for(unsigned int x=0; x<dac_values.size(); x++){
353+
if(x>7) // oops
354+
continue;
355+
356+
// Define a counter to give the DAC time to be set if needed
357+
int counter = 0;
358+
while(counter < 100){
359+
u_int32_t data = 0x4;
360+
// DAC ready register
361+
data = ReadRegister((0x1088)+(0x100*x));
362+
if(data == 0xffffffff ){
363+
usleep(1000);
364+
counter++;
365+
continue;
366+
}
367+
if(data&0x4){
368+
usleep(1000);
369+
counter++;
370+
continue;
371+
}
276372
break;
373+
}
374+
if(counter >= 100){
375+
stringstream errorstr;
376+
errorstr<<"Timed out waiting for channel "<<x<<" in DAC setting";
377+
fLog->Entry(errorstr.str(), MongoLog::Error);
378+
return -1;
379+
}
380+
381+
// Now write channel DAC values
382+
if(WriteRegister((0x1098)+(0x100*x), dac_values[x])!=0){
383+
stringstream errorstr;
384+
errorstr<<"Failed writing DAC "<<hex<<dac_values[x]<<dec<<" in channel "<<x;
385+
fLog->Entry(errorstr.str(), MongoLog::Error);
386+
return -1;
387+
}
277388
}
278-
279-
280-
// 0x1n88 channel n DAC busy 0b001 (1 - yes)
281-
// 0x1n98, 0x8098 DAC value 0xffff
282-
cout<<"Not implemented"<<endl;
283389
return 0;
390+
284391
}
392+
285393
int V1724::End(){
286394
if(fBoardHandle>=0)
287395
CAENVME_End(fBoardHandle);

V1724.hh

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,9 @@ class V1724{
2323
int WriteRegister(unsigned int register, unsigned int value);
2424
unsigned int ReadRegister(unsigned int register);
2525
u_int32_t ReadMBLT(u_int32_t *&buffer);
26-
int ConfigureBaselines(int nominal_value,
27-
int ntries,
28-
vector <unsigned int> start_values,
29-
vector <unsigned int> &end_values);
26+
int ConfigureBaselines(vector <unsigned int> &end_values,
27+
int nominal_value=16000,
28+
int ntries=100);
3029
int GetClockCounter(u_int32_t timestamp);
3130
int End();
3231

@@ -46,6 +45,8 @@ class V1724{
4645
bool seen_over_15;
4746

4847
MongoLog *fLog;
48+
49+
int LoadDAC(vector<u_int32_t>dac_values);
4950
};
5051

5152

0 commit comments

Comments
 (0)