reni_v0.77.c


1
#include <usb.h>
2
#include <stdio.h>
3
#include <getopt.h>      // needed for getopt
4
#include "version.h"
5
6
typedef struct transdata {            // data from laser for one USB packet
7
    int bAlign;       // 0: distance, 1: intensity
8
    int n;
9
    long long lldata[100];
10
} TransData;
11
12
extern void dx10_start_seq1();
13
extern void dx10_zero_seq234();
14
extern void dx10_pre_loop_seq2();
15
extern int  dx10_read_loop_seq3();
16
extern void dx10_post_loop_seq4();
17
extern void dx10_end_seq5();
18
extern int  dx10_eval(int len, int iStep, TransData *transdata);
19
20
extern void xl80_start_seq1();
21
extern void xl80_zero_seq234();
22
extern void xl80_pre_loop_seq2();
23
extern int  xl80_read_loop_seq3();
24
extern void xl80_post_loop_seq4();
25
extern void xl80_end_seq5();
26
extern int  xl80_eval(int len, int iStep, TransData *transdata);
27
28
#define WARMINGUP             0x01
29
#define NO_BEAM               0x02
30
#define INTERRUPTED_BEAM      0x04
31
#define KEYBOARD              0x08
32
33
//only this file////////////////////////////////////////////////
34
35
// this device's vendor and product id
36
#define VID_RENISHAW 0x0837  // 0x0837: Renishaw
37
#define PID_DX10     0x000b  // 0x000b: DX-10 adaptor with ML-10
38
#define PID_XL80     0x0012  // 0x0012: XL-80
39
40
int g_iDbgLevel;
41
usb_dev_handle *g_Dev = NULL;           // the device handle
42
int g_iFlags=0;
43
44
void abort(const char *fmt, ...)
45
{
46
    va_list ap;
47
    char string[4096];
48
49
    va_start(ap, fmt);
50
    vsprintf(string, fmt, ap);
51
    printf("%s", string);
52
    fflush(stdout);
53
    va_end(ap);
54
    exit(-1);
55
}
56
57
usb_dev_handle *open_dev_dx10(void)
58
{
59
    struct usb_bus *bus;
60
    struct usb_device *dev;
61
62
    for(bus = usb_get_busses(); bus; bus = bus->next)
63
        for(dev = bus->devices; dev; dev = dev->next)
64
            if(dev->descriptor.idVendor == VID_RENISHAW && dev->descriptor.idProduct == PID_DX10)
65
                return usb_open(dev);
66
    return NULL;
67
}
68
69
usb_dev_handle *open_dev_xl80(void)
70
{
71
    struct usb_bus *bus;
72
    struct usb_device *dev;
73
74
    for(bus = usb_get_busses(); bus; bus = bus->next)
75
        for(dev = bus->devices; dev; dev = dev->next)
76
            if(dev->descriptor.idVendor == VID_RENISHAW && dev->descriptor.idProduct == PID_XL80)
77
                return usb_open(dev);
78
    return NULL;
79
}
80
81
char* bargraph(int percent)
82
{
83
    static char sBar[50+4];  // 50 chars for 100%
84
    int j;
85
  strcpy(sBar, " . . . . . . . . . . . . . . . . . . . . . . . . .");
86
    if (percent > 100)
87
        percent = 100;
88
    if (percent<=16) {          // in percent => too low < 16%, low < 50%
89
        for(j=0; j<percent/2; j++)
90
            sBar[j] = '-';
91
    }else if (percent<=50) {
92
        for(j=0; j<percent/2; j++)
93
            sBar[j] = '~';
94
    }else{
95
        for(j=0; j<percent/2; j++)
96
            sBar[j] = '+';
97
    }
98
    sBar[ 16/2] = '|';
99
    sBar[ 50/2] = '|';
100
    sBar[100/2] = 0;
101
    return sBar;
102
}
103
104
#define STANDARD_MEASURE_FREQUENCY 5000
105
#define WAVELENGTH_IN_MM  0.000632818840000 // ~633nm
106
#define DEFAULT_DURATION 0.05 // in sec
107
#define DEFAULT_TIMESTEP 0.001 // in sec
108
109
int main(int argc, char**argv)
110
{
111
    int c, len, nmbr, i;
112
    char bZero=0;
113
    char bOut=0;
114
    char sDevice[32]="";
115
  double time=0;
116
    double mode_factor=1.0;
117
    double endtime=DEFAULT_DURATION;
118
    double dTmp;
119
  char sOutFile[1024];
120
    int iStep=(int)(0.5+STANDARD_MEASURE_FREQUENCY*DEFAULT_TIMESTEP); // default for -i0.001
121
  FILE *fp;
122
    TransData transdata;
123
  transdata.bAlign=0;
124
  char sDevices[2][32];
125
  int iDevices=0;
126
  
127
  void (*usb_seq1)();
128
  void (*usb_seq2)();
129
  int  (*usb_seq3)();
130
  void (*usb_seq4)();
131
  void (*usb_seq5)();
132
  void (*usb_seq234)();
133
  int  (*usb_eval)(int len, int iStep, TransData *transdata);
134
135
136
  
137
    while (  (c = getopt(argc, argv, "acsd:t:i:o:m:vh")) != -1  ) {    // check options
138
        switch (c) {
139
        case 'a':
140
            transdata.bAlign=1;
141
            break;
142
        case 'd':
143
      strcpy(sDevice, optarg);
144
            break;
145
        case 'c':
146
            bZero=1;
147
            break;
148
        case 't':
149
            sscanf(optarg, "%lf", &endtime);
150
            break;
151
        case 'i':
152
            sscanf(optarg, "%lf", &dTmp);
153
            iStep=(int)(0.5+STANDARD_MEASURE_FREQUENCY*dTmp);
154
            break;
155
        case 'm':
156
            if (optarg[0]=='a') mode_factor=33333.3333;
157
            if (optarg[0]=='p') mode_factor=0.5;
158
            if (optarg[0]=='w') mode_factor=44.248;
159
            break;
160
    case 'o':
161
      strcpy(sOutFile, optarg);
162
      bOut=1;
163
      break;
164
165
        case 'v':
166
        case 'h':
167
        default :
168
            printf("Version %s", "v0.77");
169
            if (c == 'v') return(0);
170
            printf("\n%s options:", "reni");
171
            printf("\n(no option) measure dynamic profile with given t- and i-parameters");
172
            printf("\n  -h        print this Help text");
173
            printf("\n  -v        print Version");
174
            printf("\n  -d #      use Device # (dx-10 or xl-80)");
175
            printf("\n  -o #      write Output to file # [stdout]");
176
            printf("\n  -t #      measuring-Time # sec [%g]", DEFAULT_DURATION);
177
            printf("\n  -i #      time-step-Interval # sec [%g] (fit for possible values)", DEFAULT_TIMESTEP);
178
            printf("\n  -a        Align intensity (signal strength <16%:too low, <50%:low)");
179
            printf("\n  -c        initialize Counter and Clear errors (set zero)");
180
            printf("\n  -m #      Mode listed below: [s],a,p,w");
181
            printf("\n  The given values have to be multiplied with a factor to get a result:");
182
            printf("\n     # (S)tandard linear reflector               *     1.0       => mm");
183
            printf("\n     # (A)ngular double reflector                * 33333.3       => µm/m");
184
            printf("\n     # (P)lane mirror with two beams             *     0.5       => mm");
185
            printf("\n     # (W)ollaston prisma short                  *    44.248     => mm");
186
            printf("\n");
187
            return(0);
188
        }
189
    }
190
191
    usb_init(); // initialize the library
192
    usb_find_busses(); // find all buses
193
    usb_find_devices(); // find all connected devices [GET_DESCRIPTOR_FROM_DEVICE:80 06 0100 0000 0012
194
                                                    // GET_DESCRIPTOR_FROM_DEVICE:80 06 0200 0000 0008
195
                                                    // GET_DESCRIPTOR_FROM_DEVICE:80 06 0200 0000 00xx]
196
  // test all possible devices and build a list
197
    if (open_dev_dx10())
198
    strcpy(&sDevices[iDevices++][0], "dx-10");
199
    if (open_dev_xl80())
200
    strcpy(&sDevices[iDevices++][0], "xl-80");
201
202
  if (iDevices==0)
203
    abort("\nERROR: no device not found!\nPlease plug in one USB-device");
204
205
    if (strlen(sDevice)) {      // sDevice chosen
206
        for(i=0; i<iDevices; i++) {
207
            if (!strncmp(sDevice, &sDevices[i][0], 1))  // check only 1 character
208
                break;
209
        }
210
        if (i>=iDevices) {      // not found
211
            for(i=0; i<iDevices; i++)
212
                printf("%d: %s\n", i, &sDevices[i][0]);
213
            abort("\nERROR: Please choose one device from list with -d option");
214
        }
215
    } else {                // no sDevice chosen
216
        if (iDevices==1)    // only one sDevice exists
217
            i=0;
218
        else {              // more sDevice exist
219
            for(i=0; i<iDevices; i++)
220
                printf("%d: %s\n", i, &sDevices[i][0]);
221
            abort("\nERROR: Please choose one device from list with -d option.");
222
        }
223
    }
224
225
  // bind functions to the chosen device
226
  if (!strcmp(&sDevices[i][0], "dx-10")) {
227
    if (!(g_Dev = open_dev_dx10()))
228
      abort("\nERROR: device not found!\nPlease plug in USB.");  
229
    usb_seq1=dx10_start_seq1;
230
    usb_seq2=dx10_pre_loop_seq2;
231
    usb_seq3=dx10_read_loop_seq3;
232
    usb_seq4=dx10_post_loop_seq4;
233
    usb_seq5=dx10_end_seq5;
234
    usb_seq234=dx10_zero_seq234;
235
    usb_eval=dx10_eval;
236
  } else if (!strcmp(&sDevices[i][0], "xl-80")) {
237
    if (!(g_Dev = open_dev_xl80()))
238
      abort("\nERROR: device not found!\nPlease plug in USB.");  
239
    usb_seq1=xl80_start_seq1;
240
    usb_seq2=xl80_pre_loop_seq2;
241
    usb_seq3=xl80_read_loop_seq3;
242
    usb_seq4=xl80_post_loop_seq4;
243
    usb_seq5=xl80_end_seq5;
244
    usb_seq234=xl80_zero_seq234;
245
    usb_eval=xl80_eval;
246
  } else
247
    abort("\nERROR: device not found!\nPlease plug in USB..");
248
249
  // unconfigure first before configure
250
    if (usb_set_configuration(g_Dev, 0) < 0) // select configuration [GET_DESCRIPTOR_FROM_DEVICE:80 06 0100 0000 0012
251
        abort("\nERROR: setting config 0 failed");                // GET_DESCRIPTOR_FROM_DEVICE:80 06 0200 0000 0009
252
                                                                  // GET_DESCRIPTOR_FROM_DEVICE:80 06 0200 0000 00xx
253
                                                                  // SELECT_CONFIGURATION:(unconfigured)]
254
255
    if (usb_set_configuration(g_Dev, 1) < 0) // select configuration [GET_DESCRIPTOR_FROM_DEVICE:80 06 0100 0000 0012
256
        abort("\nERROR: setting config 1 failed");                // GET_DESCRIPTOR_FROM_DEVICE:80 06 0200 0000 0009
257
                                                                  // GET_DESCRIPTOR_FROM_DEVICE:80 06 0200 0000 00xx
258
                                                                  // SELECT_CONFIGURATION:(configured)]
259
260
    if (usb_claim_interface(g_Dev, 0) < 0)
261
        abort("\nERROR: claiming interface 0 failed");
262
263
    if (transdata.bAlign) {                              // change parameters for alignment
264
    endtime=60*10;                                   // maximum 10 minutes alignment
265
    iStep=(int)(0.5+STANDARD_MEASURE_FREQUENCY*0.1); // alignment always with step of 0.1 sec
266
  }
267
  if (bOut)
268
    fp=fopen(sOutFile, "w");
269
  transdata.n=iStep-1;
270
271
    usb_seq1();
272
    if (bZero) {                       // --> either set laser to zero 
273
        usb_seq234();
274
    } else {                           // --> or measure dynamically
275
276
// We read all USB-packages which have the data for the maximum of resolution (5MHz).
277
// The procedure "eval" will give back (in transdata) only the data in THAT resolution, which will be displayed (every iStep data point).
278
// In the measuring loop here, all data from transdata will be displayed.
279
280
        usb_seq2();
281
    time=1.0/STANDARD_MEASURE_FREQUENCY*iStep-0.000001;
282
        do {                            // measuring loop
283
            len=usb_seq3();            // read complete USB-package (len is lenght of this package)
284
            nmbr=usb_eval(len, iStep, &transdata);     // fill every iStep point in transdata (nmbr is number of points to output)
285
            for (i=0; (i<nmbr) && (time<=endtime); i++) {
286
        if (transdata.bAlign==0) {
287
          if (bOut)
288
            fprintf(fp, "%.8f\n", transdata.lldata[i]*WAVELENGTH_IN_MM/32768*mode_factor);// 32768: interpolation
289
          else
290
            printf("%.4f %.8f\n", time, transdata.lldata[i]*WAVELENGTH_IN_MM/32768*mode_factor);// 32768: interpolation
291
        } else
292
          printf("%3d%% %s\n", (unsigned char)transdata.lldata[i], bargraph((unsigned char)transdata.lldata[i]));
293
        fflush(stdout);
294
        time+=1.0/STANDARD_MEASURE_FREQUENCY*iStep;
295
            }
296
      if (transdata.bAlign) {
297
        g_iFlags=0;                          // for alignment ignore all earlier errors
298
        if ( GetAsyncKeyState(VK_LCONTROL) ) // for alignment break also with left control key
299
          g_iFlags=g_iFlags|KEYBOARD;
300
      }
301
            if ( GetAsyncKeyState(VK_RCONTROL) )     // always break with right control key
302
                g_iFlags=g_iFlags|KEYBOARD;
303
        } while( (time<endtime)&&(g_iFlags==0) );
304
        usb_seq4();
305
    }
306
    usb_seq5();
307
    
308
    usb_release_interface(g_Dev, 0);
309
    usb_close(g_Dev);
310
    
311
  if (bOut)
312
    fclose(fp);
313
314
    if (g_iFlags&WARMINGUP)
315
        printf("ERROR: Warming up\n");
316
    else {
317
        if (g_iFlags&NO_BEAM)
318
            printf("ERROR: No beam at all\n");
319
        else if (g_iFlags&INTERRUPTED_BEAM)
320
            printf("ERROR: Interrupted beam, please use -c option\n");
321
    }
322
    return 0;
323
}