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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.6/] [tools/] [src/] [librlinktpp/] [RtclRlinkPort.cpp] - Rev 40

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

// $Id: RtclRlinkPort.cpp 521 2013-05-20 22:16:45Z mueller $
//
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
//
// This program is free software; you may redistribute and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 2, or at your option any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for complete details.
// 
// Revision History: 
// Date         Rev Version  Comment
// 2013-02-23   492   1.0.2  use RlogFile.Name();
// 2013-02-22   491   1.0.1  use new RlogFile/RlogMsg interfaces
// 2013-01-27   478   1.0    Initial version
// ---------------------------------------------------------------------------
 
/*!
  \file
  \version $Id: RtclRlinkPort.cpp 521 2013-05-20 22:16:45Z mueller $
  \brief   Implemenation of class RtclRlinkPort.
 */
 
#include <ctype.h>
 
#include <iostream>
 
#include "boost/bind.hpp"
 
#include "librtcltools/Rtcl.hpp"
#include "librtcltools/RtclOPtr.hpp"
#include "librtcltools/RtclNameSet.hpp"
#include "librtcltools/RtclStats.hpp"
#include "librtools/RosPrintf.hpp"
#include "librtools/RlogFile.hpp"
#include "librlink/RlinkPortFactory.hpp"
 
#include "RtclRlinkPort.hpp"
 
using namespace std;
 
/*!
  \class Retro::RtclRlinkPort
  \brief FIXME_docs
*/
 
