#include #include #include #include #include "time.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "PcieFun.h" #include #include #include #include #include #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; }