// Copyright (2019-2023) Paul Scherrer Institute #include "PCIExpressDevice.h" #include "../common/NetworkAddressConvert.h" PCIExpressDevice::PCIExpressDevice(uint16_t data_stream, uint16_t pci_slot) : PCIExpressDevice("/dev/jfjoch" + std::to_string(pci_slot), data_stream) {} PCIExpressDevice::PCIExpressDevice(uint16_t data_stream) : PCIExpressDevice("/dev/jfjoch" + std::to_string(data_stream), data_stream) {} PCIExpressDevice::PCIExpressDevice(const std::string &device_name, uint16_t data_stream) : FPGAAcquisitionDevice(data_stream), dev(device_name, true) { DataCollectionStatus status = dev.GetDataCollectionStatus(); max_modules = status.max_modules; if (max_modules == 0) throw JFJochException(JFJochExceptionCategory::PCIeError, "Max modules cannot be zero"); uint32_t num_buf = GetNumKernelBuffers(); if (num_buf < max_modules * (3 + 3 * 16)) throw JFJochException(JFJochExceptionCategory::PCIeError, "Need to increase number of host-device buffers"); buffer_device.resize(num_buf, nullptr); try { for (int i = 0; i < num_buf; i++) buffer_device[i] = dev.MapKernelBuffer(i); } catch (JFJochException &e) { UnmapBuffers(); throw; } } bool PCIExpressDevice::HW_ReadMailbox(uint32_t *values) { return dev.ReadWorkCompletion(values); } void PCIExpressDevice::Cancel() { dev.Cancel(); } bool PCIExpressDevice::HW_SendWorkRequest(uint32_t handle) { return dev.SendWorkRequest(handle); } void PCIExpressDevice::FPGA_StartAction(const DiffractionExperiment &experiment) { dev.Start(); if (experiment.IsUsingInternalPacketGen()) { FrameGeneratorConfig config{}; config.frames = experiment.GetFrameNum() + DELAY_FRAMES_STOP_AND_QUIT + 1; config.modules = experiment.GetModulesNum(data_stream); config.dest_mac_addr = dev.GetMACAddress(); config.dest_ipv4_addr = dev.GetIPv4Address(); dev.RunFrameGenerator(config); } } void PCIExpressDevice::FPGA_EndAction() { dev.End(); } bool PCIExpressDevice::HW_IsIdle() const { return dev.IsIdle(); } void PCIExpressDevice::HW_WriteActionRegister(const DataCollectionConfig *config) { dev.SetConfig(*config); } void PCIExpressDevice::HW_ReadActionRegister(DataCollectionConfig *config) { *config = dev.GetConfig(); } std::string PCIExpressDevice::GetMACAddress() const { return MacAddressToStr(dev.GetMACAddress()); } void PCIExpressDevice::SetMACAddress(uint64_t mac_addr_network_order) { dev.SetMACAddress(mac_addr_network_order); } void PCIExpressDevice::HW_GetStatus(DataCollectionStatus *status) const { *status = dev.GetDataCollectionStatus(); } void PCIExpressDevice::HW_GetEnvParams(DeviceStatus *status) const { *status = dev.GetDeviceStatus(); } uint32_t PCIExpressDevice::GetNumKernelBuffers() const { return dev.GetBufferCount(); } int32_t PCIExpressDevice::GetNUMANode() const { return dev.GetNumaNode(); } void PCIExpressDevice::SetDefaultMAC() { dev.SetDefaultMACAddress(); } void PCIExpressDevice::SetIPv4Address(uint32_t ipv4_addr_network_order) { dev.SetIPv4Address(ipv4_addr_network_order); } std::string PCIExpressDevice::GetIPv4Address() const { return IPv4AddressToStr(dev.GetIPv4Address()); } void PCIExpressDevice::HW_LoadCalibration(uint32_t in_modules, uint32_t in_storage_cells) { dev.LoadCalibration(in_modules, in_storage_cells); } void PCIExpressDevice::HW_LoadIntegrationMap(uint32_t in_modules) { dev.LoadIntegrationMap(in_modules); } uint32_t PCIExpressDevice::GetCompletedDescriptors() const { return dev.GetCompletedDescriptors(); } void PCIExpressDevice::HW_LoadInternalGeneratorFrame(uint32_t in_modules) { dev.LoadInternalGeneratorFrame(in_modules); } void PCIExpressDevice::HW_SetSpotFinderParameters(const SpotFinderParameters ¶ms) { dev.SetSpotFinderParameters(params); }