Subversion Repositories f9daq

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8 f9daq 1
#include        <math.h>
2
#include        <stdio.h>
3
#include        <string.h>
4
#include        <fcntl.h>      /* open */
5
#include        <unistd.h>     /* exit */
6
#include        <sys/ioctl.h>  /* ioctl */
7
#include        "libusmc.h"
8
#include        "usmctypes.h"
9
 
10
 
11
#define         USB_ERROR(errCode)              (errCode|0x00000000L)
12
// Linux kernel errors or'ed with this value
13
// to distinguish them from usb errors.
14
#define         LINKRN_ERROR(errCode)   (errCode|0x10000000L)
15
#define         HIBYTE(w)                       ((w&0xff00)>>8)
16
#define         LOBYTE(w)                       (w&0x00ff)
17
#define         HIWORD(dw)                      ((dw&0xffff0000)>>16)
18
#define         LOWORD(dw)                      (dw&0x0000ffff)
19
#define         PACK_WORD(w)                    (HIBYTE(w)|(LOBYTE(w)<<8))
20
//#define               PACK_WORD(w)                    (LOBYTE(w)|(HIBYTE(w)<<8))
21
#define         PACK_DWORD(w)                   (HIBYTE(HIWORD(w))| \
22
                                                                         (LOBYTE(HIWORD(w))<<8)| \
23
                                                                         (HIBYTE(LOWORD(w))<<16)| \
24
                                                                         (LOBYTE(LOWORD(w))<<24))
25
 
26
 
27
// DLL data:
28
BOOL                 g_IsInitialized = FALSE;
29
USMC_Devices         g_devices;
30
USMC_Mode            g_deviceMode            [32];
31
USMC_Parameters      g_deviceParameters      [32];
32
USMC_StartParameters g_deviceStartParameters [32];
33
DWORD                g_devicesVersions [32];
34
char                 g_lastErrDesc     [256];   // Null-terminated ASCII error description string.
35
 
36
 
37
// Error string descriptions:
38
static char * errDesc [] = {
39
        "0x???????? ( Unknown )",
40
        "0x00000000 ( Success )",
41
/*      "0x00000001 ( USB CRC )",
42
        "0x00000002 ( USB Bit stuffing )",
43
        "0x00000003 ( USB Data toggle mismatch )",
44
 
45
        "0x00000004 ( USB Stall )",
46
        "0x00000005 ( USB Device not responding )",
47
        "0x00000006 ( USB PID check failure )",
48
        "0x00000007 ( USB Unexpected PID )",
49
        "0x00000008 ( USB Data overrun )",
50
 
51
        "0x00000009 ( USB Data underrun )",
52
        "0x0000000C ( USB Buffer overrun )",
53
        "0x0000000D ( USB Buffer underrun )",
54
        "0x0000000E ( USB Not accessed )",
55
        "0x0000000F ( USB Not accessed alt )",
56
 
57
        "0x00000100 ( USB Isochronous )",
58
        "0x00000101 ( USB Canceled )",
59
        "0x00000103 ( USB Not complete )",
60
        "0x00000104 ( USB Client buffer )",*/
61
        "0x14141414 ( USMC Not initialized )",
62
        //"0x00000006 ( USMC Reffered Device not connected )",
63
        //"0x00000012 ( DeviceManager error - driver function called with invalid arguments )",
64
        "0x14141415 ( USMC No devices connected )"
65
};
66
 
67
 
68
// Internal-use functions prototypes:
69
DWORD  SetLastErr  ( const char * str, DWORD dwErrCode );
70
char * ErrCode2Str ( DWORD dwErrCode );
71
int    clamp       ( int val, int min, int max );
72
float  clampf      ( float val, float min, float max );
73
DWORD  IOCTRL       ( DWORD Device,
74
                                         DWORD dwCode,
75
                                         PVOID pInBuf,
76
                                         DWORD dwInBufSize,
77
                                         PVOID pOutBuf,
78
                                         DWORD dwOutBufSize );
79
 
80
 
81
 
82
 
83
//      Function: SetLastErr ()
84
//      Argument list:
85
//              const char * str √ in √ Null-terminated ASCII error description.
86
//      DWORD dwErrCode - in - optional - error code supplied with description.
87
//      Return value:
88
//              DWORD - modified error code.
89
//      Remarks:
90
//              The SetLastErr () sets description of last occured error.
91
DWORD SetLastErr ( const char * str, DWORD dwErrCode )
92
{
93
        if ( dwErrCode == -USMC_ERROR_REF_DEV_DISCONNECTED )
94
                sprintf ( ( char * ) g_lastErrDesc, "Error: %s. Code: %s", str, "Reffered device disconnected" );
95
        else if ( dwErrCode != 1 )
96
                sprintf ( ( char * ) g_lastErrDesc, "Error: %s. Code: %d", str, ( signed int ) dwErrCode );
97
 
98
        //if ( dwErrCode != 1 )
99
        //      sprintf ( ( char * ) g_lastErrDesc, "Error: %s. Code: %s", str, ErrCode2Str ( dwErrCode ) );
100
        //else
101
        //      sprintf ( ( char * ) g_lastErrDesc, "Error: %s.", str );
102
 
103
 
104
        return  dwErrCode;
105
}
106
 
107
 
108
 
109
 
