Subversion Repositories f9daq

Rev

Rev 212 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 212 Rev 292
Line 10... Line 10...
10
 
10
 
11
#include "H1D.h"
11
#include "H1D.h"
12
#include "H2D.h"
12
#include "H2D.h"
13
#include "H3D.h"
13
#include "H3D.h"
14
 
14
 
15
 
-
 
-
 
15
static int node[3];
16
typedef unsigned short ushort;
16
typedef unsigned short ushort;
17
typedef unsigned int uint;
17
typedef unsigned int uint;
18
 
18
 
19
static int ait;
19
static int ait;
20
static int xyscan;
20
static int xyscan;
21
//#define MIKRO
21
//#define MIKRO
22
 
22
 
23
#ifdef MIKRO
23
#ifdef MIKRO
24
#include "MIKRO.h"
24
#include "MIKRO.h"
25
#endif
25
#endif
26
 
26
 
-
 
27
#define uSMC_USB
-
 
28
#ifdef uSMC_USB
-
 
29
#  include "uSMC.h"
-
 
30
#  define uSMC_SERIAL_X "0000000000004925"
-
 
31
#  define uSMC_SERIAL_Y "0000000000006030"
-
 
32
#  define uSMC_SERIAL_Z "0000000000002894"
-
 
33
const char serials[3][16]= {uSMC_SERIAL_X,uSMC_SERIAL_Y,uSMC_SERIAL_Z};
-
 
34
#endif /* uSMC_USB */
-
 
35
 
27
static int daq_on;
36
static int daq_on;
28
static int plothandle[4]= {0,0,0, 0};
37
static int plothandle[4]= {0,0,0, 0};
29
static int tfID;
38
static int tfID;
30
static int controlID;
39
static int controlID;
31
static int verbose;
40
static int verbose;
Line 104... Line 113...
104
 
113
 
105
}
114
}
106
 
115
 
107
int AitInit() {
116
int AitInit() {
108
  InitializeConnection();
117
  InitializeConnection();
109
  return 0;
118
  return 0;
110
}
119
}
111
 
120
 
112
 
121
 
113
int AitValidEvent() {
122
int AitValidEvent() {
114
 
123
 
Line 388... Line 397...
388
 
397
 
389
    }
398
    }
390
    time(&t);
399
    time(&t);
391
    printf("%d events in %2.2f min (%d s) %s",i+1, (double)(t-tstart)/60.,t-tstart, ctime(&t));
400
    printf("%d events in %2.2f min (%d s) %s",i+1, (double)(t-tstart)/60.,t-tstart, ctime(&t));
392
 
401
 
393
  }
402
  }
394
 
403
 
395
  if (fp) fclose(fp);
404
  if (fp) fclose(fp);
396
 
405
 
397
 
406
 
398
        RefreshGraphs (ait, 0 , EVENT_TIMER_TICK ,NULL, 0, 0 );
407
        RefreshGraphs (ait, 0 , EVENT_TIMER_TICK ,NULL, 0, 0 );
399
  return 0;
408
  return 0;
Line 436... Line 445...
436
        GetCtrlVal(xyscan, SCAN_STARTX, &x0[0]);
445
        GetCtrlVal(xyscan, SCAN_STARTX, &x0[0]);
437
        GetCtrlVal(xyscan, SCAN_STARTY, &x0[1]);
446
        GetCtrlVal(xyscan, SCAN_STARTY, &x0[1]);
438
 
447
 
439
       
448
       
