#include #include #include #include #include // Inclusion of the SeaMAX library header is required #include unsigned char data[12]; seaio_type_t type; address_loc_t start; address_range_t range; HANDLE comHandle; slave_address_t slaveId = 1; unsigned long ADR; int result; struct termios original, newtio; unsigned char snd[6],rtn[6]; unsigned long EX,RESET,CMD,DATA,RDATA,sdata; int CTRL[4],FRM[4][12],FPGA[4][4]; unsigned long readback,n; int verbose=1; int debug=0; int strt,now,elapsed; int day,month,year,hour,minute,second,date,totalsec; /* ================================================================ */ /* ============================== main ============================ */ /* ================================================================ */ main(argc,argv,envs) int argc; char *argv[]; char *envs[]; { FILE *fp0,*fp1,*fp2,*fp3,*fps; extern double Date();unsigned long frame_count,stop; unsigned long l1,l2; int kkk,i,n,mb,k,ln,fpga,good,mblimit; int sn[4],event; double t0,t1; double tnow,dt; time_t now; printf(" argc=%d\n",argc); printf(" 2 argv[2]=%s %x\n",argv[2],argv[2]); printf(" 3 argv[3]=%s %x\n",argv[3],argv[3]); printf(" 4 argv[4]=%s %x\n",argv[4],argv[4]); printf(" 5 argv[5]=%s %x\n",argv[5],argv[5]); printf(" 6 argv[6]=%s %x\n",argv[6],argv[6]); printf(" 7 argv[7]=%s %x\n",argv[7],argv[7]); sscanf(argv[1],"%d",&sn[0]); sscanf(argv[2],"%d",&sn[1]); sscanf(argv[3],"%d",&sn[2]); sscanf(argv[4],"%d",&sn[3]); t0 = atof(argv[5]); t1 = atof(argv[6]); sscanf(argv[7],"%d",&event); printf(" sn=%d %d %d %d t0=%f t1=%f event=%d bpy.c\n",sn[0],sn[1],sn[2],sn[3],t0,t1,event); fps = fopen("/home/kelby/BURN/event.dat","w"); fp0 = fopen("bdat0.txt","w"); fp1 = fopen("bdat1.txt","w"); fp2 = fopen("bdat2.txt","w"); fp3 = fopen("bdat3.txt","w"); printf("pointers %x %x %x %x %x\n",fps,fp0,fp1,fp2,fp3); // fprintf(fps,"pointers %s %s %s %s %s\n",fps,fp0,fp1,fp2,fp3); time(&now); strt=now; /* read t1 and t2 */ if(verbose==1) printf("START %s\n",ctime(&now)); strt = now; kkk=open_sea(); /* ================== send and readback rantom numbers ===================== */ mb = 0; mblimit = 3; start: CTRL[mb]=0; if(verbose==1) printf("\n ==================== mb=%d ===========================\n",mb); for(n=0;n<5;n++) { // printf("\nn= %d\n",n); CMD = 0x24; l1=rand(); DATA=l1 & 0xffffff; kkk = Send_Sea(); usleep(1); kkk = Read_Sea(); if(verbose==1) { if(RDATA == DATA) printf(" controller test send=%x return=%x OK\n",DATA,RDATA); if(RDATA != DATA) printf(" controller test send=%x return=%x BAD\n",DATA,RDATA); if(RDATA != DATA) CTRL[mb]=1; } if(mb==0) fprintf(fp0,"controller %x %x\n",DATA,RDATA); if(mb==1) fprintf(fp1,"controller %x %x\n",DATA,RDATA); if(mb==2) fprintf(fp2,"controller %x %x\n",DATA,RDATA); if(mb==3) fprintf(fp3,"controller %x %x\n",DATA,RDATA); } /* ================ send and readback ADC frame clock counts==================== */ CMD = 0x20; /* clear frame clocks */ DATA = 0; // printf("\n\n clear frame clocks CMD=%x DATA=%x\n",CMD,DATA); kkk = Send_Sea(); CMD = 0x22; /* load stop pattern */ DATA = 10000; /* counters are 16 bits so the stop count must be less than 65535 */ stop = DATA; kkk = Send_Sea(); CMD = 0x21; /* start ADC frame clock counting */ DATA = 0; kkk = Send_Sea(); usleep(1); for(i=0;i<12;i++) { usleep(1); CMD = 0x040 | (mb<<4) | i; /* sent frame count to Sea input lines */ DATA = 0; // printf(" read count mb=%c tube=%d CMD=%x DATA=%x\n",mb,i,CMD,DATA); kkk = Send_Sea(CMD,DATA); /* execute SPI read of one frame count */ usleep(10); kkk = Read_Sea(); frame_count = rtn[0] + (rtn[1]<<8) + (rtn[2]<<16) + (rtn[3]<<24); good=0; if(frame_count < stop-1) good++; if(frame_count > stop+1) good++; if(verbose==1) { if(good==0) printf(" FrameClock mb=%d ADC=%d Count=%d stop=%d OK\n",mb,i,frame_count,stop); if(good!=0) printf(" FrameClock mb=%d ADC=%d Count=%d stop=%d BAD\n",mb,i,frame_count,stop); } FRM[mb][i]=0; if(good!=0) FRM[mb][i]=1; if(mb==0) fprintf(fp0,"%d %d %d\n",i,frame_count,stop); if(mb==1) fprintf(fp1,"%d %d %d\n",i,frame_count,stop); if(mb==2) fprintf(fp2,"%d %d %d\n",i,frame_count,stop); if(mb==3) fprintf(fp3,"%d %d %d\n",i,frame_count,stop); } /* =========================== FPGA read/write test ===================================== */ for(fpga=0;fpga<4;fpga++) { CMD = 0x80 | fpga | mb<<2; DATA = rand(); // DATA = 0x5555aaaa; sdata = DATA; kkk = Send_Sea(); usleep(1000); CMD = 0x100 | fpga | (mb<<2); DATA = 0; kkk = Send_Sea(); usleep(1000); kkk = Read_Sea(); usleep(1); readback = rtn[0] + (rtn[1]<<8) + (rtn[2]<<16) + (rtn[3]<<24); good=1; if(sdata == ~readback) good=0; if(sdata == readback) good=0; if(verbose==1) { if(good==0) printf(" FPGA r/w test mb=%d fpga=%d sent=%x returned=%x OK\n",mb,fpga,sdata,readback); if(good!=0) printf(" FPGA r/w mb=%d fpga=%d sent=%x returned=%x BAD\n",mb,fpga,sdata,readback); } FPGA[mb][fpga]=0; if(good!=0) FPGA[mb][fpga]=1; if(mb==0) fprintf(fp0," %x %x\n",sdata,readback); if(mb==1) fprintf(fp1," %x %x\n",sdata,readback); if(mb==2) fprintf(fp2," %x %x\n",sdata,readback); if(mb==3) fprintf(fp3," %x %x\n",sdata,readback); } mb=mb+1; if(mb<=mblimit) goto start; fprintf(fps,"mb=%d t0=%f t1=%f\n",mb,t0,t1); for (mb=0;mb<4;mb++) { fprintf(fps,"%d %d\n",mb,CTRL[mb]); fprintf(fps,"%d %d %d %d %d %d %d %d %d %d %d %d\n", FRM[mb][0],FRM[mb][1],FRM[mb][2],FRM[mb][3],FRM[mb][4],FRM[mb][5], FRM[mb][6],FRM[mb][7],FRM[mb][8],FRM[mb][9],FRM[mb][10],FRM[mb][11]); fprintf(fps,"%d %d %d %d\n",FPGA[mb][0],FPGA[mb][1],FPGA[mb][2],FPGA[mb][3]); } fclose(fps); fclose(fp0); fclose(fp1); fclose(fp2); fclose(fp3); kkk=close_sea(); time(&now); elapsed = now - strt; totalsec=elapsed; printf(" end seconds=%d\n",elapsed); return(0); } /* ================================================================ */ /* ====================== FUNCTION Send_Sea ======================= */ int Send_Sea() { unsigned long i,kkk; for(i=0;i<6;i++) snd[i]=0; kkk=write_sea(); usleep(1); EX=1; RESET=0; snd[0] = DATA & 0xff; snd[1] = (DATA>>8) & 0xff; snd[2] = (DATA>>16) & 0xff; snd[3] = (DATA>>24) & 0xff; snd[4] = CMD & 0xff; snd[5] = (EX<<2) + (RESET<<1) + ((CMD>>8)&1); if(debug==1) printf(" snd= %x %x %x %x %x %x\n",snd[5],snd[4],snd[3],snd[2],snd[1],snd[0]), usleep(10); kkk=write_sea(); usleep(10); for(i=0;i<6;i++) snd[i]=0; kkk=write_sea(); usleep(1); return 0; } /* ================================================================ */ /* ====================== FUNCTION Read_Sea ======================= */ /* ================================================================ */ int Read_Sea() { int kkk; kkk=read_sea(); usleep(10); RDATA = rtn[0] | (rtn[1]<<8) | (rtn[2]<<16) | (rtn[4]<<24); usleep(10); if(debug==1) printf(" rtn= %x %x %x %x\n",rtn[3],rtn[2],rtn[1],rtn[0]); return 0; } /* ================================================================ */ /* ============================== open device ====================== */ /* ================================================================ */ int open_sea() { // Create the SeaMAX object for accessing SeaIO modules // NOTE the difference in the OOP class name (CSeaMaxLin) and the // nonOOP struct pointer (SeaMaxLin) SeaMaxLin *myModule = SeaMaxLinCreate(); ADR= (unsigned long)myModule; // A handle to the connection f.o.p. (Only valid on RTU, not TCP) // Two termios structs, one to hold the current setup and one to // change so we can talk with our device. // Create the module string for use with SeaMaxLinOpen(...) // // APPLICATION NOTE: // // "sealevel_rtu://dev/DEVNAME" is used for RS232, RS485, and USB // connections (DEVNAME is the special device file under /dev/) // // "sealevel_tcp://xxx.xxx.xxx.xxx:yyy" is used for TCP/IP connections // (where x's represent the ip address and y's the port number) // By default your device will be DHCP enabled and use port 502. // You may choose not to enter the port number and 502 will be used // by default. You may optionally enter your device name, if you have // configured the device in this way. // char *portString = "sealevel_rtu://dev/ttyUSB0"; // Each SeaIO module has a modbus compliant slave ID. By default, // modules are shipped with the hardware ID switched to zero, // indicating a slave ID of 247. Adjusting the hardware switch // to any other address indicates that module will function at the // switch's setting (i.e. a hardware switch setting of 2 indicates // that SeaIO module's slave ID is 2). // SeaMAX conforms to modbus addressing and function definitions. // (Modbus addressing is one-indexed). To read, for example, from // inputs 3 to 5, use the following code: type = D_INPUTS, start = 3, // range = 3 // This is the struct used in the majority of IOCTL calls. For this // example code, it is used to configure the port directions. seaio_ioctl_s ioctl; // This is the data buffer used in sending and recieving from the 46X. // There are 96 bits of IO or 12 bytes. // Open the SeaIO module by calling SeaMaxLinOpen() from the library result = SeaMaxLinOpen(myModule, portString); if (result != 0) { printf("ERROR: Open failed, Returned %d\n", result); return -1; } // Get the host computer communication parameters (only applicable on // RTU type connections (RS232, RS485, USB). ie. Not for TCP type. // NOTE: This is only necessary if you have configured your device to // use different communication parameters than the defaults. Also note // that the comm parameters shown below are the defaults, if you have // used the IOCTLS to change the defaults, you should use a routine // something like this to be able to change your comm port, so you can // talk with your device. comHandle = SeaMaxLinGetCommHandle(myModule); if (comHandle > 0) //only on RTU type { tcgetattr(comHandle, &original); //save the current config bzero(&newtio, sizeof(newtio)); //clear the new config //9600 baud, 8 data bits, local use, readable newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR; //ignore parity errors newtio.c_oflag = 0; //raw data newtio.c_lflag = 0; //enable canonical output newtio.c_cc[VTIME] = 10; //1 second timeout on reads. tcflush(comHandle, TCIFLUSH); //clear the line tcsetattr(comHandle, TCSANOW, &newtio); //set this config } // For this example it has been decided to configure all ports as // outputs. Channel one configures the first six ports (bytes) and // channel two configures the second six ports (bytes). Bits 0 through // 5 control the direction of ports (bytes) 1 through 6. A bit value of // 1 indicates an input and a bit value of 0 indicates an output. ioctl.u.pio.config_state.PIO96.channel1 = 0x00; //All 6 ports outputs ioctl.u.pio.config_state.PIO96.channel2 = 0x3F; //All 6 ports inputs result = SeaMaxLinIoctl(myModule, slaveId, IOCTL_SET_PIO, &ioctl); if (result < 0) { printf("ERROR: Configuring PIO, Returned %d\n", result); return -1; } // By writing a hex value of 55 to all output ports, the device will // effectively have each bit toggled in an alternating pattern. Since // the 46X uses negative logic, a 0 is equivalent to roughly +5V and a // 1 to roughly 0V. // memset(data, 0x55, sizeof(data)); // A PIO write call expects a data buffer with 12 bytes of data to be // written to the PIO device, therefore start and range values are // unecessary and may be set to whatever you please. type = SEAMAXPIO; start = 0; range = 0; return 0; } /* ================================================================ */ /* ============================== write_sea ======================= */ /* ================================================================ */ int write_sea() { // A Write() call will only write to the PIO pins set as output. // PIO pins set as inputs discard the data to be written and continue // to remain inputs. data[0]=~snd[0]; data[1]=~snd[1]; data[2]=~snd[2]; data[3]=~snd[3]; data[4]=~snd[4]; data[5]=~snd[5]; result = SeaMaxLinWrite((unsigned long *)ADR, slaveId, type, start, range, data); if (result < 0) { printf("ERROR: Writing to PIO, Returned %d\n", result); return -1; } else { //printf("PIO Write: %02X ", data[5]); //printf("%02X ", data[4]); //printf("%02X ", data[3]); //printf("%02X ", data[2]); //printf("%02X ", data[1]); //printf("%02X \n", data[0]); } // Reading is similar to writing. Simply supply a buffer of at least // 12 bytes, and the negative logic values will be returned. This read // should return the 0x55 for all ports configured as outputs. //memset(data, 0, sizeof(data)); return 0; } /* ================================================================ */ /* ============================== read_sea ======================== */ /* ================================================================ */ int read_sea() {/* ==================== read ==================================*/ result = SeaMaxLinRead((unsigned long *)ADR, slaveId, type, start, range, data); rtn[0]= ~data[6]; rtn[1]= ~data[7]; rtn[2]= ~data[8]; rtn[3]= ~data[9]; rtn[4]= ~data[10]; rtn[5]= ~data[11]; if (result < 0) { printf("ERROR: Writing to PIO, Returned %d\n", result); return -1; } else { // printf("PIO Read: %02X ", data[6]); // printf("%02X ", data[7]); // printf("%02X ", data[8]); // printf("%02X ", data[9]); // printf("%02X ", data[10]); // printf("%02X \n", data[11]); } return 0; } /* ================================================================ */ /* ============================== close_sea ======================= */ /* ================================================================ */ int close_sea() { /* ==================== close ==================================*/ // Close the connection and clean up the memory used by SeaMAX SeaMaxLinClose((unsigned long *)ADR); SeaMaxLinDestroy((unsigned long *)ADR); // Return your comm port to it's original configuration. if (comHandle > 0) //only on RTU type { tcflush(comHandle, TCIFLUSH); //clear the line tcsetattr(comHandle, TCSANOW, &original); //set this config } return 0; }