Line data Source code
1 : /**
2 : * @file DaphneV2Interface.hpp
3 : *
4 : * Definition of the interface protocol to the daphne V2 boards
5 : *
6 : * This is part of the DUNE DAQ Software Suite, copyright 2020.
7 : * Licensing/copyright details are in the COPYING file that you should have
8 : * received with this code.
9 : *
10 : */
11 :
12 : #ifndef DAPHNEMODULES_SRC_DAPHNEV2INTERFACE_HPP_
13 : #define DAPHNEMODULES_SRC_DAPHNEV2INTERFACE_HPP_
14 :
15 : #include <sys/socket.h>
16 : #include <netinet/in.h>
17 : #include <arpa/inet.h>
18 : #include <vector>
19 : #include <cstring>
20 : #include <unistd.h>
21 : #include <memory>
22 : #include <mutex>
23 : #include <functional>
24 :
25 :
26 : #include <ers/ers.hpp>
27 : #include "logging/Logging.hpp" // NOTE: if ISSUES ARE DECLARED BEFORE include logging/Logging.hpp, TLOG_DEBUG<<issue wont work.
28 :
29 : #include "daphnemodules/CommonIssues.hpp"
30 :
31 : namespace dunedaq {
32 :
33 3 : ERS_DECLARE_ISSUE( daphnemodules,
34 : SocketCreationError,
35 : "Failed to create a socket",
36 : ERS_EMPTY
37 : )
38 :
39 3 : ERS_DECLARE_ISSUE( daphnemodules,
40 : FailedPing,
41 : "Failed to ping daphne board at " << ip << ':' << port,
42 : ((std::string)ip)((int)port)
43 : )
44 :
45 3 : ERS_DECLARE_ISSUE( daphnemodules,
46 : FailedSocketInteraction,
47 : "Failed to call " << command,
48 : ((std::string)command)
49 : )
50 :
51 3 : ERS_DECLARE_ISSUE( daphnemodules,
52 : CommandTimeout,
53 : "Command " << command << " timed out after " << timeout_us << " microseconds",
54 : ((std::string)command)((unsigned int)timeout_us)
55 : )
56 :
57 3 : ERS_DECLARE_ISSUE( daphnemodules,
58 : SocketTimeout,
59 : "Socket timed out after " << timeout_us << " microseconds",
60 : ((unsigned int)timeout_us)
61 : )
62 :
63 : } // dunedaq namespace
64 :
65 :
66 : namespace dunedaq::daphnemodules {
67 :
68 : struct command_result{
69 : std::string command;
70 : std::string result;
71 : };
72 :
73 :
74 : class DaphneV2Interface {
75 :
76 : public:
77 : DaphneV2Interface( const char* ipaddr, int port,
78 : std::chrono::milliseconds timeout = std::chrono::milliseconds(500));
79 :
80 0 : ~DaphneV2Interface() { if(m_connection_id>0) close();}
81 :
82 : DaphneV2Interface(const DaphneV2Interface &) = delete;
83 : DaphneV2Interface & operator= (const DaphneV2Interface & ) = delete;
84 : DaphneV2Interface(DaphneV2Interface &&) = delete;
85 : DaphneV2Interface & operator= (DaphneV2Interface &&) = delete;
86 :
87 0 : std::vector<uint64_t> read_register(uint64_t addr, uint8_t size) const { return read(0x00, addr, size) ; }
88 0 : void write_register(uint64_t addr, std::vector<uint64_t> && data) const { write(0x01, addr, std::move(data)) ; }
89 :
90 0 : std::vector<uint64_t> read_buffer(uint64_t addr, uint8_t size) const { return read(0x08, addr, size) ; }
91 0 : void write_buffer(uint64_t addr, std::vector<uint64_t> && data) const { write(0x09, addr, std::move(data)) ; }
92 :
93 : bool validate_connection() const ;
94 :
95 : command_result send_command(std::string cmd) const;
96 :
97 : // this will throw if it fails
98 : command_result send_command_retry( std::string cmd, size_t retry = std::numeric_limits<size_t>::max() ) const ;
99 :
100 : // this will try until success but it won't thrwo if can retry become false
101 : command_result send_command_interruptible( std::string cmd, std::function<bool()> can_retry) const ;
102 :
103 :
104 : protected:
105 :
106 : void close();
107 :
108 : void write( uint8_t command_id, uint64_t addr, std::vector<uint64_t> && data) const;
109 : std::vector<uint64_t> read(uint8_t command_id, uint64_t addr, uint8_t size) const;
110 :
111 :
112 : private:
113 : std::string m_ip;
114 : int m_connection_id = -1;
115 : sockaddr_in m_target;
116 : std::chrono::milliseconds m_timeout{5};
117 : mutable std::mutex m_access_mutex;
118 : mutable std::mutex m_command_mutex;
119 : };
120 :
121 :
122 : } // namespce dunedaq::daphnemodules
123 :
124 :
125 : #endif // DAPHNEMODULES_SRC_DAPHNEV2INTERFACE_HPP_
|