1 |
30 |
wfjm |
// $Id: RlinkConnect.hpp 666 2015-04-12 21:17:54Z mueller $
|
2 |
10 |
wfjm |
//
|
3 |
28 |
wfjm |
// Copyright 2011-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
4 |
10 |
wfjm |
//
|
5 |
|
|
// This program is free software; you may redistribute and/or modify it under
|
6 |
|
|
// the terms of the GNU General Public License as published by the Free
|
7 |
|
|
// Software Foundation, either version 2, or at your option any later version.
|
8 |
|
|
//
|
9 |
|
|
// This program is distributed in the hope that it will be useful, but
|
10 |
|
|
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
11 |
|
|
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
12 |
|
|
// for complete details.
|
13 |
|
|
//
|
14 |
|
|
// Revision History:
|
15 |
|
|
// Date Rev Version Comment
|
16 |
30 |
wfjm |
// 2015-04-12 666 2.3 add LinkInit,LinkInitDone; transfer xon
|
17 |
|
|
// 2015-04-02 661 2.2 expect logic: stat expect in Command, invert mask
|
18 |
29 |
wfjm |
// 2015-01-06 631 2.1 full rlink v4 implementation
|
19 |
28 |
wfjm |
// 2014-12-25 621 2.0.2 Reorganize packet send/revd stats
|
20 |
|
|
// 2014-12-20 616 2.0.1 add BlockDone expect checks
|
21 |
27 |
wfjm |
// 2014-12-10 611 2.0 re-organize for rlink v4
|
22 |
20 |
wfjm |
// 2013-04-21 509 1.3.3 add SndAttn() method
|
23 |
19 |
wfjm |
// 2013-03-05 495 1.3.2 add Exec() without emsg (will send emsg to LogFile)
|
24 |
|
|
// 2013-03-01 493 1.3.1 add Server(Active..|SignalAttn)() methods
|
25 |
|
|
// 2013-02-23 492 1.3 use scoped_ptr for Port; Close allways allowed
|
26 |
|
|
// use RlinkContext, add Context(), Exec(..., cntx)
|
27 |
|
|
// 2013-02-22 491 1.2 use new RlogFile/RlogMsg interfaces
|
28 |
|
|
// 2013-02-03 481 1.1.3 add SetServer(),Server()
|
29 |
|
|
// 2013-01-13 474 1.1.2 add PollAttn() method
|
30 |
15 |
wfjm |
// 2011-11-28 434 1.1.1 struct LogOpts: use uint32_t for lp64 compatibility
|
31 |
12 |
wfjm |
// 2011-04-24 380 1.1 use boost::noncopyable (instead of private dcl's);
|
32 |
|
|
// use boost::(mutex&lock), implement Lockable IF
|
33 |
|
|
// 2011-04-22 379 1.0.1 add Lock(), Unlock()
|
34 |
10 |
wfjm |
// 2011-04-02 375 1.0 Initial version
|
35 |
|
|
// 2011-01-15 356 0.1 First draft
|
36 |
|
|
// ---------------------------------------------------------------------------
|
37 |
|
|
|
38 |
|
|
/*!
|
39 |
|
|
\file
|
40 |
30 |
wfjm |
\version $Id: RlinkConnect.hpp 666 2015-04-12 21:17:54Z mueller $
|
41 |
10 |
wfjm |
\brief Declaration of class \c RlinkConnect.
|
42 |
|
|
*/
|
43 |
|
|
|
44 |
|
|
#ifndef included_Retro_RlinkConnect
|
45 |
|
|
#define included_Retro_RlinkConnect 1
|
46 |
|
|
|
47 |
|
|
#include <cstdint>
|
48 |
|
|
#include <string>
|
49 |
|
|
#include <vector>
|
50 |
|
|
#include <ostream>
|
51 |
|
|
|
52 |
12 |
wfjm |
#include "boost/utility.hpp"
|
53 |
|
|
#include "boost/thread/recursive_mutex.hpp"
|
54 |
19 |
wfjm |
#include "boost/shared_ptr.hpp"
|
55 |
|
|
#include "boost/scoped_ptr.hpp"
|
56 |
12 |
wfjm |
|
57 |
10 |
wfjm |
#include "librtools/RerrMsg.hpp"
|
58 |
|
|
#include "librtools/Rstats.hpp"
|
59 |
|
|
#include "librtools/RlogFile.hpp"
|
60 |
|
|
|
61 |
|
|
#include "RlinkPort.hpp"
|
62 |
|
|
#include "RlinkCommandList.hpp"
|
63 |
27 |
wfjm |
#include "RlinkPacketBufSnd.hpp"
|
64 |
|
|
#include "RlinkPacketBufRcv.hpp"
|
65 |
10 |
wfjm |
#include "RlinkAddrMap.hpp"
|
66 |
19 |
wfjm |
#include "RlinkContext.hpp"
|
67 |
10 |
wfjm |
|
68 |
27 |
wfjm |
#include "librtools/Rbits.hpp"
|
69 |
|
|
|
70 |
10 |
wfjm |
namespace Retro {
|
71 |
|
|
|
72 |
19 |
wfjm |
class RlinkServer; // forw decl to avoid circular incl
|
73 |
|
|
|
74 |
27 |
wfjm |
class RlinkConnect : public Rbits, private boost::noncopyable {
|
75 |
10 |
wfjm |
public:
|
76 |
|
|
|
77 |
|
|
RlinkConnect();
|
78 |
19 |
wfjm |
~RlinkConnect();
|
79 |
10 |
wfjm |
|
80 |
|
|
bool Open(const std::string& name, RerrMsg& emsg);
|
81 |
|
|
void Close();
|
82 |
|
|
bool IsOpen() const;
|
83 |
|
|
RlinkPort* Port() const;
|
84 |
|
|
|
85 |
30 |
wfjm |
bool LinkInit(RerrMsg& emsg);
|
86 |
|
|
bool LinkInitDone() const;
|
87 |
|
|
|
88 |
19 |
wfjm |
RlinkContext& Context();
|
89 |
|
|
|
90 |
|
|
void SetServer(RlinkServer* pserv);
|
91 |
|
|
RlinkServer* Server() const;
|
92 |
|
|
bool ServerActive() const;
|
93 |
|
|
bool ServerActiveInside() const;
|
94 |
|
|
bool ServerActiveOutside() const;
|
95 |
|
|
|
96 |
12 |
wfjm |
// provide boost Lockable interface
|
97 |
|
|
void lock();
|
98 |
|
|
bool try_lock();
|
99 |
|
|
void unlock();
|
100 |
|
|
|
101 |
10 |
wfjm |
bool Exec(RlinkCommandList& clist, RerrMsg& emsg);
|
102 |
19 |
wfjm |
bool Exec(RlinkCommandList& clist, RlinkContext& cntx,
|
103 |
|
|
RerrMsg& emsg);
|
104 |
29 |
wfjm |
void Exec(RlinkCommandList& clist);
|
105 |
|
|
void Exec(RlinkCommandList& clist, RlinkContext& cntx);
|
106 |
10 |
wfjm |
|
107 |
27 |
wfjm |
double WaitAttn(double timeout, uint16_t& apat, RerrMsg& emsg);
|
108 |
10 |
wfjm |
bool SndOob(uint16_t addr, uint16_t data, RerrMsg& emsg);
|
109 |
20 |
wfjm |
bool SndAttn(RerrMsg& emsg);
|
110 |
10 |
wfjm |
|
111 |
28 |
wfjm |
uint32_t SysId() const;
|
112 |
|
|
size_t RbufSize() const;
|
113 |
|
|
size_t BlockSizeMax() const;
|
114 |
|
|
size_t BlockSizePrudent() const;
|
115 |
|
|
|
116 |
10 |
wfjm |
bool AddrMapInsert(const std::string& name, uint16_t addr);
|
117 |
|
|
bool AddrMapErase(const std::string& name);
|
118 |
|
|
bool AddrMapErase(uint16_t addr);
|
119 |
|
|
void AddrMapClear();
|
120 |
28 |
wfjm |
const RlinkAddrMap& AddrMap() const;
|
121 |
10 |
wfjm |
|
122 |
|
|
const Rstats& Stats() const;
|
123 |
27 |
wfjm |
const Rstats& SndStats() const;
|
124 |
|
|
const Rstats& RcvStats() const;
|
125 |
10 |
wfjm |
|
126 |
29 |
wfjm |
void SetLogBaseAddr(uint32_t base);
|
127 |
|
|
void SetLogBaseData(uint32_t base);
|
128 |
|
|
void SetLogBaseStat(uint32_t base);
|
129 |
|
|
void SetPrintLevel(uint32_t lvl);
|
130 |
|
|
void SetDumpLevel(uint32_t lvl);
|
131 |
|
|
void SetTraceLevel(uint32_t lvl);
|
132 |
19 |
wfjm |
|
133 |
29 |
wfjm |
uint32_t LogBaseAddr() const;
|
134 |
|
|
uint32_t LogBaseData() const;
|
135 |
|
|
uint32_t LogBaseStat() const;
|
136 |
|
|
uint32_t PrintLevel() const;
|
137 |
|
|
uint32_t DumpLevel() const;
|
138 |
|
|
uint32_t TraceLevel() const;
|
139 |
|
|
|
140 |
|
|
bool LogOpen(const std::string& name, RerrMsg& emsg);
|
141 |
19 |
wfjm |
void LogUseStream(std::ostream* pstr,
|
142 |
|
|
const std::string& name = "");
|
143 |
10 |
wfjm |
RlogFile& LogFile() const;
|
144 |
19 |
wfjm |
const boost::shared_ptr<RlogFile>& LogFileSPtr() const;
|
145 |
10 |
wfjm |
|
146 |
29 |
wfjm |
void SetLogFileName(const std::string& name);
|
147 |
|
|
std::string LogFileName() const;
|
148 |
|
|
|
149 |
10 |
wfjm |
void Print(std::ostream& os) const;
|
150 |
|
|
void Dump(std::ostream& os, int ind=0, const char* text=0) const;
|
151 |
|
|
|
152 |
27 |
wfjm |
void HandleUnsolicitedData();
|
153 |
|
|
|
154 |
|
|
// some constants (also defined in cpp)
|
155 |
|
|
static const uint16_t kRbaddr_RLCNTL = 0xffff; //!< rlink core reg RLCNTL
|
156 |
|
|
static const uint16_t kRbaddr_RLSTAT = 0xfffe; //!< rlink core reg RLSTAT
|
157 |
|
|
static const uint16_t kRbaddr_RLID1 = 0xfffd; //!< rlink core reg RLID1
|
158 |
|
|
static const uint16_t kRbaddr_RLID0 = 0xfffc; //!< rlink core reg RLID0
|
159 |
|
|
|
160 |
|
|
static const uint16_t kRLCNTL_M_AnEna = kWBit15;//!< RLCNTL: an enable
|
161 |
|
|
static const uint16_t kRLCNTL_M_AtoEna= kWBit14;//!< RLCNTL: ato enable
|
162 |
|
|
static const uint16_t kRLCNTL_M_AtoVal= 0x00ff; //!< RLCNTL: ato value
|
163 |
|
|
|
164 |
|
|
static const uint16_t kRLSTAT_V_LCmd = 8; //!< RLSTAT: lcmd
|
165 |
|
|
static const uint16_t kRLSTAT_B_LCmd = 0x00ff; //!< RLSTAT: lcmd
|
166 |
|
|
static const uint16_t kRLSTAT_M_BAbo = kWBit07;//!< RLSTAT: babo
|
167 |
|
|
static const uint16_t kRLSTAT_M_RBSize= 0x0007; //!< RLSTAT: rbuf size
|
168 |
|
|
|
169 |
|
|
static const uint16_t kSBCNTL_V_RLMON = 15; //!< SBCNTL: rlmon enable bit
|
170 |
|
|
static const uint16_t kSBCNTL_V_RLBMON= 14; //!< SBCNTL: rlbmon enable bit
|
171 |
|
|
static const uint16_t kSBCNTL_V_RBMON = 13; //!< SBCNTL: rbmon enable bit
|
172 |
|
|
|
173 |
28 |
wfjm |
// space beyond data for rblk = 8 :cmd(1) cnt(2) dcnt(2) stat(1) crc(2)
|
174 |
|
|
// and wblk = 3 :cmd(1) cnt(2)
|
175 |
|
|
static const uint16_t kRbufBlkDelta=16; //!< rbuf needed for rblk or wblk
|
176 |
|
|
// 512 byte are enough space for a prudent amount of non-blk commands
|
177 |
|
|
static const uint16_t kRbufPrudentDelta=512; //!< Rbuf space reserve
|
178 |
|
|
|
179 |
10 |
wfjm |
// statistics counter indices
|
180 |
|
|
enum stats {
|
181 |
27 |
wfjm |
kStatNExec = 0, //!< Exec() calls
|
182 |
|
|
kStatNExecPart, //!< ExecPart() calls
|
183 |
|
|
kStatNCmd, //!< commands executed
|
184 |
|
|
kStatNRreg, //!< rreg commands
|
185 |
|
|
kStatNRblk, //!< rblk commands
|
186 |
|
|
kStatNWreg, //!< wreg commands
|
187 |
|
|
kStatNWblk, //!< wblk commands
|
188 |
|
|
kStatNLabo, //!< labo commands
|
189 |
|
|
kStatNAttn, //!< attn commands
|
190 |
|
|
kStatNInit, //!< init commands
|
191 |
|
|
kStatNRblkWord, //!< words rcvd with rblk
|
192 |
|
|
kStatNWblkWord, //!< words send with wblk
|
193 |
30 |
wfjm |
kStatNExpData, //!< expect for data defined
|
194 |
|
|
kStatNExpDone, //!< expect for done defined
|
195 |
|
|
kStatNExpStat, //!< expect for stat explicit
|
196 |
|
|
kStatNNoExpStat, //!< no expect for stat
|
197 |
27 |
wfjm |
kStatNChkData, //!< expect data failed
|
198 |
28 |
wfjm |
kStatNChkDone, //!< expect done failed
|
199 |
27 |
wfjm |
kStatNChkStat, //!< expect stat failed
|
200 |
|
|
kStatNSndOob, //!< SndOob() calls
|
201 |
|
|
kStatNErrMiss, //!< decode: missing data
|
202 |
|
|
kStatNErrCmd, //!< decode: command mismatch
|
203 |
|
|
kStatNErrLen, //!< decode: length mismatch
|
204 |
|
|
kStatNErrCrc, //!< decode: crc mismatch
|
205 |
10 |
wfjm |
kDimStat
|
206 |
|
|
};
|
207 |
|
|
|
208 |
|
|
protected:
|
209 |
12 |
wfjm |
bool ExecPart(RlinkCommandList& clist, size_t ibeg, size_t iend,
|
210 |
30 |
wfjm |
RerrMsg& emsg);
|
211 |
12 |
wfjm |
|
212 |
27 |
wfjm |
void EncodeRequest(RlinkCommandList& clist, size_t ibeg,
|
213 |
|
|
size_t iend);
|
214 |
30 |
wfjm |
int DecodeResponse(RlinkCommandList& clist, size_t ibeg,
|
215 |
|
|
size_t iend);
|
216 |
27 |
wfjm |
bool DecodeAttnNotify(uint16_t& apat);
|
217 |
|
|
bool ReadResponse(double timeout, RerrMsg& emsg);
|
218 |
|
|
void AcceptResponse();
|
219 |
|
|
void ProcessUnsolicitedData();
|
220 |
|
|
void ProcessAttnNotify();
|
221 |
|
|
|
222 |
12 |
wfjm |
protected:
|
223 |
19 |
wfjm |
boost::scoped_ptr<RlinkPort> fpPort; //!< ptr to port
|
224 |
30 |
wfjm |
bool fLinkInitDeferred; //!< noinit attr seen on Open
|
225 |
|
|
bool fLinkInitDone; //!< LinkInit done
|
226 |
19 |
wfjm |
RlinkServer* fpServ; //!< ptr to server (optional)
|
227 |
10 |
wfjm |
uint8_t fSeqNumber[8]; //!< command sequence number
|
228 |
27 |
wfjm |
RlinkPacketBufSnd fSndPkt; //!< send packet buffer
|
229 |
|
|
RlinkPacketBufRcv fRcvPkt; //!< receive packet buffer
|
230 |
19 |
wfjm |
RlinkContext fContext; //!< default context
|
231 |
10 |
wfjm |
RlinkAddrMap fAddrMap; //!< name<->address mapping
|
232 |
|
|
Rstats fStats; //!< statistics
|
233 |
29 |
wfjm |
uint32_t fLogBaseAddr; //!< log: base for addr
|
234 |
|
|
uint32_t fLogBaseData; //!< log: base for data
|
235 |
|
|
uint32_t fLogBaseStat; //!< log: base for stat
|
236 |
|
|
uint32_t fPrintLevel; //!< print 0=off,1=err,2=chk,3=all
|
237 |
|
|
uint32_t fDumpLevel; //!< dump 0=off,1=err,2=chk,3=all
|
238 |
|
|
uint32_t fTraceLevel; //!< trace 0=off,1=buf,2=char
|
239 |
19 |
wfjm |
boost::shared_ptr<RlogFile> fspLog; //!< log file ptr
|
240 |
|
|
boost::recursive_mutex fConnectMutex; //!< mutex to lock whole connect
|
241 |
27 |
wfjm |
uint16_t fAttnNotiPatt; //!< attn notifier pattern
|
242 |
|
|
double fTsLastAttnNoti; //!< time stamp last attn notify
|
243 |
28 |
wfjm |
uint32_t fSysId; //!< SYSID of connected device
|
244 |
|
|
size_t fRbufSize; //!< Rbuf size (in bytes)
|
245 |
10 |
wfjm |
};
|
246 |
|
|
|
247 |
|
|
} // end namespace Retro
|
248 |
|
|
|
249 |
|
|
#include "RlinkConnect.ipp"
|
250 |
|
|
|
251 |
|
|
#endif
|