440
        if (enabledoutput) {
449
        if (enabledoutput) {
441
                                fp =  fopen(filename,"ab");
450
                                fp =  fopen(filename,"ab");
442
                                if (fp) {
451
                                if (fp) {
443
                                         size=36;
452
                                         size=36;
444
                                         fwrite(&runbuf, sizeof(unsigned short),1 ,fp);
453
                                         fwrite(&runbuf, sizeof(unsigned short),1 ,fp);
445
                                         fwrite(&size  , sizeof(unsigned short),1 ,fp);
454
                                         fwrite(&size  , sizeof(unsigned short),1 ,fp);
446
                                         fwrite(x0    , 1,4*3 ,fp);
455
                                         fwrite(x0    , 1,4*3 ,fp);
Line 455... Line 464...
455
         SetCtrlVal (xyscan, SCAN_IY, j);
464
         SetCtrlVal (xyscan, SCAN_IY, j);
456
         ix[1]= x0[1]+j*dx[1];
465
         ix[1]= x0[1]+j*dx[1];
457
#ifdef MIKRO
466
#ifdef MIKRO
458
                MIKRO_MoveTo(2,ix[1]);
467
                MIKRO_MoveTo(2,ix[1]);
459
                MIKRO_GetPosition(2,&n[1]);
468
                MIKRO_GetPosition(2,&n[1]);
460
                        SetCtrlVal (xyscan, SCAN_YP, n[1]);
469
            SetCtrlVal (xyscan, SCAN_YP, n[1]);
-
 
470
#endif
-
 
471
#ifdef uSMC_USB
-
 
472
                uSMC_MoveTo(node[1],ix[1]);
-
 
473
                uSMC_GetPosition(node[1],&n[1]);
-
 
474
            SetCtrlVal (xyscan, SCAN_YP, n[1]);
461
#endif          
475
#endif
-
 
476
               
-
 
477
                       
462
                       
478
                       
463
         for (int i=0; i<nx[0]; i++) {
479
         for (int i=0; i<nx[0]; i++) {
464
                SetCtrlVal (xyscan, SCAN_IX, i);  
480
                SetCtrlVal (xyscan, SCAN_IX, i);  
465
                ix[0]= x0[0]+i*dx[0];
481
                ix[0]= x0[0]+i*dx[0];
466
#ifdef MIKRO
482
#ifdef MIKRO
467
                  MIKRO_MoveTo(1,ix[0]);
483
                    MIKRO_MoveTo(1,ix[0]);
468
                        MIKRO_GetPosition(1,&n[0]);
484
                        MIKRO_GetPosition(1,&n[0]);
469
                        SetCtrlVal (xyscan, SCAN_XP, n[0]);
485
                        SetCtrlVal (xyscan, SCAN_XP, n[0]);
-
 
486
#endif          
-
 
487
#ifdef uSMC_USB
-
 
488
                    uSMC_MoveTo(node[0],ix[0]);
-
 
489
                        uSMC_GetPosition(node[0],&n[0]);
-
 
490
                        SetCtrlVal (xyscan, SCAN_XP, n[0]);
470
                       
491
#endif                  
471
       
492
       
472
                        if (enabledoutput) {
493
                        if (enabledoutput) {
473
                                fp =  fopen(filename,"ab");
494
                                fp =  fopen(filename,"ab");
474
                                if (fp) {
495
                                if (fp) {
475
                                         time_t mtime;
496
                                         time_t mtime;
Line 484... Line 505...
484
                                         fwrite(&mtime  , sizeof(time_t),1 ,fp);
505
                                         fwrite(&mtime  , sizeof(time_t),1 ,fp);
485
                                         fclose(fp);
506
                                         fclose(fp);
486
                                }    
507
                                }    
487
                        }      
508
                        }      
488
                               
509
                               
489
#endif
510
 
490
                        int newfile=0;
511
                        int newfile=0;
491
                        daq(&newfile);
512
                        daq(&newfile);
492
                        if (!daq_on) break;
513
                        if (!daq_on) break;
493
                }
514
                }
494
                if (!daq_on) break;
515
                if (!daq_on) break;
Line 497... Line 518...
497
        return 0;
518
        return 0;
498
}
519
}
499
 
520
 
500
 
521
 
501
int main (int argc, char *argv[]) {
522
int main (int argc, char *argv[]) {
502
        short port;
523
 
503
  if (InitCVIRTE (0, argv, 0) == 0)
524
  if (InitCVIRTE (0, argv, 0) == 0)
504
    return -1;  /* out of memory */
525
    return -1;  /* out of memory */
505
  if ((ait = LoadPanel (0, "AitGui.uir", AIT)) < 0)
526
  if ((ait = LoadPanel (0, "AitGui.uir", AIT)) < 0)
506
    return -1;
527
    return -1;
507
  if ((xyscan = LoadPanel (0, "XYSCAN.uir", SCAN)) < 0)
528
  if ((xyscan = LoadPanel (0, "XYSCAN.uir", SCAN)) < 0)
Line 513... Line 534...
513
  DisplayPanel (xyscan);
534
  DisplayPanel (xyscan);
514
  AitInit();
535
  AitInit();
515
       
536
       
516
               
537
               
517
#ifdef MIKRO
538
#ifdef MIKRO
-
 
539
        short port;
518
        GetCtrlVal(xyscan, SCAN_PORT, &port);
540
    GetCtrlVal(xyscan, SCAN_PORT, &port);
519
        if (MIKRO_Open (port)) MessagePopup ("Error", "Mikro Port Not found !\n Change in the GUI") ;
541
        if (MIKRO_Open (port)) MessagePopup ("Error", "Mikro Port Not found !\n Change in the GUI") ;
520
        MIKRO_Init(1,0);
542
        MIKRO_Init(1,0);
521
        MIKRO_Init(2,0);
543
        MIKRO_Init(2,0);
522
#endif
544
#endif
-
 
545
#ifdef uSMC_USB
-
 
546
  uSMC_Open();
-
 
547
  for (int i=0; i<3; i++) {
-
 
548
    node[i]=uSMC_FindSerial(serials[i])+1;
-
 
549
    uSMC_Init(node[i],1);
-
 
550
  }
-
 
551
#endif /* uSMC_USB */   
523
       
552
       
524
       
553
       
525
  RunUserInterface ();
554
  RunUserInterface ();
526
       
555
       
527
#ifdef MIKRO    
556
#ifdef MIKRO    
528
        MIKRO_Close ();
557
        MIKRO_Close ();
529
#endif          
558
#endif 
-
 
559
#ifdef uSMC_USB
-
 
560
  for (int i=0; i<3; i++) uSMC_PowerOff(node[i]);
-
 
561
  uSMC_Close();
-
 
562
#endif /* uSMC_USB */   
530
  DiscardPanel (ait);
563
  DiscardPanel (ait);
531
  DiscardPanel (xyscan);
564
  DiscardPanel (xyscan);
532
  return 0;
565
  return 0;
533
}
566
}
534
 
567
 
535
int CVICALLBACK StopCB (int panel, int control, int event,
568
int CVICALLBACK StopCB (int panel, int control, int event,
536
                        void *callbackData, int eventData1, int eventData2) {
569
                        void *callbackData, int eventData1, int eventData2) {
537
  switch (event) {
570
  switch (event) {
538
    case EVENT_COMMIT:
571
    case EVENT_COMMIT:
539
      daq_on=0;
572
      daq_on=0;
540
      break;
573
      break;
541
  }
574
  }
542
  return 0;
575
  return 0;
543
}
576
}
544
 
577
 
545
 
578
 
546
int CVICALLBACK StartCB (int panel, int control, int event,
579
int CVICALLBACK StartCB (int panel, int control, int event,
547
                         void *callbackData, int eventData1, int eventData2) {
580
                         void *callbackData, int eventData1, int eventData2) {
Line 558... Line 591...
558
                        if (panel == xyscan && control == SCAN_SCAN)   mythread = scan;  
591
                        if (panel == xyscan && control == SCAN_SCAN)   mythread = scan;  
559
      if (mythread!=NULL) {
592
      if (mythread!=NULL) {
560
        printf("New Thread panel=%d button=%d\n", panel, control);
593
        printf("New Thread panel=%d button=%d\n", panel, control);
561
 
594
 
562
        // SetDimming(1);
595
        // SetDimming(1);
563
 
596
 
564
       
597
       
565
        CmtScheduleThreadPoolFunctionAdv (poolHandle, mythread, &controlID,
598
        CmtScheduleThreadPoolFunctionAdv (poolHandle, mythread, &controlID,
566
                                          DEFAULT_THREAD_PRIORITY,
599
                                          DEFAULT_THREAD_PRIORITY,
567
                                          EndOfThread,
600
                                          EndOfThread,
568
                                          EVENT_TP_THREAD_FUNCTION_END,
601
                                          EVENT_TP_THREAD_FUNCTION_END,
569
                                          NULL, RUN_IN_SCHEDULED_THREAD,
602
                                          NULL, RUN_IN_SCHEDULED_THREAD,
570
                                          &tfID);
603
                                          &tfID);
571
      }
604
      }
572
      break;
605
      break;
573
  }
606
  }
574
  return 0;
607
  return 0;
575
}
608
}
576
 
