00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <locale.h>
00034 #include <libintl.h>
00035 #include <time.h>
00036
00037
00038 #include "glbvars.h"
00039 #include <fcntl.h>
00040 #include <sys/ioctl.h>
00041
00042 #include "sranger_hwi.h"
00043
00044 typedef struct{
00045 DSP_UINT r_position;
00046 DSP_UINT w_position;
00047 DSP_UINT current_section_head_position;
00048 DSP_UINT current_section_index;
00049 DSP_UINT fill;
00050 DSP_UINT stall;
00051 DSP_UINT length;
00052 DSP_UINT p_buffer_base;
00053 DSP_UINT p_buffer_w;
00054 DSP_UINT p_buffer_l;
00055 } DATA_FIFO_EXTERN_PCOPY;
00056
00057 typedef struct{
00058 DSP_LONG srcs;
00059 DSP_LONG n;
00060 DSP_LONG time;
00061 DSP_INT x_offset;
00062 DSP_INT y_offset;
00063 DSP_INT z_offset;
00064 DSP_INT x_scan;
00065 DSP_INT y_scan;
00066 DSP_INT z_scan;
00067 DSP_INT u_scan;
00068 DSP_INT section;
00069 } PROBE_SECTION_HEADER;
00070
00071
00072
00073 #include "dsp-pci32/xsm/dpramdef.h"
00074 #include "dsp-pci32/xsm/xsmcmd.h"
00075
00076
00077
00078
00079 #include "../plug-ins/hard/modules/sranger_ioctl.h"
00080
00081
00082 #include "FB_spm_dataexchange.h"
00083
00084
00085 #define SRANGER_DEBUG(S) XSM_DEBUG (DBG_L4, S)
00086 #define SRANGER_ERROR(S) XSM_DEBUG_ERROR (DBG_L4, S)
00087
00088
00089 #define SR_READFIFO_RESET -1
00090 #define SR_EMPTY_PROBE_FIFO -2
00091
00092
00093 extern DSPControl *DSPControlClass;
00094 extern GxsmPlugin sranger_hwi_pi;
00095
00096
00097
00098 #define RET_FR_OK 0
00099 #define RET_FR_ERROR -1
00100 #define RET_FR_WAIT 1
00101 #define RET_FR_NOWAIT 2
00102 #define RET_FR_FCT_END 3
00103
00104 #define FR_NO 0
00105 #define FR_YES 1
00106
00107 #define FR_INIT 1
00108 #define FR_FINISH 2
00109 #define FR_FIFO_FORCE_RESET 3
00110
00111
00112 gpointer FifoReadThread (void *ptr_sr);
00113 gpointer ProbeFifoReadThread (void *ptr_sr);
00114 gpointer ProbeFifoReadFunction (void *ptr_sr, int dspdev);
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 sranger_hwi_dev::sranger_hwi_dev(){
00125 SRANGER_DEBUG("open driver");
00126 AIC_max_points = 1<<15;
00127 fifo_read_thread = NULL;
00128 probe_fifo_read_thread = NULL;
00129 probe_fifo_thread_active = FALSE;
00130 thread_dsp = 0;
00131 productid = g_strdup ("not yet identified");
00132 swap_flg = 0;
00133 magic_data.magic = 0;
00134 dsp_alternative = 0;
00135
00136 if((dsp = open (xsmres.DSPDev, O_RDWR)) <= 0){
00137 SRANGER_ERROR(
00138 "Canīt open <" << xsmres.DSPDev << ">, reason: " << strerror(errno) << std::endl
00139 << "please make sure:" << std::endl
00140 << "-> that the device exists and has proper access rights" << std::endl
00141 << "-> that the kernel module loaded" << std::endl
00142 << "-> the USB connection to SignalRanger" << std::endl
00143 << "-> that the SR-SP2 is powered on");
00144 productid=g_strdup_printf ("Device used: %s\n\n"
00145 "Make sure:\n"
00146 "-> that the device exists and has proper access rights\n"
00147 "-> that the kernel module loaded (try 'dmesg')\n"
00148 "-> the USB connection to SignalRanger is OK\n"
00149 "-> that the SR-SP2 is powered on\n"
00150 "Start 'gxsm2 -h no' to change the device path/name.",
00151 xsmres.DSPDev);
00152 gapp->alert (N_("No Hardware"), N_("Open Device failed."), productid, 1);
00153 dsp = 0;
00154 exit (-1);
00155 return;
00156 }
00157 else{
00158 int ret;
00159 unsigned int vendor, product;
00160 if ((ret=ioctl(dsp, SRANGER_IOCTL_VENDOR, (unsigned long)&vendor)) < 0){
00161 SRANGER_ERROR(strerror(ret) << " cannot query VENDOR" << std::endl
00162 << "Device: " << xsmres.DSPDev);
00163 g_free (productid);
00164 productid=g_strdup_printf ("Device used: %s\n Start 'gxsm2 -h no' to correct the problem.", xsmres.DSPDev);
00165 gapp->alert (N_("Unkonwn Hardware"), N_("Query Vendor ID failed."), productid, 1);
00166 close (dsp);
00167 dsp = 0;
00168 exit (-1);
00169 return;
00170 }
00171 if ((ret=ioctl(dsp, SRANGER_IOCTL_PRODUCT, (unsigned long)&product)) < 0){
00172 SRANGER_ERROR(strerror(ret) << " cannot query PRODUCT" << std::endl
00173 << "Device: " << xsmres.DSPDev);
00174 g_free (productid);
00175 productid=g_strdup_printf ("Device used: %s\n Start 'gxsm2 -h no' to correct the problem.", xsmres.DSPDev);
00176 gapp->alert (N_("Unkonwn Hardware"), N_("Query Product ID failed."), productid, 1);
00177 close (dsp);
00178 dsp = 0;
00179 exit (-1);
00180 return;
00181 }
00182 if (vendor == 0x0a59){
00183 g_free (productid);
00184 if (product == 0x0101)
00185 productid=g_strdup ("Vendor/Product: B.Paillard, Signal Ranger STD");
00186 else if (product == 0x0103)
00187 productid=g_strdup ("Vendor/Product: B.Paillard, Signal Ranger SP2");
00188 else{
00189 productid=g_strdup ("Vendor/Product: B.Paillard, unkown version!");
00190 gapp->alert (N_("Unkonwn Hardware detected"), N_("No Signal Ranger found."), productid, 1);
00191 close (dsp);
00192 dsp=0;
00193 exit (-1);
00194 return;
00195 }
00196
00197
00198 lseek (dsp, FB_SPM_MAGIC_ADR, SRANGER_SEEK_DATA_SPACE);
00199 read (dsp, &magic_data, sizeof (magic_data));
00200
00201 swap_flg = 0;
00202 if (magic_data.magic != FB_SPM_MAGIC){
00203 swap (&magic_data.magic);
00204 if (magic_data.magic != FB_SPM_MAGIC){
00205 SRANGER_ERROR ("DSP SPM soft cannot be identified: Magic unkown");
00206 productid=g_strdup_printf ("Bad Magic: %04x\n"
00207 "Please launch the correct DSP software before restarting GXSM.",
00208 magic_data.magic);
00209 gapp->alert (N_("Wrong DSP magic"), N_("DSP software was not identified."), productid, 1);
00210 close (dsp);
00211 dsp=0;
00212 magic_data.magic = 0;
00213 exit (-1);
00214 return;
00215 }
00216
00217 swap_flg = 1;
00218 swap (&magic_data.version);
00219 swap (&magic_data.year);
00220 swap (&magic_data.mmdd);
00221 swap (&magic_data.dsp_soft_id);
00222 swap (&magic_data.statemachine);
00223 swap (&magic_data.AIC_in);
00224 swap (&magic_data.AIC_out);
00225 swap (&magic_data.AIC_reg);
00226 swap (&magic_data.feedback);
00227 swap (&magic_data.analog);
00228 swap (&magic_data.scan);
00229 swap (&magic_data.move);
00230 swap (&magic_data.probe);
00231 swap (&magic_data.autoapproach);
00232 swap (&magic_data.datafifo);
00233 swap (&magic_data.probedatafifo);
00234 swap (&magic_data.dfm_fuzzymix);
00235 }
00236 SRANGER_DEBUG ("SRanger, FB_SPM soft: Magic data OK");
00237
00238 if (FB_SPM_SOFT_ID != magic_data.dsp_soft_id){
00239 gchar *details = g_strdup_printf(
00240 "Bad SR DSP Software ID %4X found.\n"
00241 "SR DSP Software ID %4X expected.\n"
00242 "This non SPM DSP code will not work for GSXM, cannot proceed.",
00243 "Please launch the correct DSP software before restarting GXSM.",
00244 magic_data.dsp_soft_id,
00245 FB_SPM_SOFT_ID);
00246 SRANGER_DEBUG ("Signal Ranger FB_SPM soft Version mismatch\n" << details);
00247 gapp->alert (N_("Warning"), N_("Signal Ranger FB_SPM software version mismatch detected!"), details, 1);
00248 g_free (details);
00249 close (dsp);
00250 dsp=0;
00251 magic_data.magic = 0;
00252 exit (-1);
00253 return;
00254 }
00255
00256 if (FB_SPM_VERSION != magic_data.version ||
00257 FB_SPM_SOFT_ID != magic_data.dsp_soft_id){
00258 gchar *details = g_strdup_printf(
00259 "Detected SRanger DSP Software Version: %x.%02x\n"
00260 "GXSM was build for DSP Software Version: %x.%02x\n\n"
00261 "Note: This may cause incompatility problems and unpredictable toubles,\n"
00262 "however, trying to proceed in case you know what you are doing.",
00263 magic_data.version >> 8,
00264 magic_data.version & 0xff,
00265 FB_SPM_VERSION >> 8,
00266 FB_SPM_VERSION & 0xff)
00267 SRANGER_DEBUG ("Signal Ranger FB_SPM soft Version mismatch\n" << details);
00268 gapp->alert (N_("Warning"), N_("Signal Ranger FB_SPM software version mismatch detected!"), details, 1);
00269 g_free (details);
00270 }
00271
00272 SRANGER_DEBUG ("ProductId:" << productid);
00273
00274
00275 if((thread_dsp = open (xsmres.DSPDev, O_RDWR)) <= 0){
00276 SRANGER_ERROR ("cannot open thread SR connection, trying to continue...");
00277 thread_dsp = 0;
00278 }
00279
00280 if((probe_thread_dsp = open (xsmres.DSPDev, O_RDWR)) <= 0){
00281 SRANGER_ERROR ("cannot open probe thread SR connection, trying to continue...");
00282 probe_thread_dsp = 0;
00283 }
00284 if((dsp_alternative = open (xsmres.DSPDev, O_RDWR)) <= 0){
00285 SRANGER_ERROR ("cannot open alternative SR connection, trying to continue...");
00286 dsp_alternative = 0;
00287 }
00288 }else{
00289 SRANGER_ERROR ("unkown vendor, exiting");
00290 close (dsp);
00291 dsp = 0;
00292 return;
00293 }
00294 }
00295 }
00296
00297
00298
00299
00300 sranger_hwi_dev::~sranger_hwi_dev(){
00301 SRANGER_DEBUG ("closing connection to SRanger driver");
00302 close (dsp);
00303 close (thread_dsp);
00304 close (probe_thread_dsp);
00305 close (dsp_alternative);
00306 }
00307
00308
00309
00310 void sranger_hwi_dev::swap (unsigned short *addr){
00311 unsigned short temp1, temp2;
00312 temp1 = temp2 = *addr;
00313 *addr = ((temp2 & 0xFF) << 8) | ((temp1 >> 8) & 0xFF);
00314 }
00315
00316 void sranger_hwi_dev::swap (short *addr){
00317 unsigned short temp1, temp2;
00318 temp1 = temp2 = *addr;
00319 *addr = ((temp2 & 0xFF) << 8) | ((temp1 >> 8) & 0xFF);
00320 }
00321
00322 void sranger_hwi_dev::swap (long *addr){
00323 long temp1, temp2, temp3, temp4;
00324
00325 temp1 = (*addr) & 0xFF;
00326 temp2 = (*addr >> 8) & 0xFF;
00327 temp3 = (*addr >> 16) & 0xFF;
00328 temp4 = (*addr >> 24) & 0xFF;
00329
00330 *addr = (temp1 << 24) | (temp2 << 16) | (temp3 << 8) | temp4;
00331 }
00332
00333 int sranger_hwi_dev::float_2_sranger_q15 (double x){
00334 if (x >= 1.)
00335 return 32767;
00336 if (x <= -1.)
00337 return -32766;
00338
00339 return (int)(x*32767.);
00340 }
00341
00342 int sranger_hwi_dev::int_2_sranger_int (int x){
00343 short tmp = x > 32767 ? 32767 : x < -32766 ? -32766 : x;
00344 if (swap_flg)
00345 swap (&tmp);
00346 return tmp;
00347 }
00348
00349 long sranger_hwi_dev::long_2_sranger_long (long x){
00350 if (swap_flg)
00351 swap (&x);
00352 return x;
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 int sranger_hwi_dev::start_fifo_read (int y_start,
00365 int num_srcs0, int num_srcs1, int num_srcs2, int num_srcs3,
00366 Mem2d **Mob0, Mem2d **Mob1, Mem2d **Mob2, Mem2d **Mob3){
00367 if (num_srcs0 || num_srcs1 || num_srcs2 || num_srcs3){
00368 fifo_data_num_srcs[0] = num_srcs0;
00369 fifo_data_num_srcs[1] = num_srcs1;
00370 fifo_data_num_srcs[2] = num_srcs2;
00371 fifo_data_num_srcs[3] = num_srcs3;
00372 fifo_data_Mobp[0] = Mob0;
00373 fifo_data_Mobp[1] = Mob1;
00374 fifo_data_Mobp[2] = Mob2;
00375 fifo_data_Mobp[3] = Mob3;
00376 fifo_data_y_index = y_start;
00377 fifo_read_thread = g_thread_create (FifoReadThread, this, FALSE, NULL);
00378
00379 if ((DSPControlClass->Source & 0xffff) && DSPControlClass->probe_trigger_raster_points > 0){
00380 DSPControlClass->probe_trigger_single_shot = 0;
00381 ReadProbeFifo (thread_dsp, FR_INIT);
00382 }
00383 }
00384 else{
00385 if (DSPControlClass->Source & 0xffff)
00386 probe_fifo_read_thread = g_thread_create (ProbeFifoReadThread, this, FALSE, NULL);
00387 }
00388
00389 return 0;
00390 }
00391
00392
00393
00394
00395 gpointer FifoReadThread (void *ptr_sr){
00396 sranger_hwi_dev *sr = (sranger_hwi_dev*)ptr_sr;
00397 int ny = sr->fifo_data_Mobp[sr->fifo_data_num_srcs[0] ? 0:1][0]->GetNy();
00398
00399 SRANGER_DEBUG ("Starting Fifo Read, reading " << ny << " lines, " << "y_index: " << sr->fifo_data_y_index);
00400
00401
00402 usleep(2000000);
00403
00404 sr->ReadLineFromFifo (SR_READFIFO_RESET);
00405
00406 if (sr->fifo_data_y_index == 0){
00407 for (int yi=0; yi < ny; ++yi)
00408 if (sr->ReadLineFromFifo (yi))
00409 break;
00410 }else{
00411 for (int yi=ny-1; yi >= 0; --yi)
00412 if (sr->ReadLineFromFifo (yi))
00413 break;
00414 }
00415
00416 sr->ReadLineFromFifo (SR_EMPTY_PROBE_FIFO);
00417
00418 SRANGER_DEBUG ("Fifo Read Done.");
00419
00420 return NULL;
00421 }
00422
00423
00424
00425
00426 int sranger_hwi_dev::ReadLineFromFifo (int y_index){
00427 static int len = 0;
00428 static int fifo_reads = 0;
00429 static DATA_FIFO dsp_fifo;
00430 static int max_fill = 0;
00431 int xi;
00432 static int readfifo_status = 0;
00433
00434
00435
00436
00437 if (y_index == SR_READFIFO_RESET){
00438 readfifo_status = 0;
00439 return 0;
00440 }
00441
00442
00443 if (y_index == SR_EMPTY_PROBE_FIFO){
00444
00445 if (DSPControlClass->probe_trigger_raster_points > 0){
00446 for (int i=0; i<10; ++i){
00447
00448 usleep(25000);
00449 ProbeFifoReadFunction (this, thread_dsp);
00450 }
00451 }
00452 return 0;
00453 }
00454
00455 if (!readfifo_status){
00456 fifo_reads = 0; max_fill = 0;
00457 len = fifo_data_Mobp[fifo_data_num_srcs[0] ? 0:1][0]->GetNx();
00458 lseek (thread_dsp, magic_data.datafifo, SRANGER_SEEK_DATA_SPACE);
00459 read (thread_dsp, &dsp_fifo, (MAX_WRITE_DATA_FIFO+3)<<1);
00460 dsp_fifo.stall = 0;
00461 check_and_swap (dsp_fifo.stall);
00462 write (thread_dsp, &dsp_fifo, (MAX_WRITE_DATA_FIFO+3)<<1);
00463
00464 check_and_swap (dsp_fifo.r_position);
00465 check_and_swap (dsp_fifo.w_position);
00466 readfifo_status = 1;
00467 }
00468
00469 {
00470 int maxnum = MAX (MAX (MAX (fifo_data_num_srcs[0], fifo_data_num_srcs[1]), fifo_data_num_srcs[2]), fifo_data_num_srcs[3]);
00471 SHT *linebuffer = new SHT[len*maxnum];
00472 for (int dir = 0; dir < 4 && ScanningFlg; ++dir){
00473 if (!fifo_data_num_srcs[dir]) continue;
00474 xi = 0;
00475 do{
00476
00477 if (DSPControlClass->probe_trigger_raster_points > 0)
00478 ProbeFifoReadFunction (this, thread_dsp);
00479
00480
00481 if (abs (dsp_fifo.r_position - dsp_fifo.w_position) < (DATAFIFO_LENGTH/16)){
00482
00483 check_and_swap (dsp_fifo.r_position);
00484 check_and_swap (dsp_fifo.w_position);
00485
00486
00487 if (DSPControlClass->probe_trigger_raster_points > 0)
00488 lseek (thread_dsp, magic_data.datafifo, SRANGER_SEEK_DATA_SPACE);
00489 write (thread_dsp, &dsp_fifo, MAX_WRITE_DATA_FIFO<<1);
00490
00491
00492
00493 read (thread_dsp, &dsp_fifo, sizeof (dsp_fifo));
00494 ++fifo_reads;
00495
00496
00497 check_and_swap (dsp_fifo.r_position);
00498 check_and_swap (dsp_fifo.w_position);
00499
00500
00501 {
00502 check_and_swap (dsp_fifo.length);
00503 dsp_fifo.fill = dsp_fifo.w_position - dsp_fifo.r_position;
00504 if (dsp_fifo.fill < 0) dsp_fifo.fill += dsp_fifo.length;
00505 if (dsp_fifo.fill > max_fill){
00506 max_fill = dsp_fifo.fill;
00507 }
00508
00509 dsp_fifo.fill = (int)(100*(double)dsp_fifo.fill/(double)dsp_fifo.length);
00510 g_free (AddStatusString);
00511 AddStatusString = g_strdup_printf ("Fifo: %d%% [%d%%]",
00512 dsp_fifo.fill,
00513 (int)(100*(double)max_fill/(double)dsp_fifo.length));
00514 check_and_swap (dsp_fifo.length);
00515 }
00516
00517
00518
00519 usleep(25000);
00520 }
00521
00522
00523 dsp_fifo.r_position += FifoRead (dsp_fifo.r_position, dsp_fifo.w_position,
00524 xi, fifo_data_num_srcs[dir], len,
00525 linebuffer, dsp_fifo.buffer.w);
00526 dsp_fifo.r_position &= DATAFIFO_MASK;
00527
00528 } while (xi<len && ScanningFlg);
00529
00530
00531 if (xi >= len && ScanningFlg){
00532
00533 for (int i=0; i<fifo_data_num_srcs[dir]; ++i){
00534 if (fifo_data_Mobp[dir][i])
00535 fifo_data_Mobp[dir][i]->PutDataLine (y_index, linebuffer+i*len);
00536 }
00537 }
00538 }
00539
00540 delete[] linebuffer;
00541 }
00542
00543 fifo_data_y_index = y_index;
00544
00545
00546 if (DSPControlClass->probe_trigger_raster_points > 0)
00547 ProbeFifoReadFunction (this, thread_dsp);
00548
00549 return (ScanningFlg && xi >= len) ? 0:1;
00550 }
00551
00552
00553
00554
00555 int sranger_hwi_dev::FifoRead (int start, int end, int &xi, int num_srcs, int len, short *buffer, short *fifo){
00556 int count=0;
00557 while (end < start) end += DATAFIFO_LENGTH;
00558 if (swap_flg){
00559 for (int fi=start; fi<end; fi+=num_srcs){
00560 for (int i=0; i<num_srcs; ++i){
00561 swap (&fifo[(fi+i)&DATAFIFO_MASK]);
00562 buffer[xi+i*len] = fifo[(fi+i)&DATAFIFO_MASK]-1;
00563 ++count;
00564 }
00565 if( ++xi == len) break;
00566 }
00567 } else {
00568 for (int fi=start; fi<end; fi+=num_srcs){
00569 for (int i=0; i<num_srcs; ++i){
00570 buffer[xi+i*len] = fifo[(fi+i)&DATAFIFO_MASK]-1;
00571 ++count;
00572 }
00573 if( ++xi == len) break;
00574 }
00575 }
00576 return count;
00577 }
00578
00579
00580 int sranger_hwi_dev::FifoRead (int start, int end, int &xi, int num_srcs, int len, long *buffer, long *fifo){
00581 int count=0;
00582 while (end < start) end += DATAFIFO_LENGTH;
00583 for (int fi=start; fi<end; fi+=num_srcs){
00584 for (int i=0; i<num_srcs; ++i){
00585 if (swap_flg){
00586 long tmp;
00587 tmp = fifo[(fi+i)&DATAFIFO_MASK];
00588 swap (&tmp);
00589 buffer[xi+i*len] = tmp;
00590 }else
00591 buffer[xi+i*len] = fifo[(fi+i)&DATAFIFO_MASK];
00592 ++count;
00593 }
00594 if( ++xi == len) break;
00595 }
00596 return count;
00597 }
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609 # define LOGMSGS0(X) std::cout << X
00610
00611
00612
00613 # define LOGMSGS(X)
00614
00615
00616 # define LOGMSGS2(X)
00617
00618
00619
00620 gpointer ProbeFifoReadThread (void *ptr_sr){
00621 int finish_flag=FALSE;
00622 sranger_hwi_dev *sr = (sranger_hwi_dev*)ptr_sr;
00623
00624 if (sr->probe_fifo_thread_active){
00625 LOGMSGS ( "ProbeFifoReadThread ERROR: Attempt to start again while in progress! [#" << sr->probe_fifo_thread_active << "]" << std::endl);
00626 return NULL;
00627 }
00628 sr->probe_fifo_thread_active++;
00629 DSPControlClass->probe_ready = FALSE;
00630
00631 if (DSPControlClass->probe_trigger_single_shot)
00632 finish_flag=TRUE;
00633
00634 clock_t timeout = clock() + (clock_t)(CLOCKS_PER_SEC*(0.5+sr->probe_time_estimate/22000.));
00635
00636 LOGMSGS ( "ProbeFifoReadThread START " << (DSPControlClass->probe_trigger_single_shot ? "Single":"Multiple") << "-VP[#"
00637 << sr->probe_fifo_thread_active << "] Timeout is set to:"
00638 << (timeout-clock()) << "Clks (incl. 0.5s Reserve) (" << ((double)sr->probe_time_estimate/22000.) << "s)" << std::endl);
00639
00640 sr->ReadProbeFifo (sr->probe_thread_dsp, FR_INIT);
00641
00642 int i=1;
00643 while (sr->is_scanning () || finish_flag){
00644 ++i;
00645 switch (sr->ReadProbeFifo (sr->probe_thread_dsp)){
00646 case RET_FR_NOWAIT:
00647 LOGMSGS2 ( ":NOWAIT:" << i << " TmoClk=" << (timeout-clock()) << std::endl);
00648 continue;
00649 case RET_FR_WAIT:
00650 LOGMSGS ( ":WAIT:" << i << " TmoClk=" << (timeout-clock()) << std::endl);
00651 usleep(50000);
00652 if (finish_flag && clock() > timeout)
00653 goto error;
00654 continue;
00655 case RET_FR_OK:
00656 LOGMSGS2 ( ":OK:" << i << " TmoClk=" << (timeout-clock()) << std::endl);
00657 continue;
00658 case RET_FR_ERROR:
00659 LOGMSGS ( ":ERROR:" << i << " TmoClk=" << (timeout-clock()) << std::endl);
00660 goto error;
00661 case RET_FR_FCT_END:
00662 LOGMSGS ( ":FCT_END:" << i << " TmoClk=" << (timeout-clock()) << std::endl);
00663 if (finish_flag){
00664 #ifdef G_THREADS_ENABLED
00665 if (DSPControlClass->current_auto_flags & FLAG_AUTO_PLOT){
00666 gdk_threads_enter();
00667 DSPControlClass->Probing_graph_callback (NULL, DSPControlClass);
00668 gdk_flush();
00669 gdk_threads_leave();
00670 }
00671 if (DSPControlClass->current_auto_flags & FLAG_AUTO_SAVE){
00672 gdk_threads_enter();
00673 DSPControlClass->Probing_save_callback (NULL, DSPControlClass);
00674 gdk_flush();
00675 gdk_threads_leave();
00676 }
00677 #endif
00678 goto finish;
00679 }
00680 DSPControlClass->push_probedata_arrays ();
00681 DSPControlClass->init_probedata_arrays ();
00682
00683
00684
00685 continue;
00686 }
00687 LOGMSGS ( ":FIFO THREAD ERROR DETECTION:" << i << " TmoClk=" << (timeout-clock()) << std::endl);
00688 goto error;
00689 }
00690 finish:
00691 LOGMSGS ( "ProbeFifoReadThread DONE Single-VP[#" << sr->probe_fifo_thread_active << "] Timeout left (positive is OK):" << (timeout-clock()) << std::endl);
00692
00693 error:
00694 sr->ReadProbeFifo (sr->probe_thread_dsp, FR_FINISH);
00695
00696 --sr->probe_fifo_thread_active;
00697 DSPControlClass->probe_ready = TRUE;
00698
00699 return NULL;
00700 }
00701
00702
00703
00704 gpointer ProbeFifoReadFunction (void *ptr_sr, int dspdev){
00705 sranger_hwi_dev *sr = (sranger_hwi_dev*)ptr_sr;
00706
00707 while (sr->is_scanning ()){
00708 switch (sr->ReadProbeFifo (dspdev)){
00709 case RET_FR_NOWAIT:
00710 continue;
00711 case RET_FR_WAIT:
00712 return NULL;
00713 case RET_FR_OK:
00714 continue;
00715 case RET_FR_ERROR:
00716 goto error;
00717 case RET_FR_FCT_END:
00718 if (DSPControlClass->probedata_length () > 0){
00719 DSPControlClass->push_probedata_arrays ();
00720 DSPControlClass->init_probedata_arrays ();
00721 LOGMSGS ( "ProbeFifoReadFunction -- Pushed Probe Data on Stack" << std::endl);
00722 }
00723 continue;
00724 }
00725 goto error;
00726 }
00727 error:
00728 return NULL;
00729 }
00730
00731
00732
00733 int sranger_hwi_dev::ReadProbeFifo (int dspdev, int control){
00734 int pvd_blk_size=0;
00735 static double pv[9];
00736 static int last = 0;
00737 static int last_read_end = 0;
00738 static DATA_FIFO_EXTERN_PCOPY fifo;
00739 static PROBE_SECTION_HEADER section_header;
00740 static int next_header = 0;
00741 static int number_channels = 0;
00742 static int data_index = 0;
00743 static int end_read = 0;
00744 static int data_block_size=0;
00745 static int need_fct = FR_YES;
00746 static int need_hdr = FR_YES;
00747 static int need_data = FR_YES;
00748 static int ch_lut[32];
00749 static int ch_msk[] = { 0x0000001, 0x0000002, 0x0000010, 0x0000020, 0x0000040, 0x0000080, 0x0000100, 0x0000200,
00750 0x0000800, 0x0001000, 0x0002000, 0x0004000, 0x0008000, 0x0000000 };
00751 static int ch_size[] = { 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 0 };
00752 static char *ch_header[] = {"Zmon-AIC5Out", "Umon-AIC6Out", "AIC5-I", "AIC0", "AIC1", "AIC2", "AIC3", "AIC4",
00753 "LockIn0", "LockIn1stA", "LockIn1stB", "LockIn2ndA", "LockIn2ndB", NULL };
00754 static short data[EXTERN_PROBEDATAFIFO_LENGTH];
00755 static double dataexpanded[13];
00756 #ifdef LOGMSGS0
00757 static double dbg0=0., dbg1=0.;
00758 static int dbgi0=0;
00759 #endif
00760
00761 switch (control){
00762 case FR_FIFO_FORCE_RESET:
00763 fifo.r_position = 0;
00764 fifo.w_position = 0;
00765 check_and_swap (fifo.r_position);
00766 check_and_swap (fifo.w_position);
00767 lseek (dspdev, magic_data.probedatafifo, SRANGER_SEEK_DATA_SPACE);
00768 write (dspdev, &fifo, 2*sizeof(DSP_INT));
00769 return RET_FR_OK;
00770
00771 case FR_INIT:
00772 last = 0;
00773 next_header = 0;
00774 number_channels = 0;
00775 data_index = 0;
00776 last_read_end = 0;
00777
00778 need_fct = FR_YES;
00779 need_hdr = FR_YES;
00780 need_data = FR_YES;
00781
00782 DSPControlClass->init_probedata_arrays ();
00783 for (int i=0; i<13; dataexpanded[i++]=0.);
00784
00785 LOGMSGS0 ( std::endl << "************** PROBE FIFO-READ INIT **************" << std::endl);
00786 LOGMSGS ( "FR::INIT-OK." << std::endl);
00787 return RET_FR_OK;
00788
00789 case FR_FINISH:
00790 LOGMSGS ( "FR::FINISH-OK." << std::endl);
00791 return RET_FR_OK;
00792
00793 default: break;
00794 }
00795
00796 if (need_fct){
00797 LOGMSGS2 ( "FR::NEED_FCT, last: 0x" << std::hex << last << std::dec << std::endl);
00798
00799 lseek (dspdev, magic_data.probedatafifo, SRANGER_SEEK_DATA_SPACE);
00800 read (dspdev, &fifo, sizeof (fifo));
00801 check_and_swap (fifo.w_position);
00802 check_and_swap (fifo.current_section_head_position);
00803 check_and_swap (fifo.current_section_index);
00804 check_and_swap (fifo.p_buffer_base);
00805 end_read = fifo.w_position >= last ? fifo.w_position : EXTERN_PROBEDATAFIFO_LENGTH;
00806
00807
00808 if ((end_read - last) < 1)
00809 return RET_FR_WAIT;
00810 else {
00811 need_fct = FR_NO;
00812 need_data = FR_YES;
00813 }
00814 }
00815
00816 if (need_data){
00817 LOGMSGS ( "FR::NEED_DATA" << std::endl);
00818
00819 int database = (int)fifo.p_buffer_base;
00820 int dataleft = end_read;
00821 int position = 0;
00822 if (fifo.w_position > last_read_end){
00823
00824
00825 }
00826 for (; dataleft > 0; database += 0x4000, dataleft -= 0x4000, position += 0x4000){
00827 LOGMSGS ( "FR::NEED_DATA: B::0x" << std::hex << database << std::dec << std::endl);
00828 lseek (dspdev, database, SRANGER_SEEK_DATA_SPACE);
00829 read (dspdev, &data[position], (dataleft >= 0x4000 ? 0x4000 : dataleft)<<1);
00830 }
00831 last_read_end = end_read;
00832
00833 need_data = FR_NO;
00834 }
00835
00836 if (need_hdr){
00837 LOGMSGS ( "FR::NEED_HDR" << std::endl);
00838
00839
00840 if (last > (EXTERN_PROBEDATAFIFO_LENGTH - EXTERN_PROBEDATA_MAX_LEFT)){
00841 LOGMSGS0 ( "FR:FIFO LOOP DETECTED -- FR::NEED_HDR ** Data @ "
00842 << "0x" << std::hex << last
00843 << " -2 :[" << (*((long*)&data[last-2]))
00844 << " " << (*((long*)&data[last]))
00845 << " " << (*((long*)&data[last+2]))
00846 << " " << (*((long*)&data[last+4]))
00847 << " " << (*((long*)&data[last+6]))
00848 << "] : FIFO LOOP MARK " << std::dec << ( *((long*)&data[last]) == 0 ? "OK":"ERROR")
00849 << std::endl);
00850 next_header -= last;
00851 last = 0;
00852 end_read = fifo.w_position;
00853 }
00854
00855 if (((fifo.w_position - last) < (sizeof (section_header)>>1))){
00856 need_fct = FR_YES;
00857 return RET_FR_WAIT;
00858 }
00859
00860 memcpy ((void*)&(section_header.srcs), (void*)(&data[next_header]), sizeof (section_header));
00861 check_and_swap (section_header.srcs);
00862 check_and_swap (section_header.n);
00863 check_and_swap (section_header.time);
00864 check_and_swap (section_header.x_offset);
00865 check_and_swap (section_header.y_offset);
00866 check_and_swap (section_header.z_offset);
00867 check_and_swap (section_header.x_scan);
00868 check_and_swap (section_header.y_scan);
00869 check_and_swap (section_header.z_scan);
00870 check_and_swap (section_header.u_scan);
00871 check_and_swap (section_header.section);
00872
00873
00874 pv[0] = section_header.time;
00875 pv[1] = section_header.x_offset;
00876 pv[2] = section_header.y_offset;
00877 pv[3] = section_header.z_offset;
00878 pv[4] = section_header.x_scan;
00879 pv[5] = section_header.y_scan;
00880 pv[6] = section_header.z_scan;
00881 pv[7] = section_header.u_scan;
00882 pv[8] = section_header.section;
00883
00884 LOGMSGS ( "FR::NEED_HDR -- got HDR @ 0x" << std::hex << next_header << std::dec
00885 << " section: " << section_header.section
00886 << " time: " << section_header.time
00887 << " XYZ: " << section_header.x_scan << ", " << section_header.y_scan << ", " << section_header.z_scan
00888 << std::endl);
00889
00890
00891 if (section_header.time < 0 || section_header.section < 0 || section_header.section > 50 || section_header.n < 0 || section_header.n > 10000){
00892 LOGMSGS0 ( "************** FIFO READ ERROR DETECTED: bad section header **************" << std::endl);
00893 LOGMSGS0 ( "==> read bad HDR @ 0x" << std::hex << next_header << std::dec
00894 << " last: 0x" << std::hex << last << std::dec
00895 << " section: " << section_header.section
00896 << " time: " << section_header.time
00897 << " XYZ: " << section_header.x_scan << ", " << section_header.y_scan << ", " << section_header.z_scan
00898 << std::endl);
00899 LOGMSGS0 ( "Last Sec: " << dbg0 << "Last srcs: " << dbg1 << " last last: 0x" << std::hex << dbgi0 << std::dec << std::endl);
00900
00901 goto auto_recover_and_debug;
00902 }
00903 #ifdef LOGMSGS0
00904 dbg0 = section_header.section;
00905 dbg1 = section_header.srcs;
00906 dbgi0 = last;
00907 #endif
00908
00909 need_hdr = FR_NO;
00910
00911
00912 number_channels=0;
00913 last += sizeof (section_header) >> 1;
00914 next_header += sizeof (section_header) >> 1;
00915
00916 data_block_size = 0;
00917 if (section_header.srcs){
00918 LOGMSGS ( "FR::NEED_HDR: decoding DATA_SRCS to read..." << std::endl);
00919 for (int i = 1; i <= 0x8000; i <<= 1){
00920 if (section_header.srcs & i){
00921 int j;
00922 for (j=0; ch_msk[j] && j < 32; ++j)
00923 if (ch_msk[j] == i)
00924 break;
00925 if (j<32 && ch_msk[j]){
00926 ch_lut[number_channels] = j;
00927 data_block_size += ch_size[j];
00928 ++number_channels;
00929 }
00930 }
00931 if (i == 0x400 && (data_block_size>>1) & 1){
00932 data_block_size += 2;
00933 ch_lut[number_channels] = -1;
00934 ++number_channels;
00935 }
00936
00937 }
00938 next_header += section_header.n * (data_block_size >> 1);
00939 data_index = 0;
00940
00941 } else {
00942 LOGMSGS ( "FR::NEED_HDR: DATA_SRCS ZERO." << std::endl);
00943
00944 if (section_header.n == 0){
00945 LOGMSGS ( "FR::NEED_HDR: DATA_N ZERO -> END PROBE OK." << std::endl);
00946 DSPControlClass->probe_trigger_single_shot = 0;
00947 number_channels = 0;
00948 data_index = 0;
00949 need_hdr = FR_YES;
00950 return RET_FR_FCT_END;
00951 } else {
00952 LOGMSGS ( "FR::NEED_HDR: no data in this section." << std::endl);
00953 }
00954
00955 LOGMSGS ( "FR::NEED_HDR: need next hrd!" << std::endl);
00956 need_hdr = FR_YES;
00957 return RET_FR_NOWAIT;
00958 }
00959 }
00960
00961
00962 pvd_blk_size = data_block_size >> 1;
00963 LOGMSGS ( "FR::DATA-cvt:"
00964 << " pvd_blk-sz=" << pvd_blk_size
00965 << " last=0x" << std::hex << last << std::dec
00966 << " next_header=0x" << std::hex << next_header << std::dec
00967 << " end_read=0x" << std::hex << end_read << " EPL:0x" << EXTERN_PROBEDATAFIFO_LENGTH << std::dec
00968 << " data_index=" << data_index << std::dec
00969 << std::endl);
00970
00971 for (int element=0; last < end_read; ++last, ++data_index){
00972
00973
00974 if (last == next_header){
00975 LOGMSGS ( "FR:NEXT HDR EXPECTED" << std::endl);
00976 need_hdr = FR_YES;
00977 return RET_FR_NOWAIT;
00978 }
00979 if (last > next_header){
00980 LOGMSGS0 ( "FR:ERROR:: =====> MISSED NEXT HDR?"
00981 << " last: 0x" << std::hex << last
00982 << " next_header: 0x" << std::hex << next_header
00983 << std::endl);
00984 goto auto_recover_and_debug;
00985 }
00986
00987 int channel = ch_lut[element++];
00988 if (channel >= 0){
00989
00990 if (ch_size[channel] == 4){
00991 long *tmp = (long*)&data[last];
00992 check_and_swap (*tmp);
00993 dataexpanded[channel] = (double) (*tmp);
00994 ++last; ++data_index;
00995 } else {
00996 check_and_swap (data[last]);
00997 dataexpanded[channel] = (double) data[last];
00998 }
00999 }
01000
01001
01002 if ((data_index % pvd_blk_size) == (pvd_blk_size-1)){
01003 if (data_index >= pvd_blk_size)
01004 DSPControlClass->add_probevector ();
01005 else
01006 DSPControlClass->set_probevector (pv);
01007
01008 DSPControlClass->add_probedata (dataexpanded);
01009 element = 0;
01010
01011
01012 if (last > (EXTERN_PROBEDATAFIFO_LENGTH - EXTERN_PROBEDATA_MAX_LEFT)){
01013 ++last;
01014 LOGMSGS0 ( "FR:FIFO LOOP DETECTED ** Data @ "
01015 << "0x" << std::hex << last
01016 << " -2 :[" << (*((long*)&data[last-2]))
01017 << " " << (*((long*)&data[last]))
01018 << " " << (*((long*)&data[last+2]))
01019 << " " << (*((long*)&data[last+4]))
01020 << " " << (*((long*)&data[last+6]))
01021 << "] : FIFO LOOP MARK " << std::dec << ( *((long*)&data[last]) == 0 ? "OK":"ERROR")
01022 << std::endl);
01023 next_header -= last;
01024 last = -1;
01025 end_read = fifo.w_position;
01026 }
01027 }
01028 }
01029
01030 LOGMSGS ( "FR:FIFO NEED FCT" << std::endl);
01031 need_fct = FR_YES;
01032
01033 return RET_FR_WAIT;
01034
01035
01036
01037 auto_recover_and_debug:
01038
01039 #ifdef LOGMSGS0
01040 LOGMSGS0 ( "************** -- FIFO DEBUG -- **************" << std::endl);
01041 LOGMSGS0 ( "LastArdess: " << "0x" << std::hex << last << std::dec << std::endl);
01042 for (int adr=last-8; adr < last+32; adr+=8){
01043 while (adr < 0) ++adr;
01044 LOGMSGS0 ("0x" << std::hex << adr << "::"
01045 << " " << (*((long*)&data[adr]))
01046 << " " << (*((long*)&data[adr+2]))
01047 << " " << (*((long*)&data[adr+4]))
01048 << " " << (*((long*)&data[adr+6]))
01049 << std::dec << std::endl);
01050 }
01051 LOGMSGS0 ( "************** TRYING AUTO RECOVERY **************" << std::endl);
01052 LOGMSGS0 ( "***** -- STOP * RESET FIFO * START PROBE -- ******" << std::endl);
01053 #endif
01054
01055
01056
01057 DSP_INT start_stop[2] = { 0, 1 };
01058 lseek (dspdev, magic_data.probe, SRANGER_SEEK_DATA_SPACE);
01059 write (dspdev, &start_stop, 2*sizeof(DSP_INT));
01060
01061
01062
01063 fifo.r_position = 0;
01064 fifo.w_position = 0;
01065 check_and_swap (fifo.r_position);
01066 check_and_swap (fifo.w_position);
01067 lseek (dspdev, magic_data.probedatafifo, SRANGER_SEEK_DATA_SPACE);
01068 write (dspdev, &fifo, 2*sizeof(DSP_INT));
01069
01070
01071
01072 start_stop[0] = 1;
01073 start_stop[1] = 0;
01074 lseek (dspdev, magic_data.probe, SRANGER_SEEK_DATA_SPACE);
01075 write (dspdev, &start_stop, 2*sizeof(DSP_INT));
01076
01077
01078 last = 0;
01079 next_header = 0;
01080 number_channels = 0;
01081 data_index = 0;
01082 last_read_end = 0;
01083 need_fct = FR_YES;
01084 need_hdr = FR_YES;
01085 need_data = FR_YES;
01086
01087
01088 return RET_FR_WAIT;
01089 }
01090
01091
01092
01093
01094
01095
01096
01097
01098 int sranger_hwi_dev::ReadScanData(int y_index, int num_srcs, Mem2d *m[MAX_SRCS_CHANNELS]){
01099 return 0;
01100 }
01101
01102 int sranger_hwi_dev::ReadProbeData(int nsrcs, int nprobe, int kx, int ky, Mem2d *m, double scale){
01103
01104 return 1;
01105 }
01106
01107
01108
01109
01110
01111 gchar* sranger_hwi_dev::get_info(){
01112 static gchar *magic_info = NULL;
01113 if (productid){
01114 gchar *details = NULL;
01115 if (FB_SPM_VERSION != magic_data.version){
01116 details = g_strdup_printf(
01117 "WARNING: Signal Ranger FB_SPM soft Version mismatch detected:\n"
01118 "Detected SRanger DSP Software Version: %x.%02x\n"
01119 "Detected SRanger DSP Software ID: %04X\n"
01120 "GXSM was build for DSP Software Version: %x.%02x\n"
01121 "And DSP Software ID %4X is recommended.\n"
01122 "This may cause incompatility problems, trying to proceed.\n",
01123 magic_data.version >> 8,
01124 magic_data.version & 0xff,
01125 magic_data.dsp_soft_id,
01126 FB_SPM_VERSION >> 8,
01127 FB_SPM_VERSION & 0xff,
01128 FB_SPM_SOFT_ID);
01129 } else {
01130 details = g_strdup_printf("Errors/Warnings: none\n");
01131 }
01132 g_free (magic_info);
01133 magic_info = g_strdup_printf (
01134 "Magic....... : %04X\n"
01135 "Version..... : %04X\n"
01136 "Date........ : %04X%04X\n"
01137 "*-- DSP Control Struct Locations --*\n"
01138 "statemachine : %04x\n"
01139 "feedback.... : %04x\n"
01140 "dfm_fuzzymix.: %04x\n"
01141 "analog...... : %04x\n"
01142 "move........ : %04x\n"
01143 "scan........ : %04x\n"
01144 "probe....... : %04x\n"
01145 "autoapproach : %04x\n"
01146 "datafifo.... : %04x\n"
01147 "probedatafifo: %04x\n"
01148 "------------------------------------\n"
01149 "%s",
01150 magic_data.magic,
01151 magic_data.version,
01152 magic_data.year,
01153 magic_data.mmdd,
01154 magic_data.statemachine,
01155 magic_data.feedback,
01156 magic_data.dfm_fuzzymix,
01157 magic_data.analog,
01158 magic_data.move,
01159 magic_data.scan,
01160 magic_data.probe,
01161 magic_data.autoapproach,
01162 magic_data.datafifo,
01163 magic_data.probedatafifo,
01164 details
01165 );
01166 g_free (details);
01167 return g_strconcat (
01168 "*--GXSM Sranger HwI base class--*\n",
01169 "Sranger device: ", productid, "\n",
01170 "*--Features--*\n",
01171 FB_SPM_FEATURES,
01172 "*--Magic Info--*\n",
01173 magic_info,
01174 "*--EOF--*\n",
01175 NULL
01176 );
01177 }
01178 else
01179 return g_strdup("*--GXSM Sranger HwI base class--*\n"
01180 "Sranger device not connected\n"
01181 "or not supported.");
01182 }