// $Id: Rw11CntlDL11.cpp 516 2013-05-05 21:24:52Z mueller $
|
// $Id: Rw11CntlDL11.cpp 516 2013-05-05 21:24:52Z mueller $
|
//
|
//
|
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
// 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
|
// 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
|
// 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.
|
// 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
|
// This program is distributed in the hope that it will be useful, but
|
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// for complete details.
|
// for complete details.
|
//
|
//
|
// Revision History:
|
// Revision History:
|
// Date Rev Version Comment
|
// Date Rev Version Comment
|
// 2013-05-04 516 1.0.2 add RxRlim support (receive interrupt rate limit)
|
// 2013-05-04 516 1.0.2 add RxRlim support (receive interrupt rate limit)
|
// 2013-04-20 508 1.0.1 add trace support
|
// 2013-04-20 508 1.0.1 add trace support
|
// 2013-03-06 495 1.0 Initial version
|
// 2013-03-06 495 1.0 Initial version
|
// 2013-02-05 483 0.1 First draft
|
// 2013-02-05 483 0.1 First draft
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
/*!
|
/*!
|
\file
|
\file
|
\version $Id: Rw11CntlDL11.cpp 516 2013-05-05 21:24:52Z mueller $
|
\version $Id: Rw11CntlDL11.cpp 516 2013-05-05 21:24:52Z mueller $
|
\brief Implemenation of Rw11CntlDL11.
|
\brief Implemenation of Rw11CntlDL11.
|
*/
|
*/
|
|
|
#include "boost/bind.hpp"
|
#include "boost/bind.hpp"
|
|
|
#include "librtools/RosFill.hpp"
|
#include "librtools/RosFill.hpp"
|
#include "librtools/RosPrintBvi.hpp"
|
#include "librtools/RosPrintBvi.hpp"
|
#include "librtools/RosPrintf.hpp"
|
#include "librtools/RosPrintf.hpp"
|
#include "librtools/Rexception.hpp"
|
#include "librtools/Rexception.hpp"
|
#include "librtools/RlogMsg.hpp"
|
#include "librtools/RlogMsg.hpp"
|
|
|
#include "Rw11CntlDL11.hpp"
|
#include "Rw11CntlDL11.hpp"
|
|
|
using namespace std;
|
using namespace std;
|
|
|
/*!
|
/*!
|
\class Retro::Rw11CntlDL11
|
\class Retro::Rw11CntlDL11
|
\brief FIXME_docs
|
\brief FIXME_docs
|
*/
|
*/
|
|
|
// all method definitions in namespace Retro
|
// all method definitions in namespace Retro
|
namespace Retro {
|
namespace Retro {
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
// constants definitions
|
// constants definitions
|
|
|
const uint16_t Rw11CntlDL11::kIbaddr;
|
const uint16_t Rw11CntlDL11::kIbaddr;
|
const int Rw11CntlDL11::kLam;
|
const int Rw11CntlDL11::kLam;
|
|
|
const uint16_t Rw11CntlDL11::kRCSR;
|
const uint16_t Rw11CntlDL11::kRCSR;
|
const uint16_t Rw11CntlDL11::kRBUF;
|
const uint16_t Rw11CntlDL11::kRBUF;
|
const uint16_t Rw11CntlDL11::kXCSR;
|
const uint16_t Rw11CntlDL11::kXCSR;
|
const uint16_t Rw11CntlDL11::kXBUF;
|
const uint16_t Rw11CntlDL11::kXBUF;
|
|
|
const uint16_t Rw11CntlDL11::kProbeOff;
|
const uint16_t Rw11CntlDL11::kProbeOff;
|
const bool Rw11CntlDL11::kProbeInt;
|
const bool Rw11CntlDL11::kProbeInt;
|
const bool Rw11CntlDL11::kProbeRem;
|
const bool Rw11CntlDL11::kProbeRem;
|
|
|
const uint16_t Rw11CntlDL11::kRCSR_M_RXRLIM;
|
const uint16_t Rw11CntlDL11::kRCSR_M_RXRLIM;
|
const uint16_t Rw11CntlDL11::kRCSR_V_RXRLIM;
|
const uint16_t Rw11CntlDL11::kRCSR_V_RXRLIM;
|
const uint16_t Rw11CntlDL11::kRCSR_B_RXRLIM;
|
const uint16_t Rw11CntlDL11::kRCSR_B_RXRLIM;
|
const uint16_t Rw11CntlDL11::kRCSR_M_RDONE;
|
const uint16_t Rw11CntlDL11::kRCSR_M_RDONE;
|
const uint16_t Rw11CntlDL11::kXCSR_M_XRDY;
|
const uint16_t Rw11CntlDL11::kXCSR_M_XRDY;
|
const uint16_t Rw11CntlDL11::kXBUF_M_RRDY;
|
const uint16_t Rw11CntlDL11::kXBUF_M_RRDY;
|
const uint16_t Rw11CntlDL11::kXBUF_M_XVAL;
|
const uint16_t Rw11CntlDL11::kXBUF_M_XVAL;
|
const uint16_t Rw11CntlDL11::kXBUF_M_XBUF;
|
const uint16_t Rw11CntlDL11::kXBUF_M_XBUF;
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! Default constructor
|
//! Default constructor
|
|
|
Rw11CntlDL11::Rw11CntlDL11()
|
Rw11CntlDL11::Rw11CntlDL11()
|
: Rw11CntlBase<Rw11UnitDL11,1>("dl11"),
|
: Rw11CntlBase<Rw11UnitDL11,1>("dl11"),
|
fPC_xbuf(0),
|
fPC_xbuf(0),
|
fRxRlim(0)
|
fRxRlim(0)
|
{
|
{
|
// must here because Unit have a back-pointer (not available at Rw11CntlBase)
|
// must here because Unit have a back-pointer (not available at Rw11CntlBase)
|
for (size_t i=0; i<NUnit(); i++) {
|
for (size_t i=0; i<NUnit(); i++) {
|
fspUnit[i].reset(new Rw11UnitDL11(this, i));
|
fspUnit[i].reset(new Rw11UnitDL11(this, i));
|
}
|
}
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! Destructor
|
//! Destructor
|
|
|
Rw11CntlDL11::~Rw11CntlDL11()
|
Rw11CntlDL11::~Rw11CntlDL11()
|
{}
|
{}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
void Rw11CntlDL11::Config(const std::string& name, uint16_t base, int lam)
|
void Rw11CntlDL11::Config(const std::string& name, uint16_t base, int lam)
|
{
|
{
|
ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
|
ConfigCntl(name, base, lam, kProbeOff, kProbeInt, kProbeRem);
|
return;
|
return;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
void Rw11CntlDL11::Start()
|
void Rw11CntlDL11::Start()
|
{
|
{
|
if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
|
if (fStarted || fLam<0 || !fEnable || !fProbe.Found())
|
throw Rexception("Rw11CntlDL11::Start",
|
throw Rexception("Rw11CntlDL11::Start",
|
"Bad state: started, no lam, not enable, not found");
|
"Bad state: started, no lam, not enable, not found");
|
|
|
// setup primary info clist
|
// setup primary info clist
|
fPrimClist.Clear();
|
fPrimClist.Clear();
|
Cpu().AddIbrb(fPrimClist, fBase);
|
Cpu().AddIbrb(fPrimClist, fBase);
|
fPC_xbuf = Cpu().AddRibr(fPrimClist, fBase+kXBUF);
|
fPC_xbuf = Cpu().AddRibr(fPrimClist, fBase+kXBUF);
|
|
|
// add attn handler
|
// add attn handler
|
Server().AddAttnHandler(boost::bind(&Rw11CntlDL11::AttnHandler, this, _1),
|
Server().AddAttnHandler(boost::bind(&Rw11CntlDL11::AttnHandler, this, _1),
|
uint16_t(1)<<fLam, (void*)this);
|
uint16_t(1)<<fLam, (void*)this);
|
fStarted = true;
|
fStarted = true;
|
return;
|
return;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
void Rw11CntlDL11::UnitSetup(size_t ind)
|
void Rw11CntlDL11::UnitSetup(size_t ind)
|
{
|
{
|
Rw11Cpu& cpu = Cpu();
|
Rw11Cpu& cpu = Cpu();
|
uint16_t rcsr = (fRxRlim<<kRCSR_V_RXRLIM) & kRCSR_M_RXRLIM;
|
uint16_t rcsr = (fRxRlim<<kRCSR_V_RXRLIM) & kRCSR_M_RXRLIM;
|
RlinkCommandList clist;
|
RlinkCommandList clist;
|
cpu.AddIbrb(clist, fBase);
|
cpu.AddIbrb(clist, fBase);
|
cpu.AddWibr(clist, fBase+kRCSR, rcsr);
|
cpu.AddWibr(clist, fBase+kRCSR, rcsr);
|
Server().Exec(clist);
|
Server().Exec(clist);
|
return;
|
return;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
void Rw11CntlDL11::Wakeup()
|
void Rw11CntlDL11::Wakeup()
|
{
|
{
|
if (!fspUnit[0]->RcvQueueEmpty()) {
|
if (!fspUnit[0]->RcvQueueEmpty()) {
|
RlinkCommandList clist;
|
RlinkCommandList clist;
|
Cpu().AddIbrb(clist, fBase);
|
Cpu().AddIbrb(clist, fBase);
|
size_t ircsr = Cpu().AddRibr(clist, fBase+kRCSR);
|
size_t ircsr = Cpu().AddRibr(clist, fBase+kRCSR);
|
Server().Exec(clist);
|
Server().Exec(clist);
|
// FIXME_code: handle errors
|
// FIXME_code: handle errors
|
uint16_t rcsr = clist[ircsr].Data();
|
uint16_t rcsr = clist[ircsr].Data();
|
if ((rcsr & kRCSR_M_RDONE) == 0) { // RBUF not full
|
if ((rcsr & kRCSR_M_RDONE) == 0) { // RBUF not full
|
uint8_t ichr = fspUnit[0]->RcvNext();
|
uint8_t ichr = fspUnit[0]->RcvNext();
|
clist.Clear();
|
clist.Clear();
|
Cpu().AddWibr(clist, fBase+kRBUF, ichr);
|
Cpu().AddWibr(clist, fBase+kRBUF, ichr);
|
Server().Exec(clist);
|
Server().Exec(clist);
|
// FIXME_code: handle errors
|
// FIXME_code: handle errors
|
}
|
}
|
}
|
}
|
|
|
return;
|
return;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
void Rw11CntlDL11::SetRxRlim(uint16_t rlim)
|
void Rw11CntlDL11::SetRxRlim(uint16_t rlim)
|
{
|
{
|
if (rlim > kRCSR_B_RXRLIM)
|
if (rlim > kRCSR_B_RXRLIM)
|
throw Rexception("Rw11CntlDL11::SetRxRlim","Bad args: rlim too large");
|
throw Rexception("Rw11CntlDL11::SetRxRlim","Bad args: rlim too large");
|
|
|
fRxRlim = rlim;
|
fRxRlim = rlim;
|
UnitSetup(0);
|
UnitSetup(0);
|
return;
|
return;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
uint16_t Rw11CntlDL11::RxRlim() const
|
uint16_t Rw11CntlDL11::RxRlim() const
|
{
|
{
|
return fRxRlim;
|
return fRxRlim;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
void Rw11CntlDL11::Dump(std::ostream& os, int ind, const char* text) const
|
void Rw11CntlDL11::Dump(std::ostream& os, int ind, const char* text) const
|
{
|
{
|
RosFill bl(ind);
|
RosFill bl(ind);
|
os << bl << (text?text:"--") << "Rw11CntlDL11 @ " << this << endl;
|
os << bl << (text?text:"--") << "Rw11CntlDL11 @ " << this << endl;
|
os << bl << " fPC_xbuf: " << fPC_xbuf << endl;
|
os << bl << " fPC_xbuf: " << fPC_xbuf << endl;
|
os << bl << " fRxRlim: " << fRxRlim << endl;
|
os << bl << " fRxRlim: " << fRxRlim << endl;
|
|
|
Rw11CntlBase<Rw11UnitDL11,1>::Dump(os, ind, " ^");
|
Rw11CntlBase<Rw11UnitDL11,1>::Dump(os, ind, " ^");
|
return;
|
return;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
int Rw11CntlDL11::AttnHandler(const RlinkServer::AttnArgs& args)
|
int Rw11CntlDL11::AttnHandler(const RlinkServer::AttnArgs& args)
|
{
|
{
|
RlinkCommandList* pclist;
|
RlinkCommandList* pclist;
|
size_t off;
|
size_t off;
|
|
|
GetPrimInfo(args, pclist, off);
|
GetPrimInfo(args, pclist, off);
|
|
|
uint16_t xbuf = (*pclist)[off+fPC_xbuf].Data();
|
uint16_t xbuf = (*pclist)[off+fPC_xbuf].Data();
|
|
|
uint8_t ochr = xbuf & kXBUF_M_XBUF;
|
uint8_t ochr = xbuf & kXBUF_M_XBUF;
|
bool xval = xbuf & kXBUF_M_XVAL;
|
bool xval = xbuf & kXBUF_M_XVAL;
|
bool rrdy = xbuf & kXBUF_M_RRDY;
|
bool rrdy = xbuf & kXBUF_M_RRDY;
|
|
|
if (fTraceLevel>0) {
|
if (fTraceLevel>0) {
|
RlogMsg lmsg(LogFile());
|
RlogMsg lmsg(LogFile());
|
lmsg << "-I DL11." << Name()
|
lmsg << "-I DL11." << Name()
|
<< " xbuf=" << RosPrintBvi(xbuf,8)
|
<< " xbuf=" << RosPrintBvi(xbuf,8)
|
<< " xval=" << xval
|
<< " xval=" << xval
|
<< " rrdy=" << rrdy
|
<< " rrdy=" << rrdy
|
<< " rcvq=" << RosPrintf(fspUnit[0]->RcvQueueSize(),"d",3);
|
<< " rcvq=" << RosPrintf(fspUnit[0]->RcvQueueSize(),"d",3);
|
if (xval) {
|
if (xval) {
|
lmsg << " char=";
|
lmsg << " char=";
|
if (ochr>=040 && ochr<0177) {
|
if (ochr>=040 && ochr<0177) {
|
lmsg << "'" << char(ochr) << "'";
|
lmsg << "'" << char(ochr) << "'";
|
} else {
|
} else {
|
lmsg << RosPrintBvi(ochr,8);
|
lmsg << RosPrintBvi(ochr,8);
|
lmsg << " " << ((ochr&0200) ? "|" : " ");
|
lmsg << " " << ((ochr&0200) ? "|" : " ");
|
uint8_t ochr7 = ochr & 0177;
|
uint8_t ochr7 = ochr & 0177;
|
if (ochr7 < 040) {
|
if (ochr7 < 040) {
|
switch (ochr7) {
|
switch (ochr7) {
|
case 010: lmsg << "BS"; break;
|
case 010: lmsg << "BS"; break;
|
case 011: lmsg << "HT"; break;
|
case 011: lmsg << "HT"; break;
|
case 012: lmsg << "LF"; break;
|
case 012: lmsg << "LF"; break;
|
case 013: lmsg << "VT"; break;
|
case 013: lmsg << "VT"; break;
|
case 014: lmsg << "FF"; break;
|
case 014: lmsg << "FF"; break;
|
case 015: lmsg << "CR"; break;
|
case 015: lmsg << "CR"; break;
|
default: lmsg << "^" << char('A'+ochr7);
|
default: lmsg << "^" << char('A'+ochr7);
|
}
|
}
|
} else {
|
} else {
|
if (ochr7 < 0177) {
|
if (ochr7 < 0177) {
|
lmsg << "'" << char(ochr7) << "'";
|
lmsg << "'" << char(ochr7) << "'";
|
} else {
|
} else {
|
lmsg << "DEL";
|
lmsg << "DEL";
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
if (xval) {
|
if (xval) {
|
fspUnit[0]->Snd(&ochr, 1);
|
fspUnit[0]->Snd(&ochr, 1);
|
}
|
}
|
|
|
if (rrdy && !fspUnit[0]->RcvQueueEmpty()) {
|
if (rrdy && !fspUnit[0]->RcvQueueEmpty()) {
|
uint8_t ichr = fspUnit[0]->RcvNext();
|
uint8_t ichr = fspUnit[0]->RcvNext();
|
RlinkCommandList clist;
|
RlinkCommandList clist;
|
Cpu().AddWibr(clist, fBase+kRBUF, ichr);
|
Cpu().AddWibr(clist, fBase+kRBUF, ichr);
|
Server().Exec(clist);
|
Server().Exec(clist);
|
// FIXME_code: handle errors
|
// FIXME_code: handle errors
|
}
|
}
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
} // end namespace Retro
|
} // end namespace Retro
|
|
|