// all method definitions in namespace Retro
namespace Retro {
 
//------------------------------------------+-----------------------------------
//! Default constructor
 
RtclRlinkPort::RtclRlinkPort(Tcl_Interp* interp, const char* name)
  : RtclProxyBase("RlinkPort"),
    fpObj(0),
    fspLog(new RlogFile(&cout, "<cout>")),
    fTraceLevel(0),
    fErrCnt(0)
{
  CreateObjectCmd(interp, name);
  AddMeth("open",     boost::bind(&RtclRlinkPort::M_open,    this, _1));
  AddMeth("close",    boost::bind(&RtclRlinkPort::M_close,   this, _1));
  AddMeth("errcnt",   boost::bind(&RtclRlinkPort::M_errcnt,  this, _1));
  AddMeth("rawio",    boost::bind(&RtclRlinkPort::M_rawio,   this, _1));
  AddMeth("stats",    boost::bind(&RtclRlinkPort::M_stats,   this, _1));
  AddMeth("log",      boost::bind(&RtclRlinkPort::M_log,     this, _1));
  AddMeth("dump",     boost::bind(&RtclRlinkPort::M_dump,    this, _1));
  AddMeth("config",   boost::bind(&RtclRlinkPort::M_config,  this, _1));
  AddMeth("$default", boost::bind(&RtclRlinkPort::M_default, this, _1));
}
 
//------------------------------------------+-----------------------------------
//! Destructor
 
RtclRlinkPort::~RtclRlinkPort()
{
  delete fpObj;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int RtclRlinkPort::M_open(RtclArgs& args)
{
  string path;
 
  if (!args.GetArg("?path", path)) return kERR;
  if (!args.AllDone()) return kERR;
 
  RerrMsg emsg;
  if (args.NOptMiss() == 0) {               // open path
    delete fpObj;
    fpObj = RlinkPortFactory::Open(path, emsg);
    if (!fpObj) return args.Quit(emsg);
    fpObj->SetLogFile(fspLog);
    fpObj->SetTraceLevel(fTraceLevel);
  } else {                                  // open
    string name = (fpObj && fpObj->IsOpen()) ? fpObj->Url().Url() : string();
    args.SetResult(name);
  }
  return kOK;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int RtclRlinkPort::M_close(RtclArgs& args)
{
  if (!args.AllDone()) return kERR;
  if (!TestOpen(args)) return kERR;
  delete fpObj;
  return kOK;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int RtclRlinkPort::M_errcnt(RtclArgs& args)
{
  static RtclNameSet optset("-clear");
  string opt;
  bool fclear = false;
 
  while (args.NextOpt(opt, optset)) {
    if (opt == "-clear") fclear = true;
  }
  if (!args.AllDone()) return kERR;
 
  args.SetResult(int(fErrCnt));
  if (fclear) fErrCnt = 0;
 
  return kOK;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int RtclRlinkPort::M_rawio(RtclArgs& args)
{
  return DoRawio(args, fpObj, fErrCnt);
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int RtclRlinkPort::M_stats(RtclArgs& args)
{
  RtclStats::Context cntx;
 
  if (!TestOpen(args)) return kERR;
  if (!RtclStats::GetArgs(args, cntx)) return kERR;
  if (!RtclStats::Collect(args, cntx, fpObj->Stats())) return kERR;
  return kOK;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int RtclRlinkPort::M_log(RtclArgs& args)
{
  string msg;
  if (!args.GetArg("msg", msg)) return kERR;
  if (!args.AllDone()) return kERR;
  if (fTraceLevel != 0) fspLog->Write(string("# ") + msg);
  return kOK;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int RtclRlinkPort::M_dump(RtclArgs& args)
{
  if (!args.AllDone()) return kERR;
  if (!TestOpen(args)) return kERR;
 
  ostringstream sos;
  fpObj->Dump(sos, 0);
  args.SetResult(sos);
  return kOK;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int RtclRlinkPort::M_config(RtclArgs& args)
{
  static RtclNameSet optset("-logfile|-logtracelevel");
 
  if (args.NDone() == (size_t)args.Objc()) {
    ostringstream sos;
    sos << " -logfile {" << fspLog->Name() << "}"
        << " -logtracelevel " << RosPrintf(fTraceLevel, "d");
    args.AppendResult(sos);
    return kOK;
  }
 
  string opt;
  while (args.NextOpt(opt, optset)) {
    if        (opt == "-logfile") {         // -logfile ?name ------------------
      string name;
      if (!args.Config("??name", name)) return false;
      if (args.NOptMiss() == 0) {             // new filename ?
        if (name == "-" || name == "<cout>") {
          fspLog->UseStream(&cout, "<cout>");
        } else {
          if (!fspLog->Open(name)) {
            fspLog->UseStream(&cout, "<cout>");
            return args.Quit(string("-E: open failed for '") + name +
                             "', using stdout");
          }
        }
      }
    } else if (opt == "-logtracelevel") {   // -logtracelevel ?loglevel --------
      if (!args.Config("??loglevel", fTraceLevel, 3)) return false;
      if (fpObj) fpObj->SetTraceLevel(fTraceLevel);
    }
  }
 
  if (!args.AllDone()) return kERR;
  return kOK;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int RtclRlinkPort::M_default(RtclArgs& args)
{
  if (!args.AllDone()) return kERR;
  ostringstream sos;
 
  sos << "logfile:     " << fspLog->Name()
      << "   tracelevel " << fTraceLevel; 
 
  args.AppendResultLines(sos);
  return kOK;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
bool RtclRlinkPort::TestOpen(RtclArgs& args)
{
  if (fpObj) return true;
  args.AppendResult("-E: port not open", NULL);
  return false;
}
 
//------------------------------------------+-----------------------------------
//! FIXME_docs
 
int RtclRlinkPort::DoRawio(RtclArgs& args, RlinkPort* pport, size_t& errcnt)
{
  static RtclNameSet optset("-rblk|-wblk|-edata|-timeout");
 
  if (!pport || !pport->IsOpen()) args.Quit("-E: port not open");
 
  string opt;
  char mode = 0;
 
  int32_t rsize;
  string rvname;
  vector<uint8_t> rdata;
  vector<uint8_t> wdata;
  vector<uint8_t> edata;
  vector<uint8_t> emask;
  double timeout = 1.;
 
  while (args.NextOpt(opt, optset)) {
    if        (opt == "-rblk") {            // -rblk size ?varData ------------
      if (mode) return args.Quit("-E: only one -rblk or -wblk allowed");
      mode = 'r';
      if (!args.GetArg("bsize", rsize, 1, 256)) return kERR;
      if (!args.GetArg("??varData", rvname)) return kERR;
 
    } else if (opt == "-wblk") {            // -wblk block --------------------
      if (mode) return args.Quit("-E: only one -rblk or -wblk allowed");
      mode = 'w';
      if (!args.GetArg("data", wdata, 1, 256)) return kERR;
 
    } else if (opt == "-edata") {           // -edata data ?mask --------------
      if (mode != 'r') return args.Quit("-E: -edata only allowed after -rblk");
      if (!args.GetArg("data", edata, 0, rsize)) return kERR;
      if (!args.GetArg("??mask", emask, 0, rsize)) return kERR;
 
    } else if (opt == "-timeout") {         // -timeout tsec ------------------
      if (!args.GetArg("tsec", timeout, 0.)) return kERR;
    }
  }
 
  if (!args.AllDone()) return kERR;
 
  if (!mode) return args.Quit("-E: no -rblk or -wblk given");
 
  if (mode == 'r') {                        // handle -rblk ------------------
    RerrMsg emsg;
    double tused = 0.;
    rdata.resize(rsize);
    int irc = pport->RawRead(rdata.data(), rdata.size(), true, timeout, 
                             tused, emsg);
    if (irc == RlinkPort::kErr) return args.Quit("-E: timeout on -rblk");
    if (irc != (int)rdata.size()) return args.Quit(emsg);
    if (rvname.length()) {
      RtclOPtr pres(Rtcl::NewListIntObj(rdata));
      if(!Rtcl::SetVar(args.Interp(), rvname, pres)) return kERR;
    }
    if (edata.size()) {
      size_t nerr=0;
      for (size_t i=0; i<rdata.size(); i++) {
        if (i >= edata.size()) break;
        uint8_t eval = edata[i];
        uint8_t emsk = (i < emask.size()) ? emask[i] : 0x0000;
        if ((rdata[i]|emsk) != (eval|emsk)) nerr += 1;
      }
      if (nerr) errcnt += 1;
    }
    args.SetResult(tused);
 
  } else {                                  // handle -wblk ------------------
    RerrMsg emsg;
    int irc = pport->RawWrite(wdata.data(), wdata.size(), emsg);
    if (irc != (int)wdata.size()) return args.Quit(emsg);
  }
 
  return kOK;
}
 
} // end namespace Retro
 

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

powered by: WebSVN 2.1.0

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