From a4113d92471bc05bdcf741c525de94374d839a82 Mon Sep 17 00:00:00 2001 From: LI Bin Date: Tue, 18 Mar 2014 15:31:31 +0800 Subject: [PATCH] Add rotary control panel. --- .../Interfac/Msi/Hsi/SevenOcean/SO7_Proto.cpp | 47 +- .../Interfac/Msi/Hsi/SevenOcean/SO7_Proto.h | 4 +- .../Msi/Hsi/SevenOcean/SO7_Proto_Aux.cpp | 752 ++++++++++++++++++ .../Msi/Hsi/SevenOcean/SO7_Proto_Aux.h | 304 +++++++ .../Tools/UsbUtility/Debug/UtilityDebug.Log | 136 +++- .../Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc | 74 +- .../Tools/UsbUtility/UsbUtil/So7_Option.cpp | 42 +- .../UsbUtility/UsbUtil/So7_UtilUsbCtlR.cpp | 182 +++++ .../UsbUtility/UsbUtil/So7_UtilUsbCtlR.h | 38 + .../Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj | 4 + .../UsbUtil/Usb_Util.vcxproj.filters | 8 + .../Hsi/Tools/UsbUtility/UsbUtil/resource.h | 29 + .../Hsi/Tools/UsbUtility/UsbUtil_VS2010.suo | Bin 2355712 -> 2355712 bytes 13 files changed, 1594 insertions(+), 26 deletions(-) create mode 100644 PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto_Aux.cpp create mode 100644 PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto_Aux.h create mode 100644 PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_UtilUsbCtlR.cpp create mode 100644 PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_UtilUsbCtlR.h diff --git a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto.cpp b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto.cpp index 4d6b8fc..28249d5 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto.cpp +++ b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto.cpp @@ -2719,10 +2719,11 @@ SSI_STATUS_MOTION CSO7_Proto::_process_replay_capture_commands(char *inBuff, FIL }; //****************************************************************************** -usb_dev_handle* CSO7_Proto::_open_usb_dev(void) +usb_dev_handle* CSO7_Proto::_open_usb_dev(unsigned short sSeqNumber) { struct usb_bus *bus = NULL; struct usb_device *dev = NULL; + usb_dev_handle *udev = NULL; for (bus = usb_get_busses(); bus; bus = bus->next) { @@ -2730,13 +2731,51 @@ usb_dev_handle* CSO7_Proto::_open_usb_dev(void) { if (dev->descriptor.idVendor == SEVENOCEAN_VID && dev->descriptor.idProduct == SEVENOCEAN_PID) { - return usb_open(dev); + udev = usb_open(dev); + usb_claim_interface(udev, 0); + + if(Get_SeqNumber(udev) != sSeqNumber) + { + usb_close(udev); + } + else + { + return udev; + } } } } return NULL; } +//****************************************************************************** +int CSO7_Proto::Get_SeqNumber(usb_dev_handle *udev) +{ + memset(ep_buff[EP_02_CMD_IDX]._buffer, 0x00, MAX_BUFF_SIZE); + + *(ep_buff[EP_02_CMD_IDX]._buffer) = CT_DATA; + *(ep_buff[EP_02_CMD_IDX]._buffer+1) = CT_READ_SEQ_NUMBER; + + ep_buff[EP_02_CMD_IDX]._size = 0x02; + ep_buff[EP_82_DATA_IDX]._size = 0x01; + + int _ret; + _ret = usb_bulk_write(udev, ep_buff[2]._ep, (char *)ep_buff[2]._buffer,(int) ep_buff[2]._size, 50); + if (_ret < 0) + { + return -1; + } + + _ret = usb_bulk_read(udev, ep_buff[3]._ep, (char *)ep_buff[3]._buffer,(int) ep_buff[3]._size, 5000); + if (_ret < 0) + { + return -1; + } + g_machine.SEQ_NUMBER = -1; + g_machine.SEQ_NUMBER = *(ep_buff[EP_82_DATA_IDX]._buffer); + return g_machine.SEQ_NUMBER; +} + //****************************************************************************** // Send is direct and async. // The receive thread will receive data and interpret it. @@ -2754,8 +2793,8 @@ SSI_STATUS_MOTION CSO7_Proto::Init_SO7Usb() int usb_status = NULL; usb_init(); // initialize the library usb_status = usb_find_busses(); // find all busses - usb_status = usb_find_devices(); // find all connected devices - g_dev = _open_usb_dev(); + usb_status = usb_find_devices(); // find all connected devices + g_dev = _open_usb_dev(USB_SEQ_NUMBER); if (!g_dev) { MessageBox(NULL, _T("Unable to open device"), _T("Message"), MB_OK|MB_ICONERROR); diff --git a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto.h b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto.h index 95d9c1a..68361bb 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto.h +++ b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto.h @@ -22,6 +22,7 @@ #define USB_DEVICE_DESCRIPTOR_TYPE 1 #define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 +#define USB_SEQ_NUMBER 0 #define THREAD_RUNNING_STATE1 0 #define THREAD_RUNNING_STATE2 2 @@ -337,10 +338,11 @@ public: static struct_so7_machine g_machine; + int Get_SeqNumber(usb_dev_handle *udev); SSI_STATUS_MOTION Init_SO7Usb(); SSI_STATUS_MOTION Exit_SO7Usb(); - usb_dev_handle* _open_usb_dev(void); + usb_dev_handle* _open_usb_dev(unsigned short sSeqNumber); SSI_STATUS_MOTION _do_single_threaded_usb_comm(int iEP); SSI_STATUS_MOTION _read_data_8x(int iEP_Base); diff --git a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto_Aux.cpp b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto_Aux.cpp new file mode 100644 index 0000000..eb9a2d1 --- /dev/null +++ b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto_Aux.cpp @@ -0,0 +1,752 @@ + + +#include "stdafx.h" +#include "SO7_Proto_Aux.h" +#include "math.h" + + + +#define MY_CONFIG 1 +#define MAX_DEVPATH_LENGTH 256 +#define ENDPOINT_TIMEOUT 500 +#define MAX_IN_BUFF_SIZE 1024 + +//***** Static Data ***** +static char *outBuff = NULL; +struct_so7_r_ep_buff CSO7_Proto_Aux::ep_buff[lEPSIZE]; +//================================================================ +int CSO7_Proto_Aux::g_hEP8x_Thread_State=THREAD_PAUSED; +HANDLE CSO7_Proto_Aux::g_hEP8x_Thread_Id=NULL; + +//================================================================ +int CSO7_Proto_Aux::g_hEP02_Thread_State=THREAD_PAUSED; +HANDLE CSO7_Proto_Aux::g_hEP02_Thread_Id=NULL; +HANDLE CSO7_Proto_Aux::g_hEP02_Serial_Mutex; + +//================================================================ +struct_so7_r_machine CSO7_Proto_Aux::g_machine; +usb_dev_handle *CSO7_Proto_Aux::g_dev=NULL; +CLogger *CSO7_Proto_Aux::g_pLogger1; +HANDLE CSO7_Proto_Aux::g_hHomedEvent = NULL; +CLogger* g_pLog1=NULL; + +//****************************************************************************** +CSO7_Proto_Aux::CSO7_Proto_Aux() +{ + ep_buff[EP_01_CMD_IDX]._ep = EP_S07_01; + ep_buff[EP_81_DATA_IDX]._ep = EP_S07_81; + ep_buff[EP_02_CMD_IDX]._ep = EP_S07_02; + ep_buff[EP_82_DATA_IDX]._ep = EP_S07_82; + + for (int i=0;iSend(_T("Construct Cso7_Proto.\r\n")); +}; + +//****************************************************************************** +CSO7_Proto_Aux::~CSO7_Proto_Aux() +{ + for (int i=0;iSend(_T("Destruct Cso7_Proto.\r\n")); + delete g_pLogger1; + g_pLogger1 = NULL; +} + +#pragma warning(disable:4996) +//****************************************************************************** +// Send is direct and async. +// The receive thread will receive data and interpret it. +//****************************************************************************** +SSI_STATUS_MOTION CSO7_Proto_Aux::Init_SO7Usb() +{ + //Set initial state of the machine + g_machine.s_rstatus._machine_running = false; + SSI_STATUS_MOTION rStatus=SSI_STATUS_MOTION_NORMAL; + g_machine.IsOffline=FALSE; + + int usb_status = NULL; + usb_init(); // initialize the library + usb_status = usb_find_busses(); // find all busses + usb_status = usb_find_devices(); // find all connected devices + g_dev = _open_usb_dev(USB_R_SEQ_NUMBER); + if (!g_dev) + { + MessageBox(NULL, _T("Unable to open device"), _T("Message"), MB_OK|MB_ICONERROR); + g_pLogger1->SendAndFlushPerMode(_T("Unable to open device %s \r\n"), usb_strerror()); + g_machine.IsOffline=TRUE; + rStatus= SSI_STATUS_MOTION_DATALINK_ERROR; + } + else if (usb_set_configuration(g_dev, MY_CONFIG) < 0) + { + MessageBox(NULL, _T("Unable to SET CONFIGURATION"), _T("Message"), MB_OK|MB_ICONERROR); + g_machine.IsOffline=TRUE; + rStatus=SSI_STATUS_MOTION_DATALINK_ERROR; + } + else if (usb_claim_interface(g_dev, 0) < 0) + { + usb_close(g_dev); + MessageBox(NULL, _T("Unable to CLAIM DEVICE"), _T("Message"), MB_OK|MB_ICONERROR); + g_machine.IsOffline=TRUE; + rStatus=SSI_STATUS_MOTION_DATALINK_ERROR; + } + + g_pLogger1->SendAndFlushPerMode(_T("Init:Open device succeed .\r\n")); + + // ******************************************************************** + // This event is used to kick the Serial Usb Command process. This threading model + // is important because the underlying library is not thread-safe. + // + ep_buff[EP_02_CMD_IDX]._event = CreateEvent(NULL, // default security attributes + FALSE, // manual reset event object + NULL, // signaled + NULL); // unamed object + + g_hEP02_Thread_Id = CreateThread( (LPSECURITY_ATTRIBUTES) NULL, + 0, + (LPTHREAD_START_ROUTINE) g_EP02_Thread, + (LPVOID) this, + 0, + NULL); + g_hEP02_Thread_State = THREAD_RUNNING_STATE1; + + // ******************************************************************** + // Prepare and start EP_S07_81 Thread - Use async commit. + // + ep_buff[EP_82_DATA_IDX]._event = CreateEvent(NULL, // default security attributes + FALSE, // manual reset event object + NULL, // signaled + NULL); // unamed object + g_hEP8x_Thread_State = THREAD_PAUSED; + g_hEP8x_Thread_Id = CreateThread( (LPSECURITY_ATTRIBUTES) NULL, + 0, + (LPTHREAD_START_ROUTINE) g_EP8x_Thread, + (LPVOID) this, + 0, + NULL); + g_hEP02_Serial_Mutex = CreateMutex(NULL, // default security attributes + FALSE, // initial owner + NULL); // name + + // ********************************************************************* + g_hHomedEvent = CreateEvent(NULL, // default security attributes + TRUE, // manual reset event object + FALSE, // initial state is signaled + NULL); // unamed object + + return rStatus; +} + +//****************************************************************************** +SSI_STATUS_MOTION CSO7_Proto_Aux::Exit_SO7Usb() +{ + SSI_STATUS_MOTION Status=SSI_STATUS_MOTION_NORMAL; + + g_hEP8x_Thread_State = THREAD_EXIT; + g_hEP02_Thread_State = THREAD_EXIT; + + SetEvent(ep_buff[EP_82_DATA_IDX]._event); + if (g_hEP8x_Thread_Id) + { + DWORD dwCode = STILL_ACTIVE; + while (dwCode == STILL_ACTIVE) + { + GetExitCodeThread(g_hEP8x_Thread_Id,&dwCode); + Sleep(1); + } + } + + SetEvent(ep_buff[EP_02_CMD_IDX]._event); + if (g_hEP02_Thread_Id) + { + DWORD dwCode = STILL_ACTIVE; + while (dwCode == STILL_ACTIVE) + { + GetExitCodeThread(g_hEP02_Thread_Id,&dwCode); + Sleep(1); + } + } + + if (g_dev) + { + usb_release_interface(g_dev,0); + usb_close(g_dev); + g_dev = NULL; + } + + SetEvent(ep_buff[EP_82_DATA_IDX]._event); + CloseHandle(ep_buff[EP_82_DATA_IDX]._event); + SetEvent(ep_buff[EP_02_CMD_IDX]._event); + CloseHandle(ep_buff[EP_02_CMD_IDX]._event); + g_hEP02_Thread_State = THREAD_EXIT; + ReleaseMutex(g_hEP02_Serial_Mutex); + CloseHandle(g_hEP02_Serial_Mutex); + + g_pLogger1->SendAndFlushPerMode(_T("Exit: Exit_SO7Usb \r\n")); + return Status; +} + +//****************************************************************************** +usb_dev_handle* CSO7_Proto_Aux::_open_usb_dev(unsigned short sSeqNumber) +{ + struct usb_bus *bus = NULL; + struct usb_device *dev = NULL; + usb_dev_handle *udev = NULL; + + for (bus = usb_get_busses(); bus; bus = bus->next) + { + for (dev = bus->devices; dev; dev = dev->next) + { + if (dev->descriptor.idVendor == SEVENOCEAN_VID && dev->descriptor.idProduct == SEVENOCEAN_PID) + { + udev = usb_open(dev); + usb_claim_interface(udev, 0); + + if(Get_R_SeqNumber(udev) != sSeqNumber) + { + usb_close(udev); + } + else + { + return udev; + } + } + } + } + return NULL; +} + +//****************************************************************************** +int CSO7_Proto_Aux::Get_R_SeqNumber(usb_dev_handle *udev) +{ + memset(ep_buff[EP_02_CMD_IDX]._buffer, 0x00, MAX_BUFF_SIZE); + + *(ep_buff[EP_02_CMD_IDX]._buffer) = CT_DATA; + *(ep_buff[EP_02_CMD_IDX]._buffer+1) = CT_READ_SEQ_NUMBER; + + ep_buff[EP_02_CMD_IDX]._size = 0x02; + ep_buff[EP_82_DATA_IDX]._size = 0x01; + + int _ret; + _ret = usb_bulk_write(udev, ep_buff[2]._ep, (char *)ep_buff[2]._buffer,(int)ep_buff[2]._size, 50); + if (_ret < 0) + { + return -1; + } + + _ret = usb_bulk_read(udev, ep_buff[3]._ep, (char *)ep_buff[3]._buffer,(int)ep_buff[3]._size, 5000); + if (_ret < 0) + { + return -1; + } + + g_machine.SEQ_NUMBER = -1; + g_machine.SEQ_NUMBER = *(ep_buff[EP_82_DATA_IDX]._buffer); + return g_machine.SEQ_NUMBER; +} + +//=========================================================================== +// Worker Thread to serialize EP_S07_02 commands. +//=========================================================================== +unsigned __stdcall CSO7_Proto_Aux::g_EP02_Thread(LPVOID pThis) +{ + CSO7_Proto_Aux* _This = (CSO7_Proto_Aux*)pThis; + for (;;) + { + if (g_hEP02_Thread_State == THREAD_EXIT) + ExitThread(0); + WaitForSingleObject(ep_buff[EP_02_CMD_IDX]._event,INFINITE); + switch (g_hEP02_Thread_State) + { + case THREAD_EXIT: + { + ExitThread(0); + } + case THREAD_PAUSED: + break; + case THREAD_RUNNING_STATE1: + { + _This->_send_usb_cmd(EP_02_CMD_IDX); + break; + } + case THREAD_RUNNING_STATE2: + { + _This->_write_usb_data_only(EP_02_CMD_IDX); + break; + } + default: + ExitThread(0); + } + }; + g_hEP02_Thread_State = THREAD_EXIT; + ExitThread(0); +}; + +//****************************************************************************** +// This is the worker thread to process USBD_TRANSFER_DIRECTION_IN +//****************************************************************************** +unsigned __stdcall CSO7_Proto_Aux::g_EP8x_Thread(LPVOID pThis) +{ + CSO7_Proto_Aux* _This = (CSO7_Proto_Aux*)pThis; + for (;;) + { + if (g_hEP8x_Thread_State == THREAD_EXIT) + ExitThread(0); + WaitForSingleObject(ep_buff[EP_82_DATA_IDX]._event, INFINITE); + switch (g_hEP8x_Thread_State) + { + case THREAD_EXIT: + { + ExitThread(0); + } + case THREAD_PAUSED: + break; + case THREAD_RUNNING_STATE1: + { + _This->_read_data_8x(EP_81_DATA_IDX); + break; + } + case THREAD_RUNNING_STATE2: + { + _This->_read_data_8x(EP_82_DATA_IDX); + break; + } + default: + ExitThread(0); + } + } +} + +//=============================================================================== +// _send_usb_cmd(iEP) sends data to the corresponding iEP channel. +// iEP = EP_S07_01 / EP_S07_02 EP_S07_01 = 0x01; EP_S07_02 = 0x02; +//=============================================================================== +SSI_STATUS_MOTION CSO7_Proto_Aux::_send_usb_cmd(int iEP_Base) +{ + if (g_machine.IsOffline) + { + SetEvent(ep_buff[iEP_Base+1]._event); + ep_buff[iEP_Base]._hProtoPending = false; + return SSI_STATUS_MOTION_NORMAL; + } + int _ret; + ep_buff[iEP_Base]._save_send_cmd = ep_buff[iEP_Base]._buffer[0]; + ep_buff[iEP_Base]._save_send_cmd0 = ep_buff[iEP_Base]._buffer[1]; + ep_buff[iEP_Base]._save_send_cmd1 = ep_buff[iEP_Base]._buffer[2]; + + _ret = usb_bulk_write(g_dev, ep_buff[iEP_Base]._ep, (char *)ep_buff[iEP_Base]._buffer,(int) ep_buff[iEP_Base]._size, 50); + if (_ret < 0) + { + TRACE("Write Timeout \n"); + ASSERT(0); + return SSI_STATUS_MOTION_TIMEOUT; + } + + SetEvent(ep_buff[iEP_Base+1]._event); + ep_buff[iEP_Base]._hProtoPending = false; + return SSI_STATUS_MOTION_NORMAL; +} + +//=============================================================================== +// _write_usb_data_only(iEP) sends data to the corresponding iEP channel.No need to +//process the reap async +// iEP = EP_S07_01 / EP_S07_02 EP_S07_01 = 0x01; EP_S07_02 = 0x02; +//=============================================================================== +SSI_STATUS_MOTION CSO7_Proto_Aux::_write_usb_data_only(int iEP_Base) +{ + if (g_machine.IsOffline) + { + ep_buff[iEP_Base]._hProtoPending = false; + ep_buff[iEP_Base+1]._hProtoPending = false; + return SSI_STATUS_MOTION_NORMAL; + } + int _ret; + ep_buff[iEP_Base]._save_send_cmd = ep_buff[iEP_Base]._buffer[0]; + ep_buff[iEP_Base]._save_send_cmd0 = ep_buff[iEP_Base]._buffer[1]; + ep_buff[iEP_Base]._save_send_cmd1 = ep_buff[iEP_Base]._buffer[2]; + + //TRACE3("_send_usb_cmd() iEP : %X - ep_buff[iEP]._save_send_cmd : %X ._buffer[0] : %X\r\n", iEP_Base, ep_buff[iEP_Base]._save_send_cmd, ep_buff[iEP_Base]._buffer[0]); + + _ret = usb_bulk_write(g_dev, ep_buff[iEP_Base]._ep, (char *)ep_buff[iEP_Base]._buffer,(int) ep_buff[iEP_Base]._size, 50); + if (_ret < 0) + { + TRACE("Write Timeout \n"); + ASSERT(0); + return SSI_STATUS_MOTION_TIMEOUT; + } + ep_buff[iEP_Base]._hProtoPending = false; + ep_buff[iEP_Base+1]._hProtoPending = false; + return SSI_STATUS_MOTION_NORMAL; +} + +//=============================================================================== +// iEP_Base : EP_81_DATA_IDX/EP_82_DATA_IDX +//=============================================================================== +SSI_STATUS_MOTION CSO7_Proto_Aux::_read_data_8x(int iEP_Base) +{ + if (g_machine.IsOffline) + { + ep_buff[EP_82_DATA_IDX]._hProtoPending = false; + ep_buff[EP_01_CMD_IDX]._hProtoPending = false; + ep_buff[EP_81_DATA_IDX]._hProtoPending = false; + return SSI_STATUS_MOTION_NORMAL; + } + if (iEP_Base == EP_82_DATA_IDX) + { + int _ret; + _ret = usb_bulk_read(g_dev, ep_buff[iEP_Base]._ep, (char *)ep_buff[iEP_Base]._buffer,(int) ep_buff[iEP_Base]._size, 5000); + if (_ret > 0) + { + _process_rcv_transfer_data(iEP_Base); + ep_buff[EP_82_DATA_IDX]._hProtoPending = false; + } + else + { + TRACE1("Read Timeout %xx\n", *((char *)ep_buff[iEP_Base]._buffer)); + ASSERT(0); + return SSI_STATUS_MOTION_TIMEOUT; + } + return SSI_STATUS_MOTION_NORMAL; + } + else + { + int _ret; + _ret = usb_interrupt_read(g_dev, ep_buff[iEP_Base]._ep, (char *)ep_buff[iEP_Base]._buffer,(int) ep_buff[iEP_Base]._size, 20); + if (_ret > 0) + { + _process_rcv_transfer_data(iEP_Base); + } + else + { + g_machine.InterruptFlag[0] = 0; + TRACE1("There is no data interrupt read from controller. %xx\n", *((char *)ep_buff[iEP_Base]._buffer)); + } + + ep_buff[EP_01_CMD_IDX]._hProtoPending = false; + ep_buff[EP_81_DATA_IDX]._hProtoPending = false; + return SSI_STATUS_MOTION_NORMAL; + } +} + +//****************************************************************************** +// Parse the data received based on the index (which EP are we processing). +// The CCmdObj should only have one CMD_STATUS_PROCESSING. +// Update CCmdObj _ep_01_status and _ep_81_status. +// Update _status to CMD_STATUS_COMPLETE when both _ep_01_status and _ep_81_status +// are CMD_STATUS_COMPLETE. +// +//****************************************************************************** +void CSO7_Proto_Aux::_process_rcv_transfer_data(int iEP) +{ + switch (iEP) + { + case EP_01_CMD_IDX : + TRACE0("_process_rcv_transfer_data() : Update EP_01_CMD_IDX.\r\n"); + break; + case EP_82_DATA_IDX : // + if(ep_buff[EP_02_CMD_IDX]._save_send_cmd == CT_DATA) + { + switch (ep_buff[EP_02_CMD_IDX]._save_send_cmd0) + { + case CT_READ_AXISXYZ: + _process_SO7_CMD_READ_AXIS_R(); + break; + case CT_READ_SEC_REALY: + _process_SO7_CMD_READ_ZSIGNAL_POS_R(); + break; + + default: + TRACE1("_process_rcv_transfer_data() : Unknown ep_buff[EP_02_CMD_IDX]._save_send_cmd : %X \r\n", ep_buff[EP_02_CMD_IDX]._save_send_cmd); + TRACE1("_process_rcv_transfer_data() : Unknown ep_buff[EP_81_DATA_IDX]._buffer[0] : %X \r\n", ep_buff[EP_81_DATA_IDX]._buffer[0]); + break; + }; + } + break; + case EP_02_CMD_IDX : + TRACE0("_process_rcv_transfer_data() : Update EP_02_CMD_IDX.\r\n"); + break; + case EP_81_DATA_IDX : + + TRACE0("_process_rcv_transfer_data() : Update EP_81_DATA_IDX.\r\n"); + break; + default: + break; + }; +}; + +//****************************************************************************** +// Kick the g_hEP01_Thread_Event to get the g_EP01_Thread going. +// iEP = EP_S07_01 or EP_S07_02 = 0x01 or 0x02 +//****************************************************************************** +SSI_STATUS_MOTION CSO7_Proto_Aux::_do_single_threaded_usb_comm(int iEP_Base) +{ + while ((ep_buff[iEP_Base]._hProtoPending == TRUE) || (ep_buff[iEP_Base+1]._hProtoPending == TRUE)) + { + ASSERT(0); + Sleep(3); + } + ep_buff[iEP_Base]._hProtoPending = ep_buff[iEP_Base+1]._hProtoPending = TRUE; + + if (iEP_Base == EP_01_CMD_IDX) + SetEvent(ep_buff[EP_82_DATA_IDX]._event); + else + SetEvent(ep_buff[iEP_Base]._event); + while ((ep_buff[iEP_Base]._hProtoPending == TRUE) || (ep_buff[iEP_Base+1]._hProtoPending == TRUE)) + { + Sleep(3); + } + + return SSI_STATUS_MOTION_NORMAL; +} + +//============================================================== +SSI_STATUS_MOTION CSO7_Proto_Aux::_process_SO7_CMD_READ_AXIS_R() +{ + g_machine.r._scale_pos._long_=0; + g_machine.r._scale_pos._char_[2] = *(ep_buff[EP_82_DATA_IDX]._buffer); + g_machine.r._scale_pos._char_[1] = *(ep_buff[EP_82_DATA_IDX]._buffer+1); + g_machine.r._scale_pos._char_[0] = *(ep_buff[EP_82_DATA_IDX]._buffer+2); + g_machine.r._scale_pos._char_[3] = 0; + if (g_machine.r._scale_pos._long_ > 8388608) + g_machine.r._scale_pos._long_ = g_machine.r._scale_pos._long_ - 16777216; + + return SSI_STATUS_MOTION_NORMAL; +}; + +//============================================================== +SSI_STATUS_MOTION CSO7_Proto_Aux::_process_SO7_CMD_READ_ZSIGNAL_POS_R() +{ + g_machine.r._ZSignal_pos._char_[2] = *(ep_buff[EP_82_DATA_IDX]._buffer); + g_machine.r._ZSignal_pos._char_[1] = *(ep_buff[EP_82_DATA_IDX]._buffer+1); + g_machine.r._ZSignal_pos._char_[0] = *(ep_buff[EP_82_DATA_IDX]._buffer+2); + g_machine.r._ZSignal_pos._char_[3] = 0; + + if (g_machine.r._ZSignal_pos._long_ > 8388608) + g_machine.r._ZSignal_pos._long_=g_machine.r._ZSignal_pos._long_-16777216; + + return SSI_STATUS_MOTION_NORMAL; +} + +//============================================================== +SSI_STATUS_MOTION CSO7_Proto_Aux::_send_cmd_SO7_CMD_RESET_R(int iType) +{ + iType++; + WaitForSingleObject(g_hEP02_Serial_Mutex, INFINITE); + memset(ep_buff[EP_02_CMD_IDX]._buffer, 0x00, MAX_BUFF_SIZE); + + *(ep_buff[EP_02_CMD_IDX]._buffer) = CT_SCALE; + *(ep_buff[EP_02_CMD_IDX]._buffer+1) = CT_SET_RESET_FLAG; + *(ep_buff[EP_02_CMD_IDX]._buffer+2) = 0x01; + + ep_buff[EP_02_CMD_IDX]._size = 0x03; + ep_buff[EP_82_DATA_IDX]._size = 0x02; + + g_hEP02_Thread_State=THREAD_RUNNING_STATE2; + _do_single_threaded_usb_comm(EP_02_CMD_IDX); + ReleaseMutex(g_hEP02_Serial_Mutex); + return SSI_STATUS_MOTION_NORMAL; +}; + +//============================================================== +SSI_STATUS_MOTION CSO7_Proto_Aux::_send_cmd_SO7_CMD_MOVE_R(int iType, int iMoveAngle) +{ + WaitForSingleObject(g_hEP02_Serial_Mutex, INFINITE); + memset(ep_buff[EP_02_CMD_IDX]._buffer, 0x00, MAX_BUFF_SIZE); + + g_machine.r._pos_fixed._long_ = (ONE_R_PULSE * iMoveAngle / 360); + *(ep_buff[EP_02_CMD_IDX]._buffer) = CT_MOTOR; + if(iType) + { + *(ep_buff[EP_02_CMD_IDX]._buffer+1) = CT_MOVETOY; + } + else + { + *(ep_buff[EP_02_CMD_IDX]._buffer+1) = CT_MOVETOX; + } + *(ep_buff[EP_02_CMD_IDX]._buffer+2)=(((g_machine.r._pos_fixed._char_[3])<0x80)?(g_machine.r._pos_fixed._char_[2]):((g_machine.r._pos_fixed._char_[2])|0x80));//最高位 + *(ep_buff[EP_02_CMD_IDX]._buffer+3)=(g_machine.r._pos_fixed._char_[1]); + *(ep_buff[EP_02_CMD_IDX]._buffer+4)=(g_machine.r._pos_fixed._char_[0]); + + ep_buff[EP_02_CMD_IDX]._size = 0x07; + ep_buff[EP_81_DATA_IDX]._size = 0x07; + + g_hEP02_Thread_State = THREAD_RUNNING_STATE2; + _do_single_threaded_usb_comm(EP_02_CMD_IDX); + ReleaseMutex(g_hEP02_Serial_Mutex); + return SSI_STATUS_MOTION_NORMAL; +}; + +//============================================================== +SSI_STATUS_MOTION CSO7_Proto_Aux::_send_cmd_SO7_CMD_READ_AXIS_R() +{ + WaitForSingleObject(g_hEP02_Serial_Mutex, INFINITE); + memset(ep_buff[EP_02_CMD_IDX]._buffer, 0x00, MAX_BUFF_SIZE); + + *(ep_buff[EP_02_CMD_IDX]._buffer) = CT_DATA; + *(ep_buff[EP_02_CMD_IDX]._buffer+1) = CT_READ_AXISXYZ; + *(ep_buff[EP_02_CMD_IDX]._buffer+2)=0x00; + + ep_buff[EP_02_CMD_IDX]._size = 0x03; + ep_buff[EP_82_DATA_IDX]._size = 0x09; + + g_hEP02_Thread_State=THREAD_RUNNING_STATE1; + g_hEP8x_Thread_State=THREAD_RUNNING_STATE2; + _do_single_threaded_usb_comm(EP_02_CMD_IDX); + ReleaseMutex(g_hEP02_Serial_Mutex); + return SSI_STATUS_MOTION_NORMAL; +}; + +//============================================================== +SSI_STATUS_MOTION CSO7_Proto_Aux::_send_cmd_SO7_CMD_READ_ZSIGNAL_POS_R(int iType) +{ + WaitForSingleObject(g_hEP02_Serial_Mutex, INFINITE); + memset(ep_buff[EP_02_CMD_IDX]._buffer, 0x00, MAX_BUFF_SIZE); + + *(ep_buff[EP_02_CMD_IDX]._buffer) = CT_DATA; + if(iType) + { + *(ep_buff[EP_02_CMD_IDX]._buffer+1) = CT_READ_SEC_REALY; + } + else + { + *(ep_buff[EP_02_CMD_IDX]._buffer+1) = CT_READ_SEC_REALX; + } + *(ep_buff[EP_02_CMD_IDX]._buffer+2)=0; + + ep_buff[EP_02_CMD_IDX]._size = 0x03; + ep_buff[EP_82_DATA_IDX]._size = 0x03; + + g_hEP02_Thread_State=THREAD_RUNNING_STATE1; + g_hEP8x_Thread_State=THREAD_RUNNING_STATE2; + _do_single_threaded_usb_comm(EP_02_CMD_IDX); + ReleaseMutex(g_hEP02_Serial_Mutex); + return SSI_STATUS_MOTION_NORMAL; +} + +//****************************************************************************** +long CSO7_Proto_Aux::GetRCurrentPosition(int iType) +{ + long ztos = -1; + _send_cmd_SO7_CMD_READ_AXIS_R(); + _send_cmd_SO7_CMD_READ_ZSIGNAL_POS_R(iType); + ztos = abs(g_machine.r._scale_pos._long_ - g_machine.r._ZSignal_pos._long_); + if(ztos > 8388608) + { + ztos = ztos - 9413433; + } + + return (ztos * 360 / 4720000); +} + + +//============================================================== +SSI_STATUS_MOTION CSO7_Proto_Aux::_send_cmd_SO7_CMD_STOP_R(int iType) +{ + iType++; + WaitForSingleObject(g_hEP02_Serial_Mutex, INFINITE); + memset(ep_buff[EP_02_CMD_IDX]._buffer, 0x00, MAX_BUFF_SIZE); + + *(ep_buff[EP_02_CMD_IDX]._buffer) = CT_MOTOR; + *(ep_buff[EP_02_CMD_IDX]._buffer+1) = CT_STOPA; + *(ep_buff[EP_02_CMD_IDX]._buffer+2)=0x00; + + TRACE("[STOP_R]\n"); + + ep_buff[EP_02_CMD_IDX]._size = 0x04; + ep_buff[EP_81_DATA_IDX]._size = 0x04; + + g_hEP02_Thread_State=THREAD_RUNNING_STATE2; + _do_single_threaded_usb_comm(EP_02_CMD_IDX); + ReleaseMutex(g_hEP02_Serial_Mutex); + return SSI_STATUS_MOTION_NORMAL; +}; + +//============================================================== +SSI_STATUS_MOTION CSO7_Proto_Aux::_send_cmd_SO7_CMD_SET_SEQ_NUMBER() +{ + WaitForSingleObject(g_hEP02_Serial_Mutex, INFINITE); + memset(ep_buff[EP_02_CMD_IDX]._buffer, 0x00, MAX_BUFF_SIZE); + + *(ep_buff[EP_02_CMD_IDX]._buffer) = CT_DATA; + *(ep_buff[EP_02_CMD_IDX]._buffer+1) = CT_WRITE_SEQ_NUMBER; + *(ep_buff[EP_02_CMD_IDX]._buffer+2)=g_machine.SEQ_NUMBER; + + ep_buff[EP_02_CMD_IDX]._size = 0x03; + ep_buff[EP_81_DATA_IDX]._size = 0x45; + + g_hEP02_Thread_State=THREAD_RUNNING_STATE2; + _do_single_threaded_usb_comm(EP_02_CMD_IDX); + ReleaseMutex(g_hEP02_Serial_Mutex); + return SSI_STATUS_MOTION_NORMAL; +} \ No newline at end of file diff --git a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto_Aux.h b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto_Aux.h new file mode 100644 index 0000000..25e08be --- /dev/null +++ b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/SO7_Proto_Aux.h @@ -0,0 +1,304 @@ +// protocol for control SevenOcean's Machine +// +////////////////////////////////////////////////////////////////////// +#ifndef AFX_SO7_Proto_Aux_H__B422904C_2CEB_495B_B7BD_B45AB30286DD__INCLUDED_ + #define AFX_SO7_Proto_Aux_H__B422904C_2CEB_495B_B7BD_B45AB30286DD__INCLUDED_ + +#if _MSC_VER > 1000 + #pragma once +#endif // _MSC_VER > 1000 + +#include "..\Tools\UsbUtility\logger.h" +#include "CMD_H.h" +#include "..\..\..\..\..\ThirdParty\UsbSupport\LibUsb_Win\Include\lusb0_usb.h" +#include "..\MicroVu\SsiStatus.h" + +#define MAX_BUFF_SIZE 0x200 +#define USB_R_SEQ_NUMBER 1 +#define RSPEEDGEAR 1 +#define ONE_R_PULSE 590000 +#define TYPER1 0 +#define TYPER2 1 + +#define USB_ENDPOINT_TYPE_CONTROL 0 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 1 +#define USB_ENDPOINT_TYPE_BULK 2 +#define USB_ENDPOINT_TYPE_INTERRUPT 3 + +#define USB_DEVICE_DESCRIPTOR_TYPE 1 +#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 + +#define THREAD_RUNNING_STATE1 0 +#define THREAD_RUNNING_STATE2 2 +#define THREAD_PAUSED 1 +#define THREAD_EXIT -1 + +// Device configuration and interface id. +#define SO7_USB_CONFIG 1 +#define SO7_USB_INTF 0 + +#define EP_S07_01 0x01 +#define EP_S07_02 0x02 +#define EP_S07_03 0x03 +#define EP_S07_81 0x81 +#define EP_S07_82 0x82 +#define EP_S07_84 0x84 + +#define EP_01_CMD_IDX 0 // index to usb buffers +#define EP_81_DATA_IDX 1 // +#define EP_02_CMD_IDX 2 // +#define EP_82_DATA_IDX 3 // +#define EP_03_CMD_IDX 4 // +#define EP_84_DATA_IDX 5 // + +#define lEPSIZE 6 +#define MAXRINGS 5 // for MicroVu Vertex 220 +#define MAXSEGS 8 + +#define TWO_RINGS 2 +#define EIGHT_SEGS 8 +#define FIVE_RINGS 5 + +enum EMACHINERTYPE +{ + MACHINE_SO7_R_CONTROLLER, + MACHINE_METRONICS_CONTROLLER_R, + MACHINE_TOTAL_R=255 +}; +enum EFirmwareRVer +{ + FirmwareVer_3_X_R=0, + FirmwareVer_6_X_R, + FirmwareVer_Total_R +}; + +#pragma pack(push) +#pragma pack(1) +//**************************************************************************************************** +// Set the _status to Idle after reply data has been received. +// How to recover? In order to send data, _status must be Idle. If the system is not available +// for 1 second, assume something wrong and treat it as "TimeOut". +// Another way to do this is to lock this structure is to use a mutex to ensure single-threaded +// access. +//**************************************************************************************************** +//==================================================================================================== + +typedef struct s_so7_r_axis // axis parameters +{ + char _Move_Speed_Gear; + char _MoveTo_Speed_Gear; + union + { + long _long_; + char _char_[4]; + }_pos_fixed; + union + { + long _long_; + char _char_[4]; + }_scale_pos; + union + { + long _long_; + char _char_[4]; + }_ZSignal_pos; + double _d_cur_pos_; + long _scale_probe; + double _dSet_Zero_Pos; + long _lSet_Zero_Pos; +} SO7RAXIS; + +struct s_so7_r_axis_config // axis configuration +{ + double _motor_precision;//set precision + double _motor_wheelbase;//set wheelbase + char _speed_base[5]; + char _speed_fresh[5]; + char _speed_start[5]; + char _speed_max[5]; + double _speed_slow_dis[5]; + + double _MoveToSpeed[2]; + double _MotionSpeedScale; + + long _scale_range; + double _neg_working_limit; + double _pos_working_limit; + double _scale_resolution; + bool _bhomed; +}; + +struct s_so7_r_machine_interface_config +{ + BOOL _EnCloseLoop; + int _RetryTimes; + double _ShiftPositionR; + char GetInterruptMsgMethod; + INT m_WriteDataSleepTime; + INT m_AccuraErrPulseR; + INT m_EQUIDIS_R; + INT m_SDK3000_CntThreadSleepVal; + INT m_SV4000E_DenoisePara[4]; + INT m_MachineType; + INT m_VideoCardType; +}; + +//====================== +typedef struct s_so7_r +{ + bool bFast; + long from; + long to; + long speed; + long acc; + long dec; + double dFromMM; + double dToMM; +} SO7RAXISMOVE; +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- +struct struct_so7_r_machine +{ // g_machine structure + struct s_machine_r_config + { + double _dRSpeed[2]; + + struct s_so7_r_axis_config r_axis; + struct s_so7_r_machine_interface_config motion; + } s_machine_r_config; + + struct s_rstatus + { + bool _homed; + bool _machine_running; + bool _bRMoving; + char _bIsZMMotionFinished; + bool _bRIdle; + } s_rstatus; + + char ADC_Number; + int ADC_Value; + char Sys_Reset_Flag; + char cVerNumber; + char InterruptFlag[2]; + char FPGAData; + char InPortStatus; + int _motor_pulse_num; + char FirmwareInfo[10]; + int FirmwareVer; + char GetInterruptMsg[20][2]; + BOOL IsOffline; + BOOL IsSupportReadInterrputMsg; + double dRotaryCirclDis; + char SEQ_NUMBER; + struct s_so7_r_axis r; + struct s_so7_r_axis r1; +}; + +#define SEVENOCEAN_VID 0x4532 +#define SEVENOCEAN_PID 0x5567 +//**************************************************************************************************** +// Binary SevenOcean command structure, out going +// +//**************************************************************************************************** +#define pSO7_CMD_02 ((s_SO7_CMD_BUFF_02 *) ep_buff[EP_02_CMD_IDX]._buffer) + +struct s_SO7_R_CMD_BUFF_02 +{ + UCHAR uCmdByte; + union + { + struct + { + BYTE uSubCmdByte; + char data[12]; + }s_SO7_CMD_MOVE_TO_XYZ; + struct + { + BYTE uSubCmdByte; + char data[12]; + }s_SO7_CMD_MOVETOXYZV; + struct + { + BYTE uSubCmdByte; + BYTE uStartCmdByte; + char _bottom_light; + char _top_light; + char _ring_light; + char _coaxial_light; + char _spare_light1; + char _outer_ring_light_switch; + char _inner_ring_light_switch; + BYTE uEndCmdByte; + }s_SO7_CMD_SET_LIGHT; + }; +}; + +#pragma pack(pop) + +//====================== +struct struct_so7_r_ep_buff +{ + int _ep; + BYTE _save_send_cmd; + BYTE _save_send_cmd0; + BYTE _save_send_cmd1; + char *_buffer; // MAX_BUFF_SIZE + int _size; + void *_async_context; + BOOL _hProtoPending; + HANDLE _event; +}; + +//====================================================================================== +class CSO7_Proto_Aux +{ +public: + // EP 81/82 channel threads. + static int g_hEP8x_Thread_State; + static unsigned __stdcall g_EP8x_Thread(LPVOID pThis); + static HANDLE g_hEP8x_Thread_Id; + + // EP 02channel threads. + static int g_hEP02_Thread_State; + static unsigned __stdcall g_EP02_Thread(LPVOID pThis); + static HANDLE g_hEP02_Thread_Id; + static HANDLE g_hEP02_Serial_Mutex; // EP02 + + static HANDLE g_hHomedEvent; + + static struct_so7_r_ep_buff ep_buff[lEPSIZE]; + static struct_so7_r_machine g_machine; + + static CLogger* g_pLogger1; + static usb_dev_handle *g_dev; + bool m_bHomingActive; + + // + CSO7_Proto_Aux(); + virtual ~CSO7_Proto_Aux(); + + // Global Structures + SSI_STATUS_MOTION Init_SO7Usb(); + SSI_STATUS_MOTION Exit_SO7Usb(); + + usb_dev_handle* _open_usb_dev(unsigned short sSeqNumber); + int Get_R_SeqNumber(usb_dev_handle *udev); + SSI_STATUS_MOTION _send_usb_cmd(int iEP_Base); + SSI_STATUS_MOTION _write_usb_data_only(int iEP_Base); + SSI_STATUS_MOTION _read_data_8x(int iEP_Base); + static void _process_rcv_transfer_data(int iEP); + SSI_STATUS_MOTION _do_single_threaded_usb_comm(int iEP); + + static SSI_STATUS_MOTION _process_SO7_CMD_READ_AXIS_R(); + static SSI_STATUS_MOTION _process_SO7_CMD_READ_ZSIGNAL_POS_R(); + SSI_STATUS_MOTION _send_cmd_SO7_CMD_RESET_R(int iType); + SSI_STATUS_MOTION _send_cmd_SO7_CMD_MOVE_R(int iType, int iMoveAngle); + SSI_STATUS_MOTION _send_cmd_SO7_CMD_READ_AXIS_R(); + SSI_STATUS_MOTION _send_cmd_SO7_CMD_READ_ZSIGNAL_POS_R(int iType); + long GetRCurrentPosition(int iType); + SSI_STATUS_MOTION _send_cmd_SO7_CMD_STOP_R(int iType); + SSI_STATUS_MOTION _send_cmd_SO7_CMD_SET_SEQ_NUMBER(); +}; +#endif diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/Debug/UtilityDebug.Log b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/Debug/UtilityDebug.Log index c07f320..c70f4ee 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/Debug/UtilityDebug.Log +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/Debug/UtilityDebug.Log @@ -4171,7 +4171,9 @@ _start_machine Exit: Exit_SO7Usb Destruct Cso7_Proto. Construct Cso7_Proto. -Init:Open device succeed . +Unable to open device Init:Open device succeed . +Construct Cso7_Proto. +Unable to open device Init:Open device succeed . _start_machine Exit: Exit_SO7Usb Destruct Cso7_Proto. @@ -4182,29 +4184,74 @@ Exit: Exit_SO7Usb Destruct Cso7_Proto. Construct Cso7_Proto. Init:Open device succeed . +Unable to open device Init:Open device succeed . +Destruct Cso7_Proto. +Construct Cso7_Proto. +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . _start_machine Exit: Exit_SO7Usb Destruct Cso7_Proto. Construct Cso7_Proto. +Construct Cso7_Proto. +Destruct Cso7_Proto. +Construct Cso7_Proto. +Destruct Cso7_Proto. +Construct Cso7_Proto. +Destruct Cso7_Proto. +Construct Cso7_Proto. Init:Open device succeed . _start_machine Exit: Exit_SO7Usb Destruct Cso7_Proto. Construct Cso7_Proto. Init:Open device succeed . -_start_machine -Exit: Exit_SO7Usb +Construct Cso7_Proto. +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . +Construct Cso7_Proto. +Destruct Cso7_Proto. +Construct Cso7_Proto. +Destruct Cso7_Proto. +Construct Cso7_Proto. Init:Open device succeed . _start_machine Exit: Exit_SO7Usb Destruct Cso7_Proto. Construct Cso7_Proto. Init:Open device succeed . +Construct Cso7_Proto. +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . +Construct Cso7_Proto. +Init:Open device succeed . _start_machine Exit: Exit_SO7Usb Init:Open device succeed . _start_machine Exit: Exit_SO7Usb +Unable to open device Init:Open device succeed . +_start_machine +Exit: Exit_SO7Usb +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . +_start_machine +Construct Cso7_Proto. +Init:Open device succeed . +_start_machine +Construct Cso7_Proto. +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . +_start_machine +Exit: Exit_SO7Usb Init:Open device succeed . _start_machine Exit: Exit_SO7Usb @@ -4226,6 +4273,25 @@ Exit: Exit_SO7Usb Destruct Cso7_Proto. Construct Cso7_Proto. Init:Open device succeed . +Destruct Cso7_Proto. +Construct Cso7_Proto. +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . +_start_machine +Exit: Exit_SO7Usb +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . +Construct Cso7_Proto. +Init:Open device succeed . +_start_machine +Exit: Exit_SO7Usb +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . +Construct Cso7_Proto. +Init:Open device succeed . _start_machine Exit: Exit_SO7Usb Destruct Cso7_Proto. @@ -4236,6 +4302,33 @@ Exit: Exit_SO7Usb Destruct Cso7_Proto. Construct Cso7_Proto. Init:Open device succeed . +Exit: Exit_SO7Usb +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . +_start_machine +Exit: Exit_SO7Usb +Init:Open device succeed . +_start_machine +Exit: Exit_SO7Usb +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . +Exit: Exit_SO7Usb +Construct Cso7_Proto. +Init:Open device succeed . +Exit: Exit_SO7Usb +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . +Exit: Exit_SO7Usb +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . +Exit: Exit_SO7Usb +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . _start_machine Exit: Exit_SO7Usb Init:Open device succeed . @@ -4251,6 +4344,43 @@ Construct Cso7_Proto. Destruct Cso7_Proto. Construct Cso7_Proto. Init:Open device succeed . +Exit: Exit_SO7Usb +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . +Exit: Exit_SO7Usb +Construct Cso7_Proto. +Init:Open device succeed . +Exit: Exit_SO7Usb +Construct Cso7_Proto. +Init:Open device succeed . +_start_machine +Exit: Exit_SO7Usb +Init:Open device succeed . +_start_machine +Exit: Exit_SO7Usb +Destruct Cso7_Proto. +Construct Cso7_Proto. +Construct Cso7_Proto. +Destruct Cso7_Proto. +Construct Cso7_Proto. +Init:Open device succeed . +Construct Cso7_Proto. +Init:Open device succeed . +Exit: Exit_SO7Usb +Construct Cso7_Proto. +Init:Open device succeed . +Exit: Exit_SO7Usb +Construct Cso7_Proto. +Init:Open device succeed . +Exit: Exit_SO7Usb +Init:Open device succeed . +Exit: Exit_SO7Usb +Construct Cso7_Proto. +Init:Open device succeed . +Exit: Exit_SO7Usb +Construct Cso7_Proto. +Unable to open device Init:Open device succeed . _start_machine Exit: Exit_SO7Usb Destruct Cso7_Proto. diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc index f2f886c..ce9152c 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc @@ -16,7 +16,7 @@ #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// -// Chinese (Simplified, PRC) resources +// 中文(简体,中国) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED @@ -401,24 +401,25 @@ CAPTION "Utility for SO7" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN CONTROL "SDK3000视频卡",IDC_RADIO_VIDEOCARD_SDK3000,"Button",BS_AUTORADIOBUTTON | WS_GROUP,39,39,69,10 - CONTROL "SV2000E视频卡",IDC_RADIO_VIDEOCARD_SV2000E,"Button",BS_AUTORADIOBUTTON,39,56,69,10 - CONTROL "SV4000E视频卡",IDC_RADIO_VIDEOCARD_SV4000E,"Button",BS_AUTORADIOBUTTON,39,73,68,10 - CONTROL "TC4000视频卡",IDC_RADIO_VIDEOCARD_TC4000,"Button",BS_AUTORADIOBUTTON,39,90,69,10 - CONTROL "IP Camera",IDC_RADIO_SO7_IP_CAMERA,"Button",BS_AUTORADIOBUTTON,39,107,62,10 - CONTROL "USB Camera",IDC_RADIO_SO7_USB_CAMERA,"Button",BS_AUTORADIOBUTTON,39,124,62,10 + CONTROL "SV2000E视频卡",IDC_RADIO_VIDEOCARD_SV2000E,"Button",BS_AUTORADIOBUTTON,39,55,69,10 + CONTROL "SV4000E视频卡",IDC_RADIO_VIDEOCARD_SV4000E,"Button",BS_AUTORADIOBUTTON,39,71,68,10 + CONTROL "TC4000视频卡",IDC_RADIO_VIDEOCARD_TC4000,"Button",BS_AUTORADIOBUTTON,39,87,69,10 + CONTROL "IP Camera",IDC_RADIO_SO7_IP_CAMERA,"Button",BS_AUTORADIOBUTTON,39,103,62,10 + CONTROL "USB Camera",IDC_RADIO_SO7_USB_CAMERA,"Button",BS_AUTORADIOBUTTON,39,119,62,10 CONTROL "控制器(USB)",IDC_RADIO_CONTROLLER,"Button",BS_AUTORADIOBUTTON,166,39,69,10 - CONTROL "控制器(RS232)",IDC_RADIO__SO7_RS232,"Button",BS_AUTORADIOBUTTON,166,56,77,10 - CONTROL "LK_G激光",IDC_RADIO_KEYENCE_LASER,"Button",BS_AUTORADIOBUTTON,166,73,76,10 - CONTROL "LK_H激光(USB)",IDC_RADIO_KEYENCE_LASER_LK_H,"Button",BS_AUTORADIOBUTTON,166,90,76,10 + CONTROL "控制器(RS232)",IDC_RADIO__SO7_RS232,"Button",BS_AUTORADIOBUTTON,166,71,77,10 + CONTROL "LK_G激光",IDC_RADIO_KEYENCE_LASER,"Button",BS_AUTORADIOBUTTON,166,87,76,10 + CONTROL "LK_H激光(USB)",IDC_RADIO_KEYENCE_LASER_LK_H,"Button",BS_AUTORADIOBUTTON,166,103,76,10 CONTROL "LK_H激光(ETHERNET)",IDC_RADIO_KEYENCE_LASER_LKH_ETHERNET, - "Button",BS_AUTORADIOBUTTON,166,107,85,10 - CONTROL "LJ_G激光",IDC_RADIO_KEYENCE_LASER3,"Button",BS_AUTORADIOBUTTON,166,124,76,10 + "Button",BS_AUTORADIOBUTTON,166,119,85,10 + CONTROL "LJ_G激光",IDC_RADIO_KEYENCE_LASER3,"Button",BS_AUTORADIOBUTTON,166,135,76,10 CONTROL "Verifcation algorithm",IDC_RADIO_SO7_VERIFICATION_ALGORITHM, - "Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE,39,141,81,10 - CONTROL "Image.dll",IDC_RADIO_TEST_IMAGE_DLL,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE,166,141,45,10 + "Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE,39,135,81,10 + CONTROL "Image.dll",IDC_RADIO_TEST_IMAGE_DLL,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE,39,151,45,10 DEFPUSHBUTTON "OK",IDOK,163,177,50,14 PUSHBUTTON "Cancel",IDCANCEL,221,177,50,14 - GROUPBOX "测试选项",IDC_STATIC,20,15,242,146 + GROUPBOX "测试选项",IDC_STATIC,20,15,242,157 + CONTROL "控制器(USB R)",IDC_RADIO_CONTROLLER2,"Button",BS_AUTORADIOBUTTON,166,55,75,10 END IDD_SO7_VIDEOCARD_SDK3000 DIALOGEX 0, 0, 488, 316 @@ -909,6 +910,37 @@ BEGIN PUSHBUTTON "Stop Scan",IDC_BTN_KEYENCE_LKG5000_ETHERNET_STOP_SCAN2,313,86,50,14 END +IDD_SO7_UTIL_USBCTLR DIALOGEX 0, 0, 216, 251 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "USB Control R1/R2" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + PUSHBUTTON "Exit",IDCANCEL,170,230,39,14 + GROUPBOX "USB_R Control",IDC_STATIC,17,12,181,216 + CONTROL "Enable R1",IDC_CHECK_SO7_R1_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,31,58,48,10 + PUSHBUTTON "Init_Machine",IDC_BUTTON_START_SO7_R_MACHINE,43,24,63,18 + PUSHBUTTON "Stop_Machine",IDC_BUTTON_STOP_SO7_R_MACHINE,108,24,63,18 + PUSHBUTTON "Home",IDC_BUTTON_R1_HOME,135,73,36,14 + PUSHBUTTON "Go",IDC_BUTTON_R1_GO,135,113,36,14 + EDITTEXT IDC_EDIT_R1_CURRENT_POSITION,96,73,36,14,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_R1_TARGET_POSITION,96,113,36,14,ES_CENTER | ES_AUTOHSCROLL + LTEXT "Current Position",IDC_STATIC,43,75,51,8 + CTEXT "Target Position",IDC_STATIC,43,97,51,8 + GROUPBOX "R1",IDC_STATIC,18,45,180,92 + CONTROL "Enable R2",IDC_CHECK_SO7_R2_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,31,149,48,10 + PUSHBUTTON "Home",IDC_BUTTON_R2_HOME,135,165,36,14 + PUSHBUTTON "Go",IDC_BUTTON_R2_GO,135,205,36,14 + EDITTEXT IDC_EDIT_R2_CURRENT_POSITION,96,165,36,14,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_R2_TARGET_POSITION,96,205,36,14,ES_CENTER | ES_AUTOHSCROLL + LTEXT "Current Position",IDC_STATIC,43,166,51,8 + CTEXT "Target Position",IDC_STATIC,43,189,51,8 + GROUPBOX "R2",IDC_STATIC,18,136,180,92 + CONTROL "Rel",IDC_RADIO_R1_RELATIVE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,66,110,27,8 + CONTROL "Abs",IDC_RADIO_R1_ABSOLUTE,"Button",BS_AUTORADIOBUTTON,66,121,28,8 + CONTROL "Rel",IDC_RADIO_R2_RELATIVE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,66,201,27,8 + CONTROL "Abs",IDC_RADIO_R2_ABSOLUTE,"Button",BS_AUTORADIOBUTTON,66,213,28,8 +END + ///////////////////////////////////////////////////////////////////////////// // @@ -1056,6 +1088,14 @@ BEGIN TOPMARGIN, 7 BOTTOMMARGIN, 359 END + + IDD_SO7_UTIL_USBCTLR, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 209 + TOPMARGIN, 7 + BOTTOMMARGIN, 244 + END END #endif // APSTUDIO_INVOKED @@ -1477,12 +1517,12 @@ IDB_BITMAP_Z_DOWN BITMAP "res\\bmp\\Z_DOWN.bmp" IDB_BITMAP_Z_UP BITMAP "res\\bmp\\Z_UP.bmp" IDB_BITMAP_X_LEFT BITMAP "res\\bmp\\X_LEFT.BMP" IDB_BITMAP_X_RIGHT BITMAP "res\\bmp\\X_RIGHT.bmp" -#endif // Chinese (Simplified, PRC) resources +#endif // 中文(简体,中国) resources ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// -// English (United States) resources +// 英语(美国) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US @@ -2425,7 +2465,7 @@ BEGIN IDS_SO7_ABOUTBOX "&About Utility for SO7..." END -#endif // English (United States) resources +#endif // 英语(美国) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Option.cpp b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Option.cpp index 6a3bf05..435282a 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Option.cpp +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Option.cpp @@ -7,6 +7,7 @@ #include "..\..\..\SevenOcean\CMMIO_SERIAL.H" #include "..\..\..\SevenOcean\EF8000_Interface.h" #include "..\..\..\SevenOcean\SO7_Proto.h" +#include "..\..\..\SevenOcean\SO7_Proto_Aux.h" #include "ProcessButton.h" #ifdef _RELEASE_FULL_VERSION @@ -24,6 +25,7 @@ #endif //_RELEASE_FULL_VERSION #include "SO7_UtilDlg.h" +#include "So7_UtilUsbCtlR.h" #include "..\..\..\Keyence\Keyence_Laser.h" #include "..\..\..\Keyence\Keyence_Laser_LK_H.h" #include "..\..\..\Keyence\\Keyence_Proto.h" @@ -49,6 +51,7 @@ //CSerial* m_pSO7_Serial=NULL; CPSerial* m_pSO7_PCDSerial=NULL; CSO7_Proto* m_pSO7_Proto=NULL; +CSO7_Proto_Aux* m_pSO7_Proto_Aux=NULL; CKeyence_Laser* m_pKeyence_Laser=NULL; CKeyence_Laser_LK_H* m_pKeyence_Laser_LK_H=NULL; CKeyence_Proto* m_pKeyence_Proto=NULL; @@ -187,6 +190,11 @@ void CSo7_Option::OnBnClickedOk() { delete m_pSO7_Proto; m_pSO7_Proto=NULL; + } + if (m_pSO7_Proto_Aux) + { + delete m_pSO7_Proto_Aux; + m_pSO7_Proto_Aux = NULL; } if (m_pEF8000_Interface) { @@ -194,12 +202,27 @@ void CSo7_Option::OnBnClickedOk() m_pEF8000_Interface=NULL; } } + else if (((CButton *)GetDlgItem(IDC_RADIO_CONTROLLER2))->GetCheck()) + { + if (!m_pSO7_Proto_Aux) + { + m_pSO7_Proto_Aux = new CSO7_Proto_Aux(); + } + + So7_UtilUsbCtlR* pSo7_UtilUsbCtlR=new So7_UtilUsbCtlR(); + pSo7_UtilUsbCtlR->DoModal(); + delete pSo7_UtilUsbCtlR; + } else if (((CButton *)GetDlgItem(IDC_RADIO__SO7_RS232))->GetCheck()) { if (!m_pSO7_Proto) { m_pSO7_Proto = new CSO7_Proto(); } + if (!m_pSO7_Proto_Aux) + { + m_pSO7_Proto_Aux = new CSO7_Proto_Aux(); + } if (!m_pSO7_PCDSerial) { m_pSO7_PCDSerial = new CPSerial(); @@ -219,6 +242,11 @@ void CSo7_Option::OnBnClickedOk() delete m_pSO7_Proto; m_pSO7_Proto=NULL; } + if (m_pSO7_Proto_Aux) + { + delete m_pSO7_Proto_Aux; + m_pSO7_Proto_Aux = NULL; + } } else if(((CButton *)GetDlgItem(IDC_RADIO_KEYENCE_LASER))->GetCheck()) { @@ -226,6 +254,10 @@ void CSo7_Option::OnBnClickedOk() { m_pSO7_Proto = new CSO7_Proto(); } + if (!m_pSO7_Proto_Aux) + { + m_pSO7_Proto_Aux = new CSO7_Proto_Aux(); + } if (!m_pKeyence_Proto) { m_pKeyence_Proto=new CKeyence_Proto(); @@ -245,6 +277,8 @@ void CSo7_Option::OnBnClickedOk() m_pKeyence_Proto=NULL; delete m_pSO7_Proto; m_pSO7_Proto=NULL; + delete m_pSO7_Proto_Aux; + m_pSO7_Proto_Aux = NULL; } else if(((CButton *)GetDlgItem(IDC_RADIO_KEYENCE_LASER_LK_H))->GetCheck()) { @@ -252,6 +286,10 @@ void CSo7_Option::OnBnClickedOk() { m_pSO7_Proto = new CSO7_Proto(); } + if (!m_pSO7_Proto_Aux) + { + m_pSO7_Proto_Aux = new CSO7_Proto_Aux(); + } if (!m_pKeyence_Laser_LK_H) { m_pKeyence_Laser_LK_H=new CKeyence_Laser_LK_H(); @@ -264,7 +302,9 @@ void CSo7_Option::OnBnClickedOk() delete m_pKeyence_Laser_LK_H; m_pKeyence_Laser_LK_H=NULL; delete m_pSO7_Proto; - m_pSO7_Proto=NULL; + m_pSO7_Proto=NULL; + delete m_pSO7_Proto_Aux; + m_pSO7_Proto_Aux = NULL; } else if(((CButton *)GetDlgItem(IDC_RADIO_KEYENCE_LASER_LKH_ETHERNET))->GetCheck()) { diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_UtilUsbCtlR.cpp b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_UtilUsbCtlR.cpp new file mode 100644 index 0000000..4217ebf --- /dev/null +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_UtilUsbCtlR.cpp @@ -0,0 +1,182 @@ +// So7_UtilUsbCtlR.cpp : 实现文件 +// + +#include "stdafx.h" +#include "So7_UtilUsbCtlR.h" +#include "afxdialogex.h" +#include "..\..\..\SevenOcean\SO7_Proto_Aux.h" + +extern CSO7_Proto_Aux* m_pSO7_Proto_Aux; +extern CLogger* g_pLoggerDebug; + + +// So7_UtilUsbCtlR 对话框 + +IMPLEMENT_DYNAMIC(So7_UtilUsbCtlR, CDialogEx) + + So7_UtilUsbCtlR::So7_UtilUsbCtlR(CWnd* pParent /*=NULL*/) + : CDialogEx(So7_UtilUsbCtlR::IDD, pParent) +{ +} + +So7_UtilUsbCtlR::~So7_UtilUsbCtlR() +{ +} + +void So7_UtilUsbCtlR::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); + + DDX_Text(pDX, IDC_EDIT_R1_TARGET_POSITION, m_R1_Rotary_Edit_Position); + DDX_Text(pDX, IDC_EDIT_R2_TARGET_POSITION, m_R2_Rotary_Edit_Position); +} + +BEGIN_MESSAGE_MAP(So7_UtilUsbCtlR, CDialogEx) + ON_BN_CLICKED(IDCANCEL, &So7_UtilUsbCtlR::OnBnClickedCancel) + ON_BN_CLICKED(IDC_BUTTON_START_SO7_R_MACHINE, &So7_UtilUsbCtlR::OnBnClickedButtonStartSo7RMachine) + ON_BN_CLICKED(IDC_BUTTON_STOP_SO7_R_MACHINE, &So7_UtilUsbCtlR::OnBnClickedButtonStopSo7RMachine) + ON_BN_CLICKED(IDC_BUTTON_R2_GO, &So7_UtilUsbCtlR::OnBnClickedButtonR2Go) + ON_BN_CLICKED(IDC_BUTTON_R2_HOME, &So7_UtilUsbCtlR::OnBnClickedButtonR2Home) + ON_BN_CLICKED(IDC_CHECK_SO7_R2_ENABLE, &So7_UtilUsbCtlR::OnBnClickedCheckSo7R2Enable) +END_MESSAGE_MAP() + + +// So7_UtilUsbCtlR 消息处理程序 + +BOOL So7_UtilUsbCtlR::OnInitDialog() +{ + CDialog::OnInitDialog(); + + UpdateCtrlsStatus(FALSE); + UpdateR1CtrlsStatus(FALSE); + UpdateR2CtrlsStatus(FALSE); + //R1 is x motor,is not enabled now. + GetDlgItem(IDC_CHECK_SO7_R1_ENABLE)->EnableWindow(FALSE); + + return TRUE; +} + +//===================================================================================== +void So7_UtilUsbCtlR::OnBnClickedButtonStartSo7RMachine() +{ + if (m_pSO7_Proto_Aux) + { + m_pSO7_Proto_Aux->Init_SO7Usb(); + } + + m_pSO7_Proto_Aux->_send_cmd_SO7_CMD_RESET_R(0); + + UpdateCtrlsStatus(TRUE); + UpdateR1CtrlsStatus(FALSE); + UpdateR2CtrlsStatus(FALSE); +} + +//===================================================================================== +void So7_UtilUsbCtlR::UpdateCtrlsStatus(bool _bEnable) +{ + GetDlgItem(IDC_BUTTON_START_SO7_R_MACHINE)->EnableWindow(!_bEnable); + GetDlgItem(IDCANCEL)->EnableWindow(!_bEnable); + GetDlgItem(IDC_BUTTON_STOP_SO7_R_MACHINE)->EnableWindow(_bEnable); + //GetDlgItem(IDC_CHECK_SO7_R1_ENABLE)->EnableWindow(_bEnable); + GetDlgItem(IDC_CHECK_SO7_R2_ENABLE)->EnableWindow(_bEnable); +} + +//===================================================================================== +void So7_UtilUsbCtlR::UpdateR1CtrlsStatus(bool _bEnable) +{ + GetDlgItem(IDC_BUTTON_R1_GO)->EnableWindow(_bEnable); + GetDlgItem(IDC_BUTTON_R1_HOME)->EnableWindow(_bEnable); + GetDlgItem(IDC_RADIO_R1_RELATIVE)->EnableWindow(_bEnable); + GetDlgItem(IDC_RADIO_R1_ABSOLUTE)->EnableWindow(_bEnable); + GetDlgItem(IDC_EDIT_R1_CURRENT_POSITION)->EnableWindow(_bEnable); + GetDlgItem(IDC_EDIT_R1_TARGET_POSITION)->EnableWindow(_bEnable); +} + +//===================================================================================== +void So7_UtilUsbCtlR::UpdateR2CtrlsStatus(bool _bEnable) +{ + GetDlgItem(IDC_BUTTON_R2_GO)->EnableWindow(_bEnable); + GetDlgItem(IDC_BUTTON_R2_HOME)->EnableWindow(_bEnable); + GetDlgItem(IDC_RADIO_R2_RELATIVE)->EnableWindow(_bEnable); + GetDlgItem(IDC_RADIO_R2_ABSOLUTE)->EnableWindow(_bEnable); + GetDlgItem(IDC_EDIT_R2_CURRENT_POSITION)->EnableWindow(_bEnable); + GetDlgItem(IDC_EDIT_R2_TARGET_POSITION)->EnableWindow(_bEnable); + ((CButton *)GetDlgItem(IDC_RADIO_R2_RELATIVE))->SetCheck(_bEnable); +} + +//===================================================================================== +void So7_UtilUsbCtlR::OnBnClickedButtonStopSo7RMachine() +{ + UpdateCtrlsStatus(FALSE); + ((CButton *)GetDlgItem(IDC_CHECK_SO7_R1_ENABLE))->SetCheck(0); + ((CButton *)GetDlgItem(IDC_CHECK_SO7_R2_ENABLE))->SetCheck(0); + UpdateR1CtrlsStatus(FALSE); + UpdateR2CtrlsStatus(FALSE); + m_pSO7_Proto_Aux->Exit_SO7Usb(); +} + +//===================================================================================== +void So7_UtilUsbCtlR::OnBnClickedCancel() +{ + CDialogEx::OnCancel(); +} + +//===================================================================================== +//************************************************************************************* +//===================================================================================== +void So7_UtilUsbCtlR::OnBnClickedCheckSo7R2Enable() +{ + if (((CButton *)GetDlgItem(IDC_CHECK_SO7_R2_ENABLE))->GetCheck()) + { + UpdateR2CtrlsStatus(TRUE); + m_pSO7_Proto_Aux->_send_cmd_SO7_CMD_MOVE_R(TYPER2, 360); + Sleep(4000); + CString csPosition; + csPosition.Format(_T("%8ld"),(m_pSO7_Proto_Aux->GetRCurrentPosition(TYPER2))); + GetDlgItem(IDC_EDIT_R2_CURRENT_POSITION)->SetWindowText(csPosition); + } + else + { + UpdateR2CtrlsStatus(FALSE); + } +} + +//===================================================================================== +void So7_UtilUsbCtlR::OnBnClickedButtonR2Home() +{ + int iHomeAngle = -1; + iHomeAngle = 360 - m_pSO7_Proto_Aux->GetRCurrentPosition(TYPER2); + if(iHomeAngle != 0 && iHomeAngle != 360) + { + m_pSO7_Proto_Aux->_send_cmd_SO7_CMD_MOVE_R(TYPER2, iHomeAngle); + } +} + +//===================================================================================== +void So7_UtilUsbCtlR::OnBnClickedButtonR2Go() +{ + UpdateData(TRUE); + USES_CONVERSION; + + const char* cR2_Move_to_Rotary = T2A(m_R2_Rotary_Edit_Position); + int iAngle = atoi(cR2_Move_to_Rotary); + if (((CButton *)GetDlgItem(IDC_RADIO_R2_RELATIVE))->GetCheck()) + { + m_pSO7_Proto_Aux->_send_cmd_SO7_CMD_MOVE_R(TYPER2, iAngle); + } + else if(((CButton *)GetDlgItem(IDC_RADIO_R2_ABSOLUTE))->GetCheck()) + { + int iCurrentAngle = -1; + iCurrentAngle = m_pSO7_Proto_Aux->GetRCurrentPosition(TYPER2); + if(iAngle > iCurrentAngle) + { + iAngle = iAngle - iCurrentAngle; + m_pSO7_Proto_Aux->_send_cmd_SO7_CMD_MOVE_R(TYPER2, iAngle); + } + else if(iAngle < iCurrentAngle) + { + iAngle = 360 - iCurrentAngle + iAngle; + m_pSO7_Proto_Aux->_send_cmd_SO7_CMD_MOVE_R(TYPER2, iAngle); + } + } +} \ No newline at end of file diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_UtilUsbCtlR.h b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_UtilUsbCtlR.h new file mode 100644 index 0000000..4f2d510 --- /dev/null +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_UtilUsbCtlR.h @@ -0,0 +1,38 @@ +#pragma once +#include "resource.h" + + +// So7_UtilUsbCtlR 对话框 + +class So7_UtilUsbCtlR : public CDialogEx +{ + DECLARE_DYNAMIC(So7_UtilUsbCtlR) + +public: + So7_UtilUsbCtlR(CWnd* pParent = NULL); // 标准构造函数 + virtual ~So7_UtilUsbCtlR(); + +// 对话框数据 + enum { IDD = IDD_SO7_UTIL_USBCTLR }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + + DECLARE_MESSAGE_MAP() + + virtual BOOL OnInitDialog(); + void UpdateCtrlsStatus(bool _bEnable); + void UpdateR1CtrlsStatus(bool _bEnable); + void UpdateR2CtrlsStatus(bool _bEnable); +public: + CString m_OutMessage; + CString m_R1_Rotary_Edit_Position; + CString m_R2_Rotary_Edit_Position; + + afx_msg void OnBnClickedButtonStartSo7RMachine(); + afx_msg void OnBnClickedButtonStopSo7RMachine(); + afx_msg void OnBnClickedCancel(); + afx_msg void OnBnClickedCheckSo7R2Enable(); + afx_msg void OnBnClickedButtonR2Go(); + afx_msg void OnBnClickedButtonR2Home(); +}; diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj index 87dcb8b..c569da6 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj @@ -321,6 +321,7 @@ + @@ -358,6 +359,7 @@ + @@ -402,6 +404,7 @@ + @@ -440,6 +443,7 @@ + diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj.filters b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj.filters index dfb5643..9f14414 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj.filters +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj.filters @@ -196,6 +196,10 @@ Sources Files + + + Sources Files + @@ -426,6 +430,10 @@ Header Files + + + Header Files + diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h index c1e2285..26f423e 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h @@ -56,6 +56,7 @@ #define IDC_BUTTON_INIT_MVUSB 146 #define IDD_DIALOG_TESA_STAR_E 188 #define IDD_DIALOG_KEYENCE_LKG5000_ETHERNET 190 +#define IDD_SO7_UTIL_USBCTLR 191 #define IDC_BUTTON_START_MACHINE 1000 #define IDC_BUTTON_START_MACHINE3 1001 #define IDC_BUTTON_START_POLL_58 1002 @@ -332,6 +333,7 @@ #define IDC_RADIO_SELECT_Z 1264 #define IDC_BUTTON_SO7_GET_SEQ_NUMBER 1265 #define IDC_BUTTON_SO7_SET_SEQ_NUMBER 1266 +#define IDC_BUTTON_SO7_SET_SEQ_NUMBER2 1267 #define IDC_BUTTON_SO7_SET_VER_NUMBER 1267 #define IDC_BUTTON_SET_OUT_PORT 1269 #define IDC_EDIT_SET_VER_NO 1271 @@ -666,6 +668,7 @@ #define IDC_BUTTON_STOP_SCAN_KEYENCE_LK_HLASER 1553 #define IDC_RADIO_CONTROLLER 1554 #define IDC_BUTTON_DO_MEASURE 1555 +#define IDC_RADIO_CONTROLLER2 1555 #define IDC_BUTTON_INIT_PROGRAM 1556 #define IDC_RADIO_VIDEOCARD_SV2000E 1557 #define IDC_BUTTON_SETTINGS 1558 @@ -702,8 +705,14 @@ #define IDC_BUTTON_INIT_SCAN_KEYENCE_LK_GLASER 1586 #define IDC_BUTTON_GO 1586 #define IDC_BTN_KEYENCE_LKG5000_ETHERNET_STORAGEDATA1 1586 +#define IDC_BUTTON_HOME2 1586 +#define IDC_BUTTON_R2_HOME 1586 #define IDC_EDIT_MEASURE_VALUE 1587 +#define IDC_BUTTON_GO2 1587 +#define IDC_BUTTON_R1_GO 1587 #define IDC_RADIO_OUT_EXTRACT 1588 +#define IDC_BUTTON_GO3 1588 +#define IDC_BUTTON_R2_GO 1588 #define IDC_RADIO_KEYENCE_LASER 1589 #define IDC_BUTTON_GET_SCAN_DATA_KEYENCE_LK_GLASER 1590 #define IDC_EDIT_TEST_KEYENCE_MESSAGE 1591 @@ -717,6 +726,7 @@ #define IDC_RADIO_KEYENCE_LASER_LKH_ETHERNET 1596 #define IDC_BUTTON_TEST_KEYENCE_SAVE_LOG 1597 #define IDC_BUTTON_SO7_MANUAL_MACHINE_SEND_DATA 1598 +#define IDC_RADIO_TEST_IMAGE_DLL3 1598 #define IDC_BUTTON_SO7_CNC_PROGRAM 1599 #define IDC_BUTTON_PROGRAM_SET_ZERO_Z 1600 #define IDC_BUTTON_IMAGEDLL_STOP_SCAN_LASER 1601 @@ -909,6 +919,8 @@ #define IDC_CHECK_SO7_TOP_LIGHT_ON 1819 #define IDC_LIST_SO7_MOTION_CONFIG 1820 #define IDC_CHECK_SO7_BOTTOM_LIGHT_ON 1820 +#define IDC_CHECK_SO7_TOP_LIGHT_ON2 1820 +#define IDC_CHECK_SO7_R2_ENABLE 1820 #define IDC_EDIT_SO7_MOTION_CONFIG_MSGOUT 1821 #define IDC_CHECK_SO7_RING_LIGHT_ON 1821 #define IDC_EDIT_SO7_PROGEAM_INTERCAL_TIME_PER_CNC 1822 @@ -916,14 +928,25 @@ #define IDC_CHECK_SO7_RING_LIGHT_SEG_ON2 1823 #define IDC_EDIT_POSITION 1824 #define IDC_RADIO_RELATIVE 1825 +#define IDC_EDIT_POSITION2 1825 +#define IDC_EDIT_R1_TARGET_POSITION 1825 #define IDC_RADIO_ABS 1826 #define IDC_RADIO_ABSOLUTE 1826 +#define IDC_EDIT_POSITION3 1826 +#define IDC_EDIT_R2_CURRENT_POSITION 1826 #define IDC_KEYENCE_LKG5000_IPADDRESS1 1827 #define IDC_CHECK_SO7_COAXIAL_LIGHT_ON 1827 +#define IDC_EDIT_POSITION4 1827 +#define IDC_EDIT_R2_TARGET_POSITION 1827 #define IDC_KEYENCE_LKG5000_IPADDRESS2 1828 #define IDC_CHECK_SO7_SPARE_LIGHT_ON 1828 +#define IDC_RADIO_R1_RELATIVE 1828 +#define IDC_RADIO_R1_ABSOLUTE 1829 #define IDC_EDIT_KEYENCE_LKG5000_MSG 1830 +#define IDC_RADIO_R2_RELATIVE 1830 #define IDC_BTN_KEYENCE_LKG5000_ETHERNET_START_SCAN 1831 +#define IDC_RADIO_ABSOLUTE3 1831 +#define IDC_RADIO_R2_ABSOLUTE 1831 #define IDC_BTN_KEYENCE_LKG5000_ETHERNET_STOP_SCAN 1832 #define IDC_RADIO_SO7_MOVE_SPEED_GEAR1 1832 #define IDC_BTN_KEYENCE_LKG5000_ETHERNET_START_SCAN2 1833 @@ -938,6 +961,12 @@ #define IDC_STATIC_IO_ADDR4 1840 #define IDC_STATIC_IO_ADDR5 1841 #define IDC_STATIC_IO_ADDR6 1842 +#define IDC_BUTTON_START_SO7_R_MACHINE 1843 +#define IDC_BUTTON_STOP_SO7_R_MACHINE 1844 +#define IDC_BUTTON_R1_HOME 1845 +#define IDC_CHECK_SO7_R1_ENABLE 1846 +#define IDC_EDIT_R1_CURRENT_POSITION 1847 + #define IDC_BUTTON_DIY_EXIT_BUTTON 32740 #define ID_EDIT_SO7_CONFIG_MOTION 32741 diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil_VS2010.suo b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil_VS2010.suo index 4ba9222431637accdbfbba7be5e8ffbb2baad829..c98928562e5da3a7e777ba588f9382225dc04ea9 100644 GIT binary patch delta 17775 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 delta 15481 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