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