AlcapDAQ  1
X742CorrectionRoutines.c
Go to the documentation of this file.
2 
3 static void PeakCorrection(CAEN_DGTZ_X742_GROUP_t *dataout) {
4  int offset;
5  int chaux_en;
6  unsigned int i;
7  int j;
8 
9  chaux_en = (dataout->ChSize[8] == 0)? 0:1;
10  for(j=0; j<(8+chaux_en); j++){
11  dataout->DataChannel[j][0] = dataout->DataChannel[j][1];
12  }
13  for(i=1; i<dataout->ChSize[0]; i++){
14  offset=0;
15  for(j=0; j<8; j++){
16  if (i==1){
17  if ((dataout->DataChannel[j][2]- dataout->DataChannel[j][1])>30){
18  offset++;
19  }
20  else {
21  if (((dataout->DataChannel[j][3]- dataout->DataChannel[j][1])>30)&&((dataout->DataChannel[j][3]- dataout->DataChannel[j][2])>30)){
22  offset++;
23  }
24  }
25  }
26  else{
27  if ((i==dataout->ChSize[j]-1)&&((dataout->DataChannel[j][dataout->ChSize[j]-2]- dataout->DataChannel[j][dataout->ChSize[j]-1])>30)){
28  offset++;
29  }
30  else{
31  if ((dataout->DataChannel[j][i-1]- dataout->DataChannel[j][i])>30){
32  if ((dataout->DataChannel[j][i+1]- dataout->DataChannel[j][i])>30)
33  offset++;
34  else {
35  if ((i==dataout->ChSize[j]-2)||((dataout->DataChannel[j][i+2]-dataout->DataChannel[j][i])>30))
36  offset++;
37  }
38  }
39  }
40  }
41  }
42 
43  if (offset==8){
44  for(j=0; j<(8+chaux_en); j++){
45  if (i==1){
46  if ((dataout->DataChannel[j][2]- dataout->DataChannel[j][1])>30) {
47  dataout->DataChannel[j][0]=dataout->DataChannel[j][2];
48  dataout->DataChannel[j][1]=dataout->DataChannel[j][2];
49  }
50  else{
51  dataout->DataChannel[j][0]=dataout->DataChannel[j][3];
52  dataout->DataChannel[j][1]=dataout->DataChannel[j][3];
53  dataout->DataChannel[j][2]=dataout->DataChannel[j][3];
54  }
55  }
56  else{
57  if (i==dataout->ChSize[j]-1){
58  dataout->DataChannel[j][dataout->ChSize[j]-1]=dataout->DataChannel[j][dataout->ChSize[j]-2];
59  }
60  else{
61  if ((dataout->DataChannel[j][i+1]- dataout->DataChannel[j][i])>30)
62  dataout->DataChannel[j][i]=((dataout->DataChannel[j][i+1]+dataout->DataChannel[j][i-1])/2);
63  else {
64  if (i==dataout->ChSize[j]-2){
65  dataout->DataChannel[j][dataout->ChSize[j]-2]=dataout->DataChannel[j][dataout->ChSize[j]-3];
66  dataout->DataChannel[j][dataout->ChSize[j]-1]=dataout->DataChannel[j][dataout->ChSize[j]-3];
67  }
68  else {
69  dataout->DataChannel[j][i]=((dataout->DataChannel[j][i+2]+dataout->DataChannel[j][i-1])/2);
70  dataout->DataChannel[j][i+1]=( (dataout->DataChannel[j][i+2]+dataout->DataChannel[j][i-1])/2);
71  }
72  }
73  }
74  }
75  }
76  }
77  }
78 }
79 
80 static int read_flash_page(int handle, uint8_t gr, int8_t* page, uint32_t pagenum) {
81  uint32_t flash_addr;
82  uint16_t dd;
83  uint32_t i,tmp[528];
84  uint32_t fl_a[528];
85  uint8_t addr0,addr1,addr2;
86  int ret;
87  CAENComm_ErrorCode err[528];
88 
89  flash_addr = pagenum<<9;
90  addr0 = (uint8_t)flash_addr;
91  addr1 = (uint8_t)(flash_addr>>8);
92  addr2 = (uint8_t)(flash_addr>>16);
93 
94  dd=0xffff;
95  while ((dd>>2)& 0x1)
96  if ((ret = CAENComm_Read16(handle, STATUS(gr), &dd)) != CAENComm_Success) return -1;
97  // enable flash (NCS = 0)
98  if ((ret = CAENComm_Write16(handle, SEL_FLASH(gr), (int16_t)1)) != CAENComm_Success) return -1;
99  // write opcode
100  if ((ret = CAENComm_Write16(handle, FLASH(gr), (int16_t)MAIN_MEM_PAGE_READ)) != CAENComm_Success) return -1;
101  // write address
102  dd=0xffff;
103  if ((ret = CAENComm_Write16(handle, FLASH(gr), (int16_t)addr2)) != CAENComm_Success) return -1;
104  dd=0xffff;
105  if ((ret = CAENComm_Write16(handle, FLASH(gr), (int16_t)addr1)) != CAENComm_Success) return -1;
106  dd=0xffff;
107  if ((ret = CAENComm_Write16(handle, FLASH(gr), (int16_t)addr0)) != CAENComm_Success) return -1;
108  // additional don't care bytes
109  for (i=0; i<4; i++) {
110  dd=0xffff;
111  if ((ret = CAENComm_Write16(handle, FLASH(gr), (int16_t)0)) != CAENComm_Success) return -1;
112  }
113  for (i=0; i<528; i+=2) {
114  fl_a[i] = FLASH(gr);
115  fl_a[i+1] = STATUS(gr);
116  }
117  if ((ret = CAENComm_MultiRead32(handle,fl_a,528,tmp,err)) != CAENComm_Success)
118  return -1;
119  for (i=0; i<528; i+=2) page[(int)(i/2)] = (int8_t) tmp[i];
120  // disable flash (NCS = 1)
121  if ((ret = CAENComm_Write16(handle, SEL_FLASH(gr), (int16_t)0)) != CAENComm_Success)
122  return -1;
123  return 0;
124 }
125 
126 int32_t LoadCorrectionTables(int handle, DataCorrection_t *Table, uint8_t group, uint32_t frequency) {
127  uint32_t pagenum = 0,i,n,j,start;
128  int8_t TempCell[264]; //
129  int8_t *p;
130  int ret;
131  int8_t tmp[0x1000]; // 256byte * 16 pagine
132  for (n=0;n<MAX_X742_CHANNELS+1;n++) {
133  pagenum = 0;
134  pagenum = (group %2) ? 0xC00: 0x800;
135  pagenum |= frequency << 8;
136  pagenum |= n << 2;
137  // load the Offset Cell Correction
138  p = TempCell;
139  start = 0;
140  for (i=0;i<4;i++) {
141  int endidx = 256;
142  if ((ret =read_flash_page(handle,group,p,pagenum)) != 0)
143  return ret;
144  // peak correction
145  for (j=start;j<(start+256);j++) {
146  if (p[j-start] != 0x7f) {
147  Table->cell[n][j] = p[j-start];
148  }
149  else {
150  short cel = (short)((((unsigned char)(p[endidx+1])) << 0x08) |((unsigned char) p[endidx]));
151  if (cel == 0) Table->cell[n][j] = p[j-start]; else Table->cell[n][j] = cel;
152  endidx+=2;
153  if (endidx > 263) endidx = 256;
154  }
155  }
156  start +=256;
157  pagenum++;
158  }
159  start = 0;
160  // load the Offset Num Samples Correction
161  p = TempCell;
162  pagenum &= 0xF00;
163  pagenum |= 0x40;
164  pagenum |= n << 2;
165 
166  for (i=0;i<4;i++) {
167  if ((ret =read_flash_page(handle,group,p,pagenum)) != 0)
168  return ret;
169  for (j=start;j<start+256;j++) Table->nsample[n][j] = p[j-start];
170  start +=256;
171  pagenum++;
172  }
173  if (n == MAX_X742_CHANNELS) {
174  // load the Time Correction
175  p = TempCell;
176  pagenum &= 0xF00;
177  pagenum |= 0xA0;
178  start = 0;
179  for (i=0;i<16;i++) {
180  if ((ret =read_flash_page(handle,group,p,pagenum)) != 0)
181  return ret;
182  for (j=start;j<start+256;j++) tmp[j] = p[j-start];
183  start +=256;
184  pagenum++;
185  }
186  for (i=0;i<1024;i++) {
187  p = (int8_t *) &(Table->time[i]);
188  p[0] = tmp[i*4];
189  p[1] = tmp[(i*4)+1];
190  p[2] = tmp[(i*4)+2];
191  p[3] = tmp[(i*4)+3];
192  }
193  }
194  }
195  return 0;
196 }
197 
198 void ApplyDataCorrection(DataCorrection_t* CTable, CAEN_DGTZ_DRS4Frequency_t frequency, int CorrectionLevelMask, CAEN_DGTZ_X742_GROUP_t *data) {
199 
200  int i, j,rpnt = 0, wpnt = 0, size1, size2,trg = 0,k;
201  long samples;
202  float Time[1024],t0;
203  float Tsamp;
204  float vcorr;
205  uint16_t st_ind=0;
206  uint32_t freq = frequency;
207  float wave_tmp[1024];
208  int cellCorrection =CorrectionLevelMask & 0x1;
209  int nsampleCorrection = (CorrectionLevelMask & 0x2) >> 1;
210  int timeCorrection = (CorrectionLevelMask & 0x4) >> 2;
211 
212  switch(frequency) {
214  Tsamp =(float)((1.0/2500.0)*1000.0);
215  break;
216  case CAEN_DGTZ_DRS4_1GHz:
217  Tsamp =(float)((1.0/1000.0)*1000.0);
218  break;
219  default:
220  Tsamp =(float)((1.0/5000.0)*1000.0);
221  break;
222  }
223 
224  if (data->ChSize[8] != 0) trg = 1;
225  st_ind =(uint16_t)(data->StartIndexCell);
226  for (i=0;i<MAX_X742_CHANNEL_SIZE;i++) {
227  size1 = data->ChSize[i];
228 
229  for (j=0;j<size1;j++) {
230  if (cellCorrection) data->DataChannel[i][j] -= CTable->cell[i][((st_ind+j) % 1024)];
231  if (nsampleCorrection) data->DataChannel[i][j] -= CTable->nsample[i][j];
232  }
233  }
234 
235  if (cellCorrection) PeakCorrection(data);
236  if (!timeCorrection) return;
237 
238  t0 = CTable->time[st_ind];
239  Time[0]=0.0;
240 
241  for(j=1; j < 1024; j++) {
242  t0= CTable->time[(st_ind+j)%1024]-t0;
243  if (t0 >0)
244  Time[j] = Time[j-1]+ t0;
245  else
246  Time[j] = Time[j-1]+ t0 + (Tsamp*1024);
247 
248  t0 = CTable->time[(st_ind+j)%1024];
249  }
250  for (j=0;j<8+trg;j++) {
251  data->DataChannel[j][0] = data->DataChannel[j][1];
252  wave_tmp[0] = data->DataChannel[j][0];
253  vcorr = 0.0;
254  k=0;
255  i=0;
256 
257  for(i=1; i<1024; i++) {
258  while ((k<1024-1) && (Time[k]<(i*Tsamp))) k++;
259  vcorr =(((float)(data->DataChannel[j][k] - data->DataChannel[j][k-1])/(Time[k]-Time[k-1]))*((i*Tsamp)-Time[k-1]));
260  wave_tmp[i]= data->DataChannel[j][k-1] + vcorr;
261  k--;
262  }
263  memcpy(data->DataChannel[j],wave_tmp,1024*sizeof(float));
264  }
265 }