660 lines
23 KiB
C++
660 lines
23 KiB
C++
|
|
|
|
#include "stdafx.h"
|
|
#include "Keyence_Proto.h"
|
|
#include "math.h"
|
|
|
|
|
|
|
|
#define MY_CONFIG 1
|
|
#define MAX_DEVPATH_LENGTH 256
|
|
#define ENDPOINT_TIMEOUT 500
|
|
|
|
//***** Static Data *****
|
|
struct_Keyence_ep_buff CKeyence_Proto::ep_buff[lEPSIZE];
|
|
|
|
//================================================================
|
|
int CKeyence_Proto::g_hEP81_Thread_State=THREAD_PAUSED;
|
|
HANDLE CKeyence_Proto::g_hEP81_Thread_Id=NULL;
|
|
|
|
//================================================================
|
|
int CKeyence_Proto::g_hEP82_Thread_State=THREAD_PAUSED;
|
|
HANDLE CKeyence_Proto::g_hEP82_Thread_Id=NULL;
|
|
|
|
//================================================================
|
|
int CKeyence_Proto::g_hEP01_Thread_State=THREAD_PAUSED;
|
|
HANDLE CKeyence_Proto::g_hEP01_Thread_Id=NULL;
|
|
HANDLE CKeyence_Proto::g_hEP01_Serial_Mutex;
|
|
|
|
//================================================================
|
|
int CKeyence_Proto::g_hEP02_Thread_State=THREAD_PAUSED;
|
|
HANDLE CKeyence_Proto::g_hEP02_Thread_Id=NULL;
|
|
HANDLE CKeyence_Proto::g_hEP02_Serial_Mutex;
|
|
|
|
//================================================================
|
|
struct_Keyence_machine CKeyence_Proto::g_machine;
|
|
usb_dev_handle *CKeyence_Proto::g_dev=NULL;
|
|
CLogger *CKeyence_Proto::g_pLogger;
|
|
HANDLE CKeyence_Proto::g_hHomedEvent = NULL;
|
|
|
|
//===========================================================================
|
|
// Worker Thread to serialize EP_KEYENCE_01 commands.
|
|
//===========================================================================
|
|
unsigned __stdcall CKeyence_Proto::g_EP01_Thread(LPVOID pThis)
|
|
{
|
|
CKeyence_Proto* _This = (CKeyence_Proto*)pThis;
|
|
for (;;)
|
|
{
|
|
TRACE0("g_hSerialUsbThread in loop set.\n");
|
|
if (g_hEP01_Thread_State == THREAD_EXIT)
|
|
ExitThread(0);
|
|
WaitForSingleObject(ep_buff[EP_01_CMD_IDX]._event,INFINITE);
|
|
TRACE0("g_hSerialUsbThread obtained event.\n");
|
|
switch (g_hEP01_Thread_State)
|
|
{
|
|
case THREAD_EXIT:
|
|
{
|
|
ExitThread(0);
|
|
}
|
|
case THREAD_PAUSED:
|
|
break;
|
|
case THREAD_RUNNING:
|
|
{
|
|
TRACE0("g_hSerialUsbThread processing _send_usb_data();\n");
|
|
_This->_send_usb_data(EP_01_CMD_IDX);
|
|
TRACE0("g_hSerialUsbThread return from _send_usb_data();\n");
|
|
break;
|
|
}
|
|
default:
|
|
ExitThread(0);
|
|
}
|
|
};
|
|
g_hEP01_Thread_State = THREAD_EXIT;
|
|
ExitThread(0);
|
|
};
|
|
|
|
//===========================================================================
|
|
// Worker Thread to serialize EP_KEYENCE_02 commands.
|
|
//===========================================================================
|
|
unsigned __stdcall CKeyence_Proto::g_EP02_Thread(LPVOID pThis)
|
|
{
|
|
CKeyence_Proto* _This = (CKeyence_Proto*)pThis;
|
|
for (;;)
|
|
{
|
|
TRACE0("g_hEP02_Thread in loop set.\n");
|
|
if (g_hEP02_Thread_State == THREAD_EXIT)
|
|
ExitThread(0);
|
|
WaitForSingleObject(ep_buff[EP_02_CMD_IDX]._event,INFINITE);
|
|
TRACE0("g_hEP02_Thread obtained event.\n");
|
|
switch (g_hEP02_Thread_State)
|
|
{
|
|
case THREAD_EXIT:
|
|
{
|
|
ExitThread(0);
|
|
}
|
|
case THREAD_PAUSED:
|
|
break;
|
|
case THREAD_RUNNING:
|
|
{
|
|
TRACE0("g_hEP02_Thread calling _send_usb_data. EP_KEYENCE_02; %x\n");
|
|
_This->_send_usb_data(EP_02_CMD_IDX);
|
|
TRACE0("g_hEP02_Thread return _send_usb_data. EP_KEYENCE_02; %x\n");
|
|
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 CKeyence_Proto::g_EP81_Thread(LPVOID pThis)
|
|
{
|
|
CKeyence_Proto* _This = (CKeyence_Proto*)pThis;
|
|
for (;;)
|
|
{
|
|
WaitForSingleObject(ep_buff[EP_81_DATA_IDX]._event, INFINITE);
|
|
switch (g_hEP81_Thread_State)
|
|
{
|
|
case THREAD_EXIT:
|
|
{
|
|
ExitThread(0);
|
|
}
|
|
case THREAD_PAUSED:
|
|
break;
|
|
case THREAD_RUNNING:
|
|
{
|
|
_This->_reap_async_8x(EP_81_DATA_IDX);
|
|
break;
|
|
}
|
|
default:
|
|
ExitThread(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
//******************************************************************************
|
|
// This is the worker thread to process USBD_TRANSFER_DIRECTION_IN
|
|
//******************************************************************************
|
|
unsigned __stdcall CKeyence_Proto::g_EP82_Thread(LPVOID pThis)
|
|
{
|
|
CKeyence_Proto* _This = (CKeyence_Proto*)pThis;
|
|
for (;;)
|
|
{
|
|
WaitForSingleObject(ep_buff[EP_82_DATA_IDX]._event, INFINITE);
|
|
switch (g_hEP82_Thread_State)
|
|
{
|
|
case THREAD_EXIT:
|
|
{
|
|
ExitThread(0);
|
|
}
|
|
case THREAD_PAUSED:
|
|
break;
|
|
case THREAD_RUNNING:
|
|
{
|
|
_This->_reap_async_8x(EP_82_DATA_IDX);
|
|
break;
|
|
}
|
|
default:
|
|
ExitThread(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
void CKeyence_Proto::Trace_EP_Buff(long lIndex)
|
|
{
|
|
UCHAR tmp[256];
|
|
CString csTmp;
|
|
memcpy(tmp, ep_buff[lIndex]._buffer, ep_buff[lIndex]._size);
|
|
csTmp = _T("Trace_EP_Buff _59 ");
|
|
for (int ii= 0 ; ii < ep_buff[lIndex]._size ; ++ii)
|
|
{
|
|
CString csTmpHex;
|
|
csTmpHex.Format(_T("%2X"), tmp[ii] );
|
|
csTmp += csTmpHex;
|
|
}
|
|
TRACE1("_process_KEYENCE_CMD_GET_INDEX_4E() Trace_EP_Buff %s \n", csTmp);
|
|
}
|
|
|
|
|
|
//******************************************************************************
|
|
// 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 CKeyence_Proto::_process_rcv_transfer_data(int iEP)
|
|
{
|
|
static long lRcvCnt = 0;
|
|
static long lRcvCnt2 = 0;
|
|
switch (iEP)
|
|
{
|
|
case EP_01_CMD_IDX :
|
|
TRACE0("_process_rcv_transfer_data() : Update EP_01_CMD_IDX.\r\n");
|
|
++lRcvCnt;
|
|
break;
|
|
case EP_81_DATA_IDX : //
|
|
++lRcvCnt;
|
|
TRACE0("_process_rcv_transfer_data() : Update EP_81_DATA_IDX status.\r\n");
|
|
break;
|
|
case EP_02_CMD_IDX :
|
|
TRACE0("_process_rcv_transfer_data() : Update EP_02_CMD_IDX.\r\n");
|
|
++lRcvCnt2;
|
|
break;
|
|
case EP_82_DATA_IDX :
|
|
// parse result and put into its proper place.
|
|
_process_KEYENCE_CMD_GET_LASER_DATA();
|
|
++lRcvCnt2;
|
|
break;
|
|
default:
|
|
break;
|
|
};
|
|
lRcvCnt = (lRcvCnt == 2) ? 0:lRcvCnt;
|
|
lRcvCnt2 = (lRcvCnt2 == 2) ? 0:lRcvCnt2;
|
|
};
|
|
|
|
|
|
//******************************************************************************
|
|
CKeyence_Proto::CKeyence_Proto()
|
|
{
|
|
ep_buff[EP_01_CMD_IDX]._ep = EP_KEYENCE_01;
|
|
ep_buff[EP_81_DATA_IDX]._ep = EP_KEYENCE_81;
|
|
ep_buff[EP_02_CMD_IDX]._ep = EP_KEYENCE_02;
|
|
ep_buff[EP_82_DATA_IDX]._ep = EP_KEYENCE_82;
|
|
|
|
for (int i=0;i<lEPSIZE;i++)
|
|
{
|
|
ep_buff[i]._size = 0;
|
|
ep_buff[i]._save_send_cmd = 99;
|
|
ep_buff[i]._async_context = NULL;
|
|
ep_buff[i]._buffer = (char *)malloc(MAX_BUFF_SIZE);
|
|
ep_buff[i]._hProtoPending = false;
|
|
ep_buff[i]._event = NULL;
|
|
};
|
|
|
|
|
|
g_pLogger = new CLogger(_T("UtilityDebug.Log"));
|
|
};
|
|
|
|
//******************************************************************************
|
|
CKeyence_Proto::~CKeyence_Proto()
|
|
{
|
|
for (int i=0;i<lEPSIZE;i++)
|
|
{
|
|
free(ep_buff[i]._buffer);
|
|
};
|
|
delete g_pLogger;
|
|
g_pLogger = NULL;
|
|
}
|
|
|
|
#pragma warning(disable:4996)
|
|
//******************************************************************************
|
|
|
|
//******************************************************************************
|
|
usb_dev_handle* CKeyence_Proto::_open_usb_dev(void)
|
|
{
|
|
struct usb_bus *bus = NULL;
|
|
struct usb_device *dev = NULL;
|
|
|
|
for (bus = usb_get_busses(); bus; bus = bus->next)
|
|
{
|
|
for (dev = bus->devices; dev; dev = dev->next)
|
|
{
|
|
if (dev->descriptor.idVendor == KEYENCE_VID && dev->descriptor.idProduct == KEYENCE_PID)
|
|
{
|
|
return usb_open(dev);
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//******************************************************************************
|
|
SSI_STATUS_MOTION CKeyence_Proto::_usb_reset(void)
|
|
{
|
|
if (g_dev)
|
|
{
|
|
usb_reset(g_dev);
|
|
g_dev = NULL;
|
|
}
|
|
else
|
|
{
|
|
ASSERT(0);
|
|
return SSI_STATUS_MOTION_TIMEOUT;
|
|
}
|
|
return SSI_STATUS_MOTION_TIMEOUT;
|
|
}
|
|
|
|
|
|
|
|
//******************************************************************************
|
|
// Send is direct and async.
|
|
// The receive thread will receive data and interpret it.
|
|
//******************************************************************************
|
|
SSI_STATUS_MOTION CKeyence_Proto::Init_MvUsb()
|
|
{
|
|
// Set initial state of the machine
|
|
g_machine.s_status._machine_running = false;
|
|
|
|
SSI_STATUS_MOTION Status=SSI_STATUS_MOTION_NORMAL;
|
|
UNREFERENCED_PARAMETER(Status);
|
|
/*if (g_pLogger->m_lLogMask & LOGACTIONS)
|
|
g_pLogger->SendAndFlushPerMode(_T("Enter Initialize Mv Usb\n"));
|
|
*/
|
|
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();
|
|
if (!g_dev)
|
|
{
|
|
MessageBox(NULL, _T("Unable to open device"), _T("Message"), MB_OK);
|
|
g_pLogger->SendAndFlushPerMode(_T("Unable to open device %s"), usb_strerror());
|
|
return SSI_STATUS_MOTION_DATALINK_ERROR;
|
|
}
|
|
|
|
if (usb_set_configuration(g_dev, MY_CONFIG) < 0)
|
|
{
|
|
MessageBox(NULL, _T("Unable to SET CONFIGURATION"), _T("Message"), MB_OK);
|
|
return SSI_STATUS_MOTION_DATALINK_ERROR;
|
|
}
|
|
|
|
if (usb_claim_interface(g_dev, 0) < 0)
|
|
{
|
|
usb_close(g_dev);
|
|
MessageBox(NULL, _T("Unable to CLAIM DEVICE"), _T("Message"), MB_OK);
|
|
return SSI_STATUS_MOTION_DATALINK_ERROR;
|
|
}
|
|
|
|
// ********************************************************************
|
|
// 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_01_CMD_IDX]._event = CreateEvent(NULL, // default security attributes
|
|
FALSE, // manual reset event object
|
|
NULL, // signaled
|
|
NULL); // unamed object
|
|
|
|
g_hEP01_Thread_Id = CreateThread( (LPSECURITY_ATTRIBUTES) NULL,
|
|
0,
|
|
(LPTHREAD_START_ROUTINE) g_EP01_Thread,
|
|
(LPVOID) this,
|
|
0,
|
|
NULL);
|
|
g_hEP01_Thread_State = THREAD_RUNNING;
|
|
|
|
|
|
// ********************************************************************
|
|
// 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;
|
|
|
|
// ********************************************************************
|
|
// Prepare and start EP_KEYENCE_81 Thread - Use async commit.
|
|
//
|
|
ep_buff[EP_81_DATA_IDX]._event = CreateEvent(NULL, // default security attributes
|
|
FALSE, // manual reset event object
|
|
NULL, // signaled
|
|
NULL); // unamed object
|
|
g_hEP81_Thread_State = THREAD_PAUSED;
|
|
g_hEP81_Thread_Id = CreateThread( (LPSECURITY_ATTRIBUTES) NULL,
|
|
0,
|
|
(LPTHREAD_START_ROUTINE) g_EP81_Thread,
|
|
(LPVOID) this,
|
|
0,
|
|
NULL);
|
|
g_hEP01_Serial_Mutex = CreateMutex(NULL, // default security attributes
|
|
FALSE, // initial owner
|
|
NULL); // name
|
|
|
|
// ********************************************************************
|
|
// Prepare and start EP_KEYENCE_82 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_hEP82_Thread_State = THREAD_PAUSED;
|
|
g_hEP82_Thread_Id = CreateThread( (LPSECURITY_ATTRIBUTES) NULL,
|
|
0,
|
|
(LPTHREAD_START_ROUTINE) g_EP82_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
|
|
|
|
//if (g_pLogger->m_lLogMask & LOGACTIONS)
|
|
// g_pLogger->SendAndFlushPerMode(_T("Exit Initialize Usb\n"));
|
|
return SSI_STATUS_MOTION_NORMAL;
|
|
}
|
|
|
|
//******************************************************************************
|
|
SSI_STATUS_MOTION CKeyence_Proto::Exit_MvUsb()
|
|
{
|
|
SSI_STATUS_MOTION Status=SSI_STATUS_MOTION_NORMAL;
|
|
//if (g_pLogger->m_lLogMask & LOGACTIONS)
|
|
// g_pLogger->SendAndFlushPerMode(_T("Enter Exit_MvUsb\n"));
|
|
|
|
g_hEP81_Thread_State = THREAD_EXIT;
|
|
g_hEP82_Thread_State = THREAD_EXIT;
|
|
g_hEP01_Thread_State = THREAD_EXIT;
|
|
g_hEP02_Thread_State = THREAD_EXIT;
|
|
|
|
SetEvent(ep_buff[EP_81_DATA_IDX]._event);
|
|
if (g_hEP81_Thread_Id)
|
|
{
|
|
DWORD dwCode = STILL_ACTIVE;
|
|
while (dwCode == STILL_ACTIVE)
|
|
{
|
|
GetExitCodeThread(g_hEP81_Thread_Id,&dwCode);
|
|
Sleep(1);
|
|
}
|
|
}
|
|
SetEvent(ep_buff[EP_82_DATA_IDX]._event);
|
|
if (g_hEP82_Thread_Id)
|
|
{
|
|
DWORD dwCode = STILL_ACTIVE;
|
|
while (dwCode == STILL_ACTIVE)
|
|
{
|
|
GetExitCodeThread(g_hEP82_Thread_Id,&dwCode);
|
|
Sleep(1);
|
|
}
|
|
}
|
|
SetEvent(ep_buff[EP_01_CMD_IDX]._event);
|
|
if (g_hEP01_Thread_Id)
|
|
{
|
|
DWORD dwCode = STILL_ACTIVE;
|
|
while (dwCode == STILL_ACTIVE)
|
|
{
|
|
GetExitCodeThread(g_hEP01_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_81_DATA_IDX]._event);
|
|
CloseHandle(ep_buff[EP_81_DATA_IDX]._event);
|
|
SetEvent(ep_buff[EP_82_DATA_IDX]._event);
|
|
CloseHandle(ep_buff[EP_82_DATA_IDX]._event);
|
|
g_hEP01_Thread_State = THREAD_EXIT;
|
|
SetEvent(ep_buff[EP_01_CMD_IDX]._event);
|
|
CloseHandle(ep_buff[EP_01_CMD_IDX]._event);
|
|
g_hEP02_Thread_State = THREAD_EXIT;
|
|
SetEvent(ep_buff[EP_02_CMD_IDX]._event);
|
|
CloseHandle(ep_buff[EP_02_CMD_IDX]._event);
|
|
ReleaseMutex(g_hEP01_Serial_Mutex);
|
|
CloseHandle(g_hEP01_Serial_Mutex);
|
|
ReleaseMutex(g_hEP02_Serial_Mutex);
|
|
CloseHandle(g_hEP02_Serial_Mutex);
|
|
|
|
//if (g_pLogger->m_lLogMask & LOGACTIONS)
|
|
// g_pLogger->SendAndFlushPerMode(_T("Exit Exit_MvUsb\n"));
|
|
return Status;
|
|
}
|
|
|
|
|
|
//******************************************************************************
|
|
// Kick the g_hEP01_Thread_Event to get the g_EP01_Thread going.
|
|
// iEP = EP_KEYENCE_01 or EP_KEYENCE_02 = 0x01 or 0x02
|
|
//******************************************************************************
|
|
SSI_STATUS_MOTION CKeyence_Proto::_do_single_threaded_usb_comm(int iEP_Base)
|
|
{
|
|
TRACE1("=====_do_single_threaded_usb_comm(iEP) g_hEP01_Thread_Event. %x\n", 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;
|
|
TRACE1("=====_do_single_threaded_usb_comm(iEP_Base) SetEvent(g_hEP01_Thread_Event): %X \r\n", ep_buff[iEP_Base]._save_send_cmd);
|
|
SetEvent(ep_buff[iEP_Base]._event);
|
|
while ((ep_buff[iEP_Base]._hProtoPending == TRUE) || (ep_buff[iEP_Base+1]._hProtoPending == TRUE))
|
|
{
|
|
Sleep(3);
|
|
}
|
|
TRACE1("=====_do_single_threaded_usb_comm(iEP) g_hProtoDoneEvents. %x\n", iEP_Base);
|
|
return SSI_STATUS_MOTION_NORMAL;
|
|
}
|
|
|
|
//******************************************************************************
|
|
// This startup just kicks off the EP_KEYENCE_81 worker thread.
|
|
//******************************************************************************
|
|
SSI_STATUS_MOTION CKeyence_Proto::_start_machine()
|
|
{
|
|
g_hEP81_Thread_State = THREAD_RUNNING;
|
|
g_hEP82_Thread_State = THREAD_RUNNING;
|
|
g_machine.s_status._machine_running = true;
|
|
return SSI_STATUS_MOTION_NORMAL;
|
|
};
|
|
|
|
//===============================================================================
|
|
SSI_STATUS_MOTION CKeyence_Proto::_shutdown_machine()
|
|
{
|
|
g_machine.s_status._machine_running = false;
|
|
return SSI_STATUS_MOTION_NORMAL;
|
|
};
|
|
|
|
//===============================================================================
|
|
// iEP = EP_KEYENCE_01 or EP_KEYENCE_02
|
|
//===============================================================================
|
|
SSI_STATUS_MOTION CKeyence_Proto::_submit_async_8x(int iEP_Base)
|
|
{
|
|
int _ret;
|
|
_ret = usb_bulk_setup_async(g_dev, &(ep_buff[iEP_Base]._async_context), (unsigned char)ep_buff[iEP_Base]._ep);
|
|
if (_ret < 0)
|
|
{
|
|
return SSI_STATUS_MOTION_SETUP_ASYNC_CONTEXT_ERROR;
|
|
}
|
|
_ret = usb_submit_async(ep_buff[iEP_Base]._async_context, ep_buff[iEP_Base]._buffer, ep_buff[iEP_Base]._size);
|
|
if (_ret < 0)
|
|
{
|
|
printf("error usb_submit_async_ep_xx:\n%s\n", usb_strerror());
|
|
return SSI_STATUS_MOTION_SETUP_ASYNC_CONTEXT_ERROR;
|
|
}
|
|
return SSI_STATUS_MOTION_NORMAL;
|
|
}
|
|
|
|
//===============================================================================
|
|
// iEP_Base : EP_81_DATA_IDX/EP_82_DATA_IDX
|
|
//
|
|
//===============================================================================
|
|
SSI_STATUS_MOTION CKeyence_Proto::_reap_async_8x(int iEP_Base)
|
|
{
|
|
int _ret;
|
|
_ret = usb_reap_async(ep_buff[iEP_Base]._async_context, 1000);
|
|
if (_ret > 0)
|
|
{
|
|
_process_rcv_transfer_data(iEP_Base);
|
|
usb_free_async(&(ep_buff[iEP_Base]._async_context));
|
|
ep_buff[iEP_Base]._hProtoPending = false;
|
|
}
|
|
else
|
|
{
|
|
usb_free_async(&(ep_buff[iEP_Base]._async_context));
|
|
ASSERT(0);
|
|
return SSI_STATUS_MOTION_TIMEOUT;
|
|
}
|
|
return SSI_STATUS_MOTION_NORMAL;
|
|
}
|
|
|
|
//===============================================================================
|
|
// _send_usb_data(iEP) sends data to the corresponding iEP channel.
|
|
// iEP = EP_KEYENCE_01 / EP_KEYENCE_02 EP_KEYENCE_01 = 0x01; EP_KEYENCE_02 = 0x02;
|
|
//===============================================================================
|
|
SSI_STATUS_MOTION CKeyence_Proto::_send_usb_data(int iEP_Base)
|
|
{
|
|
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_data() iEP : %X - ep_buff[iEP]._save_send_cmd : %X ._buffer[0] : %X\r\n", iEP_Base, ep_buff[EP_01_CMD_IDX]._save_send_cmd, ep_buff[EP_81_DATA_IDX]._buffer[0]);
|
|
_ret = usb_bulk_setup_async(g_dev, &(ep_buff[iEP_Base]._async_context), (unsigned char)ep_buff[iEP_Base]._ep);
|
|
if (_ret < 0)
|
|
{
|
|
return SSI_STATUS_MOTION_SETUP_ASYNC_CONTEXT_ERROR;
|
|
}
|
|
_ret = usb_submit_async(ep_buff[iEP_Base]._async_context, ep_buff[iEP_Base]._buffer, ep_buff[iEP_Base]._size);//send data
|
|
if (_ret < 0)
|
|
{
|
|
printf("error usb_submit_async_ep_xx:\n%s\n", usb_strerror());
|
|
return SSI_STATUS_MOTION_SETUP_ASYNC_CONTEXT_ERROR;
|
|
}
|
|
TRACE1("_submit_async_8x(EP:%X)\r\n", iEP_Base);
|
|
//
|
|
ep_buff[iEP_Base+1]._save_send_cmd = ep_buff[iEP_Base+1]._buffer[0];
|
|
ep_buff[iEP_Base+1]._save_send_cmd0 = ep_buff[iEP_Base+1]._buffer[1];
|
|
ep_buff[iEP_Base+1]._save_send_cmd1 = ep_buff[iEP_Base+1]._buffer[2];
|
|
//
|
|
_submit_async_8x(iEP_Base+1); // Send EP_KEYENCE_81/EP_KEYENCE_82
|
|
// Get ready to receive on EP_KEYENCE_81 or EP_KEYENCE_82
|
|
SetEvent(ep_buff[iEP_Base+1]._event);
|
|
// Get ready to receive on EP_KEYENCE_01 or EP_KEYENCE_02
|
|
_ret = usb_reap_async(ep_buff[iEP_Base]._async_context, 10000);
|
|
if (_ret > 0)
|
|
{
|
|
_process_rcv_transfer_data(iEP_Base);
|
|
usb_free_async(&(ep_buff[iEP_Base]._async_context));
|
|
ep_buff[iEP_Base]._hProtoPending = false;
|
|
}
|
|
else
|
|
{
|
|
usb_free_async(&(ep_buff[iEP_Base]._async_context));
|
|
ASSERT(0);
|
|
return SSI_STATUS_MOTION_TIMEOUT;
|
|
}
|
|
return SSI_STATUS_MOTION_NORMAL;
|
|
}
|
|
|
|
//==============================================================
|
|
SSI_STATUS_MOTION CKeyence_Proto::_send_cmd_KEYENCE_CMD_GET_LASER_DATA()
|
|
{
|
|
WaitForSingleObject(g_hEP01_Serial_Mutex, INFINITE);
|
|
memset(ep_buff[EP_01_CMD_IDX]._buffer, 0x00, MAX_BUFF_SIZE);
|
|
|
|
ep_buff[EP_01_CMD_IDX]._buffer[0] = 0x00;
|
|
ep_buff[EP_01_CMD_IDX]._buffer[1] = 0x01;
|
|
ep_buff[EP_01_CMD_IDX]._buffer[2] = 0x01;
|
|
ep_buff[EP_01_CMD_IDX]._buffer[3] = 0x01;
|
|
ep_buff[EP_01_CMD_IDX]._buffer[4] = 0x01;
|
|
ep_buff[EP_01_CMD_IDX]._buffer[5] = 0x01;
|
|
|
|
|
|
ep_buff[EP_01_CMD_IDX]._size = 0x0C;
|
|
ep_buff[EP_82_DATA_IDX]._size = 0x45;
|
|
|
|
_do_single_threaded_usb_comm(EP_01_CMD_IDX);
|
|
ReleaseMutex(g_hEP01_Serial_Mutex);
|
|
return SSI_STATUS_MOTION_NORMAL;
|
|
};
|
|
|
|
|
|
//==============================================================
|
|
SSI_STATUS_MOTION CKeyence_Proto::_process_KEYENCE_CMD_GET_LASER_DATA()
|
|
{
|
|
|
|
return SSI_STATUS_MOTION_NORMAL;
|
|
}; |