609
 
577
 
610
 
578
 
611
 
579
int CVICALLBACK ExitCB (int panel, int control, int event,
612
int CVICALLBACK ExitCB (int panel, int control, int event,
580
                        void *callbackData, int eventData1, int eventData2) {
613
                        void *callbackData, int eventData1, int eventData2) {
581
  switch (event) {
614
  switch (event) {
582
    case EVENT_COMMIT:
615
    case EVENT_COMMIT:
583
      QuitUserInterface (0);
616
      QuitUserInterface (0);
584
      break;
617
      break;
585
  }
618
  }
586
  return 0;
619
  return 0;
587
}
620
}
588
 
621
 
589
int CVICALLBACK ReadCB (int panel, int control, int event,
622
int CVICALLBACK ReadCB (int panel, int control, int event,
590
                        void *callbackData, int eventData1, int eventData2) {
623
                        void *callbackData, int eventData1, int eventData2) {
591
  switch (event) {
624
  switch (event) {
592
    case EVENT_COMMIT:
625
    case EVENT_COMMIT:
593
 
626
 
594
 
627
 
595
 
628
 
596
      ReadRegisters();
629
      ReadRegisters();
597
      break;
630
      break;
598
  }
631
  }
599
  return 0;
632
  return 0;
600
}
633
}
601
 
