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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.61/] [tools/] [src/] [librlink/] [RlinkCommand.cpp] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 wfjm
// $Id: RlinkCommand.cpp 495 2013-03-06 17:13:48Z mueller $
2 10 wfjm
//
3 19 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-05-06   495   1.0.2  add RlinkContext to Print() args
17
// 2013-02-03   481   1.0.1  use Rexception
18 10 wfjm
// 2011-03-27   374   1.0    Initial version
19
// 2011-01-15   355   0.1    First draft
20
// ---------------------------------------------------------------------------
21
 
22
/*!
23
  \file
24 19 wfjm
  \version $Id: RlinkCommand.cpp 495 2013-03-06 17:13:48Z mueller $
25 10 wfjm
  \brief   Implemenation of class RlinkCommand.
26
 */
27
 
28
// debug
29
#include <iostream>
30
 
31
#include <algorithm>
32
 
33
#include "RlinkCommand.hpp"
34
 
35
#include "librtools/RosFill.hpp"
36
#include "librtools/RosPrintf.hpp"
37
#include "librtools/RosPrintBvi.hpp"
38 19 wfjm
#include "librtools/Rexception.hpp"
39 10 wfjm
 
40
using namespace std;
41
 
42
/*!
43
  \class Retro::RlinkCommand
44
  \brief FIXME_docs
45
*/
46
 
