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 | } |