634
 
602
int CVICALLBACK ChangeChannelCB (int panel, int control, int event,
635
int CVICALLBACK ChangeChannelCB (int panel, int control, int event,
603
                                 void *callbackData, int eventData1, int eventData2) {
636
                                 void *callbackData, int eventData1, int eventData2) {
604
  int ch=0;
637
  int ch=0;
605
  switch (event) {
638
  switch (event) {
606
    case EVENT_COMMIT:
639
    case EVENT_COMMIT:
607
 
640
 
608
      int logy=0;
641
      int logy=0;
609
      GetCtrlVal(ait,AIT_CH, &ch);
642
      GetCtrlVal(ait,AIT_CH, &ch);
610
                        GetCtrlVal(ait,AIT_LOGY, &logy);
643
                        GetCtrlVal(ait,AIT_LOGY, &logy);
611
                        if (logy){
644
                        if (logy){
Line 616... Line 649...
616
                                SetCtrlAttribute (ait, AIT_GRAPH, ATTR_YMAP_MODE, VAL_LINEAR);
649
                                SetCtrlAttribute (ait, AIT_GRAPH, ATTR_YMAP_MODE, VAL_LINEAR);
617
                          SetCtrlAttribute (ait, AIT_GRAPHSUM, ATTR_YMAP_MODE, VAL_LINEAR);
650
                          SetCtrlAttribute (ait, AIT_GRAPHSUM, ATTR_YMAP_MODE, VAL_LINEAR);
618
                       
651
                       
619
                        }
652
                        }
620
      H1D_Draw(ch,ait,AIT_GRAPH,&plothandle[0]);
653
      H1D_Draw(ch,ait,AIT_GRAPH,&plothandle[0]);
621
      break;
654
      break;
622
  }
655
  }
623
  return 0;
656
  return 0;
624
}
657
}
625
 
658
 
626
 
659
 
627
 
660
 
628
 
661
 
629
 
662
 
630
int CVICALLBACK InitCB (int panel, int control, int event,
663
int CVICALLBACK InitCB (int panel, int control, int event,
631
                        void *callbackData, int eventData1, int eventData2) {
664
                        void *callbackData, int eventData1, int eventData2) {
632
  switch (event) {
665
  switch (event) {
633
    case EVENT_COMMIT:
666
    case EVENT_COMMIT:
634
      AitInit();
667
      AitInit();
Line 671... Line 704...
671
                        ((GetBit(csrDetector, BIT_CSR_DET_SUMGAIN4) ? 1 : 0) << 3) |
704
                        ((GetBit(csrDetector, BIT_CSR_DET_SUMGAIN4) ? 1 : 0) << 3) |
672
                        ((GetBit(csrDetector, BIT_CSR_DET_SUMGAIN3) ? 1 : 0) << 2) |
705
                        ((GetBit(csrDetector, BIT_CSR_DET_SUMGAIN3) ? 1 : 0) << 2) |
673
                        ((GetBit(csrDetector, BIT_CSR_DET_SUMGAIN2) ? 1 : 0) << 1) |
706
                        ((GetBit(csrDetector, BIT_CSR_DET_SUMGAIN2) ? 1 : 0) << 1) |
674
                        ((GetBit(csrDetector, BIT_CSR_DET_SUMGAIN1) ? 1 : 0) << 0);
707
                        ((GetBit(csrDetector, BIT_CSR_DET_SUMGAIN1) ? 1 : 0) << 0);
675
      SetCtrlVal (panel, AIT_GETADCSUMGAIN, ivalue);
708
      SetCtrlVal (panel, AIT_GETADCSUMGAIN, ivalue);
676
      break;
709
      break;
677
  }
710
  }
678
  return 0;
711
  return 0;
679
}
712
}
680
 
