OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.7/] [tools/] [src/] [librlink/] [RlinkPacketBufRcv.cpp] - Blame information for rev 28

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 28 wfjm
// $Id: RlinkPacketBufRcv.cpp 621 2014-12-26 21:20:05Z mueller $
2 27 wfjm
//
3
// Copyright 2014- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4
//
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 28 wfjm
// 2014-12-25   621   1.0.1  Reorganize packet send/revd stats
17 27 wfjm
// 2014-11-30   607   1.0    Initial version
18
// 2014-11-02   600   0.1    First draft (re-organize PacketBuf for rlink v4)
19
// ---------------------------------------------------------------------------
20
 
21
/*!
22
  \file
23 28 wfjm
  \version $Id: RlinkPacketBufRcv.cpp 621 2014-12-26 21:20:05Z mueller $
24 27 wfjm
  \brief   Implemenation of class RlinkPacketBuf.
25
 */
26
 
27
#include <sys/time.h>
28
 
29
#include "RlinkPacketBufRcv.hpp"
30
 
31
#include "librtools/RosFill.hpp"
32
#include "librtools/RosPrintf.hpp"
33
#include "librtools/RosPrintBvi.hpp"
34
#include "librtools/Rexception.hpp"
35
 
36
using namespace std;
37
 
38
/*!
39
  \class Retro::RlinkPacketBufRcv
40
  \brief FIXME_docs
41
*/
42
 