110
//      Function: ErrCode2Str ()
111
//      Argument list:
112
//              DWORD dwErrCode √ in √ error code returned by any operation.
113
//      Return value:
114
//      char * - string equivalent for specified numerical error code.
115
//      Remarks:
116
//      There is no need to free error string obtained with this function:
117
//      return value points to static dll variable.
118
char * ErrCode2Str ( DWORD dwErrCode )
119
{
120
        switch ( dwErrCode )
121
        {
122
/*      case USB_NO_ERROR:
123
                return  errDesc [1]; break;
124
        case USB_CRC_ERROR:
125
                return  errDesc [2]; break;
126
        case USB_BIT_STUFFING_ERROR:
127
                return  errDesc [3]; break;
128
        case USB_DATA_TOGGLE_MISMATCH_ERROR:
129
                return  errDesc [4]; break;
130
        case USB_STALL_ERROR:
131
                return  errDesc [5]; break;
132
        case USB_DEVICE_NOT_RESPONDING_ERROR:
133
                return  errDesc [6]; break;
134
        case USB_PID_CHECK_FAILURE_ERROR:
135
                return  errDesc [7]; break;
136
        case USB_UNEXPECTED_PID_ERROR:
137
                return  errDesc [8]; break;
138
        case USB_DATA_OVERRUN_ERROR:
139
                return  errDesc [9]; break;
140
        case USB_DATA_UNDERRUN_ERROR:
141
                return  errDesc [10]; break;
142
        case USB_BUFFER_OVERRUN_ERROR:
143
                return  errDesc [11]; break;
144
        case USB_BUFFER_UNDERRUN_ERROR:
145
                return  errDesc [12]; break;
146
        case USB_NOT_ACCESSED_ERROR:
147
                return  errDesc [13]; break;
148
        case USB_NOT_ACCESSED_ALT:
149
                return  errDesc [14]; break;
150
        case USB_ISOCH_ERROR:
151
                return  errDesc [15]; break;
152
        case USB_CANCELED_ERROR:
153
                return  errDesc [16]; break;
154
        case USB_NOT_COMPLETE_ERROR:
155
                return  errDesc [17]; break;
156
        case USB_CLIENT_BUFFER_ERROR:
157
                return  errDesc [18]; break;
158
        case USMC_ERROR_NOT_INITIALIZED:
159
                return  errDesc [19]; break;
160
        case USMC_ERROR_REF_DEV_DISCONNECTED:
161
                return  errDesc [20]; break;
162
        case LINKRN_ERROR ( ERROR_BAD_ARGUMENTS ):
163
                return  errDesc [21]; break;
164
        case USMC_ERROR_NO_DEVICES_CONNECTED:
165
                return  errDesc [22]; break;*/
166
        default:
167
                return  errDesc [0]; break;
168
        }
169
}
170
 
171
 
172
 
173
 
174
int clamp ( int val, int min, int max )
175
{
176
        return  val > max ? max : ( val < min ? min : val );
177
}
178
 
179
 
180
 
181
 
182
float clampf ( float val, float min, float max )
183
{
184
        return  val > max ? max : ( val < min ? min : val );
185
}
186
 
187
 
188
 
189
//      Function: InitDefaultValues ()
190
//              Initializes structures with default values.
191
//      Return Value:
192
//              The InitDefaultValues function has no return values.
193
void InitDefaultValues ()
194
{
195
        int i;
196
 
197
        for ( i = 0 ; i < 32 ; i++ )
198
        {
199
                memset ( &g_deviceMode [i], 0, sizeof ( USMC_Mode ) );
200
                memset ( &g_deviceParameters [i], 0, sizeof ( USMC_Parameters ) );
201
                memset ( &g_deviceStartParameters [i], 0, sizeof ( USMC_StartParameters ) );
202
 
203
                // USMC_Mode defaults:
204
                g_deviceMode [i].PReg      = TRUE;
205
                g_deviceMode [i].Tr1En     = TRUE;
206
                g_deviceMode [i].Tr2En     = TRUE;
207
                g_deviceMode [i].RotTrOp   = TRUE;
208
                g_deviceMode [i].SyncOUTEn = TRUE;
209
                g_deviceMode [i].SyncINOp  = TRUE;
210
                g_deviceMode [i].SyncCount = 4;
211
 
212
                // USMC_Parameters defaults:
213
                g_deviceParameters [i].MaxTemp    = 70.0f;
214
                g_deviceParameters [i].AccelT     = 200.0f;
215
                g_deviceParameters [i].DecelT     = 200.0f;
216
                g_deviceParameters [i].BTimeout1  = 500.0f;
217
                g_deviceParameters [i].BTimeout2  = 500.0f;
218
                g_deviceParameters [i].BTimeout3  = 500.0f;
219
                g_deviceParameters [i].BTimeout4  = 500.0f;
220
                g_deviceParameters [i].BTO1P      = 200.0f;
221
                g_deviceParameters [i].BTO2P      = 300.0f;
222
                g_deviceParameters [i].BTO3P      = 400.0f;
223
                g_deviceParameters [i].BTO4P      = 500.0f;
224
                g_deviceParameters [i].MinP       = 500.0f;
225
                g_deviceParameters [i].BTimeoutR  = 500.0f;
226
                g_deviceParameters [i].LoftPeriod = 500.0f;
227
                g_deviceParameters [i].RTDelta    = 200;
228
                g_deviceParameters [i].RTMinError = 15;
229
                g_deviceParameters [i].EncMult    = 2.5f;
230
                g_deviceParameters [i].MaxLoft    = 32;
231
                g_deviceParameters [i].PTimeout   = 100.0f;
232
                g_deviceParameters [i].SynOUTP    = 1;
233
                g_deviceParameters [i].StartPos   = 0;
234
 
235
                // USMC_StartParameters defaults:
236
                g_deviceStartParameters [i].SDivisor = 8;
237
                g_deviceStartParameters [i].LoftEn   = TRUE;
238
                g_deviceStartParameters [i].SlStart  = TRUE;
239
        }
240
}
241
 
