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

Subversion Repositories w11

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

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

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