47 19 wfjm
// all method definitions in namespace Retro
48
namespace Retro {
49
 
50 10 wfjm
//------------------------------------------+-----------------------------------
51
// constants definitions
52
 
53
const uint8_t  RlinkCommand::kCmdRreg;
54
const uint8_t  RlinkCommand::kCmdRblk;
55
const uint8_t  RlinkCommand::kCmdWreg;
56
const uint8_t  RlinkCommand::kCmdWblk;
57
const uint8_t  RlinkCommand::kCmdStat;
58
const uint8_t  RlinkCommand::kCmdAttn;
59
const uint8_t  RlinkCommand::kCmdInit;
60
 
61
const uint32_t RlinkCommand::kFlagInit;
62
const uint32_t RlinkCommand::kFlagSend;
63
const uint32_t RlinkCommand::kFlagDone;
64
const uint32_t RlinkCommand::kFlagPktBeg;
65
const uint32_t RlinkCommand::kFlagPktEnd;
66
const uint32_t RlinkCommand::kFlagRecov;
67
const uint32_t RlinkCommand::kFlagResend;
68
const uint32_t RlinkCommand::kFlagErrNak;
69
const uint32_t RlinkCommand::kFlagErrMiss;
70
const uint32_t RlinkCommand::kFlagErrCmd;
71
const uint32_t RlinkCommand::kFlagErrCrc;
72
const uint32_t RlinkCommand::kFlagChkStat;
73
const uint32_t RlinkCommand::kFlagChkData;
74
const uint32_t RlinkCommand::kFlagVol;
75
 
76 19 wfjm
const uint8_t RlinkCommand::kStat_M_Stat;
77
const uint8_t RlinkCommand::kStat_V_Stat;
78
const uint8_t RlinkCommand::kStat_B_Stat;
79
const uint8_t RlinkCommand::kStat_M_Attn;
80
const uint8_t RlinkCommand::kStat_M_Cerr;
81
const uint8_t RlinkCommand::kStat_M_Derr;
82
const uint8_t RlinkCommand::kStat_M_RbNak;
83
const uint8_t RlinkCommand::kStat_M_RbErr;
84
 
85
const uint16_t RlinkCommand::kRbaddr_IInt;
86
const uint16_t RlinkCommand::kIInt_M_AnEna;
87
const uint16_t RlinkCommand::kIInt_M_ItoEna;
88
const uint16_t RlinkCommand::kIInt_M_ItoVal;
89
 
90 10 wfjm
//------------------------------------------+-----------------------------------
91
//! Default constructor
92
 
93
RlinkCommand::RlinkCommand()
94
  : fRequest(0),
95
    fAddress(0),
96
    fData(0),
97
    fBlock(),
98
    fpBlockExt(0),
99
    fBlockExtSize(0),
100
    fStatRequest(0),
101
    fStatus(0),
102
    fFlags(0),
103
    fRcvSize(0),
104
    fpExpect(0)
105
{}
106
 
107
//------------------------------------------+-----------------------------------
108
//! Copy constructor
109
 
110
RlinkCommand::RlinkCommand(const RlinkCommand& rhs)
111
  : fRequest(rhs.fRequest),
112
    fAddress(rhs.fAddress),
113
    fData(rhs.fData),
114
    fBlock(rhs.fBlock),
115
    fpBlockExt(rhs.fpBlockExt),
116
    fBlockExtSize(rhs.fBlockExtSize),
117
    fStatRequest(rhs.fStatRequest),
118
    fStatus(rhs.fStatus),
119
    fFlags(rhs.fFlags),
120
    fRcvSize(rhs.fRcvSize),
121
    fpExpect(rhs.fpExpect ? new RlinkCommandExpect(*rhs.fpExpect) : 0)
122
{}
123
 
124
//------------------------------------------+-----------------------------------
125
//! Destructor
126
 
127
RlinkCommand::~RlinkCommand()
128
{
129
  delete fpExpect;                          // expect object owned by command
130
}
131
 
132
//------------------------------------------+-----------------------------------
133
//! FIXME_docs
134
 
135
void RlinkCommand::CmdRblk(uint16_t addr, size_t size)
136
{
137
  SetCommand(kCmdRblk, addr);
138
  SetBlockRead(size);
139
  return;
140
}
141
 
142
//------------------------------------------+-----------------------------------
143
//! FIXME_docs
144
 
145
void RlinkCommand::CmdRblk(uint16_t addr, uint16_t* pblock, size_t size)
146
{
147
  SetCommand(kCmdRblk, addr);
148
  SetBlockExt(pblock, size);
149
  return;
150
}
151
 
152
//------------------------------------------+-----------------------------------
153
//! FIXME_docs
154
 
155
void RlinkCommand::CmdWblk(uint16_t addr, const std::vector<uint16_t>& block)
156
{
157
  SetCommand(kCmdWblk, addr);
158
  SetBlockWrite(block);
159
  return;
160
}
161
 
162
//------------------------------------------+-----------------------------------
163
//! FIXME_docs
164
 
165
void RlinkCommand::CmdWblk(uint16_t addr, const uint16_t* pblock, size_t size)
166
{
167
  SetCommand(kCmdWblk, addr);
168
  SetBlockExt(const_cast<uint16_t*>(pblock), size);
169
  return;
170
}
171
 
172
//------------------------------------------+-----------------------------------
173
//! FIXME_docs
174
 
175
void RlinkCommand::SetCommand(uint8_t cmd, uint16_t addr, uint16_t data)
176
{
177
  if (cmd > kCmdInit)
178 19 wfjm
    throw Rexception("RlinkCommand::SetCommand()", "Bad args: invalid cmd");
179 10 wfjm
  if (addr > 0xff)
180 19 wfjm
    throw Rexception("RlinkCommand::SetCommand()", "Bad args: invalid addr");
181 10 wfjm
  fRequest = cmd;
182
  fAddress = addr;
183
  fData    = data;
184
  fpBlockExt    = 0;
185
  fBlockExtSize = 0;
186
  fStatus  = 0;
187
  fFlags   = kFlagInit;
188
  fRcvSize = 0;
189
  delete fpExpect;
190
  fpExpect = 0;
191
  return;
192
}
193
 
194
//------------------------------------------+-----------------------------------
195
//! FIXME_docs
196
 
197
void RlinkCommand::SetAddress(uint16_t addr)
198
{
199
  if (addr > 0xff)
200 19 wfjm
    throw Rexception("RlinkCommand::SetAddress()", "Bad args: invalid addr");
201 10 wfjm
  fAddress = addr;
202
  return;
203
}
204
 
205
//------------------------------------------+-----------------------------------
206
//! FIXME_docs
207
 
208
void RlinkCommand::SetBlockWrite(const std::vector<uint16_t>& block)
209
{
210
  if (block.size() == 0 || block.size() > 256)
211 19 wfjm
    throw Rexception("RlinkCommand::SetBlockWrite()",
212
                     "Bad args: invalid block size");
213 10 wfjm
  fBlock = block;
214
  fpBlockExt    = 0;
215
  fBlockExtSize = 0;
216
  return;
217
}
218
 
219
//------------------------------------------+-----------------------------------
220
//! FIXME_docs
221
 
222
void RlinkCommand::SetBlockRead(size_t size)
223
{
224
  if (size == 0 || size > 256)
225 19 wfjm
    throw Rexception("RlinkCommand::SetBlockRead()",
226
                     "Bad args: invalid block size");
227 10 wfjm
  fBlock.clear();
228
  fBlock.resize(size);
229
  fpBlockExt    = 0;
230
  fBlockExtSize = 0;
231
  return;
232
}
233
 
234
//------------------------------------------+-----------------------------------
235
//! FIXME_docs
236
 
237
void RlinkCommand::SetBlockExt(uint16_t* pblock, size_t size)
238
{
239
  if (pblock == 0)
240 19 wfjm
    throw Rexception("RlinkCommand::SetBlockExt()",
241
                     "Bad args: pblock is null");
242 10 wfjm
  if (size == 0 || size > 256)
243 19 wfjm
    throw Rexception("RlinkCommand::SetBlockExt()",
244
                     "Bad args: invalid block size");
245 10 wfjm
  fpBlockExt    = pblock;
246
  fBlockExtSize = size;
247
  return;
248
}
249
 
250
//------------------------------------------+-----------------------------------
251
//! FIXME_docs
252
 
253
void RlinkCommand::SetExpect(RlinkCommandExpect* pexp)
254
{
255
  delete fpExpect;
256
  fpExpect = pexp;
257
  return;
258
}
259
 
260
//------------------------------------------+-----------------------------------
261
//! FIXME_docs
262
 
263 19 wfjm
void RlinkCommand::Print(std::ostream& os, const RlinkContext& cntx,
264
                         const RlinkAddrMap* pamap, size_t abase,
265
                         size_t dbase, size_t sbase) const
266 10 wfjm
{
267
  uint8_t ccode = Command();
268
 
269
  // separator + command mnemonic, code and flags
270
  // separator:  ++  first in packet
271
  //             --  non-first in packet
272
  //             -=  non-first in packet (marked volatile)
273
  const char* sep = "??";
274
  if (TestFlagAny(kFlagPktBeg)) {
275
    sep = "++";
276
  } else {
277
    sep = TestFlagAny(kFlagVol) ? "-=" : "--";
278
  }
279
 
280
  os << sep << " " << CommandName(ccode)
281
     << " (" << RosPrintBvi(Request(), 8)
282
     << ","  << RosPrintBvi(fFlags, 16, 20)
283
     << ")";
284
 
285
  // address field
286
  if (ccode==kCmdRreg || ccode==kCmdRblk ||
287
      ccode==kCmdWreg || ccode==kCmdWblk ||
288
      ccode==kCmdInit) {
289
    os << " a=" << RosPrintBvi(fAddress, abase);
290
    if (pamap) {
291
      string name;
292
      if (!pamap->Find(fAddress, name)) name.clear();
293
      os << "(" << name << RosFill(pamap->MaxNameLength()-name.length()) << ")";
294
    }
295
  }
296
 
297
  // data field (scalar)
298
  if (ccode== kCmdRreg || ccode==kCmdWreg ||
299
      ccode== kCmdStat || ccode==kCmdAttn ||
300
      ccode== kCmdInit) {
301
    os << " d=" << RosPrintBvi(fData, dbase);
302
 
303
    if (fpExpect &&
304
        (ccode==kCmdRreg || ccode==kCmdStat || ccode==kCmdAttn)) {
305
      if (TestFlagAny(kFlagChkData)) {
306
        os << "#";
307
        os << " D=" << RosPrintBvi(fpExpect->DataValue(), dbase);
308
        if (fpExpect->DataMask() != 0x0000)  {
309
          os << "," << RosPrintBvi(fpExpect->DataMask(), dbase);
310
        }
311
      } else if (fpExpect->DataIsChecked()) {
312
        os << "!";
313
      } else {
314
        os << " ";
315
      }
316
    } else {
317
      os << " ";
318
    }
319
  }
320
 
321
  if (ccode== kCmdRblk || ccode==kCmdWblk) {
322
    os << " n=" << RosPrintf(BlockSize(), "d", 3);
323
  }
324
 
325
  // ccmd field
326
  if (ccode == kCmdStat) {
327
    os << " c=" << RosPrintBvi(fStatRequest, 8);
328
  }
329
 
330
  // status field
331
  os << " s=" << RosPrintBvi(fStatus, sbase);
332 19 wfjm
  uint8_t scval  = fpExpect ? fpExpect->StatusValue() : cntx.StatusValue();
333
  uint8_t scmsk  = fpExpect ? fpExpect->StatusMask()  : cntx.StatusMask();
334
  if (TestFlagAny(kFlagChkStat)) {
335
    os << "#";
336
    os << " S=" << RosPrintBvi(scval, sbase);
337
    if (scmsk != 0x00) {
338
      os << "," << RosPrintBvi(scmsk, sbase);
339 10 wfjm
    }
340
  } else {
341 19 wfjm
    os << ( scmsk != 0xff ? "!" : " " );
342 10 wfjm
  }
343
 
344
  if (TestFlagAny(kFlagDone)) {
345
    if (TestFlagAny(kFlagChkStat|kFlagChkData)) {
346
      os << " FAIL: "
347
         << Rtools::Flags2String(fFlags&(kFlagChkStat|kFlagChkData),
348
                                 FlagNames(),',');
349
    } else {
350
      os << " OK";
351
    }
352
    if (TestFlagAny(kFlagRecov|kFlagResend)) os << " WARN: retried";
353
  } else if (TestFlagAny(kFlagSend)) {
354
    os << " FAIL: "
355
       << Rtools::Flags2String(fFlags&(kFlagErrNak|kFlagErrMiss|
356
                                       kFlagErrCmd|kFlagErrCrc),
357
                               FlagNames(),',');
358
  } else {
359
    os << " PEND";
360
  }
361
 
362
  // handle data part of rblk and wblk commands
363
  size_t dwidth = (dbase==2) ? 16 : ((dbase==8) ? 6 : 4);
364
 
365
  if (ccode==kCmdRblk) {
366
    bool  dcheck = (fpExpect && fpExpect->BlockValue().size() > 0);
367
    size_t ncol  = (80-4-5)/(dwidth+2);
368
 
369
    size_t size  = BlockSize();
370
    const uint16_t* pdat = BlockPointer();
371
 
372
    for (size_t i=0; i<size; i++) {
373
      if (i%ncol == 0) os << "\n    " << RosPrintf(i,"d",3) << ": ";
374
      os << RosPrintBvi(pdat[i], dbase);
375
      if (dcheck) {
376
        if (!fpExpect->BlockCheck(i, pdat[i])) {
377
          os << "#";
378
        } else {
379
          os << (fpExpect->BlockIsChecked(i) ? "!" : "-");
380
        }
381
      } else {
382
        os << " ";
383
      }
384
      os << " ";
385
    }
386
 
387
    if (dcheck && TestFlagAny(kFlagChkData)) {
388
      const vector<uint16_t>& evalvec = fpExpect->BlockValue();
389
      const vector<uint16_t>& emskvec = fpExpect->BlockMask();
390
      for (size_t i=0; i<size; i++) {
391
        if (!fpExpect->BlockCheck(i, pdat[i])) {
392
          os << "\n      FAIL d[" << RosPrintf(i,"d",3) << "]: "
393
             << RosPrintBvi(pdat[i], dbase) << "#"
394
             << "  D=" << RosPrintBvi(evalvec[i], dbase);
395
          if (i < emskvec.size() && emskvec[i]!=0x0000) {
396
            os << "," << RosPrintBvi(emskvec[i], dbase);
397
          }
398
        }
399
      }
400
    }
401
  }
402
 
403
  if (ccode==kCmdWblk) {
404
    const uint16_t* pdat = BlockPointer();
405
    size_t size = BlockSize();
406
    size_t ncol = (80-4-5)/(dwidth+2);
407
    for (size_t i=0; i<size; i++) {
408
      if (i%ncol == 0) os << "\n    " << RosPrintf(i,"d",3) << ": ";
409
      os << RosPrintBvi(pdat[i], dbase) << "  ";
410
    }
411
  }
412
 
413
  os << endl;
414
 
415
  return;
416
}
417
 
418
//------------------------------------------+-----------------------------------
419
//! FIXME_docs
420
 
421
void RlinkCommand::Dump(std::ostream& os, int ind, const char* text) const
422
{
423
  RosFill bl(ind);
424
  os << bl << (text?text:"--") << "RlinkCommand @ " << this << endl;
425
 
426
  os << bl << "  fRequest:        " << RosPrintBvi(fRequest,8)
427
     << "  seq:" << RosPrintf(SeqNumber(),"d",2)
428
     << "  cmd:" << RosPrintf(Command(),"d",1)
429
     << " " << CommandName(Command()) << endl;
430
  os << bl << "  fAddress:        " << RosPrintBvi(fAddress,0) << endl;
431
  os << bl << "  fData:           " << RosPrintBvi(fData,0) << endl;
432
  os << bl << "  fBlock.size:     " << RosPrintf(fBlock.size(),"d",3) << endl;
433
  os << bl << "  fpBlockExt:      " << fpBlockExt << endl;
434
  os << bl << "  fBlockExtSize:   " << RosPrintf(fBlockExtSize,"d",3) << endl;
435
  os << bl << "  fStatRequest:    " << RosPrintBvi(fStatRequest,0) << endl;
436
  os << bl << "  fStatus:         " << RosPrintBvi(fStatus,0) << endl;
437
  os << bl << "  fFlags:          " << RosPrintBvi(fFlags,16,24)
438
           << "  " << Rtools::Flags2String(fFlags, FlagNames()) << endl;
439
  os << bl << "  fRcvSize:        " << RosPrintf(fRcvSize,"d",4) << endl;
440
  if (BlockSize() > 0) {
441
    size_t ncol  = max(1, (80-ind-4-5)/(4+1));
442
    os << bl << "  block data:";
443
    for (size_t i=0; i<BlockSize(); i++) {
444
      if (i%ncol == 0) os << "\n" << bl << "    " << RosPrintf(i,"d",3) << ": ";
445
      os << RosPrintBvi(BlockPointer()[i],16) << " ";
446
    }
447
    os << endl;
448
  }
449
  if (fpExpect) fpExpect->Dump(os, ind+2, "fpExpect: ");
450
 
451
  return;
452
}
453
 
454
//------------------------------------------+-----------------------------------
455
//! FIXME_docs
456
 
457
const char* RlinkCommand::CommandName(uint8_t cmd)
458
{
459
  static const char* cmdname[8] = {"rreg","rblk","wreg","wblk",
460
                                   "stat","attn","init","????"};
461
 
462
  return cmdname[cmd&0x7];
463
}
464
 
465
//------------------------------------------+-----------------------------------
466
//! FIXME_docs
467
 
468
const Retro::RflagName* RlinkCommand::FlagNames()
469
{
470
  // use msb first order, will also be printing order
471
  static Retro::RflagName fnam[] = {
472
    {kFlagChkData, "ChkData"},
473
    {kFlagChkStat, "ChkStat"},
474
    {kFlagErrCrc,  "ErrCrc"},
475
    {kFlagErrCmd,  "ErrCmd"},
476
    {kFlagErrMiss, "ErrMiss"},
477
    {kFlagErrNak,  "ErrNak"},
478
    {kFlagResend,  "Resend"},
479
    {kFlagRecov,   "Recov"},
480
    {kFlagPktEnd,  "PktEnd"},
481
    {kFlagPktBeg,  "PktBeg"},
482
    {kFlagDone,    "Done"},
483
    {kFlagSend,    "Send"},
484
    {kFlagInit,    "Init"},
485
    {0u, ""}
486
  };
487
  return fnam;
488
}
489
 
490
//------------------------------------------+-----------------------------------
491
//! FIXME_docs
492
 
493
RlinkCommand& RlinkCommand::operator=(const RlinkCommand& rhs)
494
{
495
  if (&rhs == this) return *this;
496
  fRequest      = rhs.fRequest;
497
  fAddress      = rhs.fAddress;
498
  fData         = rhs.fData;
499
  fBlock        = rhs.fBlock;
500
  fpBlockExt    = rhs.fpBlockExt;
501
  fBlockExtSize = rhs.fBlockExtSize;
502
  fStatRequest  = rhs.fStatRequest;
503
  fStatus       = rhs.fStatus;
504
  fFlags        = rhs.fFlags;
505
  fRcvSize      = rhs.fRcvSize;
506
  delete fpExpect;
507
  fpExpect      = rhs.fpExpect ? new RlinkCommandExpect(*rhs.fpExpect) : 0;
508
  return *this;
509
}
510
 
511 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.