242
 
243
 
244
 
245
//      Function: IOCTRL ()
246
//              Encapsulates DeviceIoControl call ( internal use ).
247
//      Parameters:
248
//              [in]  Device: device number to call DeviceIoControl on.
249
//              [in]  dwCode: IO Control code for operation.
250
//              [out] pInBuf: buffer pointer to store returned data in.
251
//              [in]  dwInBufSize: size of in buffer.
252
//              [in]  pOutBuf: buffer pointer to send data from.
253
//              [in]  dwOutBufSize: size of out buffer.
254
//      Return Value:
255
//              DWORD; zero means succes, other value - error code.
256
//      Remarks:
257
//              Call this function with Device == -1 when devices wasn't enumerated yet.
258
//      The IOCTRL () function DOES NOT sets error description. This routine must 
259
//      be completed by caller function to specify most appropriate information: where
260
//      error has occured and with which operation it associated.
261
DWORD IOCTRL ( DWORD Device,
262
                          DWORD dwCode,
263
                          PVOID pInBuf,
264
                          DWORD dwInBufSize,
265
                          PVOID pOutBuf,
266
                          DWORD dwOutBufSize )
267
{
268
        DWORD  deviceNumber;
269
        char   deviceName [128];        // Device name in form Prefix + DeviceNumber + ":\0".
270
        DWORD  dwErr;
271
        int    hFile;
272
        char * buf;
273
 
274
        dwErr = 0;
275
 
276
        deviceNumber = Device == -1 ? 0 : Device;
277
        sprintf ( deviceName, "/dev/usmc%d", deviceNumber );
278
 
279
        hFile = open ( deviceName, 0 );
280
 
281
        if ( hFile == -1 )
282
                return  -USMC_ERROR_REF_DEV_DISCONNECTED;
283
 
284
 
285
        if ( pInBuf && dwInBufSize ) {
286
                buf = pInBuf;
287
        } else if ( pOutBuf && dwOutBufSize ) {
288
                buf = pOutBuf;
289
        }
290
 
291
 
292
        dwErr = ioctl ( hFile,
293
                        dwCode,
294
                        buf );
295
 
296
        close ( hFile );
297
 
298
        return  dwErr;
299
}
300
 
301
 
302
 
303
 
304
DWORD USMC_Init ( USMC_Devices * Str )
305
{
306
        int nod;
307
        DWORD i;
308
 
309
        nod = 0;
310
        Str -> NOD = 0;
311
        Str -> Serial = Str -> Version = NULL;
312
 
313
        if ( !g_IsInitialized )
314
        {
315
                //InitializeCriticalSection ( &g_Lock );
316
                g_IsInitialized = TRUE;
317
        }
318
 
319
        //EnterCriticalSection ( &g_Lock );
320
        DWORD dwRes = IOCTRL ( -1,
321
                                                  IOCTL_GET_NOD,
322
                                                  ( PVOID ) &nod,
323
                                                  1, NULL, 0 );
324
 
325
        if ( ( int ) dwRes < 0 )
326
                return  USMC_SUCCESS;   // No devices connected, so return NOD = 0.
327
        else
328
                Str -> NOD = nod;
329
 
330
 
331
        // Enumerate connected devices:
332
        Str -> Serial  = ( char ** ) malloc ( ( ssize_t ) ( sizeof ( char * ) * 32 ) );
333
        Str -> Version = ( char ** ) malloc ( ( ssize_t ) ( sizeof ( char * ) * 32 ) );
334
 
335
        for ( i = 0 ; i < Str -> NOD; i++ )
336
        {
337
                char * serial  = ( char * ) malloc ( ( ssize_t ) 16 );
338
                char * version = ( char * ) malloc ( ( ssize_t ) 6 );
339
 
340
                dwRes = IOCTRL ( i,
341
                                                IOCTL_GET_SERIAL,
342
                                                ( PVOID ) serial,
343
                                                16, NULL, 0 );
344
 
345
                if ( ( int ) dwRes < 0 )
346
                {
347
                        dwRes = SetLastErr ( "USMC_Init () failed during IOCTRL ( IOCTL_GET_SERIAL ) call", dwRes );
348
                        free ( serial  );
349
                        free ( version );
350
                        Str -> NOD = 0;
351
                        Str -> Serial = Str -> Version = NULL;
352
 
353
                        return  dwRes;
354
                }
355
 
356
 
357
                dwRes = IOCTRL ( i,
358
                                                IOCTL_GET_VERSION,
359
                                                ( PVOID ) version,
360
                                                6, NULL, 0 );
361
 
362
                if ( ( int ) dwRes < 0 )
363
                {
364
                        dwRes = SetLastErr ( "USMC_Init () failed during IOCTRL ( IOCTL_GET_VERSION ) call", dwRes );
365
                        free ( serial  );
366
                        free ( version );
367
                        Str -> NOD = 0;
368
                        Str -> Serial = Str -> Version = NULL;
369
 
370
                        return  dwRes;
371
                }
372
 
373
 
374
                Str -> Serial [i] = serial;
375
 
376
                ( Str -> Version [i] ) = ( char * ) malloc ( ( ssize_t ) 4 );
377
                memcpy ( Str -> Version [i], version + 2, ( ssize_t ) 4 );
378
 
379
                //strupr ( Str -> Version [i] );
380
                sscanf ( Str -> Version [i], "%X", &g_devicesVersions [i] );
381
        }
382
 
383
 
384
        g_devices = *Str;
385
        InitDefaultValues ();
386
 
387
        //LeaveCriticalSection ( &g_Lock );
388
 
389
 
390
        return  USMC_SUCCESS;
391
}
392
 
