📄 pdc4000supportfunctions.cpp
字号:
///////////////////////////////////////////////////////////////////
// File name : PDC4000SupportFunctions.cpp
// Description :
// Version : 03/26/2002,1.00
///////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Function Name : GetDeviceViaInterface
// Description : Open a handle via a device interface
///////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "PDC4000SupportFunctions.h"
// {E1C1A5C0-BEE1-4666-9189-9BDDFA53473D}
DEFINE_GUID(GUID_INTERFACE_PDC4000,
0xe1c1a5c0, 0xbee1, 0x4666, 0x91, 0x89, 0x9b, 0xdd, 0xfa, 0x53, 0x47, 0x3d);
//Block DMA 最大缓冲区大小
const unsigned long MAX_BLOCK_DMA_BUFFER_LENGTH = 0x2000;
HANDLE hPDC4000;
HANDLE hEvent[2]; //The first is sended to the driver,
//the second is used for cancel the waitted thread.
CWinThread *m_pWaitThread;
////////////////////////////////////////////////////////////////////////////////////
// Function Name : ConnectToPDC4000
// Description : Connect to the PDC4000 driver.
////////////////////////////////////////////////////////////////////////////////////
BOOL ConnectToPDC4000(HWND hWnd)
{ //ConnectToPDC4000
ULONG i;
ULONG lReturnedBytes;
BOOL bConnectSuccess;
bConnectSuccess = TRUE;
hPDC4000 = GetDeviceViaInterface((LPGUID)&GUID_INTERFACE_PDC4000,0);
if (hPDC4000 == NULL)
{
TRACE("Can't open PDC4000, and check it.\n");
bConnectSuccess = FALSE;
return FALSE;
}
__try
{
for (i=0; i<2; i++)
{
//Create the Auto-Reset events.
hEvent[i] = CreateEvent(NULL,TRUE,FALSE,NULL);
if (hEvent[i] == NULL)
{
bConnectSuccess = FALSE;
return FALSE;
}
}
//利用Event将中断信息传递过来,利用等待函数等待Event
if (!DeviceIoControl(hPDC4000, IOCTL_PDC4000_REGISTER_EVENT,
&hEvent[0], sizeof(hEvent[0]), NULL, 0, &lReturnedBytes, NULL))
{
bConnectSuccess = FALSE;
return FALSE;
}
//Create the waited thread. 启动等待函数
m_pWaitThread = AfxBeginThread(WaitForReceiveDataThreadPro,hWnd);
if (m_pWaitThread == NULL)
{
bConnectSuccess = FALSE;
return FALSE;
}
}
__finally
{
if (!bConnectSuccess)
{
if (hPDC4000 != NULL)
CloseHandle(hPDC4000);
for (i=0; i<2; i++)
if (hEvent[i] != NULL)
CloseHandle(hEvent[i]);
}
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////
// Function Name : DisconnectToPDC4000
// Description :
////////////////////////////////////////////////////////////////////////////////////
BOOL DisconnectToPDC4000()
{ //DisconnectToPDC4000
ULONG lReturnedBytes;
//Unregister the event.
DeviceIoControl(hPDC4000, IOCTL_PDC4000_UNREGISTER_EVENT,
NULL, 0, NULL, 0, &lReturnedBytes, NULL);
//Cancel the waitted thread.
SetEvent(hEvent[1]);
if (hPDC4000 != NULL)
CloseHandle(hPDC4000);
//Close the waitted event. The other one is closed by the waitted thread.
CloseHandle(hEvent[0]);
return TRUE;
} //DisconnectToPDC4000
/////////////////////////////////////////////////////////////////////////////////////////
// Function Name : WriteDataToPDC4000
// Description : 向局部总线写数据,pData第一个传递的是偏移地址,第二个是数据
/////////////////////////////////////////////////////////////////////////////////////////
BOOL WriteDataToPDC4000(ULONG * pData)
{
if (hPDC4000 == NULL)
{
return FALSE;
}
ULONG BytesReturned;
if (!DeviceIoControl(hPDC4000, IOCTL_PDC4000_WRITE_DATA, pData, 2 * sizeof(ULONG),
NULL, 0, &BytesReturned, NULL))
{
CloseHandle(hPDC4000);
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Function Name : ReadDataFromPDC4000
// Description : 读取局部总线数据,pData传递的是偏移地址,返回的是数据
/////////////////////////////////////////////////////////////////////////////////////////
BOOL ReadDataFromPDC4000(ULONG * pData)
{
if (hPDC4000 == NULL)
{
return FALSE;
}
ULONG BytesReturned;
if (!DeviceIoControl(hPDC4000, IOCTL_PDC4000_READ_DATA, pData, sizeof(ULONG),
pData, sizeof(DWORD), &BytesReturned, NULL))
{
CloseHandle(hPDC4000);
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Function Name : BlockDmaPciToLocal
// Description : 启动Block DMA,写数据,pData是缓冲区地址,dwSize是大小
/////////////////////////////////////////////////////////////////////////////////////////
BOOL BlockDmaPciToLocal(unsigned char * pData, DWORD dwSize)
{
if ((hPDC4000 == NULL) || (dwSize > MAX_BLOCK_DMA_BUFFER_LENGTH))
{
return FALSE;
}
ULONG lBytesReturned;
if (!DeviceIoControl(hPDC4000, IOCTL_PDC4000_BLOCK_DMA_PCI_TO_LOCAL, pData, dwSize,
NULL, 0, &lBytesReturned, NULL))
{
CloseHandle(hPDC4000);
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Function Name : BlockDmaLocalToPci
// Description : 启动Block DMA,读取数据,pData是缓冲区地址,dwSize是大小
/////////////////////////////////////////////////////////////////////////////////////////
BOOL BlockDmaLocalToPci(unsigned char * pData, DWORD dwSize)
{
if ((hPDC4000 == NULL) || (dwSize > MAX_BLOCK_DMA_BUFFER_LENGTH))
{
return FALSE;
}
ULONG lBytesReturned;
if (!DeviceIoControl(hPDC4000, IOCTL_PDC4000_BLOCK_DMA_LOCAL_TO_PCI, NULL, 0,
pData, dwSize, &lBytesReturned, NULL))
{
CloseHandle(hPDC4000);
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Function Name : SglDmaPciToLocal
// Description : 启动Scatter Gather DMA,写数据,pData是缓冲区地址,dwSize是大小
/////////////////////////////////////////////////////////////////////////////////////////
BOOL SglDmaPciToLocal(unsigned char * pData, DWORD dwSize)
{
if (hPDC4000 == NULL)
{
return FALSE;
}
OVERLAPPED ol;
memset(&ol, 0, sizeof(ol));
ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
ULONG lBytesReturned;
if (!WriteFile(hPDC4000, pData, dwSize, &lBytesReturned, &ol))
{
ULONG lNumberOfBytesTransferred;
//等待DMA完成
if (!GetOverlappedResult(hPDC4000, &ol, &lNumberOfBytesTransferred, TRUE))
{
CloseHandle(ol.hEvent);
CloseHandle(hPDC4000);
return FALSE;
}
}
CloseHandle(ol.hEvent);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Function Name : SglDmaLocalToPci
// Description : 启动Scatter Gather DMA,读取数据,pData是缓冲区地址,dwSize是大小
/////////////////////////////////////////////////////////////////////////////////////////
BOOL SglDmaLocalToPci(unsigned char * pData, DWORD dwSize)
{
if (hPDC4000 == NULL)
{
return FALSE;
}
OVERLAPPED ol;
memset(&ol, 0, sizeof(ol)); //Must clear the struct
ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
ULONG lBytesReturned;
if (!ReadFile(hPDC4000, pData, dwSize, &lBytesReturned, &ol))
{
ULONG lNumberOfBytesTransferred;
//等待DMA完成
if (!GetOverlappedResult(hPDC4000, &ol, &lNumberOfBytesTransferred, TRUE))
{
CloseHandle(ol.hEvent);
CloseHandle(hPDC4000);
return FALSE;
}
CloseHandle(hPDC4000);
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Function Name : BurstWriteDataToPDC4000
// Description : 一次写多个数据,这里只是演示16个数据
/////////////////////////////////////////////////////////////////////////////////////////
BOOL BurstWriteDataToPDC4000(unsigned char * pData, unsigned int uiSize)
{
if (hPDC4000 == NULL)
{
return FALSE;
}
ULONG BytesReturned;
if (!DeviceIoControl(hPDC4000, IOCTL_PDC4000_BURST_WRITE_DATA, pData, uiSize,
NULL, 0, &BytesReturned, NULL))
{
CloseHandle(hPDC4000);
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Function Name : BurstReadDataFromPDC4000
// Description : 一次读多个数据,这里只是演示16个数据
/////////////////////////////////////////////////////////////////////////////////////////
BOOL BurstReadDataFromPDC4000(unsigned char * pData, unsigned int uiSize)
{
if (hPDC4000 == NULL)
{
return FALSE;
}
ULONG BytesReturned;
if (!DeviceIoControl(hPDC4000, IOCTL_PDC4000_BURST_READ_DATA, pData, sizeof(ULONG),
pData, uiSize, &BytesReturned, NULL))
{
CloseHandle(hPDC4000);
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Function Name : ReadDataFrom9054Reg
// Description : 读取9054的寄存器,,pData传递的是偏移地址,返回的是数据
/////////////////////////////////////////////////////////////////////////////////////////
BOOL ReadDataFrom9054Reg(unsigned long * pData)
{
if (hPDC4000 == NULL)
{
return FALSE;
}
ULONG BytesReturned;
if (!DeviceIoControl(hPDC4000, IOCTL_PDC4000_READ_REG_DATA, pData, sizeof(ULONG),
pData, sizeof(ULONG), &BytesReturned, NULL))
{
CloseHandle(hPDC4000);
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Function Name : WriteDataTo9054Reg
// Description : 写9054的寄存器,pData第一个传递的是偏移地址,第二个是数据
/////////////////////////////////////////////////////////////////////////////////////////
BOOL WriteDataTo9054Reg(unsigned long * pData)
{
if (hPDC4000 == NULL)
{
return FALSE;
}
ULONG BytesReturned;
if (!DeviceIoControl(hPDC4000, IOCTL_PDC4000_WRITE_REG_DATA, pData, 2 * sizeof(ULONG),
NULL, 0, &BytesReturned, NULL))
{
CloseHandle(hPDC4000);
return FALSE;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////
// Function Name : WaitForReceiveDataThreadPro
// Description : The thread function which wait for the receive data's event.
///////////////////////////////////////////////////////////////////////////////////////
UINT WaitForReceiveDataThreadPro(LPVOID pParam)
{
//Check that whether the user have connected to PDC4000.
if (hPDC4000 == NULL)
return FALSE;
DWORD dw;
while (TRUE)
{
dw = WaitForMultipleObjects(2,hEvent,FALSE,INFINITE);
if (dw == (WAIT_OBJECT_0))//Oh, there are some data coming
{
ResetEvent(hEvent[0]);
::PostMessage((HWND)pParam,WM_PDC4000_INTERRUPT,0,0);
}
else //OK, let me exit.
{
CloseHandle(hEvent[1]);
CloseHandle(hEvent[0]);
break;
}
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////
// Function Name : GetDeviceViaInterface
// Description : Open a device with GUID
///////////////////////////////////////////////////////////////////////////////////////
HANDLE GetDeviceViaInterface( GUID* pGuid, DWORD instance)
{ //GetDeviceViaInterface
// Get handle to relevant device information set
HDEVINFO info = SetupDiGetClassDevs(pGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
if(info==INVALID_HANDLE_VALUE)
{
printf("No HDEVINFO available for this GUID\n");
return NULL;
}
// Get interface data for the requested instance
SP_INTERFACE_DEVICE_DATA ifdata;
ifdata.cbSize = sizeof(ifdata);
if(!SetupDiEnumDeviceInterfaces(info, NULL, pGuid, instance, &ifdata))
{
printf("No SP_INTERFACE_DEVICE_DATA available for this GUID instance\n");
SetupDiDestroyDeviceInfoList(info);
return NULL;
}
// Get size of symbolic link name
DWORD ReqLen;
SetupDiGetDeviceInterfaceDetail(info, &ifdata, NULL, 0, &ReqLen, NULL);
PSP_INTERFACE_DEVICE_DETAIL_DATA ifDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)(new char[ReqLen]);
if( ifDetail==NULL)
{
SetupDiDestroyDeviceInfoList(info);
return NULL;
}
// Get symbolic link name
ifDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
if( !SetupDiGetDeviceInterfaceDetail(info, &ifdata, ifDetail, ReqLen, NULL, NULL))
{
SetupDiDestroyDeviceInfoList(info);
delete ifDetail;
return NULL;
}
printf("Symbolic link is %s\n",ifDetail->DevicePath);
// Open file
HANDLE rv = CreateFile( ifDetail->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if( rv==INVALID_HANDLE_VALUE)
rv = NULL;
delete ifDetail;
SetupDiDestroyDeviceInfoList(info);
return rv;
} //GetDeviceViaInterface
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -