DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
EthernetDevice.cxx
Go to the documentation of this file.
1
8#ifndef SSPMODULES_SRC_ANLBOARD_ETHERNETDEVICE_CXX_
9#define SSPMODULES_SRC_ANLBOARD_ETHERNETDEVICE_CXX_
10
11#include "EthernetDevice.hpp"
12
13#include "anlExceptions.hpp"
14
15#include <algorithm>
16#include <cstdlib>
17#include <vector>
18
20
22 :
23 isOpen(false)
24 , fCommSocket(fIo_service)
25 , fDataSocket(fIo_service)
26 , fIP(boost::asio::ip::address_v4(ipAddress))
27{}
28
29void
31{
32
33 fSlowControlOnly = slowControlOnly;
34
35 // dune::DAQLogger::LogInfo("SSP_EthernetDevice")<<"Looking for SSP Ethernet device at "<<fIP.to_string()<<std::endl;
36 boost::asio::ip::tcp::resolver resolver(fIo_service);
37 boost::asio::ip::tcp::resolver::query commQuery(fIP.to_string(), slowControlOnly ? "55002" : "55001");
38 boost::asio::ip::tcp::resolver::iterator commEndpointIterator = resolver.resolve(commQuery);
39 boost::asio::connect(fCommSocket, commEndpointIterator);
40
41 if (slowControlOnly) {
42 // dune::DAQLogger::LogInfo("SSP_EthernetDevice")<<"Connected to SSP Ethernet device at
43 // "<<fIP.to_string()<<std::endl;
44 return;
45 }
46
47 boost::asio::ip::tcp::resolver::query dataQuery(fIP.to_string(), "55010");
48 boost::asio::ip::tcp::resolver::iterator dataEndpointIterator = resolver.resolve(dataQuery);
49
50 boost::asio::connect(fDataSocket, dataEndpointIterator);
51
52 // Set limited receive buffer size to avoid taxing switch
53 // JTH: Remove this since it was causing event read errors. Could try again
54 // with a different value if there are more issues which point to switch problems.
55 // boost::asio::socket_base::receive_buffer_size option(16384);
56 // fDataSocket.set_option(option);
57
58 // dune::DAQLogger::LogInfo("SSP_EthernetDevice")<<"Connected to SSP Ethernet device at "<<fIP.to_string()<<std::endl;
59}
60
61void
63{
64 isOpen = false;
65 // dune::DAQLogger::LogInfo("SSP_EthernetDevice")<<"Device closed"<<std::endl;
66}
67
68void
70{
71 DevicePurge(fCommSocket);
72}
73
74void
76{
77 DevicePurge(fDataSocket);
78}
79
80void
82{
83 unsigned int numBytes = fDataSocket.available();
84 (*numWords) = numBytes / sizeof(unsigned int);
85}
86
87void
88dunedaq::sspmodules::EthernetDevice::DeviceReceive(std::vector<unsigned int>& data, unsigned int size)
89{
90 data.resize(size);
91 unsigned int dataReturned = fDataSocket.read_some(boost::asio::buffer(data));
92 if (dataReturned < size * sizeof(unsigned int)) {
93 data.resize(dataReturned / sizeof(unsigned int));
94 }
95}
96
97//==============================================================================
98// Command Functions
99//==============================================================================
100
101void
103{
106 unsigned int txSize;
107 unsigned int rxSizeExpected;
108
112 tx.header.size = 1;
114 txSize = sizeof(dunedaq::sspmodules::CtrlHeader);
115 rxSizeExpected = sizeof(dunedaq::sspmodules::CtrlHeader) + sizeof(unsigned int);
116
117 SendReceive(tx, rx, txSize, rxSizeExpected, 3);
118 *value = rx.data[0];
119}
120
121void
122dunedaq::sspmodules::EthernetDevice::DeviceReadMask(unsigned int address, unsigned int mask, unsigned int* value)
123{
126 unsigned int txSize;
127 unsigned int rxSizeExpected;
128
129 tx.header.length = sizeof(dunedaq::sspmodules::CtrlHeader) + sizeof(uint);
132 tx.header.size = 1;
134 tx.data[0] = mask;
135 txSize = sizeof(dunedaq::sspmodules::CtrlHeader) + sizeof(unsigned int);
136 rxSizeExpected = sizeof(dunedaq::sspmodules::CtrlHeader) + sizeof(unsigned int);
137
138 SendReceive(tx, rx, txSize, rxSizeExpected, 3);
139 *value = rx.data[0];
140}
141
142void
144{
147 unsigned int txSize;
148 unsigned int rxSizeExpected;
149
150 tx.header.length = sizeof(dunedaq::sspmodules::CtrlHeader) + sizeof(uint);
153 tx.header.size = 1;
155 tx.data[0] = value;
156 txSize = sizeof(dunedaq::sspmodules::CtrlHeader) + sizeof(unsigned int);
157 rxSizeExpected = sizeof(dunedaq::sspmodules::CtrlHeader);
158
159 SendReceive(tx, rx, txSize, rxSizeExpected, 3);
160}
161
162void
163dunedaq::sspmodules::EthernetDevice::DeviceWriteMask(unsigned int address, unsigned int mask, unsigned int value)
164{
167 unsigned int txSize;
168 unsigned int rxSizeExpected;
169
170 tx.header.length = sizeof(dunedaq::sspmodules::CtrlHeader) + (sizeof(uint) * 2);
173 tx.header.size = 1;
175 tx.data[0] = mask;
176 tx.data[1] = value;
177 txSize = sizeof(dunedaq::sspmodules::CtrlHeader) + (sizeof(unsigned int) * 2);
178 rxSizeExpected = sizeof(dunedaq::sspmodules::CtrlHeader) + sizeof(unsigned int);
179
180 SendReceive(tx, rx, txSize, rxSizeExpected, 3);
181}
182
183void
185{
186 DeviceWriteMask(address, mask, 0xFFFFFFFF);
187}
188
189void
191{
192 DeviceWriteMask(address, mask, 0x00000000);
193}
194
195void
196dunedaq::sspmodules::EthernetDevice::DeviceArrayRead(unsigned int address, unsigned int size, unsigned int* data)
197{
198 unsigned int i = 0;
201 unsigned int txSize;
202 unsigned int rxSizeExpected;
203
207 tx.header.size = size;
209 txSize = sizeof(dunedaq::sspmodules::CtrlHeader);
210 rxSizeExpected = sizeof(dunedaq::sspmodules::CtrlHeader) + (sizeof(unsigned int) * size);
211
212 SendReceive(tx, rx, txSize, rxSizeExpected, 3);
213 for (i = 0; i < rx.header.size; i++) {
214 data[i] = rx.data[i];
215 }
216}
217
218void
219dunedaq::sspmodules::EthernetDevice::DeviceArrayWrite(unsigned int address, unsigned int size, unsigned int* data)
220{
221 unsigned int i = 0;
224 unsigned int txSize;
225 unsigned int rxSizeExpected;
226
227 tx.header.length = sizeof(dunedaq::sspmodules::CtrlHeader) + (sizeof(uint) * size);
230 tx.header.size = size;
232 txSize = sizeof(dunedaq::sspmodules::CtrlHeader) + (sizeof(unsigned int) * size);
233 rxSizeExpected = sizeof(dunedaq::sspmodules::CtrlHeader);
234
235 for (i = 0; i < size; i++) {
236 tx.data[i] = data[i];
237 }
238
239 SendReceive(tx, rx, txSize, rxSizeExpected, 3);
240}
241
242//==============================================================================
243// Support Functions
244//==============================================================================
245
246void
249 unsigned int txSize,
250 unsigned int rxSizeExpected,
251 unsigned int retryCount)
252{
253 unsigned int timesTried = 0;
254 bool success = false;
255
256 while (!success) {
257 try {
258 SendEthernet(tx, txSize);
259 // Insert small delay between send and receive on Linux
260 usleep(100);
261 ReceiveEthernet(rx, rxSizeExpected);
262 usleep(2000);
263 success = true;
264 } catch (ETCPError&) {
265 if (timesTried < retryCount) {
266 DevicePurgeComm();
267 ++timesTried;
268 // dune::DAQLogger::LogWarning("SSP_EthernetDevice")<<"Send/receive failed "<<timesTried<<" times on Ethernet
269 // link, retrying..."<<std::endl;
270 } else {
271 // dune::DAQLogger::LogError("SSP_EthernetDevice")<<"Send/receive failed on Ethernet link, giving
272 // up."<<std::endl;
273 throw;
274 }
275 }
276 }
277}
278
279void
281{
282 unsigned int txSizeWritten = fCommSocket.write_some(boost::asio::buffer(static_cast<void*>(&tx), txSize));
283 if (txSizeWritten != txSize) {
284 throw(ETCPError(""));
285 }
286}
287
288void
290{
291 unsigned int rxSizeReturned = fCommSocket.read_some(boost::asio::buffer(static_cast<void*>(&rx), rxSizeExpected));
292 if (rxSizeReturned != rxSizeExpected) {
293 throw(ETCPError(""));
294 }
295}
296
297void
298dunedaq::sspmodules::EthernetDevice::DevicePurge(boost::asio::ip::tcp::socket& socket)
299{
300 bool done = false;
301 unsigned int bytesQueued = 0;
302 unsigned int sleepTime = 0;
303
304 // Keep getting data from channel until queue is empty
305 do {
306 bytesQueued = socket.available();
307
308 // Read data from device, up to 256 bytes
309 if (bytesQueued != 0) {
310 sleepTime = 0;
311 unsigned int bytesToGet = std::min((unsigned int)256, bytesQueued);
312 std::vector<char> junkBuf(bytesToGet);
313 socket.read_some(boost::asio::buffer(junkBuf, bytesToGet));
314 } else { // If queue is empty, wait a bit and check that it hasn't filled up again, then return
315 usleep(1000); // 1ms
316 sleepTime += 1000;
317 bytesQueued = socket.available();
318 if (bytesQueued == 0 && sleepTime > 1000000) {
319 done = 1;
320 }
321 }
322 } while (!done);
323}
324
325#endif // SSPMODULES_SRC_ANLBOARD_ETHERNETDEVICE_CXX_
virtual void DeviceQueueStatus(unsigned int *numWords)
void SendEthernet(dunedaq::sspmodules::CtrlPacket &tx, unsigned int txSize)
virtual void DeviceReadMask(unsigned int address, unsigned int mask, unsigned int *value)
virtual void DeviceArrayRead(unsigned int address, unsigned int size, unsigned int *data)
virtual void DeviceSet(unsigned int address, unsigned int mask)
virtual void DeviceWriteMask(unsigned int address, unsigned int mask, unsigned int value)
EthernetDevice(unsigned long ipAddress)
void DevicePurge(boost::asio::ip::tcp::socket &socket)
static boost::asio::io_service fIo_service
virtual void DeviceWrite(unsigned int address, unsigned int value)
virtual void Open(bool slowControlOnly)
virtual void DeviceRead(unsigned int address, unsigned int *value)
virtual void DeviceClear(unsigned int address, unsigned int mask)
virtual void DeviceArrayWrite(unsigned int address, unsigned int size, unsigned int *data)
void ReceiveEthernet(dunedaq::sspmodules::CtrlPacket &rx, unsigned int rxSizeExpected)
void SendReceive(dunedaq::sspmodules::CtrlPacket &tx, dunedaq::sspmodules::CtrlPacket &rx, unsigned int txSize, unsigned int rxSizeExpected, unsigned int retryCount=0)
virtual void DeviceReceive(std::vector< unsigned int > &data, unsigned int size)
Definition file.hpp:28
FELIX Initialization std::string initerror FELIX queue timed std::string queuename Unexpected chunk size
unsigned int data[max_control_data]
Definition SSPTypes.hpp:98