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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [tools/] [src/] [librlink/] [RlinkPacketBuf.cpp] - Blame information for rev 19

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

Line No. Rev Author Line
1 19 wfjm
// $Id: RlinkPacketBuf.cpp 492 2013-02-24 22:14:47Z mueller $
2 10 wfjm
//
3 18 wfjm
// Copyright 2011-2013 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 19 wfjm
// 2013-02-03   481   1.0.3  use Rexception
17
// 2013-01-13   474   1.0.2  add PollAttn() method
18 18 wfjm
// 2013-01-04   469   1.0.1  SndOob(): Add filler 0 to ensure escape state
19 10 wfjm
// 2011-04-02   375   1.0    Initial version
20
// 2011-03-05   366   0.1    First draft
21
// ---------------------------------------------------------------------------
22
 
23
/*!
24
  \file
25 19 wfjm
  \version $Id: RlinkPacketBuf.cpp 492 2013-02-24 22:14:47Z mueller $
26 10 wfjm
  \brief   Implemenation of class RlinkPacketBuf.
27
 */
28
 
29
#include <sys/time.h>
30
 
31
// debug
32
#include <iostream>
33
 
34
#include "RlinkPacketBuf.hpp"
35
 
36
#include "librtools/RosFill.hpp"
37
#include "librtools/RosPrintf.hpp"
38
#include "librtools/RosPrintBvi.hpp"
39 19 wfjm
#include "librtools/Rexception.hpp"
40 10 wfjm
 
41
using namespace std;
42
 
43
/*!
44
  \class Retro::RlinkPacketBuf
45
  \brief FIXME_docs
46
*/
47
 
