Line data Source code
1 : /**
2 : * @file DeviceManager.cxx
3 : *
4 : * This is part of the DUNE DAQ , copyright 2020.
5 : * Licensing/copyright details are in the COPYING file that you should have
6 : * received with this code.
7 : */
8 : #ifndef SSPMODULES_SRC_ANLBOARD_DEVICEMANAGER_CXX_
9 : #define SSPMODULES_SRC_ANLBOARD_DEVICEMANAGER_CXX_
10 :
11 : #include "DeviceManager.hpp"
12 : // #include "ftd2xx.h"
13 : // #include "dune-artdaq/DAQLogger/DAQLogger.hh"
14 : #include "anlExceptions.hpp"
15 :
16 : #include "boost/asio.hpp"
17 :
18 : #include <cstdint>
19 : #include <cstdio>
20 : #include <cstring>
21 : #include <iomanip>
22 : #include <iostream>
23 : #include <memory>
24 : #include <string>
25 : #include <unistd.h>
26 : #include <utility>
27 :
28 : dunedaq::sspmodules::DeviceManager&
29 0 : dunedaq::sspmodules::DeviceManager::Get()
30 : {
31 0 : static dunedaq::sspmodules::DeviceManager instance;
32 0 : return instance;
33 : }
34 :
35 0 : dunedaq::sspmodules::DeviceManager::DeviceManager() {}
36 :
37 : //
38 : // unsigned int SSPDAQ::DeviceManager::GetNUSBDevices(){
39 : // if(!fHaveLookedForDevices){
40 : // this->RefreshDevices();
41 : // }
42 : // return fUSBDevices.size();
43 : //}
44 : //
45 :
46 : void
47 0 : dunedaq::sspmodules::DeviceManager::RefreshDevices()
48 : {
49 0 : for (auto device = fEthernetDevices.begin(); device != fEthernetDevices.end(); ++device) {
50 0 : if ((device->second)->IsOpen()) {
51 : // dune::DAQLogger::LogWarning("SSP_DeviceManager")<<"Device manager refused request to refresh device list"
52 : //<<"due to ethernet devices still open"<<std::endl;
53 : }
54 : }
55 :
56 : // Clear Device List
57 : // fUSBDevices.clear();
58 0 : fEthernetDevices.clear();
59 :
60 : //
61 : // //===========================//
62 : // //==Find USB devices=========//
63 : // //===========================//
64 : //
65 : // unsigned int ftNumDevs;
66 : //
67 : // std::map<std::string,FT_DEVICE_LIST_INFO_NODE*> dataChannels;
68 : // std::map<std::string,FT_DEVICE_LIST_INFO_NODE*> commChannels;
69 : //
70 : // // This code uses FTDI's D2XX driver to determine the available devices
71 : // if(FT_CreateDeviceInfoList(&ftNumDevs)!=FT_OK){
72 : // try {
73 : // //dune::DAQLogger::LogError("SSP_DeviceManager")<<"Failed to create FTDI device info list"<<std::endl;
74 : // } catch (...) {}
75 : // throw(EFTDIError("Error in FT_CreateDeviceInfoList"));
76 : // }
77 : //
78 : // FT_DEVICE_LIST_INFO_NODE* deviceInfoNodes=new FT_DEVICE_LIST_INFO_NODE[ftNumDevs];
79 : //
80 : // if(FT_GetDeviceInfoList(deviceInfoNodes,&ftNumDevs)!=FT_OK){
81 : // delete deviceInfoNodes;
82 : // try {
83 : // //dune::DAQLogger::LogError("SSP_DeviceManager")<<"Failed to get FTDI device info list"<<std::endl;
84 : // } catch (...) {}
85 : // throw(EFTDIError("Error in FT_GetDeviceInfoList"));
86 : // }
87 : //
88 : // //Search through all devices for compatible interfaces
89 : // for (unsigned int i = 0; i < ftNumDevs; i++) {
90 : // // NOTE 1: Each device is actually 2 FTDI devices. Device with "A" at the end of serial number is the
91 : // // data channel. "B" is the comms channel. Need to associate FTDI devices with the same base
92 : // // number together to get a "whole" board.
93 : // //
94 : // // NOTE 2: There is a rare error in which the FTDI driver returns FT_OK but the device info is incorrect
95 : // // In this case, the check on ftType and/or length of ftSerial will fail
96 : // // The discover code will therefore fail to find any useable devices but will not return an error
97 : // // The calling code should check numDevices and rerun FindDevices if it equals zero
98 : //
99 : // // Search only for devices we can use (skip any others)
100 : // if (deviceInfoNodes[i].Type != FT_DEVICE_2232H) {
101 : // continue; // Skip to next device
102 : // }
103 : //
104 : // // Add FTDI device to Device List using Serial number
105 : // //If length is zero, then device is probably open in another process (though maybe we don't get type then
106 : // either...)
107 : // //===TODO: Should check flags for open devices and report the number open in other processes to cout
108 : // unsigned int length = strlen(deviceInfoNodes[i].SerialNumber); // Find length of serial number
109 : // (including 'A' or 'B') if (length == 0) {
110 : // continue; // Skip to next device
111 : // }
112 : //
113 : // char serial[16];
114 : //
115 : // strncpy(serial, deviceInfoNodes[i].SerialNumber, length - 1); // Copy base serial number
116 : // serial[length-1] = 0; // Append NULL because strncpy() didn't!
117 : //
118 : // // Update device list with FTDI device number
119 : // switch (deviceInfoNodes[i].SerialNumber[length -1]) {
120 : // case 'A':
121 : // dataChannels[serial]=&(deviceInfoNodes[i]);
122 : // break;
123 : // case 'B':
124 : // commChannels[serial]=&(deviceInfoNodes[i]);
125 : // break;
126 : // default:
127 : // break;
128 : // }
129 : // }
130 : //
131 : // //Check that device list is as expected, then construct USB device objects for each board
132 : // if(dataChannels.size()!=commChannels.size()){
133 : // try {
134 : // //dune::DAQLogger::LogError("SSP_DeviceManager")<<"Different number of data and comm channels on
135 : // FTDI!"<<std::endl;
136 : // } catch (...) {}
137 : // delete deviceInfoNodes;
138 : // throw(EBadDeviceList());
139 : // }
140 : // std::map<std::string,FT_DEVICE_LIST_INFO_NODE*>::iterator dIter=dataChannels.begin();
141 : // std::map<std::string,FT_DEVICE_LIST_INFO_NODE*>::iterator cIter=commChannels.begin();
142 : //
143 : // for(;dIter!=dataChannels.end();++dIter,++cIter){
144 : // if(dIter->first!=cIter->first){
145 : // try {
146 : // //dune::DAQLogger::LogError("SSP_DeviceManager")<<"Non-matching serial numbers for data and comm channels on
147 : // FTDI!"<<std::endl;
148 : // } catch (...) {}
149 : // delete deviceInfoNodes;
150 : // throw(EBadDeviceList());
151 : // }
152 : // fUSBDevices.push_back(USBDevice(dIter->second,cIter->second));
153 : // //dune::DAQLogger::LogInfo("SSP_DeviceManager")<<"Found a device with serial "<<dIter->first<<std::endl;
154 : // }
155 : //
156 : // delete[] deviceInfoNodes;
157 : //
158 0 : }
159 :
160 : dunedaq::sspmodules::Device*
161 0 : dunedaq::sspmodules::DeviceManager::OpenDevice(unsigned int deviceNum, bool slowControlOnly)
162 : {
163 :
164 0 : Device* device = 0;
165 0 : if (fEthernetDevices.find(deviceNum) == fEthernetDevices.end()) {
166 0 : fEthernetDevices[deviceNum] = (std::move(
167 0 : std::unique_ptr<dunedaq::sspmodules::EthernetDevice>(new dunedaq::sspmodules::EthernetDevice(deviceNum))));
168 : }
169 0 : if (fEthernetDevices[deviceNum]->IsOpen()) {
170 : // dune::DAQLogger::LogError("SSP_DeviceManager")<<"Attempt to open already open device!"<<std::endl;
171 0 : throw(EDeviceAlreadyOpen());
172 : } else {
173 0 : device = fEthernetDevices[deviceNum].get();
174 0 : device->Open(slowControlOnly);
175 : }
176 0 : return device;
177 : }
178 :
179 : #endif // SSPMODULES_SRC_ANLBOARD_DEVICEMANAGER_CXX_
|