43
// all method definitions in namespace Retro
44
namespace Retro {
45
 
46
//------------------------------------------+-----------------------------------
47
//! Default constructor
48
 
49
RlinkPacketBufRcv::RlinkPacketBufRcv()
50
  : fRawBufSize(0),
51
    fRawBufDone(0),
52
    fRcvState(kRcvIdle),
53
    fNDone(0),
54
    fEscSeen(false),
55
    fNakIndex(-1),
56
    fDropData()
57
{
58
  // Statistic setup
59 28 wfjm
  fStats.Define(kStatNRxPktByt, "NRxPktByt", "Rx packet bytes rcvd");
60 27 wfjm
  fStats.Define(kStatNRxDrop,   "NRxDrop",   "Rx bytes dropped");
61
  fStats.Define(kStatNRxSop,    "NRxSop",    "Rx SOP commas seen");
62
  fStats.Define(kStatNRxEop,    "NRxEop",    "Rx EOP commas seen");
63
  fStats.Define(kStatNRxNak,    "NRxNak",    "Rx NAK commas seen");
64
  fStats.Define(kStatNRxAttn,   "NRxAttn",   "Rx ATTN commas seen");
65
  fStats.Define(kStatNRxEsc,    "NRxEsc",    "Rx data escapes");
66
  fStats.Define(kStatNRxClobber,"NRxClobber","Rx clobbered escapes");
67
}
68
 
69
//------------------------------------------+-----------------------------------
70
//! Destructor
71
 
72
RlinkPacketBufRcv::~RlinkPacketBufRcv()
73
{}
74
 
75
//------------------------------------------+-----------------------------------
76
//! FIXME_docs
77
 
78
int RlinkPacketBufRcv::ReadData(RlinkPort* port, double timeout, RerrMsg& emsg)
79
{
80
  if (port == 0)
81
    throw Rexception("RlinkPacketBufRcv::ReadData()",
82
                     "Bad state: port not open");
83
  if (fRawBufDone != fRawBufSize)
84
    throw Rexception("RlinkPacketBufRcv::ReadData()",
85
                     "Bad state: called while data pending in buffer");
86
 
87
  fRawBufDone = 0;
88
  fRawBufSize = 0;
89
 
90
  int irc = port->Read(fRawBuf, sizeof(fRawBuf), timeout, emsg);
91
 
92
  if (timeout == 0 && irc == RlinkPort::kTout) return 0;
93
 
94
  if (irc < 0) {
95
    if (irc == RlinkPort::kTout) {
96
      SetFlagBit(kFlagErrTout);
97
    } else {
98
      SetFlagBit(kFlagErrIO);
99
      if (irc == RlinkPort::kEof) {
100
        emsg.Init("RlinkPacketBuf::ReadData()", "eof on read");
101
      }
102
    }
103
  } else {
104
    fRawBufSize = size_t(irc);
105
  }
106
 
107
  return irc;
108
}
109
 
110
//------------------------------------------+-----------------------------------
111
//! FIXME_docs
112
 
113
bool RlinkPacketBufRcv::ProcessData()
114
{
115
  if (fRawBufDone ==fRawBufSize) return false;
116
 
117
  while (fRawBufDone < fRawBufSize) {
118
    switch (fRcvState) {
119
    case kRcvIdle:
120
      ProcessDataIdle();
121
      break;
122
 
123
    case kRcvFill:
124
      ProcessDataFill();
125
      break;
126
 
127
    default:
128
      return true;
129
    }
130
  }
131
  return true;
132
}
133
 
134
//------------------------------------------+-----------------------------------
135
//! FIXME_docs
136
 
137
void RlinkPacketBufRcv::AcceptPacket()
138
{
139
  fPktBuf.clear();
140
  fCrc.Clear();
141
  fFlags    = 0;
142
  fRcvState = kRcvIdle;
143
  fNDone    = 0;
144
  fNakIndex = -1;
145
  fDropData.clear();
146
  return;
147
}
148
 
149
//------------------------------------------+-----------------------------------
150
//! FIXME_docs
151
 
152
void RlinkPacketBufRcv::FlushRaw()
153
{
154
  fRawBufSize = 0;
155
  fRawBufDone = 0;
156
  fEscSeen    = false;
157
  return;
158
}
159
 
160
//------------------------------------------+-----------------------------------
161
//! FIXME_docs
162
 
163
RlinkPacketBufRcv::pkt_state RlinkPacketBufRcv::PacketState()
164
{
165
  if (fRcvState==kRcvIdle || fRcvState==kRcvFill) return kPktPend;
166
  if (fRcvState==kRcvDone) return TestFlag(kFlagSopSeen) ? kPktResp : kPktAttn;
167
  return kPktError;
168
}
169
 
170
//------------------------------------------+-----------------------------------
171
//! FIXME_docs
172
 
173
void RlinkPacketBufRcv::GetWithCrc(uint16_t* pdata, size_t count)
174
{
175
  uint16_t* pend = pdata + count;
176
  while (pdata < pend) GetWithCrc(*pdata++);
177
  return;
178
}
179
 
180
//------------------------------------------+-----------------------------------
181
//! FIXME_docs
182
 
183
void RlinkPacketBufRcv::Dump(std::ostream& os, int ind, const char* text) const
184
{
185
  RosFill bl(ind);
186
  os << bl << (text?text:"--") << "RlinkPacketBufRcv @ " << this << endl;
187
  os << bl << "  fRawBufSize:   " << RosPrintf(fRawBufSize,"d",4) << endl;
188
  os << bl << "  fRawBufDone:   " << RosPrintf(fRawBufDone,"d",4) << endl;
189
  if (fRawBufDone > 0) {
190
    os << bl << "  fRawBuf[last]: "
191
       << RosPrintBvi(fRawBuf[fRawBufDone-1],16) << endl;
192
  }
193
  os << bl << "  fRcvState:     " << RosPrintf(fRcvState,"d",4) << endl;
194
  os << bl << "  fNDone:        " << RosPrintf(fNDone,"d",4) << endl;
195
  os << bl << "  fEscSeen:      " << RosPrintf(fEscSeen) << endl;
196
  os << bl << "  fNakIndex:     " << RosPrintf(fNakIndex,"d",4) << endl;
197
 
198
  os << bl << "  fDropData(size): " << RosPrintf(fDropData.size(),"d",4);
199
  size_t ncol  = max(1, (80-ind-4-6)/(2+1));
200
  for (size_t i=0; i<fDropData.size(); i++) {
201
    if (i%ncol == 0) os << "\n" << bl << "    " << RosPrintf(i,"d",4) << ": ";
202
    os << RosPrintBvi(fDropData[i],16) << " ";
203
  }
204
  os << endl;
205
 
206
  RlinkPacketBuf::Dump(os, ind, " ^");
207
  return;
208
}
209
 
210
//------------------------------------------+-----------------------------------
211
//! FIXME_docs
212
 
213
void RlinkPacketBufRcv::ProcessDataIdle()
214
{
215
  // loop over buffer
216
  while (fRawBufDone < fRawBufSize) {
217
 
218
    // handle escapes
219
    if (fEscSeen) {
220
      uint8_t ec = GetEcode();
221
      switch (ec) {
222
 
223
      case kEcSop:
224
        SetFlagBit(kFlagSopSeen);
225
        fRcvState = kRcvFill;
226
        return;
227
 
228
      case kEcAttn:
229
        SetFlagBit(kFlagAttnSeen);
230
        fRcvState = kRcvFill;
231
        return;
232
 
233
      default:
234
        fDropData.push_back(kSymEsc);
235
        fDropData.push_back(fRawBuf[fRawBufDone-1]);
236
        fStats.Inc(kStatNRxDrop, 2.);
237
        break;
238
      }
239
    } //if (fEscSeen)
240
 
241
    // handle plain data (till next escape)
242
    uint8_t* pi   = fRawBuf+fRawBufDone;
243
    uint8_t* pend = fRawBuf+fRawBufSize;
244
 
245
    while (pi < pend) {
246
      uint8_t c = *pi++;
247
      if (c == kSymEsc) {
248
        fEscSeen = true;
249
        break;
250
      }
251
      fDropData.push_back(c);
252
      fStats.Inc(kStatNRxDrop);
253
    }
254
    fRawBufDone = pi - fRawBuf;
255
 
256
  } // while (fRawBufDone < fRawBufSize)
257
 
258
  return;
259
}
260
 
261
//------------------------------------------+-----------------------------------
262
//! FIXME_docs
263
 
264
void RlinkPacketBufRcv::ProcessDataFill()
265
{
266
  // loop over buffer
267
  while (fRawBufDone < fRawBufSize) {
268
 
269
    // handle escapes
270
    if (fEscSeen) {
271
      uint8_t ec = GetEcode();
272
      switch (ec) {
273
 
274
      case kEcEop:                          // EOP seen
275
        SetFlagBit(kFlagEopSeen);           // -> set eop and return
276
        fRcvState = kRcvDone;
277 28 wfjm
        fStats.Inc(kStatNRxPktByt, double(PktSize()));
278 27 wfjm
        return;
279
 
280
      case kEcNak:                          // NAK seen
281
        if (TestFlag(kFlagAttnSeen|kFlagNakSeen)) {  // NAK after ATTN or NAK
282
          SetFlagBit(kFlagErrFrame);          // -> set frame error and return
283
          fRcvState = kRcvError;
284
          return;
285
        }                                   // else 1st NAK
286
        SetFlagBit(kFlagNakSeen);             // -> set flag and index; continue
287
        fNakIndex = fPktBuf.size();
288
        break;
289
 
290
      // data escapes seen: add escaped char and continue
291
      case kEcXon:   fPktBuf.push_back(kSymXon);  break;
292
      case kEcXoff:  fPktBuf.push_back(kSymXoff); break;
293
      case kEcFill:  fPktBuf.push_back(kSymFill); break;
294
      case kEcEsc:   fPktBuf.push_back(kSymEsc);  break;
295
 
296
      case kEcClobber:                      // Clobber(ed) escape seen
297
        SetFlagBit(kFlagErrClobber);        // -> set clobber error and return
298
        fRcvState = kRcvError;
299
        return;
300
 
301
      default:                              // unexpected escape (SOP,ATTN)
302
        SetFlagBit(kFlagErrFrame);          // -> set frame error and return
303
        fRcvState = kRcvError;
304
        return;
305
      }
306
    } // if (fEscSeen)
307
 
308
    // handle plain data (till next escape)
309
    uint8_t* pi   = fRawBuf+fRawBufDone;
310
    uint8_t* pend = fRawBuf+fRawBufSize;
311
 
312
    while (pi < pend) {
313
      uint8_t c = *pi++;
314
      if (c == kSymEsc) {
315
        fEscSeen = true;
316
        break;
317
      }
318
      fPktBuf.push_back(c);
319
    }
320
    fRawBufDone = pi - fRawBuf;
321
 
322
  } // while (fRawBufDone < fRawBufSize)
323
 
324
  return;
325
}
326
 
327
//------------------------------------------+-----------------------------------
328
//! FIXME_docs
329
 
330
uint8_t RlinkPacketBufRcv::GetEcode()
331
{
332
  if (!fEscSeen || fRawBufDone >= fRawBufSize)
333
    throw Rexception("RlinkPacketBufRcv::GetEcode()", "Bad state");
334
 
335
  fEscSeen = false;
336
 
337
  uint8_t c  = fRawBuf[fRawBufDone++];
338
  uint8_t ec = c & 0x7;
339
  if ((c & 0xC0) != kSymEdPref || (((~c)>>3)&0x7) != ec) ec = kEcClobber;
340
 
341
  switch (ec) {
342
  case kEcSop:     fStats.Inc(kStatNRxSop);     break; // SOP  comma seen
343
  case kEcEop:     fStats.Inc(kStatNRxEop);     break; // EOP  comma seen
344
  case kEcNak:     fStats.Inc(kStatNRxNak);     break; // NAK  comma seen
345
  case kEcAttn:    fStats.Inc(kStatNRxAttn);    break; // ATTN comma seen
346
  case kEcClobber: fStats.Inc(kStatNRxClobber); break; // clobbered esc seen
347
  default:         fStats.Inc(kStatNRxEsc);     break; // escaped data seen
348
  }
349
 
350
  return ec;
351
}
352
 
353
} // end namespace Retro

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.