// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include "PCIExpressDevice.h" #include "../common/NetworkAddressConvert.h" #define PCI_EXCEPT(x) try {x;} catch (const std::exception &e) { throw PCIeDeviceException(e.what()); } PCIExpressDevice::PCIExpressDevice(uint16_t data_stream, uint16_t pci_slot) : PCIExpressDevice(data_stream, "/dev/jfjoch" + std::to_string(pci_slot)) {} PCIExpressDevice::PCIExpressDevice(uint16_t data_stream) : PCIExpressDevice(data_stream, "/dev/jfjoch" + std::to_string(data_stream)) {} PCIExpressDevice::PCIExpressDevice(uint16_t data_stream, const std::string &device_name) : FPGAAcquisitionDevice(data_stream), dev(device_name, true) { DataCollectionStatus status; PCI_EXCEPT(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(); 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) { PCI_EXCEPT(return dev.ReadWorkCompletion(values);) } void PCIExpressDevice::Cancel() { PCI_EXCEPT(dev.Cancel();) } bool PCIExpressDevice::HW_SendWorkRequest(uint32_t handle) { PCI_EXCEPT(return dev.SendWorkRequest(handle);) } void PCIExpressDevice::FPGA_StartAction(const DiffractionExperiment &experiment) { PCI_EXCEPT(dev.Start();) } void PCIExpressDevice::HW_RunInternalGenerator(const FrameGeneratorConfig &config) { PCI_EXCEPT(dev.RunFrameGenerator(config);) } void PCIExpressDevice::FPGA_EndAction() { PCI_EXCEPT(dev.End();) } bool PCIExpressDevice::HW_IsIdle() const { PCI_EXCEPT(return dev.IsIdle();) } void PCIExpressDevice::HW_WriteActionRegister(const DataCollectionConfig *config) { PCI_EXCEPT(dev.SetConfig(*config);) } void PCIExpressDevice::HW_ReadActionRegister(DataCollectionConfig *config) { PCI_EXCEPT(*config = dev.GetConfig();) } std::string PCIExpressDevice::GetMACAddress() const { PCI_EXCEPT(return MacAddressToStr(dev.GetMACAddress());) } uint32_t PCIExpressDevice::GetNumKernelBuffers() const { PCI_EXCEPT(return dev.GetBufferCount();) } int32_t PCIExpressDevice::GetNUMANode() const { PCI_EXCEPT(return dev.GetNumaNode();) } void PCIExpressDevice::SetIPv4Address(uint32_t ipv4_addr_network_order) { PCI_EXCEPT( // Configure all links with the same IPv4 address auto dev_status = dev.GetDeviceStatus(); for (int i = 0; i < dev_status.eth_link_count; i++) dev.SetIPv4Address(ipv4_addr_network_order, i); dev.SetIPv4Address(ipv4_addr_network_order, NET_IF_FRAME_GENERATOR); ) } std::string PCIExpressDevice::GetIPv4Address() const { PCI_EXCEPT( return IPv4AddressToStr(dev.GetIPv4Address()); ) } void PCIExpressDevice::HW_SetSpotFinderParameters(const SpotFinderParameters ¶ms) { PCI_EXCEPT( dev.SetSpotFinderParameters(params); ) } DeviceStatus PCIExpressDevice::GetDeviceStatus() const { PCI_EXCEPT( return dev.GetDeviceStatus(); ) } DataCollectionStatus PCIExpressDevice::GetDataCollectionStatus() const { PCI_EXCEPT( return dev.GetDataCollectionStatus(); ) } void PCIExpressDevice::HW_LoadCalibration(const LoadCalibrationConfig &config) { PCI_EXCEPT(dev.LoadCalibration(config);) }