713
 
681
 
714
 
682
 
715
 
683
int CVICALLBACK MoveStageCB (int panel, int control, int event,
716
int CVICALLBACK MoveStageCB (int panel, int control, int event,
684
                             void *callbackData, int eventData1, int eventData2) {
717
                             void *callbackData, int eventData1, int eventData2) {
685
  int axis=0, step=1000, direction=1;
718
  int axis=0, step=1000, direction=1;
686
  switch (event) {
719
  switch (event) {
687
    case EVENT_COMMIT:
720
    case EVENT_COMMIT:
688
 
721
 
689
      if (panel == xyscan) {
722
      if (panel == xyscan) {
690
        switch (control) {
723
        switch (control) {
691
          case SCAN_BR :
724
          case SCAN_BR :
692
            axis = 1;
725
            axis = 1;
693
            direction = 1;
726
            direction = 1;
694
            GetCtrlVal(panel, SCAN_STEPX, &step);
727
            GetCtrlVal(panel, SCAN_STEPX, &step);
695
            break;
728
            break;
696
          case SCAN_BL :
729
          case SCAN_BL :
697
            axis = 1;
730
            axis = 1;
698
            direction = -1;
731
            direction = -1;
699
            GetCtrlVal(panel, SCAN_STEPX, &step);
732
            GetCtrlVal(panel, SCAN_STEPX, &step);
Line 715... Line 748...
715
          MIKRO_MoveFor(axis,  direction*step );
748
          MIKRO_MoveFor(axis,  direction*step );
716
          MIKRO_GetPosition(axis,&n);
749
          MIKRO_GetPosition(axis,&n);
717
          if (axis == 1) SetCtrlVal (panel, SCAN_XP, n);
750
          if (axis == 1) SetCtrlVal (panel, SCAN_XP, n);
718
          if (axis == 2) SetCtrlVal (panel, SCAN_YP, n);
751
          if (axis == 2) SetCtrlVal (panel, SCAN_YP, n);
719
        }
752
        }
-
 
753
#endif // MIKRO  
-
 
754
               
-
 
755
#ifdef uSMC_USB
-
 
756
        {
-
 
757
          int n=0;
-
 
758
          uSMC_MoveFor(node[axis-1],  direction*step );
-
 
759
          uSMC_GetPosition(node[axis-1],&n);
-
 
760
          if (axis == 1) SetCtrlVal (panel, SCAN_XP, n);
-
 
761
          if (axis == 2) SetCtrlVal (panel, SCAN_YP, n);
-
 
762
        }
720
#endif // MIKRO         
763
#endif // MIKRO                 
721
      }
764
      }
722
 
765
 
723
      break;
766
      break;
724
  }
767
  }
725
  return 0;
768
  return 0;
726
}
769
}
727
 
770
 
728
 
771
 
729
 
772
 
730
 
773
 
731
 
774
 
