| 1 | /*******************************v1.3******************************** | 
| 2 |  | 
| 3 | Functions to read AC physics data (ACphysics) and AC calibration | 
| 4 | data (ACcalib). | 
| 5 | Author: Petter Hofverberg, petter@particle.kth.se | 
| 6 |  | 
| 7 | 0410 v1.0 alive | 
| 8 | 0412 v1.1 fixed problem with found, and changed headers | 
| 9 | 0502 v1.2 added a crc check | 
| 10 | 0502 v1.3 increased buffer size | 
| 11 |  | 
| 12 | Errors: (returned to the main program as the variable "err") | 
| 13 | err= | 
| 14 | 0xFF - data (physics or calibration) from both cards found | 
| 15 | 0xF0 - only data from main card found | 
| 16 | 0x0F - only data from extra card found | 
| 17 | 0x00 - no data found | 
| 18 |  | 
| 19 | CRCcheck:  1 - OK, 0 - error | 
| 20 | ******************************************************************/ | 
| 21 |  | 
| 22 | #include <stdio.h> | 
| 23 | #include <string.h> | 
| 24 |  | 
| 25 | #include "AC.h" | 
| 26 | #define TRUE 1 | 
| 27 | #define FALSE 0 | 
| 28 |  | 
| 29 | int i,j,found; | 
| 30 | unsigned short buffer[8300]; | 
| 31 | unsigned short tmp1,tmp2,check; | 
| 32 | unsigned char err; | 
| 33 |  | 
| 34 | struct physicsstruct physicsdata[2]; | 
| 35 | struct physicsstruct *physicspointer; | 
| 36 |  | 
| 37 | struct calibstruct calibdata; | 
| 38 | struct calibstruct *calibpointer; | 
| 39 |  | 
| 40 |  | 
| 41 | //CRC check function | 
| 42 | short crc(short old,short new) | 
| 43 | { | 
| 44 | union crc_data { | 
| 45 | short word; | 
| 46 | struct bit_field { | 
| 47 | unsigned b0:1; | 
| 48 | unsigned b1:1; | 
| 49 | unsigned b2:1; | 
| 50 | unsigned b3:1; | 
| 51 | unsigned b4:1; | 
| 52 | unsigned b5:1; | 
| 53 | unsigned b6:1; | 
| 54 | unsigned b7:1; | 
| 55 | unsigned b8:1; | 
| 56 | unsigned b9:1; | 
| 57 | unsigned b10:1; | 
| 58 | unsigned b11:1; | 
| 59 | unsigned b12:1; | 
| 60 | unsigned b13:1; | 
| 61 | unsigned b14:1; | 
| 62 | unsigned b15:1; | 
| 63 | } bit; | 
| 64 | } c,d,r; | 
| 65 |  | 
| 66 | c.word = old; | 
| 67 | d.word = new; | 
| 68 | r.word = 0; | 
| 69 |  | 
| 70 | r.bit.b0 = c.bit.b0 ^ c.bit.b4 ^ c.bit.b8 ^ c.bit.b11 ^ c.bit.b12 ^ | 
| 71 | d.bit.b0 ^ d.bit.b4 ^ d.bit.b8 ^ d.bit.b11 ^ d.bit.b12; | 
| 72 |  | 
| 73 | r.bit.b1 = c.bit.b1 ^ c.bit.b5 ^ c.bit.b9 ^ c.bit.b12 ^ c.bit.b13 ^ | 
| 74 | d.bit.b1 ^ d.bit.b5 ^ d.bit.b9 ^ d.bit.b12 ^ d.bit.b13; | 
| 75 |  | 
| 76 | r.bit.b2 = c.bit.b2 ^ c.bit.b6 ^ c.bit.b10 ^ c.bit.b13 ^ c.bit.b14 ^ | 
| 77 | d.bit.b2 ^ d.bit.b6 ^ d.bit.b10 ^ d.bit.b13 ^ d.bit.b14; | 
| 78 |  | 
| 79 | r.bit.b3 = c.bit.b3 ^ c.bit.b7 ^ c.bit.b11 ^ c.bit.b14 ^ c.bit.b15 ^ | 
| 80 | d.bit.b3 ^ d.bit.b7 ^ d.bit.b11 ^ d.bit.b14 ^ d.bit.b15; | 
| 81 |  | 
| 82 | r.bit.b4 = c.bit.b4 ^ c.bit.b8 ^ c.bit.b12 ^ c.bit.b15 ^ | 
| 83 | d.bit.b4 ^ d.bit.b8 ^ d.bit.b12 ^ d.bit.b15; | 
| 84 |  | 
| 85 | r.bit.b5 = c.bit.b0 ^ c.bit.b4 ^ c.bit.b5 ^ c.bit.b8 ^ c.bit.b9 ^ | 
| 86 | c.bit.b11 ^ c.bit.b12 ^ c.bit.b13 ^ | 
| 87 | d.bit.b0 ^ d.bit.b4 ^ d.bit.b5 ^ d.bit.b8 ^ d.bit.b9 ^ | 
| 88 | d.bit.b11 ^ d.bit.b12 ^ d.bit.b13; | 
| 89 |  | 
| 90 | r.bit.b6 = c.bit.b1 ^ c.bit.b5 ^ c.bit.b6 ^ c.bit.b9 ^ c.bit.b10 ^ | 
| 91 | c.bit.b12 ^ c.bit.b13 ^ c.bit.b14 ^ | 
| 92 | d.bit.b1 ^ d.bit.b5 ^ d.bit.b6 ^ d.bit.b9 ^ d.bit.b10 ^ | 
| 93 | d.bit.b12 ^ d.bit.b13 ^ d.bit.b14; | 
| 94 |  | 
| 95 | r.bit.b7 = c.bit.b2 ^ c.bit.b6 ^ c.bit.b7 ^ c.bit.b10 ^ c.bit.b11 ^ | 
| 96 | c.bit.b13 ^ c.bit.b14 ^ c.bit.b15 ^ | 
| 97 | d.bit.b2 ^ d.bit.b6 ^ d.bit.b7 ^ d.bit.b10 ^ d.bit.b11 ^ | 
| 98 | d.bit.b13 ^ d.bit.b14 ^ d.bit.b15; | 
| 99 |  | 
| 100 | r.bit.b8 = c.bit.b3 ^ c.bit.b7 ^ c.bit.b8 ^ c.bit.b11 ^ c.bit.b12 ^ | 
| 101 | c.bit.b14 ^ c.bit.b15 ^ | 
| 102 | d.bit.b3 ^ d.bit.b7 ^ d.bit.b8 ^ d.bit.b11 ^ d.bit.b12 ^ | 
| 103 | d.bit.b14 ^ d.bit.b15; | 
| 104 |  | 
| 105 | r.bit.b9 = c.bit.b4 ^ c.bit.b8 ^ c.bit.b9 ^ c.bit.b12 ^ c.bit.b13 ^ | 
| 106 | c.bit.b15 ^ | 
| 107 | d.bit.b4 ^ d.bit.b8 ^ d.bit.b9 ^ d.bit.b12 ^ d.bit.b13 ^ | 
| 108 | d.bit.b15; | 
| 109 |  | 
| 110 | r.bit.b10 = c.bit.b5 ^ c.bit.b9 ^ c.bit.b10 ^ c.bit.b13 ^ c.bit.b14 ^ | 
| 111 | d.bit.b5 ^ d.bit.b9 ^ d.bit.b10 ^ d.bit.b13 ^ d.bit.b14; | 
| 112 |  | 
| 113 | r.bit.b11 = c.bit.b6 ^ c.bit.b10 ^ c.bit.b11 ^ c.bit.b14 ^ c.bit.b15 ^ | 
| 114 | d.bit.b6 ^ d.bit.b10 ^ d.bit.b11 ^ d.bit.b14 ^ d.bit.b15; | 
| 115 |  | 
| 116 | r.bit.b12 = c.bit.b0 ^ c.bit.b4 ^ c.bit.b7 ^ c.bit.b8 ^ c.bit.b15 ^ | 
| 117 | d.bit.b0 ^ d.bit.b4 ^ d.bit.b7 ^ d.bit.b8 ^ d.bit.b15; | 
| 118 |  | 
| 119 | r.bit.b13 = c.bit.b1 ^ c.bit.b5 ^ c.bit.b8 ^ c.bit.b9 ^ | 
| 120 | d.bit.b1 ^ d.bit.b5 ^ d.bit.b8 ^ d.bit.b9; | 
| 121 |  | 
| 122 | r.bit.b14 = c.bit.b2 ^ c.bit.b6 ^ c.bit.b9 ^ c.bit.b10 ^ | 
| 123 | d.bit.b2 ^ d.bit.b6 ^ d.bit.b9 ^ d.bit.b10; | 
| 124 |  | 
| 125 | r.bit.b15 = c.bit.b3 ^ c.bit.b7 ^ c.bit.b10 ^ c.bit.b11 ^ | 
| 126 | d.bit.b3 ^ d.bit.b7 ^ d.bit.b10 ^ d.bit.b11; | 
| 127 |  | 
| 128 | return r.word; | 
| 129 | } | 
| 130 |  | 
| 131 |  | 
| 132 | //Fill physicsdata from buffer | 
| 133 | void fillphys(int k,unsigned short *buff) | 
| 134 | { | 
| 135 | for(i=0;i<2;i++) physicsdata[k].header[i]=buff[i]; | 
| 136 | physicsdata[k].status=buff[2]; | 
| 137 | physicsdata[k].hitmap=buff[3]; | 
| 138 | for(i=0;i<6;i++) physicsdata[k].regist[i]=buff[4+i]; | 
| 139 | for(i=0;i<16;i++) physicsdata[k].shift[i]=buff[10+i]; | 
| 140 | for(i=0;i<16;i++) physicsdata[k].counters[i]=buff[26+i]; | 
| 141 | for(i=0;i<8;i++) physicsdata[k].coinc[i]=buff[42+i]; | 
| 142 | physicsdata[k].trigg=buff[50]; | 
| 143 | for(i=0;i<2;i++) physicsdata[k].clock[i]=buff[51+i]; | 
| 144 | for(i=0;i<2;i++) physicsdata[k].temp[i]=buff[53+i]; | 
| 145 | for(i=0;i<8;i++) physicsdata[k].DAC[i]=buff[55+i]; | 
| 146 | physicsdata[k].CRC=buff[63]; | 
| 147 | if(check==physicsdata[k].CRC) | 
| 148 | physicsdata[k].CRCcheck=TRUE; | 
| 149 | else | 
| 150 | physicsdata[k].CRCcheck=FALSE; | 
| 151 | } | 
| 152 |  | 
| 153 | //Fill calibdata from buffer | 
| 154 | void fillcalib(unsigned short *buff) | 
| 155 | { | 
| 156 | for(i=0;i<2;i++) calibdata.header[i]=buff[i]; | 
| 157 | for(i=0;i<5;i++) calibdata.status[i]=buff[2+i]; | 
| 158 | for(i=0;i<8;i++) calibdata.temp[i]=buff[7+i]; | 
| 159 | for(i=0;i<8;i++) calibdata.DAC1[i]=buff[15+i]; | 
| 160 | for(i=0;i<8;i++) calibdata.DAC2[i]=buff[23+i]; | 
| 161 | for(i=0;i<6;i++) calibdata.regist[i]=buff[31+i]; | 
| 162 | for(i=0;i<8;i++) calibdata.time[i]=buff[37+i]; | 
| 163 | calibdata.n_tr=buff[45]; | 
| 164 | for(i=0;i<16;i++) calibdata.hitmap_tr[i]=buff[46+i]; | 
| 165 | for(i=0;i<4096;i++) calibdata.curve1[i]=buff[62+i]; | 
| 166 | for(i=0;i<4096;i++) calibdata.curve2[i]=buff[4158+i]; | 
| 167 | calibdata.iCRC=buff[8254]; | 
| 168 | calibdata.tail=buff[8255]; | 
| 169 | calibdata.CRC=buff[8256]; | 
| 170 | if(check==calibdata.CRC) | 
| 171 | calibdata.CRCcheck=TRUE; | 
| 172 | else | 
| 173 | calibdata.CRCcheck=FALSE; | 
| 174 | } | 
| 175 |  | 
| 176 | unsigned char ACphysics(int length,unsigned char* datapointer,struct physicsstruct* physicspointer) | 
| 177 | { | 
| 178 |  | 
| 179 | err=0; | 
| 180 | found=0; | 
| 181 | check=0; | 
| 182 | int iter=2; | 
| 183 | for(i=0;i<8300;i++) | 
| 184 | buffer[i]=0; | 
| 185 | fillphys(0,&buffer[0]); | 
| 186 | fillphys(1,&buffer[0]); | 
| 187 |  | 
| 188 | //look for top header ACAC, then unpack data to main card buffer or extra card buffer depending on the subheader | 
| 189 | //AC11 for main, AC22 for extra | 
| 190 | while(found<2 && iter<length) | 
| 191 | { | 
| 192 | tmp1 = ((*datapointer) << 8) | *(datapointer+1); | 
| 193 | tmp2 = ((*(datapointer+2)) << 8) | *(datapointer+3); | 
| 194 | if(tmp1 == 0xACAC && ((tmp2 == 0xAC11 && (err&0xF0)==0x0) || (tmp2 == 0xAC22 && (err&0x0F)==0x0))) | 
| 195 | { | 
| 196 | for(i=0;i<64;i++) | 
| 197 | { | 
| 198 | buffer[i]=((*datapointer) << 8) | *(datapointer+1); | 
| 199 | if(i<63) | 
| 200 | check=crc(check,buffer[i]); | 
| 201 | datapointer=datapointer+2; | 
| 202 | } | 
| 203 | if(tmp2==0xAC11){          //main card | 
| 204 | fillphys(0,&buffer[0]); | 
| 205 | err |= 0xF0; | 
| 206 | } | 
| 207 | else{                      //extra card | 
| 208 | fillphys(1,&buffer[0]); | 
| 209 | err |= 0x0F; | 
| 210 | } | 
| 211 | tmp1=tmp2=0x0000; | 
| 212 | check=0x0; | 
| 213 | found++; | 
| 214 | } | 
| 215 | else{ | 
| 216 | datapointer++; | 
| 217 | iter=iter+1;} | 
| 218 | } | 
| 219 | //point struct-pointer to physicsdata | 
| 220 | physicspointer[0]=physicsdata[0];  //card1 | 
| 221 | physicspointer[1]=physicsdata[1];  //card2 | 
| 222 |  | 
| 223 | return err; | 
| 224 |  | 
| 225 | } | 
| 226 |  | 
| 227 |  | 
| 228 | unsigned char ACcalib(int length, unsigned char* datapointer, struct calibstruct* calibpointer) | 
| 229 | { | 
| 230 |  | 
| 231 | err=0; | 
| 232 | found=0; | 
| 233 | check=0; | 
| 234 | int iter=2; | 
| 235 | for(i=0;i<8300;i++) | 
| 236 | buffer[i]=0; | 
| 237 | fillcalib(&buffer[0]); | 
| 238 |  | 
| 239 | //look for the top header 0xACCA, then the subheaders 0xAC11 and 0xAC22, and unpack the data | 
| 240 | //to each card depending on these. | 
| 241 | while(found<1 && iter<length) | 
| 242 | { | 
| 243 | tmp1 = ((*datapointer) << 8) | *(datapointer+1); | 
| 244 | tmp2 = ((*(datapointer+2)) << 8) | *(datapointer+3); | 
| 245 |  | 
| 246 | if(tmp1 == 0xACCA && ((tmp2 == 0xAC11 && (err&0xF0)==0x0) || (tmp2 == 0xACA2 && (err&0x0F)==0x0))) | 
| 247 | { | 
| 248 | for(i=0;i<8257;i++) | 
| 249 | { | 
| 250 | buffer[i]=((*datapointer) << 8) | *(datapointer+1); | 
| 251 | if(i<8256) //8257 | 
| 252 | check=crc(check,buffer[i]); | 
| 253 | datapointer=datapointer+2; | 
| 254 | } | 
| 255 |  | 
| 256 | if(tmp2==0xAC11){          //main | 
| 257 | fillcalib(&buffer[0]); | 
| 258 | err |= 0xF0; | 
| 259 | } | 
| 260 | else{                      //extra | 
| 261 | fillcalib(&buffer[0]); | 
| 262 | err |= 0x0F; | 
| 263 | } | 
| 264 | tmp1=tmp2=0x0000; | 
| 265 | found++; | 
| 266 | } | 
| 267 | else{ | 
| 268 | datapointer++; | 
| 269 | iter=iter+1;} | 
| 270 | } | 
| 271 | memcpy(calibpointer,&calibdata,sizeof(calibdata)); | 
| 272 |  | 
| 273 | return err; | 
| 274 | } | 
| 275 |  |