Files
CodeRepository/Projects/App_DataCapturer/GdPCIE/PcieFun.cpp

506 lines
15 KiB
C++
Raw Normal View History

2026-02-01 22:23:06 +08:00
#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;
}