00001
00002
00003
00004
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdlib.h>
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include <sys/ioctl.h>
00031 #include <unistd.h>
00032 #include <sys/types.h>
00033 #include <asm/types.h>
00034 #include <sys/stat.h>
00035 #include <fcntl.h>
00036 #include <signal.h>
00037 #include <sched.h>
00038 #include <sys/resource.h>
00039 #include <sys/io.h>
00040 #include <E12user.h>
00041 #include <packet.h>
00042 #include <coprocessor.h>
00043 #include <counter.h>
00044 #include <curses.h>
00045 #include <form.h>
00046
00047
00048 #define COLOR_FORE COLOR_BLACK
00049 #define COLOR_BACK COLOR_GREEN
00050
00051
00053 #define ARGCHECK(num){if(argc<=num){printf("invalid number of arguements\n");help();return -1;}}
00054
00055 #define OPENDEV(filed,dev){if((filed = open(dev, O_RDWR))<=0){printf("couldn't open %s\n",dev);return -1;}}
00056
00057
00058
00060 #define YSTART 4
00061
00062 #define HEADER_Y YSTART-1
00063
00064 #define FIELDSEP 7
00065
00066 #define FIELDNUM 6
00067
00069 enum FIELDNUMBERS {COUNT,RELOAD,TRIG,FLAG,ZERO,FREQ};
00070
00071
00072
00073 #define NUM_X 3 + FIELDSEP
00074 #define COUNT_X NUM_X + FIELDSEP
00075 #define RELOAD_X COUNT_X + FIELDSEP
00076 #define TRIG_X RELOAD_X + FIELDSEP
00077 #define FLAG_X TRIG_X + FIELDSEP
00078 #define ZERO_X FLAG_X + FIELDSEP
00079 #define FREQ_X ZERO_X + FIELDSEP
00080 #define FIRST_FIELD COUNT_X
00081
00083 #define ARRAYCALC (channel*FIELDNUM + fieldnum) //array element number calculation
00084
00085
00086 #define MESSAGE_Y (YSTART+COUNTNUM + 2)
00087 #define MESSAGE_X 0
00088
00089
00090 int current_y,current_x;
00091 #define CURSEMESSAGE(fmt, args...) {getsyx(current_y,current_x);mvprintw(MESSAGE_Y,MESSAGE_X,fmt, ## args);setsyx(current_y,current_x);}
00092
00093
00095 volatile int modified;
00097 FIELD *counter_field[COUNTNUM*FIELDNUM+1];
00099 FORM *counter_form;
00101 int global_fd;
00103 Cop_Data *Cop;
00104
00106 const char *trig_strings[] = {" ","rise ","fall ","any ",NULL};
00108 const char *flag_strings[] = {" ","__N ","_R_ ","_RN ","S__ ","S_N ","SR_ ","SRN ",NULL};
00109
00110
00111
00119 static int indexenum(const char *enumptr, const char **fieldptr)
00120 {
00121 int index;
00122
00123 for(index=0;index<10;index++)
00124 {
00125 if(!(strcmp(enumptr,fieldptr[index])))
00126 return index;
00127 }
00128 return 0;
00129 }
00130
00131
00132
00133
00134 static void destroyform()
00135 {
00136 int channel,fieldnum;
00137 FORM *form = counter_form;
00138
00139 unpost_form(form);
00140 free_form(form);
00141
00142
00143 for(channel=0;channel<COUNTNUM;channel++)
00144 for(fieldnum=0;fieldnum<FIELDNUM;fieldnum++)
00145 free_field(counter_field[ARRAYCALC]);
00146
00147 endwin();
00148 }
00149
00153 static int help(void)
00154 {
00155 const char *help_table = "**********************************************
00156 *e12count *
00157 *Nathan Z. Gustavson *
00158 *Emac.inc *
00159 *"__DATE__" *
00160 *usage: *
00161 *e12count device *
00162 *ex *
00163 *e12count /dev/37e12 *
00164 **********************************************\n";
00165 printf("%s",help_table);
00166 return 0;
00167 }
00168
00173 static void field_commit_change(FORM *form)
00174 {
00175 FIELD *field = current_field(form);
00176 int index = field_index(field);
00177 int counter = index/FIELDNUM;
00178 int fieldnum = index%FIELDNUM;
00179 int fd = global_fd;
00180
00181 char *dataptr = field_buffer(field,0);
00182 int count;
00183 countconfig *oldconfig = &Cop->counter_config[counter];
00184 int trigger,threshold,flags;
00185
00186 if(!modified)
00187 return;
00188
00189 switch(fieldnum)
00190 {
00191 case COUNT:
00192 count = atoi(dataptr);
00193 E12_CounterLoad(fd, counter,count, Cop);
00194 break;
00195
00196
00197 case RELOAD:
00198 threshold = atoi(dataptr);
00199 E12_CountConfig(fd, counter, oldconfig->trigger, threshold,oldconfig->flags,Cop);
00200 break;
00201
00202
00203 case TRIG:
00204 trigger = indexenum(dataptr, trig_strings);
00205 E12_CountConfig(fd, counter, trigger, oldconfig->threshold,oldconfig->flags,Cop);
00206 if(trigger)
00207 E12_CountCommand(fd,counter, ICSTART);
00208 else
00209 E12_CountCommand(fd, counter,ICSTOP);
00210 CURSEMESSAGE("trigger changed to %u\n",trigger);
00211 break;
00212
00213
00214 case FLAG:
00215 flags = indexenum(dataptr, flag_strings);
00216 E12_CountConfig(fd, counter, oldconfig->trigger, oldconfig->threshold,flags,Cop);
00217 CURSEMESSAGE("flags changed to %u\n",flags);
00218 break;
00219 }
00220
00221 modified=0;
00222
00223 }
00224
00225
00226
00227
00228 static int InitForm()
00229 {
00230 int channel,fieldnum;
00231
00232 initscr();
00233 start_color();
00234 cbreak();
00235 noecho();
00236 keypad(stdscr, TRUE);
00237
00238 nodelay(stdscr, TRUE);
00239
00240 modified=0;
00241
00242
00243 init_pair(1, COLOR_FORE, COLOR_BACK);
00244 init_pair(2, COLOR_FORE, COLOR_BACK);
00245
00246 for(channel=0;channel<(COUNTNUM);channel++)
00247 {
00248 for(fieldnum=0;fieldnum<(FIELDNUM);fieldnum++)
00249 {
00250 counter_field[ARRAYCALC] = new_field(1, FIELDSEP, YSTART+channel, FIRST_FIELD+(fieldnum*FIELDSEP), 0, 0);
00251
00252
00253 #ifdef COLOR_FIELDS
00254 set_field_fore(counter_field[ARRAYCALC], COLOR_PAIR(1));
00255 set_field_back(counter_field[ARRAYCALC], COLOR_PAIR(2));
00256 #endif
00257 set_field_back(counter_field[ARRAYCALC], A_UNDERLINE);
00258 field_opts_off(counter_field[ARRAYCALC], O_AUTOSKIP);
00259
00260 switch(fieldnum)
00261 {
00262 case COUNT:
00263 set_field_type(counter_field[ARRAYCALC],
00264 TYPE_INTEGER,
00265 0,
00266 0, 65535);
00267 break;
00268
00269 case RELOAD:
00270 set_field_type(counter_field[ARRAYCALC],
00271 TYPE_INTEGER,
00272 0,
00273 0, 65535);
00274 break;
00275
00276 case TRIG:
00277 set_field_type(counter_field[ARRAYCALC],
00278 TYPE_ENUM,
00279 trig_strings,
00280 0, 0);
00281 break;
00282 case FLAG:
00283 set_field_type(counter_field[ARRAYCALC],
00284 TYPE_ENUM,
00285 flag_strings,
00286 0, 0);
00287 break;
00288
00289 }
00290
00291
00292 }
00293
00294 }
00295 counter_field[COUNTNUM*FIELDNUM+1] = NULL;
00296
00297
00298 counter_form = new_form(counter_field);
00299 set_field_term(counter_form, field_commit_change);
00300 post_form(counter_form);
00301 refresh();
00302
00303 mvprintw(HEADER_Y, NUM_X, "count");
00304 mvprintw(HEADER_Y, COUNT_X, "value");
00305 mvprintw(HEADER_Y, RELOAD_X, "load ");
00306 mvprintw(HEADER_Y, TRIG_X, "trig ");
00307 mvprintw(HEADER_Y, FLAG_X, "flags");
00308 mvprintw(HEADER_Y, ZERO_X, "zeros");
00309 mvprintw(HEADER_Y, FREQ_X, "freq ");
00310
00311 for(channel=0;channel<(COUNTNUM);channel++)
00312 mvprintw(YSTART+channel, NUM_X+2, "%u",channel);
00313
00314 refresh();
00315
00316 set_current_field(counter_form, counter_field[0]);
00317
00318 return 0;
00319 }
00320
00325 static int handlecrossing(Cop_Data *Cop)
00326 {
00327 int channel;
00328 int fieldnum;
00329 int freq = 0;
00330 char freqstring[FIELDSEP+1];
00331 char zerostring[FIELDSEP+1];
00332
00333 for(channel=0;channel<COUNTNUM;channel++)
00334 {
00335 if(Cop->parsemask.zero&(1<<channel))
00336 {
00337 CURSEMESSAGE("channel = %u\nlaststamp=%lu\ntimestamp=%lu\nlaststart =%lu\nstart = %u\n",channel,Cop->counter_data[channel].laststamp,Cop->counter_data[channel].timestamp,Cop->counter_data[channel].laststart,Cop->counter_data[channel].countstart);
00338 if(Cop->counter_data[channel].zerocross)
00339 freq = E12_CounterCalcFreq(channel, Cop);
00340 sprintf(freqstring,"%u",freq);
00341 fieldnum=FREQ;
00342 set_field_buffer(counter_field[ARRAYCALC],0,freqstring);
00343 sprintf(zerostring,"%u",Cop->counter_data[channel].zerocross);
00344 fieldnum=ZERO;
00345 set_field_buffer(counter_field[ARRAYCALC],0,zerostring);
00346 }
00347
00348 }
00349 return 0;
00350 }
00351
00352
00353
00354
00355
00356 void UpdateFields(Cop_Data *Cop)
00357 {
00358 int channel;
00359 int fieldnum;
00360 char buffer[FIELDSEP+1];
00361
00362 for(channel=0;channel<COUNTNUM;channel++)
00363 {
00364 fieldnum = RELOAD;
00365 sprintf(buffer,"%u",Cop->counter_config[channel].threshold);
00366 set_field_buffer(counter_field[ARRAYCALC],0,buffer);
00367 fieldnum = TRIG;
00368 set_field_buffer(counter_field[ARRAYCALC],0,trig_strings[Cop->counter_config[channel].trigger]);
00369 fieldnum = FLAG;
00370 set_field_buffer(counter_field[ARRAYCALC],0,flag_strings[Cop->counter_config[channel].flags]);
00371 }
00372
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382 static int DisplayCounters(int fd, FORM *form, Cop_Data *Cop, unsigned char mask)
00383 {
00384 int channel;
00385 char buffer[1000];
00386 int fieldnum=0;
00387 char countstr[FIELDSEP+1];
00388 __u32 typemask=0;
00389 int rxnum=0;
00390
00391 for(channel=0;channel<COUNTNUM;channel++)
00392 {
00393
00394 if(mask&(1<<channel))
00395 {
00396 E12_CounterReadRQ(fd, channel);
00397
00398 while(!(typemask&(COUNTRESPONSE)))
00399 {
00400 rxnum =read(fd,buffer,sizeof(buffer));
00401 typemask = E12_Packet_Route(Cop,buffer, rxnum);
00402
00403 if(typemask&(NOTIFYRESPONSE))
00404 handlecrossing(Cop);
00405 }
00406
00407 sprintf(countstr,"%u",Cop->counter_data[channel].counter);
00408
00409 set_field_buffer(counter_field[ARRAYCALC],0,countstr);
00410 typemask=0;
00411 }
00412 }
00413
00414 return 0;
00415 }
00416
00417
00418
00419
00420
00421 static int DisplayUnusedCounters(int fd, FORM *form, Cop_Data *Cop)
00422 {
00423 FIELD *field = current_field(form);
00424 int index = field_index(field);
00425 int counter = index/FIELDNUM;
00426 int fieldnum = index%FIELDNUM;
00427 unsigned char mask = 0xff;
00428
00429 if(fieldnum==COUNT)
00430 {
00431 mask&=~(1<<counter);
00432
00433 }
00434 DisplayCounters(fd,counter_form,Cop,mask);
00435 return 0;
00436 }
00437
00438
00439
00440
00441
00442 static int Insert_char(FORM *form,char ch)
00443 {
00444 FIELD *field = current_field(form);
00445 int index = field_index(field);
00446 int fieldnum = index%FIELDNUM;
00447
00448 if(fieldnum<ZERO)
00449 {
00450 modified=1;
00451 form_driver(counter_form, ch);
00452 }
00453 return 0;
00454 }
00455
00456
00457
00458
00459 static int Form_Display(int fd)
00460 {
00461 int ch;
00462
00463 Cop = CopDeviceCreate(0);
00464
00465 UpdatetHardwareCounterInfo(fd, Cop);
00466 UpdateFields(Cop);
00467
00468 while((ch = getch()) != KEY_F(1))
00469 {
00470 DisplayUnusedCounters(fd,counter_form,Cop);
00471 switch(ch)
00472 { case KEY_DOWN:
00473
00474 form_driver(counter_form, REQ_DOWN_FIELD);
00475
00476
00477
00478 break;
00479 case KEY_UP:
00480
00481 form_driver(counter_form, REQ_UP_FIELD);
00482
00483 break;
00484 case KEY_LEFT:
00485
00486 form_driver(counter_form, REQ_LEFT_FIELD);
00487
00488 break;
00489 case KEY_RIGHT:
00490
00491 form_driver(counter_form, REQ_RIGHT_FIELD);
00492
00493 break;
00494 case KEY_BACKSPACE:
00495
00496 form_driver(counter_form, REQ_DEL_PREV);
00497 modified=1;
00498
00499 break;
00500 case 10:
00501
00502 modified=1;
00503
00504 form_driver(counter_form, REQ_RIGHT_FIELD);
00505 form_driver(counter_form, REQ_LEFT_FIELD);
00506 break;
00507 case ERR:
00508 break;
00509 default:
00510
00511 Insert_char(counter_form, ch);
00512 break;
00513 }
00514 }
00515
00516 CopDeviceDestroy(Cop);
00517 return 0;
00518 }
00519
00523 int main(int argc, char **argv)
00524 {
00525 int fd;
00526 ARGCHECK(1);
00527 OPENDEV(fd,argv[1]);
00528 global_fd = fd;
00529 InitForm();
00530 Form_Display(fd);
00531 close(fd);
00532 destroyform();
00533 return 0;
00534 }