// Copyright (2019-2023) Paul Scherrer Institute #include "PCIExpressDevice.h" #include "../common/NetworkAddressConvert.h" 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 = 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) { 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(); } void PCIExpressDevice::HW_RunInternalGenerator(const FrameGeneratorConfig &config) { 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()); } uint32_t PCIExpressDevice::GetNumKernelBuffers() const { return dev.GetBufferCount(); } int32_t PCIExpressDevice::GetNUMANode() const { return dev.GetNumaNode(); } void PCIExpressDevice::SetIPv4Address(uint32_t ipv4_addr_network_order) { // 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 { return IPv4AddressToStr(dev.GetIPv4Address()); } void PCIExpressDevice::HW_SetSpotFinderParameters(const SpotFinderParameters ¶ms) { dev.SetSpotFinderParameters(params); } DeviceStatus PCIExpressDevice::GetDeviceStatus() const { return dev.GetDeviceStatus(); } DataCollectionStatus PCIExpressDevice::GetDataCollectionStatus() const { return dev.GetDataCollectionStatus(); } void PCIExpressDevice::HW_LoadCalibration(const LoadCalibrationConfig &config) { dev.LoadCalibration(config); }