393
 
394
 
395
 
396
DWORD USMC_GetState ( DWORD Device, USMC_State * Str )
397
{
398
        if ( !g_IsInitialized )
399
                return  SetLastErr ( "USMC_GetState () failed", -USMC_ERROR_NOT_INITIALIZED );
400
 
401
 
402
 
403
        STATE_PACKET getStateData;
404
 
405
        //EnterCriticalSection ( &g_Lock );
406
        DWORD dwRes = IOCTRL ( Device,
407
                                                  IOCTL_GET_STATE,
408
                                                  ( PVOID ) &getStateData,
409
                                                  11, NULL, 0 );
410
        //LeaveCriticalSection ( &g_Lock );
411
 
412
        if ( ( int ) dwRes < 0 )
413
                return  SetLastErr ( "USMC_GetState () failed during IOCTRL ( IOCTL_GET_STATE ) call", dwRes );
414
 
415
 
416
        Str -> AReset    = getStateData.AFTRESET;
417
        Str -> CurPos    = ( ( signed int ) getStateData.CurPos ) / 8;
418
        Str -> CW_CCW    = getStateData.CW_CCW;
419
        Str -> EmReset   = getStateData.EMRESET;
420
        Str -> FullPower = getStateData.REFIN;
421
        Str -> FullSpeed = getStateData.FULLSPEED;
422
        Str -> Loft      = getStateData.LOFT;
423
        Str -> Power     = getStateData.RESET;
424
        Str -> RotTr     = getStateData.ROTTR;
425
        Str -> RotTrErr  = getStateData.ROTTRERR;
426
        Str -> RUN       = getStateData.RUN;
427
        /*Str -> SDivisor= See below;*/
428
        Str -> SyncIN    = getStateData.SYNCIN;
429
        Str -> SyncOUT   = getStateData.SYNCOUT;
430
        /*Str -> Temp    = See below;*/
431
        Str -> Trailer1  = getStateData.TRAILER1;
432
        Str -> Trailer2  = getStateData.TRAILER2;
433
        /*Str -> Voltage = See below;*/
434
 
435
        Str -> SDivisor  = ( BYTE ) ( 1 << ( getStateData.M2 << 1 | getStateData.M1 ) );
436
        double t      = ( double ) getStateData.Temp;
437
 
438
        if ( g_devicesVersions [Device] < 0x2400 )
439
        {
440
                t = t * 3.3 / 65536.0;
441
                t = t * 10.0 / ( 5.0 - t );
442
                t = ( 1.0 / 298.0 ) + ( 1.0 / 3950.0 ) * log ( t / 10.0 );
443
                t = 1.0 / t - 273.0;
444
        }
445
        else
446
        {
447
                t = ( ( t * 3.3 * 100.0 / 65536.0 ) - 50.0 );
448
        }
449
 
450
 
451
        Str -> Temp    = ( float ) t;
452
        Str -> Voltage = ( float ) ( ( ( double ) getStateData.Voltage ) / 65536.0 * 3.3 * 20.0 );
453
        Str -> Voltage = Str -> Voltage < 5.0f ? 0.0f : Str -> Voltage;
454
 
455
 
456
        return  USMC_SUCCESS;
457
}
458
 
459
 
460
 
461
 
462
DWORD USMC_SaveParametersToFlash ( DWORD Device )
463
{
464
        if ( !g_IsInitialized )
465
                return  SetLastErr ( "USMC_SaveParametersToFlash () failed", -USMC_ERROR_NOT_INITIALIZED );
466
 
467
 
468
        //EnterCriticalSection ( &g_Lock );
469
        DWORD dwRes = IOCTRL ( Device,
470
                                                  IOCTL_SAVE_PARAMETERS,
471
                                                  NULL, 0, NULL, 0 );
472
        //LeaveCriticalSection ( &g_Lock );
473
 
474
 
475
        if ( ( int ) dwRes < 0 )
476
                return  SetLastErr ( "USMC_SaveParametersToFlash () failed during IOCTRL ( IOCTL_SAVE_PARAMETERS ) call", dwRes );
477
 
478
 
479
 
480
        return  USMC_SUCCESS;
481
}
482
 
483
 
484
 
485
 
486
DWORD USMC_GetMode ( DWORD Device, USMC_Mode * Str )
487
{
488
        if ( !g_IsInitialized )
489
                return  SetLastErr ( "USMC_GetMode () failed", -USMC_ERROR_NOT_INITIALIZED );
490
 
491
 
492
        *Str = g_deviceMode [Device];
493
 
494
 
495
        return  USMC_SUCCESS;
496
}
497
 
