| 0,0 → 1,901 |
| #include <math.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <fcntl.h> /* open */ |
| #include <unistd.h> /* exit */ |
| #include <sys/ioctl.h> /* ioctl */ |
| #include "libusmc.h" |
| #include "usmctypes.h" |
| |
| |
| #define USB_ERROR(errCode) (errCode|0x00000000L) |
| // Linux kernel errors or'ed with this value |
| // to distinguish them from usb errors. |
| #define LINKRN_ERROR(errCode) (errCode|0x10000000L) |
| #define HIBYTE(w) ((w&0xff00)>>8) |
| #define LOBYTE(w) (w&0x00ff) |
| #define HIWORD(dw) ((dw&0xffff0000)>>16) |
| #define LOWORD(dw) (dw&0x0000ffff) |
| #define PACK_WORD(w) (HIBYTE(w)|(LOBYTE(w)<<8)) |
| //#define PACK_WORD(w) (LOBYTE(w)|(HIBYTE(w)<<8)) |
| #define PACK_DWORD(w) (HIBYTE(HIWORD(w))| \ |
| (LOBYTE(HIWORD(w))<<8)| \ |
| (HIBYTE(LOWORD(w))<<16)| \ |
| (LOBYTE(LOWORD(w))<<24)) |
| |
| |
| // DLL data: |
| BOOL g_IsInitialized = FALSE; |
| USMC_Devices g_devices; |
| USMC_Mode g_deviceMode [32]; |
| USMC_Parameters g_deviceParameters [32]; |
| USMC_StartParameters g_deviceStartParameters [32]; |
| DWORD g_devicesVersions [32]; |
| char g_lastErrDesc [256]; // Null-terminated ASCII error description string. |
| |
| |
| // Error string descriptions: |
| static char * errDesc [] = { |
| "0x???????? ( Unknown )", |
| "0x00000000 ( Success )", |
| /* "0x00000001 ( USB CRC )", |
| "0x00000002 ( USB Bit stuffing )", |
| "0x00000003 ( USB Data toggle mismatch )", |
| |
| "0x00000004 ( USB Stall )", |
| "0x00000005 ( USB Device not responding )", |
| "0x00000006 ( USB PID check failure )", |
| "0x00000007 ( USB Unexpected PID )", |
| "0x00000008 ( USB Data overrun )", |
| |
| "0x00000009 ( USB Data underrun )", |
| "0x0000000C ( USB Buffer overrun )", |
| "0x0000000D ( USB Buffer underrun )", |
| "0x0000000E ( USB Not accessed )", |
| "0x0000000F ( USB Not accessed alt )", |
| |
| "0x00000100 ( USB Isochronous )", |
| "0x00000101 ( USB Canceled )", |
| "0x00000103 ( USB Not complete )", |
| "0x00000104 ( USB Client buffer )",*/ |
| "0x14141414 ( USMC Not initialized )", |
| //"0x00000006 ( USMC Reffered Device not connected )", |
| //"0x00000012 ( DeviceManager error - driver function called with invalid arguments )", |
| "0x14141415 ( USMC No devices connected )" |
| }; |
| |
| |
| // Internal-use functions prototypes: |
| DWORD SetLastErr ( const char * str, DWORD dwErrCode ); |
| char * ErrCode2Str ( DWORD dwErrCode ); |
| int clamp ( int val, int min, int max ); |
| float clampf ( float val, float min, float max ); |
| DWORD IOCTRL ( DWORD Device, |
| DWORD dwCode, |
| PVOID pInBuf, |
| DWORD dwInBufSize, |
| PVOID pOutBuf, |
| DWORD dwOutBufSize ); |
| |
| |
| |
| |
| // Function: SetLastErr () |
| // Argument list: |
| // const char * str √ in √ Null-terminated ASCII error description. |
| // DWORD dwErrCode - in - optional - error code supplied with description. |
| // Return value: |
| // DWORD - modified error code. |
| // Remarks: |
| // The SetLastErr () sets description of last occured error. |
| DWORD SetLastErr ( const char * str, DWORD dwErrCode ) |
| { |
| if ( dwErrCode == -USMC_ERROR_REF_DEV_DISCONNECTED ) |
| sprintf ( ( char * ) g_lastErrDesc, "Error: %s. Code: %s", str, "Reffered device disconnected" ); |
| else if ( dwErrCode != 1 ) |
| sprintf ( ( char * ) g_lastErrDesc, "Error: %s. Code: %d", str, ( signed int ) dwErrCode ); |
| |
| //if ( dwErrCode != 1 ) |
| // sprintf ( ( char * ) g_lastErrDesc, "Error: %s. Code: %s", str, ErrCode2Str ( dwErrCode ) ); |
| //else |
| // sprintf ( ( char * ) g_lastErrDesc, "Error: %s.", str ); |
| |
| |
| return dwErrCode; |
| } |
| |
| |
| |
| |
| // Function: ErrCode2Str () |
| // Argument list: |
| // DWORD dwErrCode √ in √ error code returned by any operation. |
| // Return value: |
| // char * - string equivalent for specified numerical error code. |
| // Remarks: |
| // There is no need to free error string obtained with this function: |
| // return value points to static dll variable. |
| char * ErrCode2Str ( DWORD dwErrCode ) |
| { |
| switch ( dwErrCode ) |
| { |
| /* case USB_NO_ERROR: |
| return errDesc [1]; break; |
| case USB_CRC_ERROR: |
| return errDesc [2]; break; |
| case USB_BIT_STUFFING_ERROR: |
| return errDesc [3]; break; |
| case USB_DATA_TOGGLE_MISMATCH_ERROR: |
| return errDesc [4]; break; |
| case USB_STALL_ERROR: |
| return errDesc [5]; break; |
| case USB_DEVICE_NOT_RESPONDING_ERROR: |
| return errDesc [6]; break; |
| case USB_PID_CHECK_FAILURE_ERROR: |
| return errDesc [7]; break; |
| case USB_UNEXPECTED_PID_ERROR: |
| return errDesc [8]; break; |
| case USB_DATA_OVERRUN_ERROR: |
| return errDesc [9]; break; |
| case USB_DATA_UNDERRUN_ERROR: |
| return errDesc [10]; break; |
| case USB_BUFFER_OVERRUN_ERROR: |
| return errDesc [11]; break; |
| case USB_BUFFER_UNDERRUN_ERROR: |
| return errDesc [12]; break; |
| case USB_NOT_ACCESSED_ERROR: |
| return errDesc [13]; break; |
| case USB_NOT_ACCESSED_ALT: |
| return errDesc [14]; break; |
| case USB_ISOCH_ERROR: |
| return errDesc [15]; break; |
| case USB_CANCELED_ERROR: |
| return errDesc [16]; break; |
| case USB_NOT_COMPLETE_ERROR: |
| return errDesc [17]; break; |
| case USB_CLIENT_BUFFER_ERROR: |
| return errDesc [18]; break; |
| case USMC_ERROR_NOT_INITIALIZED: |
| return errDesc [19]; break; |
| case USMC_ERROR_REF_DEV_DISCONNECTED: |
| return errDesc [20]; break; |
| case LINKRN_ERROR ( ERROR_BAD_ARGUMENTS ): |
| return errDesc [21]; break; |
| case USMC_ERROR_NO_DEVICES_CONNECTED: |
| return errDesc [22]; break;*/ |
| default: |
| return errDesc [0]; break; |
| } |
| } |
| |
| |
| |
| |
| int clamp ( int val, int min, int max ) |
| { |
| return val > max ? max : ( val < min ? min : val ); |
| } |
| |
| |
| |
| |
| float clampf ( float val, float min, float max ) |
| { |
| return val > max ? max : ( val < min ? min : val ); |
| } |
| |
| |
| |
| // Function: InitDefaultValues () |
| // Initializes structures with default values. |
| // Return Value: |
| // The InitDefaultValues function has no return values. |
| void InitDefaultValues () |
| { |
| int i; |
| |
| for ( i = 0 ; i < 32 ; i++ ) |
| { |
| memset ( &g_deviceMode [i], 0, sizeof ( USMC_Mode ) ); |
| memset ( &g_deviceParameters [i], 0, sizeof ( USMC_Parameters ) ); |
| memset ( &g_deviceStartParameters [i], 0, sizeof ( USMC_StartParameters ) ); |
| |
| // USMC_Mode defaults: |
| g_deviceMode [i].PReg = TRUE; |
| g_deviceMode [i].Tr1En = TRUE; |
| g_deviceMode [i].Tr2En = TRUE; |
| g_deviceMode [i].RotTrOp = TRUE; |
| g_deviceMode [i].SyncOUTEn = TRUE; |
| g_deviceMode [i].SyncINOp = TRUE; |
| g_deviceMode [i].SyncCount = 4; |
| |
| // USMC_Parameters defaults: |
| g_deviceParameters [i].MaxTemp = 70.0f; |
| g_deviceParameters [i].AccelT = 200.0f; |
| g_deviceParameters [i].DecelT = 200.0f; |
| g_deviceParameters [i].BTimeout1 = 500.0f; |
| g_deviceParameters [i].BTimeout2 = 500.0f; |
| g_deviceParameters [i].BTimeout3 = 500.0f; |
| g_deviceParameters [i].BTimeout4 = 500.0f; |
| g_deviceParameters [i].BTO1P = 200.0f; |
| g_deviceParameters [i].BTO2P = 300.0f; |
| g_deviceParameters [i].BTO3P = 400.0f; |
| g_deviceParameters [i].BTO4P = 500.0f; |
| g_deviceParameters [i].MinP = 500.0f; |
| g_deviceParameters [i].BTimeoutR = 500.0f; |
| g_deviceParameters [i].LoftPeriod = 500.0f; |
| g_deviceParameters [i].RTDelta = 200; |
| g_deviceParameters [i].RTMinError = 15; |
| g_deviceParameters [i].EncMult = 2.5f; |
| g_deviceParameters [i].MaxLoft = 32; |
| g_deviceParameters [i].PTimeout = 100.0f; |
| g_deviceParameters [i].SynOUTP = 1; |
| g_deviceParameters [i].StartPos = 0; |
| |
| // USMC_StartParameters defaults: |
| g_deviceStartParameters [i].SDivisor = 8; |
| g_deviceStartParameters [i].LoftEn = TRUE; |
| g_deviceStartParameters [i].SlStart = TRUE; |
| } |
| } |
| |
| |
| |
| |
| // Function: IOCTRL () |
| // Encapsulates DeviceIoControl call ( internal use ). |
| // Parameters: |
| // [in] Device: device number to call DeviceIoControl on. |
| // [in] dwCode: IO Control code for operation. |
| // [out] pInBuf: buffer pointer to store returned data in. |
| // [in] dwInBufSize: size of in buffer. |
| // [in] pOutBuf: buffer pointer to send data from. |
| // [in] dwOutBufSize: size of out buffer. |
| // Return Value: |
| // DWORD; zero means succes, other value - error code. |
| // Remarks: |
| // Call this function with Device == -1 when devices wasn't enumerated yet. |
| // The IOCTRL () function DOES NOT sets error description. This routine must |
| // be completed by caller function to specify most appropriate information: where |
| // error has occured and with which operation it associated. |
| DWORD IOCTRL ( DWORD Device, |
| DWORD dwCode, |
| PVOID pInBuf, |
| DWORD dwInBufSize, |
| PVOID pOutBuf, |
| DWORD dwOutBufSize ) |
| { |
| DWORD deviceNumber; |
| char deviceName [128]; // Device name in form Prefix + DeviceNumber + ":\0". |
| DWORD dwErr; |
| int hFile; |
| char * buf; |
| |
| dwErr = 0; |
| |
| deviceNumber = Device == -1 ? 0 : Device; |
| sprintf ( deviceName, "/dev/usmc%d", deviceNumber ); |
| |
| hFile = open ( deviceName, 0 ); |
| |
| if ( hFile == -1 ) |
| return -USMC_ERROR_REF_DEV_DISCONNECTED; |
| |
| |
| if ( pInBuf && dwInBufSize ) { |
| buf = pInBuf; |
| } else if ( pOutBuf && dwOutBufSize ) { |
| buf = pOutBuf; |
| } |
| |
| |
| dwErr = ioctl ( hFile, |
| dwCode, |
| buf ); |
| |
| close ( hFile ); |
| |
| return dwErr; |
| } |
| |
| |
| |
| |
| DWORD USMC_Init ( USMC_Devices * Str ) |
| { |
| int nod; |
| DWORD i; |
| |
| nod = 0; |
| Str -> NOD = 0; |
| Str -> Serial = Str -> Version = NULL; |
| |
| if ( !g_IsInitialized ) |
| { |
| //InitializeCriticalSection ( &g_Lock ); |
| g_IsInitialized = TRUE; |
| } |
| |
| //EnterCriticalSection ( &g_Lock ); |
| DWORD dwRes = IOCTRL ( -1, |
| IOCTL_GET_NOD, |
| ( PVOID ) &nod, |
| 1, NULL, 0 ); |
| |
| if ( ( int ) dwRes < 0 ) |
| return USMC_SUCCESS; // No devices connected, so return NOD = 0. |
| else |
| Str -> NOD = nod; |
| |
| |
| // Enumerate connected devices: |
| Str -> Serial = ( char ** ) malloc ( ( ssize_t ) ( sizeof ( char * ) * 32 ) ); |
| Str -> Version = ( char ** ) malloc ( ( ssize_t ) ( sizeof ( char * ) * 32 ) ); |
| |
| for ( i = 0 ; i < Str -> NOD; i++ ) |
| { |
| char * serial = ( char * ) malloc ( ( ssize_t ) 16 ); |
| char * version = ( char * ) malloc ( ( ssize_t ) 6 ); |
| |
| dwRes = IOCTRL ( i, |
| IOCTL_GET_SERIAL, |
| ( PVOID ) serial, |
| 16, NULL, 0 ); |
| |
| if ( ( int ) dwRes < 0 ) |
| { |
| dwRes = SetLastErr ( "USMC_Init () failed during IOCTRL ( IOCTL_GET_SERIAL ) call", dwRes ); |
| free ( serial ); |
| free ( version ); |
| Str -> NOD = 0; |
| Str -> Serial = Str -> Version = NULL; |
| |
| return dwRes; |
| } |
| |
| |
| dwRes = IOCTRL ( i, |
| IOCTL_GET_VERSION, |
| ( PVOID ) version, |
| 6, NULL, 0 ); |
| |
| if ( ( int ) dwRes < 0 ) |
| { |
| dwRes = SetLastErr ( "USMC_Init () failed during IOCTRL ( IOCTL_GET_VERSION ) call", dwRes ); |
| free ( serial ); |
| free ( version ); |
| Str -> NOD = 0; |
| Str -> Serial = Str -> Version = NULL; |
| |
| return dwRes; |
| } |
| |
| |
| Str -> Serial [i] = serial; |
| |
| ( Str -> Version [i] ) = ( char * ) malloc ( ( ssize_t ) 4 ); |
| memcpy ( Str -> Version [i], version + 2, ( ssize_t ) 4 ); |
| |
| //strupr ( Str -> Version [i] ); |
| sscanf ( Str -> Version [i], "%X", &g_devicesVersions [i] ); |
| } |
| |
| |
| g_devices = *Str; |
| InitDefaultValues (); |
| |
| //LeaveCriticalSection ( &g_Lock ); |
| |
| |
| return USMC_SUCCESS; |
| } |
| |
| |
| |
| |
| DWORD USMC_GetState ( DWORD Device, USMC_State * Str ) |
| { |
| if ( !g_IsInitialized ) |
| return SetLastErr ( "USMC_GetState () failed", -USMC_ERROR_NOT_INITIALIZED ); |
| |
| |
| |
| STATE_PACKET getStateData; |
| |
| //EnterCriticalSection ( &g_Lock ); |
| DWORD dwRes = IOCTRL ( Device, |
| IOCTL_GET_STATE, |
| ( PVOID ) &getStateData, |
| 11, NULL, 0 ); |
| //LeaveCriticalSection ( &g_Lock ); |
| |
| if ( ( int ) dwRes < 0 ) |
| return SetLastErr ( "USMC_GetState () failed during IOCTRL ( IOCTL_GET_STATE ) call", dwRes ); |
| |
| |
| Str -> AReset = getStateData.AFTRESET; |
| Str -> CurPos = ( ( signed int ) getStateData.CurPos ) / 8; |
| Str -> CW_CCW = getStateData.CW_CCW; |
| Str -> EmReset = getStateData.EMRESET; |
| Str -> FullPower = getStateData.REFIN; |
| Str -> FullSpeed = getStateData.FULLSPEED; |
| Str -> Loft = getStateData.LOFT; |
| Str -> Power = getStateData.RESET; |
| Str -> RotTr = getStateData.ROTTR; |
| Str -> RotTrErr = getStateData.ROTTRERR; |
| Str -> RUN = getStateData.RUN; |
| /*Str -> SDivisor= See below;*/ |
| Str -> SyncIN = getStateData.SYNCIN; |
| Str -> SyncOUT = getStateData.SYNCOUT; |
| /*Str -> Temp = See below;*/ |
| Str -> Trailer1 = getStateData.TRAILER1; |
| Str -> Trailer2 = getStateData.TRAILER2; |
| /*Str -> Voltage = See below;*/ |
| |
| Str -> SDivisor = ( BYTE ) ( 1 << ( getStateData.M2 << 1 | getStateData.M1 ) ); |
| double t = ( double ) getStateData.Temp; |
| |
| if ( g_devicesVersions [Device] < 0x2400 ) |
| { |
| t = t * 3.3 / 65536.0; |
| t = t * 10.0 / ( 5.0 - t ); |
| t = ( 1.0 / 298.0 ) + ( 1.0 / 3950.0 ) * log ( t / 10.0 ); |
| t = 1.0 / t - 273.0; |
| } |
| else |
| { |
| t = ( ( t * 3.3 * 100.0 / 65536.0 ) - 50.0 ); |
| } |
| |
| |
| Str -> Temp = ( float ) t; |
| Str -> Voltage = ( float ) ( ( ( double ) getStateData.Voltage ) / 65536.0 * 3.3 * 20.0 ); |
| Str -> Voltage = Str -> Voltage < 5.0f ? 0.0f : Str -> Voltage; |
| |
| |
| return USMC_SUCCESS; |
| } |
| |
| |
| |
| |
| DWORD USMC_SaveParametersToFlash ( DWORD Device ) |
| { |
| if ( !g_IsInitialized ) |
| return SetLastErr ( "USMC_SaveParametersToFlash () failed", -USMC_ERROR_NOT_INITIALIZED ); |
| |
| |
| //EnterCriticalSection ( &g_Lock ); |
| DWORD dwRes = IOCTRL ( Device, |
| IOCTL_SAVE_PARAMETERS, |
| NULL, 0, NULL, 0 ); |
| //LeaveCriticalSection ( &g_Lock ); |
| |
| |
| if ( ( int ) dwRes < 0 ) |
| return SetLastErr ( "USMC_SaveParametersToFlash () failed during IOCTRL ( IOCTL_SAVE_PARAMETERS ) call", dwRes ); |
| |
| |
| |
| return USMC_SUCCESS; |
| } |
| |
| |
| |
| |
| DWORD USMC_GetMode ( DWORD Device, USMC_Mode * Str ) |
| { |
| if ( !g_IsInitialized ) |
| return SetLastErr ( "USMC_GetMode () failed", -USMC_ERROR_NOT_INITIALIZED ); |
| |
| |
| *Str = g_deviceMode [Device]; |
| |
| |
| return USMC_SUCCESS; |
| } |
| |
| |
| |
| |
| DWORD USMC_SetMode ( DWORD Device, USMC_Mode * Str ) |
| { |
| if ( !g_IsInitialized ) |
| return SetLastErr ( "USMC_SetMode () failed", -USMC_ERROR_NOT_INITIALIZED ); |
| |
| |
| MODE_PACKET setModeData; |
| // Byte 0: |
| setModeData.PMODE = Str -> PMode; |
| setModeData.REFINEN = Str -> PReg; |
| setModeData.RESETD = Str -> ResetD; |
| setModeData.EMRESET = Str -> EMReset; |
| setModeData.TR1T = Str -> Tr1T; |
| setModeData.TR2T = Str -> Tr2T; |
| setModeData.ROTTRT = Str -> RotTrT; |
| setModeData.TRSWAP = Str -> TrSwap; |
| // Byte 1: |
| setModeData.TR1EN = Str -> Tr1En; |
| setModeData.TR2EN = Str -> Tr2En; |
| setModeData.ROTTREN = Str -> RotTeEn; |
| setModeData.ROTTROP = Str -> RotTrOp; |
| setModeData.BUTT1T = Str -> Butt1T; |
| setModeData.BUTT2T = Str -> Butt2T; |
| /*setModeData.BUTSWAP = ...;*/ |
| setModeData.RESETRT = Str -> ResetRT; |
| // Byte 2: |
| setModeData.SNCOUTEN = Str -> SyncOUTEn; |
| setModeData.SYNCOUTR = Str -> SyncOUTR; |
| setModeData.SYNCINOP = Str -> SyncINOp; |
| setModeData.SYNCOPOL = Str -> SyncInvert; |
| setModeData.ENCODER = Str -> EncoderEn; |
| setModeData.INVENC = Str -> EncoderInv; |
| setModeData.RESBENC = Str -> ResBEnc; |
| setModeData.RESENC = Str -> ResEnc; |
| |
| setModeData.SYNCCOUNT = PACK_DWORD ( Str -> SyncCount ); |
| |
| // Save parameters within DLL for further USMC_GetMode () calls: |
| //EnterCriticalSection ( &g_Lock ); |
| g_deviceMode [Device] = *Str; |
| |
| DWORD dwRes = IOCTRL ( Device, |
| IOCTL_SET_MODE, |
| NULL, 0, |
| ( PVOID ) &setModeData, 7 ); |
| //LeaveCriticalSection ( &g_Lock ); |
| |
| |
| if ( ( int ) dwRes < 0 ) |
| return SetLastErr ( "USMC_SetMode () failed during IOCTRL ( IOCTL_SET_MODE ) call", dwRes ); |
| |
| |
| return USMC_SUCCESS; |
| } |
| |
| |
| |
| |
| DWORD USMC_GetParameters ( DWORD Device, USMC_Parameters * Str ) |
| { |
| if ( !g_IsInitialized ) |
| return SetLastErr ( "USMC_GetParameters () failed", -USMC_ERROR_NOT_INITIALIZED ); |
| |
| |
| *Str = g_deviceParameters [Device]; |
| |
| |
| return USMC_SUCCESS; |
| } |
| |
| |
| |
| |
| DWORD USMC_SetParameters ( DWORD Device, USMC_Parameters * Str ) |
| { |
| if ( !g_IsInitialized ) |
| return SetLastErr ( "USMC_SetParameters () failed", -USMC_ERROR_NOT_INITIALIZED ); |
| |
| |
| PARAMETERS_PACKET setParametersData; |
| |
| /*=====================*/ |
| /* ----Conversion:---- */ |
| /*=====================*/ |
| setParametersData.DELAY1 = ( BYTE ) clamp ( ( int ) ( Str -> AccelT / 98.0f + 0.5f ), 1, 15 ); |
| setParametersData.DELAY2 = ( BYTE ) clamp ( ( int ) ( Str -> DecelT / 98.0f + 0.5f ), 1, 15 ); |
| setParametersData.RefINTimeout = ( WORD ) ( clampf ( Str -> PTimeout , 1.0f, 9961.0f ) / 0.152f + 0.5f ); |
| setParametersData.BTIMEOUT1 = PACK_WORD ( ( WORD ) ( clampf ( Str -> BTimeout1, 1.0f, 9961.0f ) / 0.152f + 0.5f ) ); |
| setParametersData.BTIMEOUT2 = PACK_WORD ( ( WORD ) ( clampf ( Str -> BTimeout2, 1.0f, 9961.0f ) / 0.152f + 0.5f ) ); |
| setParametersData.BTIMEOUT3 = PACK_WORD ( ( WORD ) ( clampf ( Str -> BTimeout3, 1.0f, 9961.0f ) / 0.152f + 0.5f ) ); |
| setParametersData.BTIMEOUT4 = PACK_WORD ( ( WORD ) ( clampf ( Str -> BTimeout4, 1.0f, 9961.0f ) / 0.152f + 0.5f ) ); |
| setParametersData.BTIMEOUTR = PACK_WORD ( ( WORD ) ( clampf ( Str -> BTimeoutR, 1.0f, 9961.0f ) / 0.152f + 0.5f ) ); |
| setParametersData.BTIMEOUTD = PACK_WORD ( ( WORD ) ( clampf ( Str -> BTimeoutD, 1.0f, 9961.0f ) / 0.152f + 0.5f ) ); |
| setParametersData.MINPERIOD = PACK_WORD ( ( WORD ) ( 65536.0f - ( 125000.0f / clampf ( Str -> MinP , 2.0f, 625.0f ) ) + 0.5f ) ); |
| setParametersData.BTO1P = PACK_WORD ( ( WORD ) ( 65536.0f - ( 125000.0f / clampf ( Str -> BTO1P, 2.0f, 625.0f ) ) + 0.5f ) ); |
| setParametersData.BTO2P = PACK_WORD ( ( WORD ) ( 65536.0f - ( 125000.0f / clampf ( Str -> BTO2P, 2.0f, 625.0f ) ) + 0.5f ) ); |
| setParametersData.BTO3P = PACK_WORD ( ( WORD ) ( 65536.0f - ( 125000.0f / clampf ( Str -> BTO3P, 2.0f, 625.0f ) ) + 0.5f ) ); |
| setParametersData.BTO4P = PACK_WORD ( ( WORD ) ( 65536.0f - ( 125000.0f / clampf ( Str -> BTO4P, 2.0f, 625.0f ) ) + 0.5f ) ); |
| setParametersData.MAX_LOFT = PACK_WORD ( ( WORD ) ( clamp ( Str -> MaxLoft, 1, 1023 ) * 64 ) ); |
| |
| if ( g_devicesVersions [Device] < 0x2407 ) |
| { |
| setParametersData.STARTPOS = 0x00000000L; |
| } |
| else |
| { |
| setParametersData.STARTPOS = PACK_DWORD ( Str -> StartPos * 8 & 0xFFFFFF00 ); |
| } |
| |
| |
| setParametersData.RTDelta = PACK_WORD ( ( WORD ) ( clamp ( Str -> RTDelta , 4, 1023 ) * 64 ) ); |
| setParametersData.RTMinError = PACK_WORD ( ( WORD ) ( clamp ( Str -> RTMinError, 4, 1023 ) * 64 ) ); |
| |
| double t = ( double ) clampf ( Str -> MaxTemp, 0.0f, 100.0f ); |
| |
| if ( g_devicesVersions [Device] < 0x2400 ) |
| { |
| t = 10.0 * exp ( 3950.0 * ( 1.0 / ( t + 273.0 ) - 1.0 / 298.0 ) ); |
| t = ( ( 5 * t / ( 10 + t ) ) * 65536.0 / 3.3 + 0.5 ); |
| } |
| else |
| { |
| t = ( t + 50.0 ) / 330.0 * 65536.0; |
| t = ( t + 0.5f ); |
| } |
| |
| |
| setParametersData.MaxTemp = PACK_WORD ( ( WORD ) t ); |
| setParametersData.SynOUTP = Str -> SynOUTP; |
| setParametersData.LoftPeriod = Str -> LoftPeriod == 0.0f ? 0 : |
| PACK_WORD ( ( WORD ) ( 65536.0f - ( 125000.0f / clampf ( Str -> LoftPeriod, 16.0f, 5000.0f ) ) + 0.5f ) ); |
| setParametersData.EncVSCP = ( BYTE ) ( Str -> EncMult * 4.0f + 0.5f ); |
| //setParametersData.EncVSCP = 1; /////////// |
| |
| memset ( setParametersData.Reserved, 0, 15 ); |
| //unsigned char testBuf [sizeof ( PARAMETERS_PACKET )]; |
| //memcpy ( ( void * ) testBuf, ( const void * ) &setParametersData, ( size_t ) sizeof ( PARAMETERS_PACKET ) ); |
| /*=======================*/ |
| /* ----Deconversion:---- */ |
| /*=======================*/ |
| Str -> AccelT = setParametersData.DELAY1 * 98.0f; |
| Str -> DecelT = setParametersData.DELAY2 * 98.0f; |
| Str -> PTimeout = ( float ) ( setParametersData.RefINTimeout * 0.152f ); |
| Str -> BTimeout1 = ( float ) ( PACK_WORD ( setParametersData.BTIMEOUT1 ) * 0.152f ); |
| Str -> BTimeout2 = ( float ) ( PACK_WORD ( setParametersData.BTIMEOUT2 ) * 0.152f ); |
| Str -> BTimeout3 = ( float ) ( PACK_WORD ( setParametersData.BTIMEOUT3 ) * 0.152f ); |
| Str -> BTimeout4 = ( float ) ( PACK_WORD ( setParametersData.BTIMEOUT4 ) * 0.152f ); |
| Str -> BTimeoutR = ( float ) ( PACK_WORD ( setParametersData.BTIMEOUTR ) * 0.152f ); |
| Str -> BTimeoutD = ( float ) ( PACK_WORD ( setParametersData.BTIMEOUTD ) * 0.152f ); |
| Str -> MinP = 125000.0f / ( 65536.0f - ( float ) ( PACK_WORD ( setParametersData.MINPERIOD ) ) ); |
| Str -> BTO1P = 125000.0f / ( 65536.0f - ( float ) ( PACK_WORD ( setParametersData.BTO1P ) ) ); |
| Str -> BTO2P = 125000.0f / ( 65536.0f - ( float ) ( PACK_WORD ( setParametersData.BTO2P ) ) ); |
| Str -> BTO3P = 125000.0f / ( 65536.0f - ( float ) ( PACK_WORD ( setParametersData.BTO3P ) ) ); |
| Str -> BTO4P = 125000.0f / ( 65536.0f - ( float ) ( PACK_WORD ( setParametersData.BTO4P ) ) ); |
| Str -> MaxLoft = PACK_WORD ( setParametersData.MAX_LOFT ) / 64; |
| |
| if( g_devicesVersions [Device] < 0x2407 ) |
| { |
| Str -> StartPos = 0x00000000L; |
| } |
| else |
| { |
| Str -> StartPos = PACK_DWORD ( setParametersData.STARTPOS ) / 8; |
| } |
| |
| |
| Str -> RTDelta = PACK_WORD ( setParametersData.RTDelta ) / 64; |
| Str -> RTMinError = PACK_WORD ( setParametersData.RTMinError ) / 64; |
| |
| if ( g_devicesVersions [Device] < 0x2400 ) |
| { |
| t = ( double )( PACK_WORD ( setParametersData.MaxTemp ) ); |
| t = t * 3.3 / 65536.0; |
| t = 10.0 * t / ( 5.0 - t ); |
| t = ( 1.0 / 298.0 ) + ( 1.0 / 3950.0 ) * log ( t / 10.0 ); |
| t = 1.0 / t - 273.0; |
| } |
| else |
| { |
| t = ( double ) ( PACK_WORD ( setParametersData.MaxTemp ) ); |
| t = ( t * 3.3 * 100.0 / 65536.0 ) - 50.0; |
| } |
| |
| |
| Str -> MaxTemp = ( float ) t; |
| |
| Str -> SynOUTP = setParametersData.SynOUTP; |
| Str -> LoftPeriod = PACK_WORD ( setParametersData.LoftPeriod ) == 0 ? 0.0f : |
| 125000.0f / ( 65536.0f - ( float ) ( PACK_WORD ( setParametersData.LoftPeriod ) ) ); |
| Str -> EncMult = ( ( float ) setParametersData.EncVSCP ) / 4.0f; |
| |
| // Save parameters within DLL for further USMC_GetParameters () calls: |
| //EnterCriticalSection ( &g_Lock ); |
| g_deviceParameters [Device] = *Str; |
| |
| DWORD dwRes = IOCTRL ( Device, |
| IOCTL_SET_PARAMETERS, |
| NULL, 0, |
| ( PVOID ) &setParametersData, 57 ); |
| //LeaveCriticalSection ( &g_Lock ); |
| |
| |
| if ( ( int ) dwRes < 0 ) |
| return SetLastErr ( "USMC_SetParameters () failed during IOCTRL ( IOCTL_SET_PARAMETERS ) call", dwRes ); |
| |
| |
| return USMC_SUCCESS; |
| } |
| |
| |
| |
| |
| DWORD USMC_GetStartParameters ( DWORD Device, USMC_StartParameters * Str ) |
| { |
| if ( !g_IsInitialized ) |
| return SetLastErr ( "USMC_GetStartParameters () failed", -USMC_ERROR_NOT_INITIALIZED ); |
| |
| |
| *Str = g_deviceStartParameters [Device]; |
| |
| |
| return USMC_SUCCESS; |
| } |
| |
| |
| |
| |
| DWORD USMC_Start ( DWORD Device, int DestPos, |
| float * Speed, |
| USMC_StartParameters * Str ) |
| { |
| if ( !g_IsInitialized ) |
| return SetLastErr ( "USMC_Start () failed", -USMC_ERROR_NOT_INITIALIZED ); |
| |
| |
| GO_TO_PACKET goToData; |
| |
| /*=====================*/ |
| /* ----Conversion:---- */ |
| /*=====================*/ |
| goToData.DestPos = ( DWORD ) ( DestPos * 8 ); |
| goToData.TimerPeriod = PACK_WORD ( ( WORD ) ( 65536.0f - ( 1000000.0f / clampf ( *Speed, 16.0f, 5000.0f ) ) + 0.5f ) ); |
| switch ( Str -> SDivisor ) |
| { |
| case 1: |
| goToData.M1 = goToData.M2 = 0; |
| break; |
| case 2: |
| goToData.M1 = 1; |
| goToData.M2 = 0; |
| break; |
| case 4: |
| goToData.M1 = 0; |
| goToData.M2 = 1; |
| break; |
| case 8: |
| goToData.M1 = 1; |
| goToData.M2 = 1; |
| break; |
| } |
| //goToData.M1 = Str -> SDivisor && 0x01; |
| //goToData.M2 = Str -> SDivisor && 0x02; |
| goToData.DEFDIR = Str -> DefDir; |
| goToData.LOFTEN = Str -> LoftEn; |
| goToData.SLSTRT = Str -> SlStart; |
| goToData.WSYNCIN = Str -> WSyncIN; |
| goToData.SYNCOUTR = Str -> SyncOUTR; |
| goToData.FORCELOFT = Str -> ForceLoft; |
| |
| |
| /*=======================*/ |
| /* ----Deconversion:---- */ |
| /*=======================*/ |
| *Speed = 1000000.0f / ( 65536.0f - ( float ) PACK_WORD ( goToData.TimerPeriod ) ); |
| Str -> SDivisor = 1 << ( ( goToData.M2 << 1 ) | goToData.M1 ); |
| |
| // Save start parameters within DLL for further USMC_GetStartParameters () calls: |
| //EnterCriticalSection ( &g_Lock ); |
| g_deviceStartParameters [Device] = *Str; |
| |
| DWORD dwRes = IOCTRL ( Device, |
| IOCTL_GO_TO, |
| NULL, 0, |
| ( PVOID ) &goToData, 7 ); |
| //LeaveCriticalSection ( &g_Lock ); |
| |
| |
| if ( ( int ) dwRes < 0 ) |
| return SetLastErr ( "USMC_Start () failed during IOCTRL ( IOCTL_GO_TO ) call", dwRes ); |
| |
| |
| return USMC_SUCCESS; |
| } |
| |
| |
| |
| |
| DWORD USMC_Stop ( DWORD Device ) |
| { |
| if ( !g_IsInitialized ) |
| return SetLastErr ( "USMC_Stop () failed", -USMC_ERROR_NOT_INITIALIZED ); |
| |
| |
| //EnterCriticalSection ( &g_Lock ); |
| DWORD dwRes = IOCTRL ( Device, |
| IOCTL_STOP_STEP_MOTOR, |
| NULL, 0, NULL, 0 ); |
| //LeaveCriticalSection ( &g_Lock ); |
| |
| |
| if ( ( int ) dwRes < 0 ) |
| return SetLastErr ( "USMC_Stop () failed during IOCTRL ( IOCTL_STOP_STEP_MOTOR ) call", dwRes ); |
| |
| |
| return USMC_SUCCESS; |
| } |
| |
| |
| |
| |
| DWORD USMC_SetCurrentPosition ( DWORD Device, int Position ) |
| { |
| if ( !g_IsInitialized ) |
| return SetLastErr ( "USMC_SetCurrentPosition () failed", -USMC_ERROR_NOT_INITIALIZED ); |
| |
| |
| Position *= 8; |
| Position &= 0xFFFFFFE0; |
| //EnterCriticalSection ( &g_Lock ); |
| DWORD dwRes = IOCTRL ( Device, |
| IOCTL_SET_CURRENT_POSITION, |
| NULL, 0, |
| ( PVOID ) &Position, 4 ); |
| //LeaveCriticalSection ( &g_Lock ); |
| |
| |
| if ( ( int ) dwRes < 0 ) |
| return SetLastErr ( "USMC_SetCurrentPosition () failed during IOCTRL ( IOCTL_SET_CURRENT_POSITION ) call", dwRes ); |
| |
| |
| return USMC_SUCCESS; |
| } |
| |
| |
| |
| |
| DWORD USMC_GetEncoderState ( DWORD Device, USMC_EncoderState * Str ) |
| { |
| if ( !g_IsInitialized ) |
| return SetLastErr ( "USMC_GetEncoderState () failed", -USMC_ERROR_NOT_INITIALIZED ); |
| |
| |
| if ( g_devicesVersions [Device] < 0x2410 ) |
| return USMC_SUCCESS; |
| |
| |
| //EnterCriticalSection ( &g_Lock ); |
| ENCODER_STATE_PACKET getEncoderStateData; |
| |
| DWORD dwRes = IOCTRL ( Device, |
| IOCTL_GET_ENCODER_STATE, |
| ( PVOID ) &getEncoderStateData, |
| 8, NULL, 0 ); |
| //LeaveCriticalSection ( &g_Lock ); |
| |
| |
| if ( ( int ) dwRes < 0 ) |
| return SetLastErr ( "USMC_GetEncoderState () failed during IOCTRL ( IOCTL_GET_STATE ) call", dwRes ); |
| |
| |
| Str -> ECurPos = getEncoderStateData.ECurPos; |
| Str -> EncoderPos = getEncoderStateData.EncPos; |
| |
| |
| return USMC_SUCCESS; |
| } |
| |
| |
| |
| |
| void USMC_GetLastErr ( char * str, ssize_t len ) |
| { |
| //EnterCriticalSection ( &g_Lock ); |
| if ( strlen ( g_lastErrDesc ) > len ) |
| memcpy ( str, g_lastErrDesc, len ); |
| else |
| strcpy ( str, ( const char * ) g_lastErrDesc ); |
| //LeaveCriticalSection ( &g_Lock ); |
| } |
| |
| |
| |
| |
| DWORD USMC_Close ( void ) |
| { |
| if ( !g_IsInitialized ) |
| return SetLastErr ( "USMC_Close () failed", -USMC_ERROR_NOT_INITIALIZED ); |
| |
| |
| return USMC_SUCCESS; |
| } |