sranger_hwi_dev.C

Go to the documentation of this file.
00001 /* Gxsm - Gnome X Scanning Microscopy
00002  * universal STM/AFM/SARLS/SPALEED/... controlling and
00003  * data analysis software
00004  * 
00005  * Copyright (C) 1999,2000,2001,2002,2003 Percy Zahl
00006  *
00007  * Authors: Percy Zahl <zahl@users.sf.net>
00008  * additional features: Andreas Klust <klust@users.sf.net>
00009  * WWW Home: http://gxsm.sf.net
00010  *
00011  * This program is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00024  */
00025 
00026 /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 8 c-style: "K&R" -*- */
00027 
00028 /* irnore this module for docuscan
00029 % PlugInModuleIgnore
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;   /* read pos (Gxsm) (always in word size) (WO) by host =WO */
00046         DSP_UINT    w_position;   /* write pos (DSP) (always in word size) (RO) by host =RO */
00047         DSP_UINT    current_section_head_position; /* resync/verify and status info =RO */
00048         DSP_UINT    current_section_index; /* index of current section =RO */
00049         DSP_UINT    fill;             /* filled indicator = max num to read =RO */
00050         DSP_UINT    stall;            /* number of fifo stalls =RO */
00051         DSP_UINT    length;           /* constant, buffer size =RO */
00052         DSP_UINT    p_buffer_base; /* pointer to external memory, buffer start =RO */
00053         DSP_UINT    p_buffer_w;    /* pointer to external memory =RO */
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 // you may want to handle/emulate some DSP commands later...
00073 #include "dsp-pci32/xsm/dpramdef.h"
00074 #include "dsp-pci32/xsm/xsmcmd.h"
00075 
00076 
00077 // need some SRanger io-controls 
00078 // HAS TO BE IDENTICAL TO THE DRIVER's FILE!
00079 #include "../plug-ins/hard/modules/sranger_ioctl.h"
00080 
00081 // SRanger data exchange structs and consts
00082 #include "FB_spm_dataexchange.h" 
00083 
00084 // enable debug:
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 // some thread states
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 /* Construktor for Gxsm sranger support base class
00119  * ==================================================
00120  * - open device
00121  * - init things
00122  * - ...
00123  */
00124 sranger_hwi_dev::sranger_hwi_dev(){
00125         SRANGER_DEBUG("open driver");
00126         AIC_max_points = 1<<15; // SR-AIC resolution is limiting...
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; // set to zero, this means all data is invalid!
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                         // now read magic struct data
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; // set to zero, this means all data is invalid!
00213                                         exit (-1);
00214                                         return;
00215                                 }
00216                                 // no swapp all to fix endianess
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; // set to zero, this means all data is invalid!
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                         // open some more DSP connections, used by threads
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                         // testing...
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 /* Destructor
00298  * close device
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 // data translation helpers
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; // saturate
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 // Image Data FIFO read thread section
00358 // ==================================================
00359 
00360 // start_fifo_read:
00361 // Data Transfer Setup:
00362 // Prepare and Fork Image Data FIFO read thread
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; // if > 0, scan dir is "bottom-up"
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); // 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 // FifoReadThread:
00393 // Image Data FIFO read thread
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         // This delay is to avoid some not yet exploited initial fifo-reading delay and unnecessary early fifo overflow - PZ
00402         usleep(2000000); // wait for GUI stuff to get ready, empiric -- 4s
00403 
00404         sr->ReadLineFromFifo (SR_READFIFO_RESET); // init read fifo status
00405 
00406         if (sr->fifo_data_y_index == 0){ // top-down
00407                 for (int yi=0; yi < ny; ++yi)
00408                         if (sr->ReadLineFromFifo (yi))
00409                                 break;
00410         }else{ // bottom-up
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); // finish reading all FIFO's (probe may have to be emptied)
00417 
00418         SRANGER_DEBUG ("Fifo Read Done.");
00419 
00420         return NULL;
00421 }
00422 
00423 // ReadLineFromFifo:
00424 // read scan line from FIFO -- wait for data, and empty FIFO as quick as possible, 
00425 // sort data chunks away int scan-mem2d objects
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 //              SRANGER_DEBUG ("ReadData: yindex=" << y_index << "---------------------------");
00435                 
00436         // initiate and unlock scan process now!
00437         if (y_index == SR_READFIFO_RESET){
00438                 readfifo_status = 0;
00439                 return 0;
00440         }
00441 
00442         // finish reading all FIFO's (probe may have to be emptied)
00443         if (y_index == SR_EMPTY_PROBE_FIFO){
00444                 // check probe fifo
00445                 if (DSPControlClass->probe_trigger_raster_points > 0){
00446                         for (int i=0; i<10; ++i){ // about 1/4s finish time
00447                                 // free some cpu time now
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; // unlock scanning
00461                 check_and_swap (dsp_fifo.stall);
00462                 write (thread_dsp, &dsp_fifo, (MAX_WRITE_DATA_FIFO+3)<<1);
00463                 // to PC format
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                                 // check probe fifo
00477                                 if (DSPControlClass->probe_trigger_raster_points > 0)
00478                                         ProbeFifoReadFunction (this, thread_dsp);
00479 
00480                                 // transfer data from DSP fifo into local fifo buffer -- empty DSP fifo
00481                                 if (abs (dsp_fifo.r_position - dsp_fifo.w_position) < (DATAFIFO_LENGTH/16)){
00482                                         // to DSP format
00483                                         check_and_swap (dsp_fifo.r_position);
00484                                         check_and_swap (dsp_fifo.w_position);
00485 
00486                                         // set DSP fifo read position
00487                                         if (DSPControlClass->probe_trigger_raster_points > 0)
00488                                                 lseek (thread_dsp, magic_data.datafifo, SRANGER_SEEK_DATA_SPACE); // added for mixed probe/scan data read
00489                                         write (thread_dsp, &dsp_fifo, MAX_WRITE_DATA_FIFO<<1);
00490 //                                                              SRANGER_DEBUG ("fifo buffer read #" << fifo_reads << " w-r: " << dsp_fifo.w_position - dsp_fifo.r_position << "  dir: " << dir);
00491                                         // Get all and empty fifo
00492                                         // lseek (thread_dsp, magic_data.datafifo, SRANGER_SEEK_DATA_SPACE);
00493                                         read  (thread_dsp, &dsp_fifo, sizeof (dsp_fifo));
00494                                         ++fifo_reads;
00495                                                                 
00496                                         // to PC format
00497                                         check_and_swap (dsp_fifo.r_position);
00498                                         check_and_swap (dsp_fifo.w_position);
00499                                                                 
00500                                         // calc and update Fifo stats
00501                                         {
00502                                                 check_and_swap (dsp_fifo.length); // to PC
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                                                 // calc fill percentage
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); // to DSP
00515                                         }
00516                                                                 
00517 
00518                                         // free some cpu time now
00519                                         usleep(25000);
00520                                 }
00521                                                 
00522                                 // transfer and convert data from fifo buffer
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                         // skip if scan was canceled
00531                         if (xi >= len && ScanningFlg){
00532                                 // read data into linebuffer
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         // check probe fifo again
00546         if (DSPControlClass->probe_trigger_raster_points > 0)
00547                 ProbeFifoReadFunction (this, thread_dsp);
00548 
00549         return (ScanningFlg && xi >= len) ? 0:1;
00550 }
00551 
00552 // FifoRead:
00553 // Read data from FIFO ring buffer (ring) now in host memory and convert and sort into temporary secondary buffer (linear)
00554 // Short-Type Data
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 // Long-Type Data
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 // Probe Data FIFO read thread section
00605 //
00606 // ==================================================
00607  
00608 // FIFO watch verbosity...
00609 # define LOGMSGS0(X) std::cout << X
00610 //# define LOGMSGS0(X)
00611 
00612 //# define LOGMSGS(X) std::cout << X
00613 # define LOGMSGS(X)
00614 
00615 //# define LOGMSGS2(X) std::cout << X
00616 # define LOGMSGS2(X)
00617 
00618 // ProbeFifoReadThread:
00619 // Independent ProbeFifoRead Thread (manual probe)
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); // 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();  // Protect from gtk main loop which also performs a gtk_entry_set_text.
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();  // Protect from gtk main loop which also performs a gtk_entry_set_text.
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                         // reset timeout
00684 //                      timeout = clock() + (clock_t)(CLOCKS_PER_SEC*(0.5+sr->probe_time_estimate/22000.));
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); // finish
00695 
00696         --sr->probe_fifo_thread_active;
00697         DSPControlClass->probe_ready = TRUE;
00698 
00699         return NULL;
00700 }
00701 
00702 // ProbeFifoReadFunction:
00703 // inlineable ProbeFifoRead Function -- similar to the thread, is called/inlined by/into the Image Data Thread
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 // ReadProbeFifo:
00732 // read from probe FIFO, this engine needs to be called several times from master thread/function
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;  // need fifo control
00746         static int need_hdr = FR_YES;  // need header
00747         static int need_data = FR_YES; // need data
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: // not used normally -- FIFO is reset by DSP at probe_init (single probe)
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)); // reset positions now to prevent reading old/last dataset before DSP starts init/putting data
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; // init OK.
00788 
00789         case FR_FINISH:
00790                 LOGMSGS ( "FR::FINISH-OK." << std::endl);
00791                 return RET_FR_OK; // finish OK.
00792 
00793         default: break;
00794         }
00795 
00796         if (need_fct){ // read and check fifo control?
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                 // check for new data
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){ // read full FIFO block
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 //                      database += last_read_end;
00824 //                      dataleft -= last_read_end;
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){ // we have enough data if control gets here!
00837                 LOGMSGS ( "FR::NEED_HDR" << std::endl);
00838 
00839                 // check for FIFO loop
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                 // set vector of expanded data array representation, section start
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                 // validate header -- if stupid things are happening, values are messed up so check:
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                         // baild out and try recovery
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                 // analyze header and setup channel lookup table
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){ // adjust for even LONG position
00932                                         data_block_size += 2;
00933                                         ch_lut[number_channels] = -1; // dummy fill
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; // if single shot, stop reading next
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         // now read/convert all available/valid data from fifo block we just copied
00962         pvd_blk_size = data_block_size >> 1; // data block size in "word"-indices
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                 // got all data, at next header?
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){ // only if valid (skip possible dummy (2) fillings)
00989                         // check for long data (4)
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 { // normal data (2)
00996                                 check_and_swap (data[last]);
00997                                 dataexpanded[channel] = (double) data[last];
00998                         }
00999                 }
01000 
01001                 // add vector and data to expanded data array representation
01002                 if ((data_index % pvd_blk_size) == (pvd_blk_size-1)){
01003                         if (data_index >= pvd_blk_size) // skip to next vector
01004                                 DSPControlClass->add_probevector ();
01005                         else // set vector as previously read from section header (pv[]) at sec start
01006                                 DSPControlClass->set_probevector (pv);
01007                         // add full data vector
01008                         DSPControlClass->add_probedata (dataexpanded);
01009                         element = 0;
01010 
01011                         // check for FIFO loop now
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; // compensate for ++last at of for(;;)!
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 // emergency bailout and auto recovery, FIFO restart
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         // STOP PROBE
01056         // reset positions now to prevent reading old/last dataset before DSP starts init/putting data
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         // RESET FIFO
01062         // reset positions now to prevent reading old/last dataset before DSP starts init/putting data
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         // START PROBE
01071         // reset positions now to prevent reading old/last dataset before DSP starts init/putting data
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         // reset all internal and partial reinit FIFO read thread
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         // and start over on next call
01088         return RET_FR_WAIT;
01089 }
01090 
01091 
01092 
01093 
01094 
01095 // ==================================================
01096 // obsolete
01097 
01098 int sranger_hwi_dev::ReadScanData(int y_index, int num_srcs, Mem2d *m[MAX_SRCS_CHANNELS]){
01099         return 0; // done by thread
01100 }
01101 
01102 int sranger_hwi_dev::ReadProbeData(int nsrcs, int nprobe, int kx, int ky, Mem2d *m, double scale){
01103         // this function is obsolete since vector probe
01104         return 1;
01105 }
01106 
01107 
01108 /*
01109  * provide some info about the connected hardware/driver/etc.
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); // g_free irgnors NULL ptr!
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 }

Generated on Sat Apr 1 09:04:19 2006 for GXSM by  doxygen 1.4.6