498
 
499
 
500
 
501
DWORD USMC_SetMode ( DWORD Device, USMC_Mode * Str )
502
{
503
        if ( !g_IsInitialized )
504
                return  SetLastErr ( "USMC_SetMode () failed", -USMC_ERROR_NOT_INITIALIZED );
505
 
506
 
507
        MODE_PACKET setModeData;
508
        // Byte 0:
509
        setModeData.PMODE     = Str -> PMode;
510
        setModeData.REFINEN   = Str -> PReg;
511
        setModeData.RESETD    = Str -> ResetD;
512
        setModeData.EMRESET   = Str -> EMReset;
513
        setModeData.TR1T      = Str -> Tr1T;
514
        setModeData.TR2T      = Str -> Tr2T;
515
        setModeData.ROTTRT    = Str -> RotTrT;
516
        setModeData.TRSWAP    = Str -> TrSwap; 
517
        // Byte 1:
518
        setModeData.TR1EN     = Str -> Tr1En;
519
        setModeData.TR2EN     = Str -> Tr2En;
520
        setModeData.ROTTREN   = Str -> RotTeEn;
521
        setModeData.ROTTROP   = Str -> RotTrOp;
522
        setModeData.BUTT1T    = Str -> Butt1T;
523
        setModeData.BUTT2T    = Str -> Butt2T;
524
        /*setModeData.BUTSWAP = ...;*/
525
        setModeData.RESETRT   = Str -> ResetRT;
526
        // Byte 2:
527
        setModeData.SNCOUTEN  = Str -> SyncOUTEn;
528
        setModeData.SYNCOUTR  = Str -> SyncOUTR;
529
        setModeData.SYNCINOP  = Str -> SyncINOp;
530
        setModeData.SYNCOPOL  = Str -> SyncInvert;
531
        setModeData.ENCODER   = Str -> EncoderEn;
532
        setModeData.INVENC    = Str -> EncoderInv;
533
        setModeData.RESBENC   = Str -> ResBEnc;
534
        setModeData.RESENC    = Str -> ResEnc;
535
 
536
        setModeData.SYNCCOUNT = PACK_DWORD ( Str -> SyncCount );
537
 
538
        // Save parameters within DLL for further USMC_GetMode () calls:
539
        //EnterCriticalSection ( &g_Lock );
540
        g_deviceMode [Device] = *Str;
541
 
542
        DWORD dwRes = IOCTRL ( Device,
543
                                                  IOCTL_SET_MODE,
544
                                                  NULL, 0,
545
                                                  ( PVOID ) &setModeData, 7 );
546
        //LeaveCriticalSection ( &g_Lock );
547
 
548
 
549
        if ( ( int ) dwRes < 0 )
550
                return  SetLastErr ( "USMC_SetMode () failed during IOCTRL ( IOCTL_SET_MODE ) call", dwRes );
551
 
552
 
553
        return  USMC_SUCCESS;
554
}
555
 
556
 
557
 
558
 
559
DWORD USMC_GetParameters ( DWORD Device, USMC_Parameters * Str )
560
{
561
        if ( !g_IsInitialized )
562
                return  SetLastErr ( "USMC_GetParameters () failed", -USMC_ERROR_NOT_INITIALIZED );
563
 
564
 
565
        *Str = g_deviceParameters [Device];
566
 
567
 
568
        return  USMC_SUCCESS;
569
}
570
 
571
 
572
 
573
 
