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 28

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

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