732
int CVICALLBACK GoXCB (int panel, int control, int event,
775
int CVICALLBACK GoXCB (int panel, int control, int event,
733
                       void *callbackData, int eventData1, int eventData2) {
776
                       void *callbackData, int eventData1, int eventData2) {
734
  int n2;
777
  int n2;
735
  switch (event) {
778
  switch (event) {
736
    case EVENT_COMMIT:
779
    case EVENT_COMMIT:
737
      GetCtrlVal (panel, SCAN_XG, &n2);
780
      GetCtrlVal (panel, SCAN_XG, &n2);
738
#ifdef MIKRO
781
#ifdef MIKRO
739
      MIKRO_MoveTo(1,n2);
782
      MIKRO_MoveTo(1,n2);
740
      MIKRO_GetPosition(1,&n2);
783
      MIKRO_GetPosition(1,&n2);
741
 
784
#endif
-
 
785
#ifdef uSMC_USB  
-
 
786
      uSMC_MoveTo(node[0],n2);
-
 
787
      uSMC_GetPosition(node[0],&n2);
742
#endif
788
#endif    
-
 
789
         
743
      SetCtrlVal (panel, SCAN_XP, n2);
790
      SetCtrlVal (panel, SCAN_XP, n2);
744
      break;
791
      break;
745
  }
792
  }
746
  return 0;
793
  return 0;
747
}
794
}
Line 755... Line 802...
755
#ifdef MIKRO
802
#ifdef MIKRO
756
      MIKRO_MoveTo(2,n2);
803
      MIKRO_MoveTo(2,n2);
757
      MIKRO_GetPosition(2,&n2);
804
      MIKRO_GetPosition(2,&n2);
758
 
805
 
759
#endif
806
#endif
-
 
807
#ifdef uSMC_USB  
-
 
808
      uSMC_MoveTo(node[1],n2);
-
 
809
      uSMC_GetPosition(node[1],&n2);
-
 
810
#endif            
760
      SetCtrlVal (panel, SCAN_YP, n2);
811
      SetCtrlVal (panel, SCAN_YP, n2);
761
      break;
812
      break;
762
  }
813
  }
763
  return 0;
814
  return 0;
764
}
815
}
765
 
816
 
766
int CVICALLBACK GetCurrentPositionCB (int panel, int control, int event,
817
int CVICALLBACK GetCurrentPositionCB (int panel, int control, int event,
767
                                      void *callbackData, int eventData1, int eventData2) {
818
                                      void *callbackData, int eventData1, int eventData2) {
768
 
819
 
769
 
820
  int n[2];
770
  switch (event) {
821
  switch (event) {
771
    case EVENT_COMMIT: {
822
    case EVENT_COMMIT: {
772
#ifdef MIKRO
823
#ifdef MIKRO
773
      int n[2];
-
 
774
      MIKRO_GetPosition(1,&n[0]);
824
      MIKRO_GetPosition(1,&n[0]);
775
      SetCtrlVal (panel, SCAN_XP, n[0]);
825
      SetCtrlVal (panel, SCAN_XP, n[0]);
776
      MIKRO_GetPosition(2,&n[1]);
826
      MIKRO_GetPosition(2,&n[1]);
777
      SetCtrlVal (panel, SCAN_YP, n[1]);
827
      SetCtrlVal (panel, SCAN_YP, n[1]);
778
#endif
828
#endif
-
 
829
#ifdef uSMC_USB  
-
 
830
      uSMC_GetPosition(node[0],&n[0]);
-
 
831
      SetCtrlVal (panel, SCAN_XP, n[0]);
-
 
832
      uSMC_GetPosition(node[1],&n[1]);
-
 
833
      SetCtrlVal (panel, SCAN_YP, n[1]);
-
 
834
#endif            
779
      break;
835
      break;
780
    }
836
    }
781
  }
837
  }
782
  return 0;
838
  return 0;
783
}
839
}
Line 789... Line 845...
789
#ifdef MIKRO
845
#ifdef MIKRO
790
      MIKRO_ReferenceMove(1);
846
      MIKRO_ReferenceMove(1);
791
      MIKRO_ReferenceMove(2);
847
      MIKRO_ReferenceMove(2);
792
      GetCurrentPositionCB(panel, control, event, NULL, 0, 0);
848
      GetCurrentPositionCB(panel, control, event, NULL, 0, 0);
793
#endif
849
#endif
-
 
850
#ifdef uSMC_USB
-
 
851
        //SetCtrlVal(panel,P1_STAGELED,1);
-
 
852
        for (int i=0; i<3; i++) uSMC_ReferenceMove(node[i]);
-
 
853
                GetCurrentPositionCB(panel, control, event, NULL, 0, 0);
-
 
854
        //SetCtrlVal(panel,P1_STAGELED,0);
-
 
855
#endif /* uSMC_USB */     
794
      break;
856
      break;
795
  }
857
  }
796
  return 0;
858
  return 0;
797
}
859
}
798
 
860