574
DWORD USMC_SetParameters ( DWORD Device, USMC_Parameters * Str )
575
{
576
        if ( !g_IsInitialized )
577
                return  SetLastErr ( "USMC_SetParameters () failed", -USMC_ERROR_NOT_INITIALIZED );
578
 
579
 
580
        PARAMETERS_PACKET setParametersData;
581
 
582
        /*=====================*/
583
        /* ----Conversion:---- */
584
        /*=====================*/
585
        setParametersData.DELAY1       = ( BYTE ) clamp ( ( int ) ( Str -> AccelT / 98.0f + 0.5f ), 1, 15 );
586
        setParametersData.DELAY2       = ( BYTE ) clamp ( ( int ) ( Str -> DecelT / 98.0f + 0.5f ), 1, 15 );
587
        setParametersData.RefINTimeout = ( WORD ) ( clampf ( Str -> PTimeout , 1.0f, 9961.0f ) / 0.152f + 0.5f );
588
        setParametersData.BTIMEOUT1    = PACK_WORD ( ( WORD ) ( clampf ( Str -> BTimeout1, 1.0f, 9961.0f ) / 0.152f + 0.5f ) );
589
        setParametersData.BTIMEOUT2    = PACK_WORD ( ( WORD ) ( clampf ( Str -> BTimeout2, 1.0f, 9961.0f ) / 0.152f + 0.5f ) );
590
        setParametersData.BTIMEOUT3    = PACK_WORD ( ( WORD ) ( clampf ( Str -> BTimeout3, 1.0f, 9961.0f ) / 0.152f + 0.5f ) );
591
        setParametersData.BTIMEOUT4    = PACK_WORD ( ( WORD ) ( clampf ( Str -> BTimeout4, 1.0f, 9961.0f ) / 0.152f + 0.5f ) );
592
        setParametersData.BTIMEOUTR    = PACK_WORD ( ( WORD ) ( clampf ( Str -> BTimeoutR, 1.0f, 9961.0f ) / 0.152f + 0.5f ) );
593
        setParametersData.BTIMEOUTD    = PACK_WORD ( ( WORD ) ( clampf ( Str -> BTimeoutD, 1.0f, 9961.0f ) / 0.152f + 0.5f ) );
594
        setParametersData.MINPERIOD    = PACK_WORD ( ( WORD ) ( 65536.0f - ( 125000.0f / clampf ( Str -> MinP , 2.0f, 625.0f ) ) + 0.5f ) );
595
        setParametersData.BTO1P        = PACK_WORD ( ( WORD ) ( 65536.0f - ( 125000.0f / clampf ( Str -> BTO1P, 2.0f, 625.0f ) ) + 0.5f ) );
596
        setParametersData.BTO2P        = PACK_WORD ( ( WORD ) ( 65536.0f - ( 125000.0f / clampf ( Str -> BTO2P, 2.0f, 625.0f ) ) + 0.5f ) );
597
        setParametersData.BTO3P        = PACK_WORD ( ( WORD ) ( 65536.0f - ( 125000.0f / clampf ( Str -> BTO3P, 2.0f, 625.0f ) ) + 0.5f ) );
598
        setParametersData.BTO4P        = PACK_WORD ( ( WORD ) ( 65536.0f - ( 125000.0f / clampf ( Str -> BTO4P, 2.0f, 625.0f ) ) + 0.5f ) );
599
        setParametersData.MAX_LOFT     = PACK_WORD ( ( WORD ) ( clamp ( Str -> MaxLoft, 1, 1023 ) * 64 ) );
600
 
601
        if ( g_devicesVersions [Device] < 0x2407 )
602
        {
603
                setParametersData.STARTPOS = 0x00000000L;
604
        }
605
        else
606
        {
607
                setParametersData.STARTPOS = PACK_DWORD ( Str -> StartPos * 8 & 0xFFFFFF00 );
608
        }
609
 
610
 
611
        setParametersData.RTDelta    = PACK_WORD ( ( WORD ) ( clamp ( Str -> RTDelta   , 4, 1023 ) * 64 ) );
612
        setParametersData.RTMinError = PACK_WORD ( ( WORD ) ( clamp ( Str -> RTMinError, 4, 1023 ) * 64 ) );
613
 
614
        double t = ( double ) clampf ( Str -> MaxTemp, 0.0f, 100.0f );
615
 
616
        if ( g_devicesVersions [Device] < 0x2400 )
617
        {
618
                t = 10.0 * exp ( 3950.0 * ( 1.0 / ( t + 273.0 ) - 1.0 / 298.0 ) );
619
                t = ( ( 5 * t / ( 10 + t ) ) * 65536.0 / 3.3 + 0.5 );
620
        }
621
        else
622
        {
623
                t = ( t + 50.0 ) / 330.0 * 65536.0;
624
                t = ( t + 0.5f );
625
        }
626
 
627
 
628
        setParametersData.MaxTemp    = PACK_WORD ( ( WORD ) t );
629
        setParametersData.SynOUTP    = Str -> SynOUTP;
630
        setParametersData.LoftPeriod = Str -> LoftPeriod == 0.0f ? 0 :
631
                                                                         PACK_WORD ( ( WORD ) ( 65536.0f - ( 125000.0f / clampf ( Str -> LoftPeriod, 16.0f, 5000.0f ) ) + 0.5f ) );
632
        setParametersData.EncVSCP    = ( BYTE ) ( Str -> EncMult * 4.0f + 0.5f );
633
//setParametersData.EncVSCP = 1;        ///////////
634
 
635
        memset ( setParametersData.Reserved, 0, 15 );
636
        //unsigned char testBuf [sizeof ( PARAMETERS_PACKET )];
637
        //memcpy ( ( void * ) testBuf, ( const void * ) &setParametersData, ( size_t ) sizeof ( PARAMETERS_PACKET ) );
638
        /*=======================*/
639
        /* ----Deconversion:---- */
640
        /*=======================*/
641
        Str -> AccelT    = setParametersData.DELAY1 * 98.0f;
642
        Str -> DecelT    = setParametersData.DELAY2 * 98.0f;
643
        Str -> PTimeout  = ( float ) ( setParametersData.RefINTimeout * 0.152f );
644
        Str -> BTimeout1 = ( float ) ( PACK_WORD ( setParametersData.BTIMEOUT1 ) * 0.152f );
645
        Str -> BTimeout2 = ( float ) ( PACK_WORD ( setParametersData.BTIMEOUT2 ) * 0.152f );
646
        Str -> BTimeout3 = ( float ) ( PACK_WORD ( setParametersData.BTIMEOUT3 ) * 0.152f );
647
        Str -> BTimeout4 = ( float ) ( PACK_WORD ( setParametersData.BTIMEOUT4 ) * 0.152f );
648
        Str -> BTimeoutR = ( float ) ( PACK_WORD ( setParametersData.BTIMEOUTR ) * 0.152f );
649
        Str -> BTimeoutD = ( float ) ( PACK_WORD ( setParametersData.BTIMEOUTD ) * 0.152f );
650
        Str -> MinP      = 125000.0f / ( 65536.0f - ( float ) ( PACK_WORD ( setParametersData.MINPERIOD ) ) );
651
        Str -> BTO1P     = 125000.0f / ( 65536.0f - ( float ) ( PACK_WORD ( setParametersData.BTO1P ) ) );
652
        Str -> BTO2P     = 125000.0f / ( 65536.0f - ( float ) ( PACK_WORD ( setParametersData.BTO2P ) ) );
653
        Str -> BTO3P     = 125000.0f / ( 65536.0f - ( float ) ( PACK_WORD ( setParametersData.BTO3P ) ) );
654
        Str -> BTO4P     = 125000.0f / ( 65536.0f - ( float ) ( PACK_WORD ( setParametersData.BTO4P ) ) );
655
        Str -> MaxLoft   = PACK_WORD ( setParametersData.MAX_LOFT ) / 64;
656
 
657
        if( g_devicesVersions [Device] < 0x2407 )
658
        {
659
                Str -> StartPos = 0x00000000L;
660
        }
661
        else
662
        {
663
                Str -> StartPos = PACK_DWORD ( setParametersData.STARTPOS ) / 8;
664
        }
665
 
666
 
667
        Str -> RTDelta    = PACK_WORD ( setParametersData.RTDelta )    / 64;
668
        Str -> RTMinError = PACK_WORD ( setParametersData.RTMinError ) / 64;
669
 
670
        if ( g_devicesVersions [Device] < 0x2400 )
671
        {
672
                t = ( double )( PACK_WORD ( setParametersData.MaxTemp ) );
673
                t = t * 3.3 / 65536.0;
674
                t = 10.0 * t / ( 5.0 - t );
675
                t = ( 1.0 / 298.0 ) + ( 1.0 / 3950.0 ) * log ( t / 10.0 );
676
                t = 1.0 / t - 273.0;
677
        }
678
        else
679
        {
680
                t = ( double ) ( PACK_WORD ( setParametersData.MaxTemp ) );
681
                t = ( t * 3.3 * 100.0 / 65536.0 ) - 50.0;
682
        }
683
 
684
 
685
        Str -> MaxTemp = ( float ) t;
686
 
687
        Str -> SynOUTP = setParametersData.SynOUTP;
688
        Str -> LoftPeriod = PACK_WORD ( setParametersData.LoftPeriod ) == 0 ? 0.0f :
689
                                         125000.0f / ( 65536.0f - ( float ) ( PACK_WORD ( setParametersData.LoftPeriod ) ) );
690
        Str -> EncMult = ( ( float ) setParametersData.EncVSCP ) / 4.0f;
691
 
692
        // Save parameters within DLL for further USMC_GetParameters () calls:
693
        //EnterCriticalSection ( &g_Lock );
694
        g_deviceParameters [Device] = *Str;
695
 
696
        DWORD dwRes = IOCTRL ( Device,
697
                                                  IOCTL_SET_PARAMETERS,
698
                                                  NULL, 0,
699
                                                  ( PVOID ) &setParametersData, 57 );
700
        //LeaveCriticalSection ( &g_Lock );
701
 
702
 
703
        if ( ( int ) dwRes < 0 )
704
                return  SetLastErr ( "USMC_SetParameters () failed during IOCTRL ( IOCTL_SET_PARAMETERS ) call", dwRes );
705
 
706
 
707
        return  USMC_SUCCESS;
708
}
709
 
