00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014 #include <string.h>
00015 #include <sys/ioctl.h>
00016 #include <unistd.h>
00017 #include <sys/types.h>
00018 #include <asm/types.h>
00019 #include <sys/stat.h>
00020 #include <fcntl.h>
00021 #include <signal.h>
00022 #include <sched.h>
00023 #include <sys/resource.h>
00024 #include <sys/io.h>
00025 #include <signal.h>
00026 #include <packet.h>
00027 #include <coprocessor.h>
00028 #include <counter.h>
00029
00030 typedef struct Cop_DataBlock
00031 {
00032 __u8 *data;
00033 int size;
00034 }Cop_DataBlock;
00035
00036
00044 int CopParsePacket(Cop_Data *data);
00045
00051 int CopGetPacket(Cop_Data *data, Cop_DataBlock *block);
00052
00058 int CopPacketMask(Cop_Data *data, Cop_DataBlock *block);
00059
00065 int CopPacketStart(Cop_Data *data, Cop_DataBlock *block);
00066
00067
00071 void CopPackBreak(Cop_Data *data);
00072
00073
00074 static int BlockPull(Cop_DataBlock *block,__u8 *buffer, int count)
00075 {
00076 int tcount = 0;
00077
00078 while((block->size)&&(count))
00079 {
00080 *buffer = *block->data;
00081 GENDEBUG("pulled %c from block\n",*buffer);
00082 ++block->data;
00083 ++buffer;
00084
00085 block->size--;
00086 tcount++;
00087 count--;
00088 }
00089
00090
00091 return tcount;
00092 }
00093
00094
00095 int CopPacketStart(Cop_Data *data, Cop_DataBlock *block)
00096 {
00097 GENDEBUG("Parsing for a Header\r\n");
00098
00099 while(1)
00100 {
00101
00102 if(!(BlockPull(block,&data->packet[DELIMITER],1)))
00103 break;
00104
00105
00106 if((DLMIN<=data->packet[DELIMITER])&&(data->packet[DELIMITER]<=DLMAX))
00107 {
00108
00109 data->psize = 1;
00110 return SUCCESS;
00111 }
00112
00113 if(data->packetdata.extended==TRUE)
00114 {
00115 data->psize = 1;
00116 data->packet[DELIMITER] = (char)EXT_TRANS(data->packet[DELIMITER]);
00117 return SUCCESS;
00118
00119 }
00120
00121
00122 }
00123
00124 return FAILURE;
00125 }
00126
00127 int CopPacketMask(Cop_Data *data, Cop_DataBlock *block)
00128 {
00129 GENDEBUG("Parsing for packet mask\n");
00130
00131
00132 if(BlockPull(block,&data->packet[MASKNIB],1))
00133 {
00134 if((DLMIN<=data->packet[MASKNIB])&&(data->packet[MASKNIB]<=DLMAX))
00135 {
00136 CopPackBreak(data);
00137 return FAILURE;
00138 }
00139
00140
00141 data->psize = 2;
00142 PcpkParseHeader(&data->packet[0],&data->packetdata);
00143
00144 if(data->packetdata.extended==TRUE)
00145 {
00146 data->psize=0;
00147 data->ptogo=0;
00148 }
00149 else
00150 data->ptogo = 2*data->packetdata.datanum*data->packetdata.datasize;
00151
00152
00153 return SUCCESS;
00154 }
00155
00156 return FAILURE;
00157 }
00158
00159
00160
00161 void CopPackBreak(Cop_Data *data)
00162 {
00163 GENDEBUG("New Header received, restart packet\n");
00164 data->packet[DELIMITER] = data->packet[MASKNIB];
00165 data->psize = 1;
00166 return;
00167 }
00168
00169
00170
00171
00172
00173 int CopGetPacket(Cop_Data *data, Cop_DataBlock *block)
00174 {
00175 int retval = 0;
00176 GENDEBUG("getting packet\n");
00177
00178 while(data->ptogo>0)
00179 {
00180
00181 if(BlockPull(block,&data->packet[data->psize],1))
00182 {
00183
00184 if((DLMIN<=data->packet[data->psize])&&(data->packet[data->psize]<=DLMAX))
00185 {
00186 data->packet[MASKNIB] = data->packet[data->psize];
00187 CopPackBreak(data);
00188 return FAILURE;
00189 }
00190
00191 data->ptogo--;
00192 data->psize++;
00193 }
00194 else
00195 break;
00196
00197 }
00198
00199
00200 GENDEBUG("ptogo is %u at end of get packet\n",data->ptogo);
00201
00202 if(data->ptogo==0)
00203 retval = CopParsePacket(data);
00204
00205
00206 return retval;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 int CopParsePacket(Cop_Data *data)
00219 {
00220 void *datapntr = data->packetdata.data;
00221 RG_ParseMask *parsemask = &data->parsemask;
00222 unsigned long long cross_stamp;
00223 int channel;
00224
00225 GENDEBUG("Parsing Packet data\n");
00226 PcpkParseData(&data->packet[0],&data->packetdata);
00227
00228 GENDEBUG("data parsed assigning data\n");
00229 switch(data->packetdata.type)
00230 {
00231 case EXTNULCMD:
00232 GENDEBUG("null command no data assigned\n");
00233 break;
00234
00235
00236 case VERSIONINFO:
00237 GENDEBUG("version info returned\n");
00238 data->version.version = ((__u8 *)datapntr)[0];
00239 strcpy(data->version.date,(datapntr+1));
00240 break;
00241
00242
00243
00244 case ADBLK0:
00245 GENDEBUG("Internal AD channel %x returned\n",(unsigned int)data->packetdata.maskcnt);
00246 data->Internal_AD[data->packetdata.maskcnt] = *(__u16 *)datapntr;
00247 parsemask->Internal_AD|=BITMASK(data->packetdata.maskcnt);
00248 break;
00249
00250
00251 case ADBLK1:
00252 GENDEBUG("External Analog to digital channel, mask = %x, data =%x\n",data->packetdata.maskcnt,*(__u16 *)datapntr);
00253 data->External_AD[data->packetdata.maskcnt] = *(__u16 *)datapntr;
00254 parsemask->External_AD|=BITMASK(data->packetdata.maskcnt);
00255 break;
00256
00257
00258
00259 case PRTIN0:
00260 GENDEBUG("Digital Port Data\n");
00261 if(data->packetdata.maskcnt&0x08)
00262 data->Digital[0] = *((__u8 *)datapntr);
00263 if(data->packetdata.maskcnt&0x04)
00264 data->Digital[1] = ((__u8 *)datapntr)[1];
00265 break;
00266
00267
00268
00269
00270 case CAN:
00271 GENDEBUG("Can Data\n");
00272 if(data->CAN_message);
00273 data->CAN_message = datapntr;
00274 break;
00275
00276
00277
00278 case KEYPAD:
00279 GENDEBUG("Keypad Data\n");
00280 data->Key = *(char *)datapntr;
00281 break;
00282
00283 case SER422:
00284 GENDEBUG("422 Data\n");
00285 ((__u8 *)datapntr)[data->packetdata.maskcnt] = 0;
00286
00287 if((strlen(data->RS422_string)+data->packetdata.maskcnt)>RS422BUFSIZE)
00288 break;
00289
00290 strcat(data->RS422_string,datapntr);
00291 break;
00292
00293 case SER232:
00294 GENDEBUG("232 Data\n");
00295 ((__u8 *)datapntr)[data->packetdata.maskcnt] = 0;
00296
00297 if((strlen(data->RS232_string)+data->packetdata.maskcnt)>RS232BUFSIZE)
00298 break;
00299
00300 strcat(data->RS232_string, datapntr);
00301 break;
00302
00303 case COUNTER:
00304 GENDEBUG("Counter data\n");
00305 if(data->packetdata.maskcnt>7)
00306 break;
00307
00308 data->counter_data[data->packetdata.maskcnt].counter = ((__u16 *)(datapntr))[0];
00309 parsemask->counter|=BITMASK(data->packetdata.maskcnt);
00310 break;
00311
00312 case COUNTERD:
00313 channel = ((__u16 *)(datapntr))[0];
00314 data->counter_config[channel].trigger = ((__u16 *)(datapntr))[1];
00315 data->counter_config[channel].threshold = ((__u16 *)(datapntr))[2];
00316 data->counter_config[channel].flags = ((__u16 *)(datapntr))[3];
00317 parsemask->counter|=BITMASK(channel);
00318 break;
00319
00320
00321 case PWMCON:
00322 channel = ((__u16 *)(datapntr))[0];
00323 data->PWM_config[channel].pwm = channel;
00324 data->PWM_config[channel].frequency = ((__u16 *)(datapntr))[1];
00325 data->PWM_config[channel].duty = ((__u16 *)(datapntr))[2];
00326 data->PWM_config[channel].delay = ((__u16 *)(datapntr))[3];
00327 parsemask->pwm|=BITMASK(channel);
00328 break;
00329
00330
00331
00332
00333 case ICNOTIFY:
00334
00335 channel = ((__u16 *)(datapntr))[0];
00336
00337 GENDEBUG("counter zero detection, channel %x\n",channel);
00338
00339
00340
00341 cross_stamp = ((__u16 *)(datapntr))[2];
00342 cross_stamp <<=16;
00343 cross_stamp += ((__u16 *)(datapntr))[3];
00344
00345 if(channel<COUNTNUM)
00346 {
00347 data->counter_data[channel].zerocross++;
00348 data->counter_data[channel].laststart = data->counter_data[channel].countstart;
00349
00350
00351
00352 if(!(data->counter_config[channel].flags&AUTOSTOP))
00353 {
00354 if(data->counter_config[channel].flags&AUTOLOAD)
00355 data->counter_data[channel].countstart=data->counter_config[channel].threshold;
00356 else
00357 data->counter_data[channel].countstart=0xffff;
00358 }
00359
00360 }
00361 else
00362 {
00363 channel-=COUNTNUM;
00364 data->counter_data[channel].zerocross = 0;
00365 data->counter_data[channel].countstart = ((__u16 *)(datapntr))[1];
00366 }
00367 data->counter_data[channel].laststamp = data->counter_data[channel].timestamp;
00368 data->counter_data[channel].timestamp = cross_stamp;
00369 parsemask->zero|=BITMASK(channel);
00370 break;
00371
00372 }
00373
00374 data->psize=0;
00375 data->ptogo=0;
00376
00377 return(data->packetdata.type);
00378 }
00379
00380 static void CopInit(Cop_Data *CopData)
00381 {
00382 int num;
00383 CopData->psize=0;
00384 CopData->ptogo=0;
00385 CopData->Datarxd=TRUE;
00386 CopData->packetdata.extended=FALSE;
00387 CopData->packetdata.mult = 0;
00388 CopData->RS232_string[0] = 0;
00389 CopData->RS422_string[0] = 0;
00390 CopData->CAN_message = NULL;
00391
00392 for(num=0;num<COUNTNUM;num++)
00393 {
00394 CopData->counter_config[num].counter = num;
00395 CopData->counter_config[num].trigger = 0;
00396 CopData->counter_config[num].threshold = 0;
00397 CopData->counter_config[num].flags =0;
00398 CopData->counter_data[num].counter =0;
00399 CopData->counter_data[num].countstart =0;
00400 CopData->counter_data[num].timestamp =0;
00401 CopData->counter_data[num].laststamp =0;
00402 CopData->counter_data[num].zerocross =0;
00403 }
00404
00405 for(num=0;num<PWMNUM;num++)
00406 {
00407 CopData->PWM_config[num].pwm = num;
00408 CopData->PWM_config[num].frequency = 0;
00409 CopData->PWM_config[num].duty = 0;
00410 CopData->PWM_config[num].delay = 0;
00411 }
00412
00413
00414 }
00415
00416
00417
00418 Cop_Data *CopDeviceCreate(int flags)
00419 {
00420 Cop_Data *Cop = malloc(sizeof(Cop_Data));
00421 CopInit(Cop);
00422 return(Cop);
00423 }
00424
00425 int CopDeviceDestroy(Cop_Data *Cop)
00426 {
00427 free(Cop);
00428 return 0;
00429 }
00430
00431 static int COPclearmem(Cop_Data *Cop)
00432 {
00433 Cop->RS232_string[0] = 0;
00434 Cop->RS422_string[0] = 0;
00435 return 0;
00436 }
00437
00438 __u32 E12_Packet_Route(Cop_Data *Cop, unsigned char *data, int datasize)
00439 {
00440 Cop_DataBlock datablock;
00441 int type = 0;
00442 __u32 retval=0;
00443 datablock.size = datasize;
00444 datablock.data = data;
00445
00446 memset(&Cop->parsemask,0,sizeof(RG_ParseMask));
00447
00448
00449 while(datablock.size)
00450 {
00451 if(Cop->psize==0)
00452 CopPacketStart(Cop,&datablock);
00453
00454 if(Cop->psize==1)
00455 CopPacketMask(Cop,&datablock);
00456
00457 if(Cop->psize>1)
00458 type = CopGetPacket(Cop,&datablock);
00459
00460 retval |= BITMASK(type);
00461 }
00462 return retval;
00463 }
00464
00465
00466
00467
00468 __u32 E12_Parse_Until(int fd, Cop_Data *Cop, __u32 bitmask )
00469 {
00470 Cop_DataBlock datablock;
00471 int type = 0;
00472 __u32 typemask=0;
00473 char buffer[1000];
00474 int loopcount=0;
00475
00476 memset(&Cop->parsemask,0,sizeof(RG_ParseMask));
00477
00478 while(!(typemask&bitmask))
00479 {
00480
00481 datablock.size = read(fd,buffer,sizeof(buffer));
00482 datablock.data = buffer;
00483
00484 while(datablock.size)
00485 {
00486 if(Cop->psize==0)
00487 CopPacketStart(Cop,&datablock);
00488
00489 if(Cop->psize==1)
00490 CopPacketMask(Cop,&datablock);
00491
00492 if(Cop->psize>1)
00493 type = CopGetPacket(Cop,&datablock);
00494
00495 typemask |= BITMASK(type);
00496 }
00497 if(loopcount++==1000)
00498 return 0;
00499 }
00500 return typemask;
00501 }
00502
00503
00504 int UpdatetHardwareCounterInfo(int fd, Cop_Data *Cop)
00505 {
00506 int counter;
00507 int parseneeded = 0xff;
00508
00509 for(counter=0;counter<COUNTNUM;counter++)
00510 E12_CountCfg_Req(fd, counter);
00511
00512 while(parseneeded)
00513 {
00514 E12_Parse_Until(fd, Cop, BITMASK(COUNTERD));
00515 parseneeded&=~(Cop->parsemask.counter);
00516 }
00517
00518 return 0;
00519 }
00520
00521 int UpdatetHardwarePWMInfo(int fd, Cop_Data *Cop)
00522 {
00523 int pwm;
00524 int parseneeded = 0xffff;
00525
00526 for(pwm=0;pwm<PWMNUM;pwm++)
00527 E12_PWMCfg_Req(fd, pwm);
00528
00529 while(parseneeded)
00530 {
00531 E12_Parse_Until(fd, Cop, BITMASK(PWMCON));
00532 parseneeded&=~(Cop->parsemask.pwm);
00533 }
00534
00535 return 0;
00536 }
00537
00538
00539 int e12packetout(int fd,__u8 device,__u8 maskcnt,void *data)
00540 {
00541 __u8 *packet = PcpkPackGen(device,maskcnt,data);
00542 write(fd,packet,strlen(packet));
00543 free(packet);
00544 return 0;
00545 }
00546
00547
00548
00549 int E12_PWMControl(int fd,int pwm, int frequency, int duty,Cop_Data *Cop)
00550 {
00551 PWMconfig *config = &Cop->PWM_config[pwm];
00552
00553 config->pwm = pwm;
00554 config->frequency = frequency;
00555 config->duty = duty;
00556 config->delay = 0;
00557
00558 if(pwm<COUNTNUM)
00559 {
00560 Cop->counter_config[pwm].flags=0;
00561 Cop->counter_config[pwm].threshold = 0;
00562 Cop->counter_config[pwm].trigger = 0;
00563 }
00564
00565 e12packetout(fd,PWMCON,0x0F,config);
00566 return 0;
00567 }
00568
00569 int E12_PWMCfg_Req(int fd, int pwm)
00570 {
00571 PWMconfig config;
00572 config.pwm=pwm+PWMNUM;
00573 e12packetout(fd,PWMCON,0x0f,&config);
00574 return 0;
00575 }
00576
00577
00578 int E12_CountConfig(int fd, int counter, int trigger, int threshold,int flags,Cop_Data *Cop)
00579 {
00580 countconfig *config = &Cop->counter_config[counter];
00581 Cop->PWM_config[counter].frequency = 0;
00582 Cop->PWM_config[counter].duty = 0;
00583
00584 config->trigger = trigger;
00585 config->threshold = threshold;
00586 config->flags = flags;
00587
00588 e12packetout(fd,COUNTERD,0x0F,config);
00589 return 0;
00590 }
00591
00592 int E12_CountCfg_Req(int fd, int counter)
00593 {
00594 countconfig config;
00595 config.counter=counter+COUNTNUM;
00596 e12packetout(fd,COUNTERD,0x0f,&config);
00597 return 0;
00598 }
00599
00600
00601 int E12_CounterReadRQ(int fd, int counter)
00602 {
00603 int command =0;
00604 e12packetout(fd,COUNTER,counter,&command);
00605 return 0;
00606 }
00607
00608 int E12_CounterLoad(int fd, int counter, int data, Cop_Data *Cop)
00609 {
00610 e12packetout(fd,COUNTER,counter+8,&data);
00611
00612 return 0;
00613 }
00614
00615
00616 int E12_CounterCalcFreq(int counter, Cop_Data *Cop)
00617 {
00618 unsigned long timediff_ms = (Cop->counter_data[counter].timestamp - Cop->counter_data[counter].laststamp);
00619 unsigned long count_ms = Cop->counter_data[counter].laststart*(unsigned long)1000;
00620 unsigned int freq=0;
00621
00622 if(timediff_ms!=0)
00623 freq = count_ms/timediff_ms;
00624 return(freq);
00625 }
00626
00627
00628 int E12_CountCommand(int fd, int counter,int command)
00629 {
00630 __u16 commandstruct[4];
00631 commandstruct[0] = counter;
00632 commandstruct[1] = command;
00633 commandstruct[2] = 0x77;
00634 commandstruct[3] = 0x77;
00635 e12packetout(fd,ICNOTIFY,0x0f,commandstruct);
00636 return 0;
00637 }
00638
00639
00640
00641
00642 int E12_Digitalout(int fd, __u8 data,int port)
00643 {
00644 __u8 mask = 8>>port;
00645 __u8 dataa[4];
00646
00647 dataa[port] = data;
00648
00649 if(port>1)
00650 return -1;
00651
00652 e12packetout(fd,PRTOUT,mask,dataa);
00653 return 0;
00654 }
00655
00656
00657
00658 int E12_Digital_Req(int fd)
00659 {
00660 __u8 placeholder;
00661 e12packetout(fd,DREQ,0x0C,&placeholder);
00662 return 0;
00663 }
00664
00665
00666 int E12_Digital_Cfg(int fd, __u8 mask, int port)
00667 {
00668
00669 __u8 pmask = 8>>port;
00670 __u8 maska[4];
00671
00672 maska[port] = mask;
00673
00674 if(port>1)
00675 return -1;
00676
00677 e12packetout(fd,PRTCFG0,pmask,maska);
00678 return 0;
00679 }
00680
00681
00682 int E12_Internal_AtoD_Req(int fd, int channel)
00683 {
00684 e12packetout(fd,ADREQ0,channel,NULL);
00685 return 0;
00686 }
00687
00688 int E12_External_AtoD_Req(int fd, int channel)
00689 {
00690 e12packetout(fd,ADREQ1,channel,NULL);
00691 return 0;
00692 }
00693
00694
00695 int E12_AtoD_Req(int fd, int channel)
00696 {
00697 if(channel<INTERNAL_ATOD_NUM)
00698 E12_Internal_AtoD_Req(fd, channel);
00699 else
00700 {
00701 channel-=INTERNAL_ATOD_NUM;
00702 E12_External_AtoD_Req(fd, channel);
00703 }
00704 return 0;
00705 }
00706
00707
00708 int E12_DtoA_Write(int fd, int channel,int data)
00709 {
00710 __u8 mask = 8>>channel;
00711 __u16 dataa[4];
00712 dataa[channel] = data;
00713 e12packetout(fd,DAQ,mask,dataa);
00714 return 0;
00715 }
00716
00717 int E12_Serial_Write(int fd, int port, int numchars,char *buffer)
00718 {
00719 int charnum=0;
00720 int chars_tx;
00721
00722 if(!(chars_tx=numchars%15))
00723 chars_tx = 15;
00724
00725 while(charnum<numchars)
00726 {
00727
00728 switch(port)
00729 {
00730 case RS232PORT:
00731 e12packetout(fd,RS232DATA,chars_tx,&buffer[charnum]);
00732 break;
00733
00734 case RS422PORT:
00735 e12packetout(fd,RS422DATA,chars_tx,&buffer[charnum]);
00736 break;
00737 }
00738
00739 charnum+=chars_tx;
00740
00741 chars_tx = 15;
00742 }
00743
00744
00745 return charnum;
00746 }
00747
00748
00749 int E12_Serial_Config(int fd, int port, int baud,int mode)
00750 {
00751 Serconfig config;
00752 config.id = port;
00753 config.mode = mode;
00754 config.baud = baud;
00755 e12packetout(fd,SERCFG,0x0F,&config);
00756 return 0;
00757 }
00758