• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

abbplugin/src/AbbDevice.cxx (r4864/r4183)

Go to the documentation of this file.
00001 #include "roc/AbbDevice.h"
00002 
00003 #include <iostream>
00004 #include <fstream>
00005 #include <stdio.h>
00006 
00007 #include "dabc/Manager.h"
00008 #include "dabc/Port.h"
00009 #include "dabc/Command.h"
00010 #include "dabc/CommandsSet.h"
00011 
00012 #include "base/Url.h"
00013 
00014 #include "roc/defines_roc.h"
00015 #include "roc/defines_optic.h"
00016 #include "roc/Commands.h"
00017 #include "roc/Board.h"
00018 
00019 #include "roc/AbbTransport.h"
00020 #include "roc/AbbBoard.h"
00021 
00022 #include "ABBdaemon.h"
00023 
00024 const char* roc::OpticPathPar = "OpticPath";
00025 
00026 enum { PUT_BIT = 0x80000000 };
00027 
00028 roc::AbbDevice::AbbDevice(const char* name, const char* thrdname, dabc::Command cmd) :
00029    dabc::Device(name),
00030    fContext(),
00031    fTransport(0),
00032    fDaqRunning(false),
00033    fPathes(),
00034    fUseDlmForStartStopDaq(true)
00035 {
00036    if (!dabc::mgr()->MakeThreadFor(this, thrdname)) return;
00037 //   AssignProcessorToThread(dabc::mgr()->ProcessorThread());
00038 
00039    fUseDlmForStartStopDaq = Cfg(roc::xmlUseDLM, cmd).AsBool(false);
00040 
00041    fContext.CreateDaemon();
00042 
00043    DOUT2(("Create ABB device name:%s useDLM:%s", GetName(), DBOOL(fUseDlmForStartStopDaq)));
00044 }
00045 
00046 roc::AbbDevice::~AbbDevice()
00047 {
00048    DOUT2(("Destroy ABB device %s", GetName()));
00049 }
00050 
00051 void roc::AbbDevice::ObjectCleanup()
00052 {
00053    if (fTransport) { 
00054       fTransport->fDevice = 0; 
00055       fTransport = 0; 
00056     }
00057 
00058    dabc::Device::ObjectCleanup();
00059 }
00060 
00061 const char* roc::AbbDevice::ClassName() const 
00062 { 
00063    return roc::typeAbbDevice; 
00064 }
00065 
00066 unsigned roc::AbbDevice::GetOpticPath(const char* abburl)
00067 {
00068    // optic path is specified in following form
00069    // abb0 - ROC, directly connected to SFP0
00070    // abb1 - ROC, directly connected to SFP1
00071    // abb00 - ROC, connected to first port on DCB via SFP0
00072    // abb12 - ROC, connected to third port on DCB via SFP1
00073    
00074    base::Url url(abburl);
00075    if (!url.GetProtocol().empty() && (url.GetProtocol()!="optic")) return UndefinedOpticPath;
00076    
00077 //   DOUT0(("url %s host %s fname %s", abburl, url.GetHostName().c_str(), url.GetFileName().c_str()));
00078 
00079    if ((url.GetHostName().length()<4) || (url.GetHostName().length()>5)) return UndefinedOpticPath;
00080    
00081    if (url.GetHostName().find("abb", 0) != 0)  return UndefinedOpticPath;
00082 
00083    unsigned path = 0;
00084    
00085    switch (url.GetHostName()[3]) {
00086       case '0': path = 0; break;
00087       case '1': path = 0x20; break;
00088       default: return UndefinedOpticPath;
00089    }
00090 
00091    if (url.GetHostName().length() == 5)
00092       switch (url.GetHostName()[4]) {
00093          case '0': path = path | 0; break;
00094          case '1': path = path | 1; break;
00095          case '2': path = path | 2; break;
00096          case '3': path = path | 3; break;
00097          default: return UndefinedOpticPath;
00098       }
00099    
00100    return path;
00101 }
00102 
00103 unsigned roc::AbbDevice::GetOpticRetPath(unsigned path)
00104 {
00105    if (path==UndefinedOpticPath) return 0x8000;
00106    
00107    return path & 0x20 ? 0x8020 : 0x8000;
00108 }
00109 
00110 
00111 int roc::AbbDevice::ExecuteCommand(dabc::Command cmd)
00112 {
00113    uint32_t path = cmd.GetUInt(OpticPathPar, 0x0);
00114    uint32_t retpath = GetOpticRetPath(path);
00115    uint32_t hwtyp = cmd.GetUInt("HwTyp", 0x0);
00116 
00117    bool isnewnx = (hwtyp >> 16) == base::kind_newNX;
00118 
00119    uint32_t res = 0;
00120    
00121 //   DOUT0(("AbbDevice cmd %s path 0x%x", cmd->GetName(), path));
00122 
00123    if (cmd.IsName(CmdPut::CmdName())) {
00124       uint32_t addr = cmd.GetUInt(AddrPar, 0);
00125       uint32_t value = cmd.GetUInt(ValuePar, 0);
00126 
00127       res = fContext.daemon()->submitPut(path, retpath, addr, value);
00128 
00129       DOUT2(("ABB::submitPut addr:%04x value:%04x res = %u", addr, value, res));
00130       cmd.SetUInt(ErrNoPar, res);
00131       return cmd_bool(res==0);
00132    } else
00133    
00134    if (cmd.IsName(CmdGet::CmdName())) {
00135       uint32_t addr = cmd.GetUInt(AddrPar, 0);
00136       uint32_t value = 0;
00137 
00138       res = fContext.daemon()->submitGet(path, retpath, addr, &value);
00139 
00140       DOUT2(("ABB::submitGet addr:%04x value:%04x res = %u", addr, value, res));
00141 
00142       cmd.SetUInt(ValuePar, value);
00143       cmd.SetUInt(ErrNoPar, res);
00144 
00145       return (res==0) ? dabc::cmd_true : dabc::cmd_false;
00146 
00147    } else
00148    if (cmd.IsName(CmdDLM::CmdName())) {
00149       uint32_t addr = cmd.GetUInt(AddrPar, 0);
00150 
00151       res = fContext.daemon()->submitPutDLM(addr);
00152 
00153       cmd.SetUInt(ErrNoPar, res);
00154       return (res==0) ? dabc::cmd_true : dabc::cmd_false;
00155 
00156    } else
00157    if (cmd.IsName(CmdNOper::CmdName())) {
00158 
00159       base::OperList* lst = (base::OperList*) cmd.GetPtr(OperListPar, 0);
00160       
00161       lst->setErrorOper(-1);
00162       lst->setErrorCode(0);
00163 
00164       DOUT2(("Start CmdNOper %d", lst->number()));
00165 
00166 
00167 /*
00168       // work around to process lists longer than 7 commands
00169       
00170       int currpos(0);
00171       
00172       while (currpos < lst->number()) {
00173          int currlen = lst->number() - currpos;
00174          if (currlen>7) currlen = 7;
00175 
00176          uint32_t addrs[8], values[8], retvals[8];
00177 
00178          for (int n=0;n<currlen;n++) {
00179             addrs[n] = lst->oper(currpos + n).addr;
00180             values[n] = lst->oper(currpos + n).value;
00181             retvals[n] = 0;
00182             if (lst->oper(currpos + n).isput) addrs[n] = addrs[n] | 0x80000000; 
00183          }
00184 
00185          try {
00186             fContext.daemon()->submitNOper(path, retpath, currlen, addrs, values, retvals);
00187 
00188          } catch (abbdaemon::ABBexception e) {
00189             EOUT(("Problem with NOper  %s", e.what()));
00190             res = roc::Board::operErrBuild(roc::Board::kHostError, 0);
00191             for (int n=0;n<lst->number();n++)
00192                printf("Oper %d retval = %u\n", n, retvals[n]);
00193                
00194             lst->setErrorOper(currpos);
00195             lst->setErrorCode(roc::Board::kHostError);
00196             
00197             res = roc::Board::operErrBuild(roc::Board::kHostError, currpos);
00198          }
00199          
00200          if (res!=0) break;
00201 
00202          for (int n=0;n<currlen;n++) {
00203             if (retvals[n]!=0) {
00204                lst->setErrorOper(currpos + n);
00205                lst->setErrorCode(roc::Board::kOperAddrErr);
00206                res = roc::Board::operErrBuild(roc::Board::kOperAddrErr, currpos + n);
00207                break;
00208             }
00209             
00210             if (!lst->oper(currpos + n).isput)
00211                lst->oper(currpos + n).value = values[n]; 
00212          }
00213          
00214          if (res!=0) break;
00215 
00216          currpos += currlen;
00217       }
00218 */
00219       
00220       uint32_t *addrs = new uint32_t[lst->number()];
00221       uint32_t *values = new uint32_t[lst->number()];
00222       uint32_t *retvals = new uint32_t[lst->number()];
00223       for (int n=0;n<lst->number();n++) {
00224          addrs[n] = lst->oper(n).addr;
00225          values[n] = lst->oper(n).value;
00226          retvals[n] = 0;
00227          if (lst->oper(n).isput) addrs[n] = addrs[n] | PUT_BIT;
00228       }
00229 
00230       try {
00231          res = fContext.daemon()->submitNOper(path, retpath, lst->number(), addrs, values, retvals);
00232 
00233          for (int n=0;n<lst->number();n++) {
00234             if (!lst->oper(n).isput)
00235                lst->oper(n).value = values[n]; 
00236          }
00237 
00238       } catch (abbdaemon::ABBexception e) {
00239          EOUT(("Problem with NOper  %s", e.what()));
00240          res = base::Board::operErrBuild(roc::Board::kHostError, 0);
00241          for (int n=0;n<lst->number();n++)
00242             EOUT(("Oper %d retval = %u\n", n, retvals[n]));
00243             
00244          lst->setErrorOper(1);
00245          lst->setErrorCode(1);
00246       }
00247 
00248       for (int n=0;n<lst->number();n++)
00249          DOUT2(("Oper %d retval = %08x\n", n, retvals[n]));
00250 
00251       delete[] addrs;
00252       delete[] values;
00253       delete[] retvals;
00254   
00255 /*
00256       // execute all put/get cmds sequentially
00257 
00258       for (int n=0;n<lst->number();n++)
00259         try {
00260            if (lst->oper(n).isput)
00261                fContext.daemon()->submitPut(path, retpath, lst->oper(n).addr, lst->oper(n).value);
00262            else
00263                fContext.daemon()->submitGet(path, retpath, lst->oper(n).addr, &(lst->oper(n).value));
00264         } catch (abbdaemon::ABBexception e) {
00265                 EOUT(("Problem with operation  %d %s", n, e.what()));
00266            res = roc::Board::operErrBuild(roc::Board::kHostError, n);
00267            break;
00268         }
00269 */      
00270       DOUT2(("Did CmdNOper %d", lst->number()));
00271         
00272       //      uint32_t res = fContext.daemon()->submitNOper(num, addrs, values);
00273 
00274       // DOUT0(("ABB::submitNOpr num:%u  res = %u", num, res));
00275 
00276       cmd.SetUInt(ErrNoPar, res);
00277       return (res==0) ? dabc::cmd_true : dabc::cmd_false;
00278    } else
00279 
00280    if (cmd.IsName("StartABBTransport")) {
00281       fDaqRunning = true;
00282       
00283       fContext.daemon()->submitReset();
00284       
00285       DOUT2(("roc::AbbDevice::StartABBTransport path = 0x%02x transport %p", path, fTransport));
00286       
00287       if (isnewnx) {
00288          DOUT0(("!!Start DAQ for new NX readout!!"));
00289 
00290          uint32_t addrs[3], values[3], retvals[3];
00291 
00292          addrs[0] = ROC_NX_FIFO_RESET | PUT_BIT; values[0] = 1;
00293          addrs[1] = ROC_NX_FIFO_RESET | PUT_BIT; values[1] = 0;
00294          addrs[2] = ROC_OPTICS_START_DAQ | PUT_BIT; values[1] = 0;
00295 
00296          try {
00297             res = fContext.daemon()->submitNOper(path, retpath, 3, addrs, values, retvals);
00298 
00299          } catch (abbdaemon::ABBexception e) {
00300             EOUT(("Problem with StartDAQ NOper  %s", e.what()));
00301             res = base::Board::operErrBuild(roc::Board::kHostError, 0);
00302          }
00303 
00304       } else {
00305 
00306          if (path == UndefinedOpticPath) {
00307 
00308             if (fUseDlmForStartStopDaq || (fPathes.size()==0)) {
00309                DOUT0(("Issue DLM 8"));
00310                res = fContext.daemon()->submitPutDLM(8);
00311             } else {
00312                DOUT0(("Replace DLM 8 with PUTs num %u", fPathes.size()));
00313                for (unsigned n=0;n<fPathes.size();n++)
00314                   if (res==0)
00315                      res = fContext.daemon()->submitPut(fPathes[n], GetOpticRetPath(fPathes[n]), ROC_CMD_LST_NR, 0);
00316             }
00317          } else {
00318             res = fContext.daemon()->submitPut(path, retpath, ROC_CMD_LST_NR, 0);
00319          }
00320          
00321          DOUT0(("Start DAQ res = %u", res));
00322       }
00323 
00324       return (res==0) ? dabc::cmd_true : dabc::cmd_false;
00325    } else
00326 
00327    if (cmd.IsName("SuspendBoardDaq")) {
00328 
00329       if (isnewnx) {
00330          DOUT0(("!!Suspend DAQ for new NX readout!!"));
00331          res = fContext.daemon()->submitPut(path, retpath, ROC_OPTICS_STOP_DAQ, 0); // stop DAQ
00332 
00333       } else {
00334          res = fContext.daemon()->submitPut(path, retpath, ROC_CMD_LST_NR, 1);
00335       }
00336       return (res==0) ? dabc::cmd_true : dabc::cmd_false;
00337    } else
00338       
00339    if (cmd.IsName("StopABBTransport")) {
00340       fDaqRunning = false;
00341 
00342       DOUT2(("StopABBTransport 0x%02x", path));
00343 
00344       if (isnewnx) {
00345          DOUT0(("!!Stop DAQ for new NX readout!!"));
00346 
00347          res = fContext.daemon()->submitPut(path, retpath, ROC_OPTICS_STOP_DAQ, 0); // stop DAQ
00348 
00349       } else {
00350 
00351          if (path == UndefinedOpticPath) {
00352 
00353             if (fUseDlmForStartStopDaq || (fPathes.size()==0)) {
00354                DOUT0(("Issue DLM 9"));
00355                res = fContext.daemon()->submitPutDLM(9);
00356             } else {
00357                DOUT0(("Replace DLM 9 with PUTs num %u", fPathes.size()));
00358                for (unsigned n=0;n<fPathes.size();n++)
00359                   if (res==0)
00360                      res = fContext.daemon()->submitPut(fPathes[n], GetOpticRetPath(fPathes[n]), ROC_CMD_LST_NR, 1);
00361             }
00362 
00363          } else {
00364             res = fContext.daemon()->submitPut(path, retpath, ROC_CMD_LST_NR, 1);
00365          }
00366       }
00367 
00368       return (res==0) ? dabc::cmd_true : dabc::cmd_false;
00369    } else
00370       
00371    if (cmd.IsName("SetFlushTimeout")) {
00372       if (fTransport==0) {
00373          EOUT(("No ABB transports - cannot setup flush timeout"));
00374          return dabc::cmd_false;
00375       }
00376 
00377       fTransport->Submit(cmd);
00378 
00379       return dabc::cmd_postponed;
00380    } else
00381 
00382    if (cmd.IsName("AddExtraBoard")) {
00383 
00384       unsigned path = GetOpticPath(cmd.GetStr(roc::xmlBoardAddr, "abb0"));
00385 
00386       uint32_t rocid(0), res(1);
00387 
00388       if (path != UndefinedOpticPath) {
00389          fPathes.push_back(path);
00390          res = fContext.daemon()->submitGet(path, GetOpticRetPath(path), ROC_ROCID, &rocid);
00391          if (res!=0) EOUT(("Cannot get ROCID from specified ROC path %u", path));
00392       }
00393 
00394       return res!=0 ? dabc::cmd_false : rocid + 256;
00395    } else
00396 
00397    if (cmd.IsName(CmdGetBoardPtr::CmdName())) {
00398 
00399       unsigned path = GetOpticPath(cmd.GetStr(roc::xmlBoardAddr, "abb0"));
00400       
00401       if (path==UndefinedOpticPath) return dabc::cmd_false;
00402 
00403       roc::AbbBoard* brd = new roc::AbbBoard(this, path, base::roleControl);
00404       if (!brd->initAbbBoard()) { delete brd; return dabc::cmd_false; }
00405 
00406       cmd.SetPtr(CmdGetBoardPtr::Board(), brd);
00407 
00408       return dabc::cmd_true;
00409    } else
00410 
00411    if (cmd.IsName(CmdReturnBoardPtr::CmdName())) {
00412       roc::AbbBoard* brd = (roc::AbbBoard*) cmd.GetPtr(CmdReturnBoardPtr::Board());
00413       if (brd!=0) delete brd;
00414       return dabc::cmd_true;
00415    }
00416 
00417    return dabc::Device::ExecuteCommand(cmd);
00418 }
00419 
00420 dabc::Transport* roc::AbbDevice::CreateTransport(dabc::Command cmd, dabc::Reference port)
00421 {
00422    if (fContext.daemon() == 0) return 0;
00423    
00424    if (fTransport!=0) {
00425       EOUT(("There are transports already created !!!!"));
00426       return 0;
00427    }
00428 
00429    std::string spath = cmd.GetStdStr(roc::xmlBoardAddr, "abb0");
00430    unsigned path = GetOpticPath(spath.c_str());
00431 
00432    uint32_t brdid(0), hwtyp(0);
00433    
00434    DOUT2(("roc::AbbDevice::CreateTransport path 0x%02x", path));
00435 
00436    if (path != UndefinedOpticPath) {
00437 
00438       fPathes.push_back(path);
00439 
00440       uint32_t res = fContext.daemon()->submitGet(path, GetOpticRetPath(path), base::addr_BoardId, &brdid);
00441       if (res!=0) { EOUT(("Cannot get board ID from path %s", spath.c_str())); return 0; }
00442 
00443       res = fContext.daemon()->submitGet(path, GetOpticRetPath(path), base::addr_HardwareType, &hwtyp);
00444       if (res!=0) { EOUT(("Cannot get hardware type from path %s", spath.c_str())); return 0; }
00445 
00446       DOUT2(("roc::AbbDevice::CreateTransport  brdid %u hwtyp 0x%08x", (unsigned) brdid, (unsigned) hwtyp));
00447 
00448    } else
00449       DOUT2(("Create transport with undefined path"));
00450 
00451    fTransport = new AbbTransport(this, port, path, brdid, hwtyp, cmd);
00452 
00453    return fTransport;
00454 }

Generated on Tue Dec 10 2013 04:52:16 for ROCsoft by  doxygen 1.7.1