00001
00007 #include <stdio.h>
00008 #include <string.h>
00009
00010 #include "edtinc.h"
00011
00012 #include "cl_logic_lib.h"
00013
00014 #include "pciload.h"
00015
00016
00017
00018 #define FLAGS(v, testmask) (v & testmask)
00019 #define CLOCKS(v) (((v) & CLOCK_MASK)+1)
00020
00021 #define FV(v) (v & FV_MASK)
00022 #define DV(v) (v & DV_MASK)
00023 #define LV(v) (v & LV_MASK)
00024
00025
00026
00027 static int default_numbufs = 8;
00028 static int default_bufsize = CL_LOGIC_DEFAULT_BUFSIZE;
00029
00030
00031
00032 static int default_testmask = FV_MASK | LV_MASK;
00033 static int default_timeout = 0;
00034
00035
00036
00037
00038
00039
00040
00041
00042 void
00043 cl_logic_summary_init(ClLogicSummary * cls_p,
00044 int testmask,
00045 int numbufs,
00046 int bufsize,
00047 int timeout,
00048 double pixel_clock)
00049
00050 {
00051 memset(cls_p, 0, sizeof(ClLogicSummary));
00052
00053 if (testmask)
00054 cls_p->testmask = testmask;
00055 else
00056 cls_p->testmask = default_testmask;
00057
00058 if (numbufs)
00059 cls_p->numbufs = numbufs;
00060 else
00061 cls_p->numbufs = default_numbufs;
00062
00063 if (bufsize)
00064 cls_p->bufsize = bufsize;
00065 else
00066 cls_p->bufsize = default_bufsize;
00067
00068 if (timeout)
00069 cls_p->timeout = timeout;
00070 else
00071 cls_p->timeout = default_timeout;
00072
00073 cls_p->pixel_clock = pixel_clock;
00074
00075 }
00076
00077 cl_logic_stat_clear(ClLogicStat *clp)
00078
00079 {
00080 memset(clp, 0, sizeof(ClLogicStat));
00081
00082 }
00083
00084
00085
00086
00087
00088
00089
00090 void
00091 cl_logic_stat_add(ClLogicStat * clp, int value)
00092
00093 {
00094
00095 if (clp->n > 0)
00096 {
00097 if (clp->high < value)
00098 clp->high = value;
00099 if (clp->low > value)
00100 clp->low = value;
00101
00102 }
00103 else
00104 {
00105 clp->high = clp->low = value;
00106
00107 }
00108
00109 clp->sum += value;
00110 clp->n++;
00111
00112 clp->mean = (int) (clp->sum / clp->n);
00113
00114 }
00115
00116
00117
00118 void
00119 cl_logic_stat_print(char *label, ClLogicStat * clp, double clockspeed, int verbose)
00120
00121 {
00122 if (verbose)
00123 printf("%-30s: %8d (%8d - %-8d) %8d\n", label,
00124 clp->mean, clp->low, clp->high, clp->n);
00125 else
00126 {
00127 printf("%-30s: %8d clocks %10g ms", label,
00128 clp->mean, (clp->mean * 1000.0) / clockspeed );
00129
00130 if (clp->low != clp->high)
00131 printf(" (%8d - %8d)\n", clp->low, clp->high);
00132 else
00133 printf("\n");
00134 }
00135
00136 }
00137
00138 int
00139 cl_logic_stats_neq(ClLogicStat * clp1, ClLogicStat * clp2)
00140
00141 {
00142 return (clp1->high != clp2->high ||
00143 clp1->low != clp2->low ||
00144 clp1->mean != clp2->mean ||
00145 clp1->n != clp2->n);
00146 }
00147
00148
00149 u_int
00150 edt_read_pci_config(EdtDev * edt_p, int addr)
00151 {
00152 int ret;
00153 edt_buf buf;
00154
00155 buf.desc = addr;
00156 if ((addr < 0) || (addr > 0x3c))
00157 {
00158 printf("pr_cfg: addr out of range\n");
00159 return (0);
00160 }
00161 ret = edt_ioctl(edt_p, EDTG_CONFIG, &buf);
00162 if (ret < 0)
00163 {
00164 perror("EDTG_CONFIG");
00165 }
00166 return (u_int) (buf.value);
00167 }
00168
00169 void
00170 edt_write_pci_config(EdtDev * edt_p, int addr, int value)
00171 {
00172 int ret;
00173 edt_buf buf;
00174
00175 buf.desc = addr;
00176 if ((addr < 0) || (addr > 0x3c))
00177 {
00178 printf("pw_cfg: addr out of range\n");
00179 return;
00180 }
00181 buf.value = value;
00182 ret = edt_ioctl(edt_p, EDTS_CONFIG, &buf);
00183 if (ret < 0)
00184 {
00185 perror("EDTS_CONFIG");
00186 }
00187 }
00188
00189 void
00190 edt_reboot_pci(EdtDev * edt_p, int verbose)
00191
00192 {
00193
00194 int addr, data;
00195 int buf[0x40];
00196 int old, copy, new_one;
00197 FILE *fd2;
00198
00199 if ((fd2 = fopen("./pdb_reboot.cfg", "wb")) == NULL)
00200 {
00201 fprintf(stderr, "cfgr: Couldn't write to ./pdb_reboot.cfg\n");
00202 return;
00203
00204 }
00205
00206 for (addr = 0; addr <= 0x3c; addr += 4)
00207 {
00208 data = edt_read_pci_config(edt_p, addr);
00209 buf[addr] = data;
00210 putc(data, fd2);
00211 putc(data >> 8, fd2);
00212 putc(data >> 16, fd2);
00213 putc(data >> 24, fd2);
00214
00215 }
00216 fclose(fd2);
00217
00218 printf("Wrote config space state out to ./pdb_reboot.cfg\n");
00219
00220 edt_reg_write(edt_p, 0x01000085, 0x40);
00221
00222 edt_msleep(500);
00223
00224 if (verbose)
00225 printf(" old copy new\n");
00226
00227 for (addr = 0; addr <= 0x3c; addr += 4)
00228 {
00229 old = edt_read_pci_config(edt_p, addr);
00230 copy = buf[addr];
00231 edt_write_pci_config(edt_p, addr, copy);
00232
00233 new_one = edt_read_pci_config(edt_p, addr);
00234
00235 if (verbose)
00236 {
00237 printf("%02x: %08x %08x %08x ", addr, old, copy, new_one);
00238
00239 if (copy != new_one)
00240 printf("ERROR\n");
00241 else if (old != new_one)
00242 printf("changed\n");
00243 else
00244 printf("\n");
00245
00246 }
00247
00248 }
00249
00250 printf("PCI firmware reconfigured...\n");
00251
00252 edt_msleep(2000);
00253
00254 }
00255
00256
00257
00258
00259
00260
00261
00262 size_t
00263 get_buffer_file(unsigned short *buffer, int size, FILE * f)
00264
00265 {
00266 size_t r = fread(buffer, 2, size, f);
00267
00268 return r;
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278 size_t
00279 get_buffer_card(unsigned short *buffer, int size, PdvDev * f)
00280
00281 {
00282 unsigned short *b;
00283
00284 int done = f->donecount;
00285
00286 b = (unsigned short *) edt_wait_for_buffers(f, 1);
00287
00288 memcpy(buffer, b, size);
00289
00290 edt_start_buffers(f, 1);
00291
00292 return (size_t) size / 2;
00293
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303 size_t
00304 get_next_logic_buffer(unsigned short *buffer, int size, PdvDev * pdv_p, FILE * f)
00305
00306 {
00307 if (pdv_p)
00308 return get_buffer_card(buffer, size, pdv_p);
00309 else
00310 return get_buffer_file(buffer, size, f);
00311
00312 }
00313
00314
00315 #define CL_LOGIC_FRAME_GRAN 256
00316
00317 void
00318 cl_logic_summary_add_frame(ClLogicSummary *clp, int width, int height, int hblank, int vblank)
00319
00320 {
00321 if (clp->nframes + 1 > clp->nframesallocated)
00322 {
00323 int newsize = clp->nframesallocated + CL_LOGIC_FRAME_GRAN;
00324
00325 if (clp->nframesallocated == 0)
00326 {
00327
00328 clp->frames = (ClFrameSummary *) calloc(newsize, sizeof(ClFrameSummary));
00329
00330 }
00331 else
00332 {
00333
00334
00335 clp->frames = (ClFrameSummary *) realloc(clp->frames, newsize * sizeof(ClFrameSummary));
00336
00337 }
00338
00339 clp->nframesallocated = newsize;
00340
00341 }
00342
00343 clp->frames[clp->nframes].width = width;
00344 clp->frames[clp->nframes].height = height;
00345 clp->frames[clp->nframes].line_blank = hblank;
00346 clp->frames[clp->nframes].frame_blank = vblank;
00347
00348 clp->nframes ++;
00349
00350 }
00351
00352 int
00353 pdv_cl_logic_sample(PdvDev *pdv_p,
00354 FILE *f,
00355 ClLogicSummary *clsp,
00356 int verbose,
00357 int quiet,
00358 int load,
00359 char *outfilename,
00360 unsigned int loops,
00361 int timeout,
00362 int max_timeouts)
00363
00364 {
00365 FILE *outfile = NULL;
00366 size_t r, offset;
00367 int i;
00368 int clocks = 0;
00369 int lastflags = 0;
00370 int lastval = 0;
00371 int start_h_gap;
00372 int end_h_gap;
00373
00374 int frame_gap = 0;
00375 int lastframegap = 0;
00376
00377 int lines = 0;
00378 int inframe = 0;
00379 int frameclocks = 0;
00380 int lineclocks = 0;
00381 int fv_state = -1;
00382
00383 unsigned short * buffer;
00384 int unit = 0;
00385 char oldname[MAX_STRING+1];
00386 char *trunc;
00387 u_char stat;
00388 int vb = 0;
00389 int promcode;
00390
00391 int last_width = 1;
00392 int last_hblank = 0;
00393
00394
00395 if (pdv_p)
00396 {
00397 unit = pdv_p->unit_no;
00398
00399 promcode = edt_x_prom_detect(pdv_p, &stat, vb);
00400 edt_x_getname(pdv_p, promcode, oldname);
00401
00402
00403 if ((trunc = strchr(oldname, '-')) != NULL)
00404 *trunc = '\0';
00405
00406 if (!quiet)
00407 printf("Current firmware is %s\n", oldname);
00408
00409 if (load || (strncmp(oldname,"camlkla", 7) != 0))
00410 {
00411 char cmd[80];
00412
00413 FILE *f = fopen("pciload.y","w");
00414 fprintf(f,"\n");
00415 fclose(f);
00416 if (!quiet)
00417 {
00418 printf("\n*********************************\n");
00419
00420 printf("Loading PCI firmware camlkla - this takes about 20 sec\n");
00421 }
00422
00423 sprintf(cmd, "pciload -u %d -q camlkla < pciload.y > pciload.out", unit);
00424 system(cmd);
00425
00426 edt_reboot_pci(pdv_p, verbose);
00427 edt_reboot_pci(pdv_p, verbose);
00428 if (!quiet)
00429 printf("*********************************\n");
00430
00431
00432 }
00433
00434
00435 edt_set_rtimeout(pdv_p, timeout);
00436
00437 if (outfilename && outfilename[0])
00438 {
00439 outfile = fopen(outfilename, "wb");
00440 }
00441
00442 if (pdv_p)
00443 {
00444
00445
00446 edt_reg_write(pdv_p, PDV_CMD, 0x80);
00447
00448 edt_msleep(50);
00449
00450 clsp->pixel_clock = edt_intfc_read(pdv_p, 4) |
00451 (edt_intfc_read(pdv_p, 5) << 8) |
00452 (edt_intfc_read(pdv_p, 6) << 16);
00453
00454 clsp->pixel_clock *= 100;
00455
00456
00457 edt_reg_write(pdv_p, PDV_CFG, (~clsp->testmask >> 12) & 0xf);
00458
00459 edt_reg_write(pdv_p, PDV_CMD, 2);
00460 }
00461
00462 edt_configure_ring_buffers(pdv_p, clsp->bufsize, clsp->numbufs, EDT_READ, NULL);
00463
00464 edt_start_buffers(pdv_p, clsp->numbufs);
00465 }
00466
00467 buffer = (unsigned short *) edt_alloc(2 * clsp->bufsize);
00468
00469 offset = 0;
00470
00471 if (!quiet)
00472 {
00473 printf("\n*********************************\n");
00474 printf("Sampling transition data from the camera\n");
00475 printf("*********************************\n");
00476 }
00477
00478 while (clsp->nframes < loops &&
00479 ((r = get_next_logic_buffer(buffer, clsp->bufsize, pdv_p, f)) > 0))
00480 {
00481 if (pdv_p)
00482 {
00483 if ((max_timeouts != 0) && (edt_timeouts(pdv_p) > max_timeouts))
00484 {
00485 break;
00486 }
00487 }
00488 if (outfile)
00489 fwrite(buffer,clsp->bufsize,1,outfile);
00490
00491 for (i = 0; i < (int) r; i++)
00492 {
00493
00494 if (lastflags != FLAGS(buffer[i], clsp->testmask))
00495 {
00496 if (FV(lastflags) != FV(buffer[i]))
00497 {
00498 if (FV(buffer[i]))
00499 {
00500 frame_gap = clocks;
00501
00502
00503 if (LV(buffer[i]))
00504 {
00505 start_h_gap = 0;
00506 }
00507 else
00508 {
00509 start_h_gap = CLOCKS(buffer[i]);
00510 }
00511
00512 if (fv_state > 1)
00513 {
00514
00515 cl_logic_stat_add(&clsp->start_hblank, start_h_gap);
00516 if (clocks)
00517 {
00518 cl_logic_stat_add(&clsp->frame_gap, clocks);
00519 lastframegap = clocks;
00520 }
00521
00522 }
00523
00524 inframe = 1;
00525 }
00526 else
00527 {
00528
00529 if (LV(lastflags))
00530 {
00531 end_h_gap = 0;
00532 }
00533 else
00534 {
00535 end_h_gap = CLOCKS(lastval);
00536 }
00537
00538 if (fv_state > 1)
00539 {
00540 cl_logic_stat_add(&clsp->end_hblank, end_h_gap);
00541
00542 cl_logic_stat_add(&clsp->height, lines);
00543
00544 cl_logic_stat_add(&clsp->frameclocks, frameclocks);
00545 cl_logic_stat_add(&clsp->totalframeclocks, frameclocks + lastframegap);
00546
00547 cl_logic_summary_add_frame(clsp, last_width, lines, last_hblank, frame_gap/last_width);
00548
00549 }
00550
00551 if (verbose && fv_state > 1)
00552 printf("%5d: F gap = %6d frame = %d total = %d width = %d height = %6d hblank = %d\n",
00553 clsp->frame_gap.n, frame_gap, frameclocks, frame_gap + frameclocks, last_width, lines,
00554 clsp->hblank_frame.mean);
00555
00556
00557 lines = 0;
00558 frameclocks = 0;
00559 inframe = 0;
00560 cl_logic_stat_clear(&clsp->hblank_frame);
00561 fv_state++;
00562
00563
00564 }
00565 }
00566
00567 if (inframe && fv_state > 1)
00568 {
00569 if (LV(buffer[i]))
00570 {
00571 lineclocks = CLOCKS(buffer[i]);
00572 if (lines > 0)
00573 {
00574 cl_logic_stat_add(&clsp->hblank, CLOCKS(lastval));
00575 cl_logic_stat_add(&clsp->hblank_frame, CLOCKS(lastval));
00576 cl_logic_stat_add(&clsp->totallineclocks, CLOCKS(lastval) + lineclocks);
00577 }
00578
00579 last_hblank = CLOCKS(lastval);
00580 last_width = lineclocks;
00581
00582 cl_logic_stat_add(&clsp->width, lineclocks);
00583 cl_logic_stat_add(&clsp->line_stats[lines], lineclocks);
00584
00585 lines++;
00586 }
00587 }
00588
00589 lastflags = FLAGS(buffer[i],clsp->testmask);
00590 lastval = buffer[i];
00591
00592 if (inframe)
00593 clocks = 0;
00594
00595 }
00596 clocks += CLOCKS(buffer[i]);
00597 if (inframe)
00598 frameclocks += clocks;
00599 if (clsp->height.n >= loops)
00600 {
00601
00602 break;
00603
00604 }
00605 }
00606
00607 offset += r;
00608 }
00609
00610
00611 if (outfile)
00612 fclose(outfile);
00613
00614 if (pdv_p)
00615 {
00616 if (load)
00617 {
00618 char cmd[80];
00619
00620 if (!quiet)
00621 {
00622 printf("\n*********************************\n");
00623
00624 printf("Loading PCI firmware %s - this takes about 20 sec\n", oldname);
00625 }
00626 sprintf(cmd, "pciload -u %d -q %s < pciload.y > pciload.out", unit, oldname);
00627 system(cmd);
00628
00629 edt_reboot_pci(pdv_p, verbose);
00630 edt_reboot_pci(pdv_p, verbose);
00631 if (!quiet)
00632 printf("*********************************\n");
00633
00634 }
00635
00636 }
00637
00638 return 0;
00639
00640 }