710
 
711
 
712
 
713
DWORD USMC_GetStartParameters ( DWORD Device, USMC_StartParameters * Str )
714
{
715
        if ( !g_IsInitialized )
716
                return  SetLastErr ( "USMC_GetStartParameters () failed", -USMC_ERROR_NOT_INITIALIZED );
717
 
718
 
719
        *Str = g_deviceStartParameters [Device];
720
 
721
 
722
        return  USMC_SUCCESS;
723
}
724
 
725
 
726
 
727
 
728
DWORD USMC_Start ( DWORD Device, int DestPos,
729
                                                           float * Speed,
730
                                                           USMC_StartParameters * Str )
731
{
732
        if ( !g_IsInitialized )
733
                return  SetLastErr ( "USMC_Start () failed", -USMC_ERROR_NOT_INITIALIZED );
734
 
735
 
736
        GO_TO_PACKET goToData;
737
 
738
        /*=====================*/
739
        /* ----Conversion:---- */
740
        /*=====================*/
741
        goToData.DestPos     = ( DWORD ) ( DestPos * 8 );
742
        goToData.TimerPeriod = PACK_WORD ( ( WORD  ) ( 65536.0f - ( 1000000.0f / clampf ( *Speed, 16.0f, 5000.0f ) ) + 0.5f ) );
743
        switch ( Str -> SDivisor )
744
        {
745
        case 1:
746
                goToData.M1 = goToData.M2 = 0;
747
                break;
748
        case 2:
749
                goToData.M1 = 1;
750
                goToData.M2 = 0;
751
                break;
752
        case 4:
753
                goToData.M1 = 0;
754
                goToData.M2 = 1;
755
                break;
756
        case 8:
757
                goToData.M1 = 1;
758
                goToData.M2 = 1;
759
                break;
760
        }
761
        //goToData.M1          = Str -> SDivisor && 0x01;
762
        //goToData.M2          = Str -> SDivisor && 0x02;
763
        goToData.DEFDIR      = Str -> DefDir;
764
        goToData.LOFTEN      = Str -> LoftEn;
765
        goToData.SLSTRT      = Str -> SlStart;
766
        goToData.WSYNCIN     = Str -> WSyncIN;
767
        goToData.SYNCOUTR    = Str -> SyncOUTR;
768
        goToData.FORCELOFT   = Str -> ForceLoft;
769
 
770
 
771
        /*=======================*/
772
        /* ----Deconversion:---- */
773
        /*=======================*/
774
        *Speed        = 1000000.0f / ( 65536.0f - ( float ) PACK_WORD ( goToData.TimerPeriod ) );
775
        Str -> SDivisor = 1 << ( ( goToData.M2 << 1 ) | goToData.M1 );
776
 
777
        // Save start parameters within DLL for further USMC_GetStartParameters () calls:
778
        //EnterCriticalSection ( &g_Lock );
779
        g_deviceStartParameters [Device] = *Str;
780
 
781
        DWORD dwRes = IOCTRL ( Device,
782
                                                  IOCTL_GO_TO,
783
                                                  NULL, 0,
784
                                                  ( PVOID ) &goToData, 7 );
785
        //LeaveCriticalSection ( &g_Lock );
786
 
787
 
788
        if ( ( int ) dwRes < 0 )
789
                return  SetLastErr ( "USMC_Start () failed during IOCTRL ( IOCTL_GO_TO ) call", dwRes );
790
 
791
 
792
        return  USMC_SUCCESS;
793
}
794
 
