506 lines
15 KiB
C++
506 lines
15 KiB
C++
#include <QMutex>
|
||
#include <QMutexLocker>
|
||
#include <iostream>
|
||
#include <chrono>
|
||
#include "time.h"
|
||
#include <sstream>
|
||
#include <ctime>
|
||
#include <QString>
|
||
#include <QDebug>
|
||
#include <QSpinBox>
|
||
|
||
|
||
#include <Windows.h>
|
||
#include <assert.h>
|
||
#include <stdlib.h>
|
||
#include <stdio.h>
|
||
#include <strsafe.h>
|
||
#include <stdint.h>
|
||
#include <SetupAPI.h>
|
||
#include <INITGUID.H>
|
||
#include <WinIoCtl.h>
|
||
#include "PcieFun.h"
|
||
#include <io.h>
|
||
#include <setupapi.h>
|
||
#include <cfgmgr32.h>
|
||
#include <QThread>
|
||
#include <QDateTime>
|
||
#include "./XDmaCommDef.h"
|
||
|
||
|
||
|
||
#define BigLittleSwap32(A) ((((int)(A) & 0xff000000) >> 24) | \
|
||
(((int)(A) & 0x00ff0000) >> 8) | \
|
||
(((int)(A) & 0x0000ff00) << 8) | \
|
||
(((int)(A) & 0x000000ff) << 24))
|
||
|
||
typedef unsigned int uint;
|
||
|
||
#pragma comment(lib, "setupapi.lib")
|
||
|
||
#define MAX_BYTES_PER_TRANSFER 0x800000
|
||
#define FPGA_DDR_START_ADDR 0x00000000
|
||
|
||
static HANDLE h_c2h0 = INVALID_HANDLE_VALUE;
|
||
static HANDLE h_h2c0 = INVALID_HANDLE_VALUE;
|
||
static HANDLE h_user = INVALID_HANDLE_VALUE;
|
||
static HANDLE h_control = INVALID_HANDLE_VALUE;
|
||
|
||
static DWORD user_start_en;
|
||
static char base_path[MAX_PATH + 1] = "";
|
||
static bool m_bIsCardOpen = false;
|
||
QMutex g_regControlMutex;
|
||
|
||
|
||
static int verbose_msg(const char* const fmt, ...)
|
||
{
|
||
int ret = 0;
|
||
va_list args;
|
||
if (1)
|
||
{
|
||
va_start(args, fmt);
|
||
ret = vprintf(fmt, args);
|
||
va_end(args);
|
||
}
|
||
return ret;
|
||
}
|
||
static BYTE* allocate_buffer(size_t size, size_t alignment)
|
||
{
|
||
if (size == 0)
|
||
{
|
||
size = 4;
|
||
}
|
||
if (alignment == 0)
|
||
{
|
||
SYSTEM_INFO sys_info;
|
||
GetSystemInfo(&sys_info);
|
||
alignment = sys_info.dwPageSize;
|
||
//printf("alignment = %d\n",alignment);
|
||
}
|
||
verbose_msg("Allocating host-side buffer of size %d, aligned to %d bytes\n", size, alignment);
|
||
return (BYTE*)_aligned_malloc(size, alignment);
|
||
}
|
||
|
||
|
||
int Pcie_GetDevices(GUID id, char** devpath)
|
||
{
|
||
size_t path_len = MAX_PATH + 1;
|
||
for (int i = 0; i < 4; i++)
|
||
{
|
||
devpath[i] = (char*)malloc(sizeof(char) * path_len);
|
||
memset(devpath[i], 0, MAX_PATH + 1);
|
||
}
|
||
SP_DEVICE_INTERFACE_DATA device_interface;
|
||
PSP_DEVICE_INTERFACE_DETAIL_DATA dev_detail;
|
||
DWORD index;
|
||
HDEVINFO device_info;
|
||
wchar_t tmp[256];
|
||
device_info = SetupDiGetClassDevs((LPGUID)&id, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||
if (device_info == INVALID_HANDLE_VALUE)
|
||
{
|
||
// fprintf(stderr, "GetDevices INVALID_HANDLE_VALUE\n");
|
||
exit(-1);
|
||
}
|
||
device_interface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
|
||
// enumerate through devices
|
||
for (index = 0; SetupDiEnumDeviceInterfaces(device_info, NULL, &id, index, &device_interface); ++index)
|
||
{
|
||
// get required buffer size
|
||
ULONG detailLength = 0;
|
||
if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_interface, NULL, 0, &detailLength, NULL) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||
{
|
||
// fprintf(stderr, "SetupDiGetDeviceInterfaceDetail - get length failed\n");
|
||
break;
|
||
}
|
||
// allocate space for device interface detail
|
||
dev_detail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, detailLength);
|
||
if (!dev_detail)
|
||
{
|
||
// fprintf(stderr, "HeapAlloc failed\n");
|
||
break;
|
||
}
|
||
dev_detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||
// get device interface detail
|
||
if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_interface, dev_detail, detailLength, NULL, NULL))
|
||
{
|
||
// fprintf(stderr, "SetupDiGetDeviceInterfaceDetail - get detail failed\n");
|
||
HeapFree(GetProcessHeap(), 0, dev_detail);
|
||
break;
|
||
}
|
||
StringCchCopy(tmp, path_len, dev_detail->DevicePath);
|
||
wcstombs(devpath[index], tmp, 256);
|
||
HeapFree(GetProcessHeap(), 0, dev_detail);
|
||
}
|
||
SetupDiDestroyDeviceInfoList(device_info);
|
||
// //禁用启用设备
|
||
// EnableDisableDevice();
|
||
return index;
|
||
}
|
||
|
||
|
||
HANDLE open_devices(char* device_base_path, char* device_name, DWORD accessFlags)
|
||
{
|
||
char device_path[MAX_PATH + 1] = "";
|
||
wchar_t device_path_w[MAX_PATH + 1];
|
||
HANDLE h;
|
||
// extend device path to include target device node (xdma_control, xdma_user etc)
|
||
verbose_msg("Device base path: %s\n", device_base_path);
|
||
strcpy_s(device_path, sizeof device_path, device_base_path);
|
||
strcat_s(device_path, sizeof device_path, device_name);
|
||
verbose_msg("Device node: %s\n", device_name);
|
||
// open device file
|
||
mbstowcs(device_path_w, device_path, sizeof(device_path));
|
||
h = CreateFile(device_path_w, accessFlags, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||
qDebug() << QString::fromWCharArray(device_path_w) ;
|
||
// qDebug << "open_devices : " << QString::fromStdString(device_path_w) ;
|
||
if (h == INVALID_HANDLE_VALUE)
|
||
{
|
||
fprintf(stderr, "Error opening device, win32 error code: %ld\n", GetLastError());
|
||
}
|
||
return h;
|
||
}
|
||
|
||
static int read_device(HANDLE device, long address, DWORD size, BYTE* buffer)
|
||
{
|
||
DWORD rd_size = 0;
|
||
unsigned int transfers;
|
||
unsigned int i;
|
||
if (INVALID_SET_FILE_POINTER == SetFilePointer(device, address, NULL, FILE_BEGIN))
|
||
{
|
||
fprintf(stderr, "Error setting file pointer, win32 error code: %ld\n", GetLastError());
|
||
return -3;
|
||
}
|
||
// qDebug() << "Start ";
|
||
transfers = (unsigned int)(size / MAX_BYTES_PER_TRANSFER);
|
||
for (i = 0; i < transfers; i++)
|
||
{
|
||
if (!ReadFile(device, (void*)(buffer + i * MAX_BYTES_PER_TRANSFER), (DWORD)MAX_BYTES_PER_TRANSFER, &rd_size, NULL))
|
||
{
|
||
return -1;
|
||
}
|
||
if (rd_size != MAX_BYTES_PER_TRANSFER) //采集到的数据大小不到MAX_BYTES_PER_TRANSFER,异常
|
||
{
|
||
return -2;
|
||
}
|
||
qDebug() << "Each 8M Unit: " << QString::number(i * MAX_BYTES_PER_TRANSFER, 16) ;
|
||
}
|
||
long addressLeave = address + transfers * MAX_BYTES_PER_TRANSFER;
|
||
if (INVALID_SET_FILE_POINTER == SetFilePointer(device, addressLeave, NULL, FILE_BEGIN))
|
||
{
|
||
fprintf(stderr, "Error setting file pointer, win32 error code: %ld\n", GetLastError());
|
||
return -3;
|
||
}
|
||
if (!ReadFile(device, (void*)(buffer + i * MAX_BYTES_PER_TRANSFER), (DWORD)(size - i * MAX_BYTES_PER_TRANSFER), &rd_size, NULL))
|
||
{
|
||
return -1;
|
||
}
|
||
if (rd_size != (size - i * MAX_BYTES_PER_TRANSFER)) //采集到的数据大小不到(size - i * MAX_BYTES_PER_TRANSFER),异常
|
||
{
|
||
return -2;
|
||
}
|
||
return size;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
static int write_device(HANDLE device, long address, DWORD size, BYTE* buffer)
|
||
{
|
||
// fprintf(stderr, "........Enter Write device.........");
|
||
DWORD wr_size = 0;
|
||
unsigned int transfers;
|
||
unsigned int i;
|
||
transfers = (unsigned int)(size / MAX_BYTES_PER_TRANSFER);
|
||
// qDebug() << "write_device " << address;
|
||
if (INVALID_SET_FILE_POINTER == SetFilePointer(device, address, NULL, FILE_BEGIN))
|
||
{
|
||
fprintf(stderr, "Error setting file pointer, win32 error code: %ld\n", GetLastError());
|
||
return -3;
|
||
}
|
||
for (i = 0; i < transfers; i++)
|
||
{
|
||
if (!WriteFile(device, (void*)(buffer + i * MAX_BYTES_PER_TRANSFER), MAX_BYTES_PER_TRANSFER, &wr_size, NULL))
|
||
{
|
||
return -1;
|
||
}
|
||
if (wr_size != MAX_BYTES_PER_TRANSFER)
|
||
{
|
||
return -2;
|
||
}
|
||
}
|
||
long addressLeave = address + transfers * MAX_BYTES_PER_TRANSFER;
|
||
if (INVALID_SET_FILE_POINTER == SetFilePointer(device, addressLeave, NULL, FILE_BEGIN))
|
||
{
|
||
fprintf(stderr, "Error setting file pointer, win32 error code: %ld\n", GetLastError());
|
||
return -3;
|
||
}
|
||
if (!WriteFile(device, (void*)(buffer + i * MAX_BYTES_PER_TRANSFER), (DWORD)(size - i * MAX_BYTES_PER_TRANSFER), &wr_size, NULL))
|
||
{
|
||
return -1;
|
||
}
|
||
if (wr_size != (size - i * MAX_BYTES_PER_TRANSFER))
|
||
{
|
||
return -2;
|
||
}
|
||
return size;
|
||
}
|
||
|
||
|
||
bool Pcie_ReadControlRegData(unsigned int address, unsigned int size, unsigned char* buffer)
|
||
{
|
||
if (h_control == INVALID_HANDLE_VALUE)
|
||
{
|
||
return false;
|
||
}
|
||
int iCaptureSize = read_device(h_control, address, size, buffer);
|
||
if (iCaptureSize < 0)
|
||
{
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
int Pcie_WriteControlRegData(unsigned int address, unsigned char* buffer)
|
||
{
|
||
if (h_control == INVALID_HANDLE_VALUE)
|
||
{
|
||
return false;
|
||
}
|
||
int iCaptureSize = write_device(h_control, address, 4, buffer);
|
||
if (iCaptureSize < 0)
|
||
{
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
bool Pcie_ReadData(unsigned int address, unsigned int size, unsigned char* buffer)
|
||
{
|
||
if (h_c2h0 == INVALID_HANDLE_VALUE)
|
||
{
|
||
return false;
|
||
}
|
||
int iCaptureSize = read_device(h_c2h0, address, size, buffer);
|
||
if (iCaptureSize < 0)
|
||
{
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool Pcie_WriteData(unsigned int address, unsigned int size, unsigned char* buffer)
|
||
{
|
||
if (h_h2c0 == INVALID_HANDLE_VALUE)
|
||
{
|
||
return false;
|
||
}
|
||
int iInjectSize = write_device(h_h2c0, address, size, buffer);
|
||
if (iInjectSize < 0)
|
||
{
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
bool Pcie_WriteRegCmdData(unsigned int address, unsigned char* buffer, int length)
|
||
{
|
||
QMutexLocker locker(&g_regControlMutex);
|
||
if (h_user == INVALID_HANDLE_VALUE)
|
||
{
|
||
return false;
|
||
}
|
||
write_device(h_user, address, length, buffer);
|
||
return true;
|
||
}
|
||
|
||
|
||
bool Pcie_ReadRegCmdData(unsigned int address, unsigned char* buffer, int length)
|
||
{
|
||
QMutexLocker locker(&g_regControlMutex);
|
||
if (h_user == INVALID_HANDLE_VALUE)
|
||
{
|
||
return false;
|
||
}
|
||
read_device(h_user, address, length, buffer);
|
||
return true;
|
||
}
|
||
|
||
int Pcie_WriteReg(unsigned int address, unsigned char* buffer)
|
||
{
|
||
QMutexLocker locker(&g_regControlMutex);
|
||
if (h_user == INVALID_HANDLE_VALUE)
|
||
{
|
||
return -1;
|
||
}
|
||
int iStatus = 4;
|
||
iStatus = write_device(h_user, address, 4, buffer);
|
||
return iStatus;
|
||
}
|
||
|
||
|
||
|
||
DWORD Pcie_AcquireReg(unsigned int address, bool& isSuccess)
|
||
{
|
||
QMutexLocker locker(&g_regControlMutex);
|
||
if (h_user == INVALID_HANDLE_VALUE)
|
||
{
|
||
isSuccess = false;
|
||
return 0;
|
||
}
|
||
DWORD value = 0;
|
||
int status = read_device(h_user, address, 4, (BYTE*)&value);
|
||
if (status < 0)
|
||
{
|
||
isSuccess = false;
|
||
}
|
||
else
|
||
{
|
||
isSuccess = true;
|
||
}
|
||
return value;
|
||
}
|
||
|
||
DWORD Pcie_ReadReg(unsigned int address)
|
||
{
|
||
QMutexLocker locker(&g_regControlMutex);
|
||
if (h_user == INVALID_HANDLE_VALUE)
|
||
{
|
||
return 0;
|
||
}
|
||
DWORD value = 0;
|
||
read_device(h_user, address, 4, (BYTE*)&value);
|
||
return value;
|
||
}
|
||
|
||
void Pcie_CloseCard()
|
||
{
|
||
if (m_bIsCardOpen)
|
||
{
|
||
if (h_user != INVALID_HANDLE_VALUE)
|
||
{
|
||
user_start_en = 0x00000000;
|
||
write_device(h_user, 0x04, 4, (BYTE*)&user_start_en); //clear irq
|
||
CloseHandle(h_user);
|
||
h_user = INVALID_HANDLE_VALUE;
|
||
}
|
||
if (h_c2h0 != INVALID_HANDLE_VALUE)
|
||
{
|
||
CloseHandle(h_c2h0);
|
||
h_c2h0 = INVALID_HANDLE_VALUE;
|
||
}
|
||
if (h_h2c0 != INVALID_HANDLE_VALUE)
|
||
{
|
||
CloseHandle(h_h2c0);
|
||
h_h2c0 = INVALID_HANDLE_VALUE;
|
||
}
|
||
if (h_control != INVALID_HANDLE_VALUE)
|
||
{
|
||
CloseHandle(h_control);
|
||
h_control = INVALID_HANDLE_VALUE;
|
||
}
|
||
m_bIsCardOpen = false;
|
||
}
|
||
}
|
||
|
||
|
||
bool Pcie_OpenCard(char* devicepath)
|
||
{
|
||
//禁用启用设备
|
||
Pcie_CloseCard();
|
||
char user_name[] = "\\user";
|
||
char c2h0_name[] = "\\c2h_0";
|
||
char h2c0_name[] = "\\h2c_0";
|
||
char control_name[] = "\\control";
|
||
qDebug() << "xxx55 " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
|
||
h_user = open_devices(devicepath, user_name, GENERIC_READ | GENERIC_WRITE);
|
||
if (h_user == INVALID_HANDLE_VALUE)
|
||
return false;
|
||
uint resetValue = 1;
|
||
qDebug() << "xxx11 " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
|
||
write_device(h_user, ControlRegBaseAddr + 0x014, 4, (BYTE*)&resetValue); // 复位采集卡
|
||
QThread::msleep(50); //等待FPGA复位 清除上一次的数据
|
||
CloseHandle(h_user);
|
||
h_user = INVALID_HANDLE_VALUE;
|
||
//禁用启用设备
|
||
EnableDisableDevice();
|
||
qDebug() << "xxx44 " << QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
|
||
h_user = open_devices(devicepath, user_name, GENERIC_READ | GENERIC_WRITE);
|
||
if (h_user == INVALID_HANDLE_VALUE)
|
||
return false;
|
||
h_h2c0 = open_devices(devicepath, h2c0_name, GENERIC_WRITE);
|
||
if (h_h2c0 == INVALID_HANDLE_VALUE)
|
||
return false;
|
||
h_c2h0 = open_devices(devicepath, c2h0_name, GENERIC_READ);
|
||
if (h_c2h0 == INVALID_HANDLE_VALUE)
|
||
return false;
|
||
h_control = open_devices(devicepath, control_name, GENERIC_READ);
|
||
if (h_control == INVALID_HANDLE_VALUE)
|
||
return false;
|
||
// open_event();
|
||
user_start_en = 0xffff0000;
|
||
write_device(h_user, 0x04, 4, (BYTE*)&user_start_en); //start irq
|
||
m_bIsCardOpen = true;
|
||
return true;
|
||
}
|
||
|
||
|
||
|
||
bool EnableDisableDevice()
|
||
{
|
||
HDEVINFO hDevInfo = SetupDiGetClassDevs(nullptr, nullptr, nullptr, DIGCF_ALLCLASSES | DIGCF_PRESENT);
|
||
if (hDevInfo == INVALID_HANDLE_VALUE)
|
||
return false;
|
||
SP_DEVINFO_DATA devInfoData;
|
||
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
|
||
bool success = false;
|
||
for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &devInfoData); ++i)
|
||
{
|
||
WCHAR deviceId[MAX_DEVICE_ID_LEN];
|
||
if (CM_Get_Device_IDW(devInfoData.DevInst, deviceId, MAX_DEVICE_ID_LEN, 0) == CR_SUCCESS)
|
||
{
|
||
// qDebug() << "deviceId List: " << i << " " << QString::fromWCharArray(deviceId) << deviceId;
|
||
if (QString::fromWCharArray(deviceId).contains("VEN_10EE")) //xilinx设备
|
||
{
|
||
bool isSuccess = false;
|
||
int code = CM_Disable_DevNode(devInfoData.DevInst, CM_DISABLE_POLITE);
|
||
if (code == CR_SUCCESS)
|
||
{
|
||
isSuccess = true;
|
||
}
|
||
qDebug() << "isSuccess01 : " << isSuccess << GetLastError() ;
|
||
Sleep(20);
|
||
isSuccess = false;
|
||
if (CM_Enable_DevNode(devInfoData.DevInst, 0) == CR_SUCCESS)
|
||
{
|
||
isSuccess = true;
|
||
}
|
||
qDebug() << "isSuccess02 : " << isSuccess << GetLastError() ;
|
||
Sleep(20);
|
||
}
|
||
}
|
||
}
|
||
SetupDiDestroyDeviceInfoList(hDevInfo);
|
||
return success;
|
||
}
|
||
|
||
|
||
|
||
bool Pcie_IsCardOpen()
|
||
{
|
||
return m_bIsCardOpen;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|