48 19 wfjm
// all method definitions in namespace Retro
49
namespace Retro {
50
 
51 10 wfjm
//------------------------------------------+-----------------------------------
52
// constants definitions
53
 
54
const uint32_t RlinkPacketBuf::kFlagSopSeen;
55
const uint32_t RlinkPacketBuf::kFlagEopSeen;
56
const uint32_t RlinkPacketBuf::kFlagNakSeen;
57
const uint32_t RlinkPacketBuf::kFlagAttnSeen;
58
const uint32_t RlinkPacketBuf::kFlagTout;
59
const uint32_t RlinkPacketBuf::kFlagDatDrop;
60
const uint32_t RlinkPacketBuf::kFlagDatMiss;
61
 
62
const uint8_t RlinkPacketBuf::kCPREF;
63
const uint8_t RlinkPacketBuf::kNCOMM;
64
const uint8_t RlinkPacketBuf::kCommaIdle;
65
const uint8_t RlinkPacketBuf::kCommaSop;
66
const uint8_t RlinkPacketBuf::kCommaEop;
67
const uint8_t RlinkPacketBuf::kCommaNak;
68
const uint8_t RlinkPacketBuf::kCommaAttn;
69
const uint8_t RlinkPacketBuf::kSymEsc;
70
 
71
//------------------------------------------+-----------------------------------
72
//! Default constructor
73
 
74
RlinkPacketBuf::RlinkPacketBuf()
75
  : fPktBuf(),
76
    fRawBuf(),
77
    fRawBufSize(0),
78
    fCrc(),
79
    fFlags(0),
80
    fNdone(0),
81
    fNesc(0),
82
    fNattn(0),
83
    fNidle(0),
84
    fNdrop(0)
85
{}
86
 
87
//------------------------------------------+-----------------------------------
88
//! Destructor
89
 
90
RlinkPacketBuf::~RlinkPacketBuf()
91
{}
92
 
93
//------------------------------------------+-----------------------------------
94
//! FIXME_docs
95
 
96
void RlinkPacketBuf::Init()
97
{
98
  fPktBuf.clear();
99
  fRawBufSize = 0;
100
  fCrc.Clear();
101
  fFlags = 0;
102
  fNdone = 0;
103
  fNesc  = 0;
104
  fNattn = 0;
105
  fNidle = 0;
106
  fNdrop = 0;
107
 
108
  return;
109
}
110
 
111
//------------------------------------------+-----------------------------------
112
//! FIXME_docs
113
 
114
bool RlinkPacketBuf::SndPacket(RlinkPort* port, RerrMsg& emsg)
115
{
116
  fRawBuf.reserve(2*fPktBuf.size()+2);        // max. size of raw data
117
  fRawBuf.clear();
118
 
119
  fRawBuf.push_back(kCommaSop);
120
 
121
  size_t   ni = fPktBuf.size();
122
  uint8_t* pi = fPktBuf.data();
123
  for (size_t i=0; i<ni; i++) {
124
    uint8_t c = *pi++;
125
    if (c == kSymEsc || (c >= kCPREF && c <= kCPREF+kNCOMM)) {
126
      fRawBuf.push_back(kSymEsc);
127
      fRawBuf.push_back(((~kCPREF) & 0xf0) | (c & 0x0f));
128
      fNesc += 1;
129
    } else {
130
      fRawBuf.push_back(c);
131
    }
132
  }
133
 
134
  fRawBuf.push_back(kCommaEop);
135
 
136
  return SndRaw(port, emsg);
137
 
138
}
139
 
140
//------------------------------------------+-----------------------------------
141
//! FIXME_docs
142
 
143
bool RlinkPacketBuf::RcvPacket(RlinkPort* port, size_t nrcv, float timeout,
144
                               RerrMsg& emsg)
145
{
146
  fPktBuf.clear();
147
 
148
  bool   escseen = false;                   // in esc
149
  bool   sopseen = false;                   // sop seen
150
  bool   eopseen = false;                   // eop seen
151
  bool   nakseen = false;                   // nak seen
152
 
153
  while (!(eopseen|nakseen)) {              // try till eop or nak received
154
    size_t   nread = nrcv - fPktBuf.size();
155
    // FIXME_code: if the 'enough data' handling below correct ?
156 19 wfjm
    if (nread < 0)  return true;
157
 
158 10 wfjm
    if (!sopseen) nread += 1;
159
    if (!eopseen) nread += 1;
160
 
161
    size_t sizeold = fRawBufSize;
162
    int irc = RcvRaw(port, nread, timeout, emsg);
163
 
164
    if (irc <= 0) {
165
      if (irc == RlinkPort::kTout) {
166
        SetFlagBit(kFlagTout);
167
        return true;
168
      } else {
169
        return false;
170
      }
171
    }
172
 
173
    uint8_t* pi = fRawBuf.data()+sizeold;
174
    for (int i=0; i<irc; i++) {
175
      uint8_t c = *pi++;
176
      if (escseen) {
177
        escseen = false;
178
        if (sopseen && !(nakseen || eopseen)) {
179
          fPktBuf.push_back((kCPREF & 0xf0) | (c & 0x0f));
180
        }
181
      } else if (c == kCommaSop) {
182
        if (!eopseen) {
183
          SetFlagBit(kFlagSopSeen);
184
          sopseen  = true;
185
        } else {
186
          // FIXME_code: handle multiple sop
187
        }
188
      } else if (c == kCommaEop) {
189
        SetFlagBit(kFlagEopSeen);
190
        eopseen  = true;
191
      } else if (c == kCommaNak) {
192
        SetFlagBit(kFlagNakSeen);
193
        nakseen  = true;
194
      } else if (c == kCommaAttn) {
195
        SetFlagBit(kFlagAttnSeen);
196
        fNattn += 1;
197
      } else if (c == kCommaIdle) {
198
        fNidle += 1;
199
      } else if (c == kSymEsc) {
200
        fNesc += 1;
201
        escseen = true;
202
      } else {
203
        if (sopseen && !(nakseen || eopseen)) {
204
          fPktBuf.push_back(c);
205
        } else {
206
          fNdrop += 1;
207
        }
208
      }
209 19 wfjm
    } // for (int i=0; i<irc; i++)
210 10 wfjm
 
211 19 wfjm
  } // while (!(eopseen|nakseen))
212
 
213 10 wfjm
  return true;
214
}
215
 
216
//------------------------------------------+-----------------------------------
217
//! FIXME_docs
218
 
219
double RlinkPacketBuf::WaitAttn(RlinkPort* port, double timeout, RerrMsg& emsg)
220
{
221
  if (timeout <= 0.)
222 19 wfjm
    throw Rexception("RlinkPacketBuf::WaitAttn()", "Bad args: timeout <= 0.");
223 10 wfjm
 
224
  struct timeval tval;
225
  gettimeofday(&tval, 0);
226
  double tbeg  = double(tval.tv_sec) + 1.e-6*double(tval.tv_usec);
227
  double trest = timeout;
228
 
229
  Init();
230
 
231
  while (trest > 0.) {
232
    size_t sizeold = fRawBufSize;
233
    int irc = RcvRaw(port, 1, trest, emsg);
234
 
235
    if (irc <= 0) {
236
      if (irc == RlinkPort::kTout) {
237
        SetFlagBit(kFlagTout);
238
        return -1.;
239
      } else {
240
        return -2.;
241
      }
242
    }
243
 
244
    gettimeofday(&tval, 0);
245
    double tend  = double(tval.tv_sec) + 1.e-6*double(tval.tv_usec);
246
    trest -= (tend-tbeg);
247
 
248
    uint8_t c = fRawBuf[sizeold];
249
 
250
    if (c == kCommaAttn) {
251
      fNattn += 1;
252
      SetFlagBit(kFlagAttnSeen);
253
      break;
254
    } else if (c == kCommaIdle) {
255
      fNidle += 1;
256
    } else {
257
      fNdrop += 1;
258
    }
259
 
260
    tbeg   = tend;
261
  }
262
 
263
  return timeout - trest;
264
}
265
 
266
//------------------------------------------+-----------------------------------
267
//! FIXME_docs
268
 
269 19 wfjm
int RlinkPacketBuf::PollAttn(RlinkPort* port, RerrMsg& emsg)
270
{
271
  Init();
272
 
273
  int irc = RcvRaw(port, 128, 0., emsg);
274
 
275
  if (irc <= 0) {
276
    if (irc == RlinkPort::kTout) {
277
      SetFlagBit(kFlagTout);
278
      return 0;
279
    } else {
280
      return -2;
281
    }
282
  }
283
 
284
  for (size_t i=0; i<(size_t)irc; i++) {
285
    uint8_t c = fRawBuf[i];
286
    if (c == kCommaAttn) {
287
      fNattn += 1;
288
      SetFlagBit(kFlagAttnSeen);
289
      break;
290
    } else if (c == kCommaIdle) {
291
      fNidle += 1;
292
    } else {
293
      fNdrop += 1;
294
    }
295
  }
296
 
297
  return fNattn;
298
}
299
 
300
//------------------------------------------+-----------------------------------
301
//! FIXME_docs
302
 
303 10 wfjm
bool RlinkPacketBuf::SndOob(RlinkPort* port, uint16_t addr, uint16_t data,
304
                            RerrMsg& emsg)
305
{
306
  Init();
307
 
308
  fRawBuf.clear();
309
  fRawBuf.push_back(kSymEsc);                       // ESC
310
  fRawBuf.push_back(kSymEsc);                       // ESC
311
  fRawBuf.push_back((uint8_t)addr);                 // ADDR 
312
  fRawBuf.push_back((uint8_t)(data & 0x00ff));      // DL
313
  fRawBuf.push_back((uint8_t)((data>>8) & 0x00ff)); // DH
314 18 wfjm
  // write a filler char (just 0) to ensure that the 8b->9b stage in the
315
  // receiver (byte2cdata) is always out if the escape state...
316
  fRawBuf.push_back(0);                             // filler
317 10 wfjm
 
318
  return SndRaw(port, emsg);
319
}
320
 
321
//------------------------------------------+-----------------------------------
322
//! FIXME_docs
323
 
324
bool RlinkPacketBuf::SndKeep(RlinkPort* port, RerrMsg& emsg)
325
{
326
  Init();
327
 
328
  fRawBuf.clear();
329
  fRawBuf.push_back(kSymEsc);                       // ESC
330
  fRawBuf.push_back(kSymEsc);                       // ESC
331
 
332
  return SndRaw(port, emsg);
333
}
334
 
335
//------------------------------------------+-----------------------------------
336
//! FIXME_docs
337
 
338
void RlinkPacketBuf::Dump(std::ostream& os, int ind, const char* text) const
339
{
340
  RosFill bl(ind);
341
  os << bl << (text?text:"--") << "RlinkPacketBuf @ " << this << endl;
342
  os << bl << "  fCrc:          " << RosPrintBvi(fCrc.Crc(), 0) << endl;
343
  os << bl << "  fFlags:        " << RosPrintBvi(fFlags, 0) << endl;
344
  os << bl << "  fNdone:        " << RosPrintf(fNdone,"d",4) << endl;
345
  os << bl << "  fNesc:         " << RosPrintf(fNesc,"d",4) << endl;
346
  os << bl << "  fNattn:        " << RosPrintf(fNattn,"d",4) << endl;
347
  os << bl << "  fNidle:        " << RosPrintf(fNidle,"d",4) << endl;
348
  os << bl << "  fNdrop:        " << RosPrintf(fNdrop,"d",4) << endl;
349
 
350
  os << bl << "  fPktBuf(size): " << RosPrintf(fPktBuf.size(),"d",4);
351
  size_t ncol  = max(1, (80-ind-4-6)/(2+1));
352
  for (size_t i=0; i< fPktBuf.size(); i++) {
353
    if (i%ncol == 0) os << "\n" << bl << "    " << RosPrintf(i,"d",4) << ": ";
354
    os << RosPrintBvi(fPktBuf[i],16) << " ";
355
  }
356
  os << endl;
357
 
358
  os << bl << "  fRawBuf(size): " << RosPrintf(fRawBufSize,"d",4);
359
  for (size_t i=0; i< fRawBufSize; i++) {
360
    if (i%ncol == 0) os << "\n" << bl << "    " << RosPrintf(i,"d",4) << ": ";
361
    os << RosPrintBvi(fRawBuf[i],16) << " ";
362
  }
363
  os << endl;
364
 
365
  return;
366
}
367
 
368
//------------------------------------------+-----------------------------------
369
//! FIXME_docs
370
 
371
bool RlinkPacketBuf::SndRaw(RlinkPort* port, RerrMsg& emsg)
372
{
373
  if (port==0 || !port->IsOpen())
374 19 wfjm
    throw Rexception("RlinkPacketBuf::SndRaw()", "Bad state: port not open");
375 10 wfjm
 
376
  fRawBufSize = fRawBuf.size();
377
  int irc = port->Write(fRawBuf.data(), fRawBuf.size(), emsg);
378
  if (irc < 0) return false;
379
  if ((size_t)irc != fRawBuf.size()) {
380
    emsg.Init("RlinkPacketBuf::SndRaw()", "failed to write all data");
381
    return false;
382
  }
383
 
384
  return true;
385
}
386
 
387
//------------------------------------------+-----------------------------------
388
//! FIXME_docs
389
 
390
int RlinkPacketBuf::RcvRaw(RlinkPort* port, size_t size, float timeout,
391
                           RerrMsg& emsg)
392
{
393
  if (port==0 || !port->IsOpen())
394 19 wfjm
    throw Rexception("RlinkPacketBuf::RcvRaw()", "Bad state: port not open");
395 10 wfjm
 
396
  if (fRawBuf.size() < fRawBufSize+size) fRawBuf.resize(fRawBufSize+size);
397
  int irc = port->Read(fRawBuf.data()+fRawBufSize, size, timeout, emsg);
398
  if (irc == RlinkPort::kEof) {
399
    emsg.Init("RlinkPacketBuf::RcvRaw()", "eof on read");
400
  }
401
 
402
  if (irc > 0) {
403
    fRawBufSize += irc;
404
  }
405
 
406
  return irc;
407
}
408
 
409 19 wfjm
} // end namespace Retro

powered by: WebSVN 2.1.0

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