795
 
796
 
797
 
798
DWORD USMC_Stop ( DWORD Device )
799
{
800
        if ( !g_IsInitialized )
801
                return  SetLastErr ( "USMC_Stop () failed", -USMC_ERROR_NOT_INITIALIZED );
802
 
803
 
804
        //EnterCriticalSection ( &g_Lock );
805
        DWORD dwRes = IOCTRL ( Device,
806
                                                  IOCTL_STOP_STEP_MOTOR,
807
                                                  NULL, 0, NULL, 0 );
808
        //LeaveCriticalSection ( &g_Lock );
809
 
810
 
811
        if ( ( int ) dwRes < 0 )
812
                return  SetLastErr ( "USMC_Stop () failed during IOCTRL ( IOCTL_STOP_STEP_MOTOR ) call", dwRes );
813
 
814
 
815
        return  USMC_SUCCESS;
816
}
817
 
818
 
819
 
820
 
821
DWORD USMC_SetCurrentPosition ( DWORD Device, int Position )
822
{
823
        if ( !g_IsInitialized )
824
                return  SetLastErr ( "USMC_SetCurrentPosition () failed", -USMC_ERROR_NOT_INITIALIZED );
825
 
826
 
827
        Position *= 8;
828
        Position &= 0xFFFFFFE0;
829
        //EnterCriticalSection ( &g_Lock );
830
        DWORD dwRes = IOCTRL ( Device,
831
                                                  IOCTL_SET_CURRENT_POSITION,
832
                                                  NULL, 0,
833
                                                  ( PVOID ) &Position, 4 );
834
        //LeaveCriticalSection ( &g_Lock );
835
 
836
 
837
        if ( ( int ) dwRes < 0 )
838
                return  SetLastErr ( "USMC_SetCurrentPosition () failed during IOCTRL ( IOCTL_SET_CURRENT_POSITION ) call", dwRes );
839
 
840
 
841
        return  USMC_SUCCESS;
842
}
843
 
844
 
845
 
846
 
847
DWORD USMC_GetEncoderState ( DWORD Device, USMC_EncoderState * Str )
848
{
849
        if ( !g_IsInitialized )
850
                return  SetLastErr ( "USMC_GetEncoderState () failed", -USMC_ERROR_NOT_INITIALIZED );
851
 
852
 
853
        if ( g_devicesVersions [Device] < 0x2410 )
854
                return  USMC_SUCCESS;
855
 
856
 
857
        //EnterCriticalSection ( &g_Lock );
858
        ENCODER_STATE_PACKET getEncoderStateData;
859
 
860
        DWORD dwRes = IOCTRL ( Device,
861
                                                  IOCTL_GET_ENCODER_STATE,
862
                                                  ( PVOID ) &getEncoderStateData,
863
                                                  8, NULL, 0 );
864
        //LeaveCriticalSection ( &g_Lock );
865
 
866
 
867
        if ( ( int ) dwRes < 0 )
868
                return  SetLastErr ( "USMC_GetEncoderState () failed during IOCTRL ( IOCTL_GET_STATE ) call", dwRes );
869
 
870
 
871
        Str -> ECurPos    = getEncoderStateData.ECurPos;
872
        Str -> EncoderPos = getEncoderStateData.EncPos;
873
 
874
 
875
        return  USMC_SUCCESS;
876
}
877
 
878
 
879
 
880
 
881
void USMC_GetLastErr ( char * str, ssize_t len )
882
{
883
        //EnterCriticalSection ( &g_Lock );
884
        if ( strlen ( g_lastErrDesc ) > len )
885
                memcpy ( str, g_lastErrDesc, len );
886
        else
887
                strcpy ( str, ( const char * ) g_lastErrDesc );
888
        //LeaveCriticalSection ( &g_Lock );
889
}
890
 
891
 
892
 
893
 
894
DWORD USMC_Close ( void )
895
{
896
        if ( !g_IsInitialized )
897
                return  SetLastErr ( "USMC_Close () failed", -USMC_ERROR_NOT_INITIALIZED );
898
 
899
 
900
        return  USMC_SUCCESS;
901
}