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

abbplugin/src/AbbTransport.cxx (r4864/r4221)

Go to the documentation of this file.
00001 #include "roc/AbbTransport.h"
00002 
00003 #include "roc/AbbDevice.h"
00004 #include "roc/Board.h"
00005 
00006 #include "dabc/Port.h"
00007 #include "dabc/DataIO.h"
00008 #include "dabc/Application.h"
00009 #include "dabc/Manager.h"
00010 
00011 #include "mbs/MbsTypeDefs.h"
00012 
00013 #include <mprace/Board.h>
00014 #include <mprace/DMABuffer.h>
00015 #include <mprace/ABB.h>
00016 #include <mprace/Exception.h>
00017 
00018 #include "ABBdaemon.h"
00019 
00020 
00021 #define MbsHeaderSize (sizeof(mbs::EventHeader) + sizeof(mbs::SubeventHeader)) 
00022 
00023 #define MbsShift 64
00024 
00025 roc::AbbTransport::AbbTransport(AbbDevice* dev, dabc::Reference port, unsigned path,
00026                                 uint32_t brdid, uint32_t hwtyp, dabc::Command cmd) :
00027    dabc::DataTransport(port, true, false),
00028    fDevice(dev),
00029    fContext(),
00030    fDaqRunning(false),
00031    fMbsHeader(false),
00032    fBufCounter(0),
00033    fManyRocs(false),
00034    fDMABuffers(),
00035    fMapError(false),
00036    fOpticPath(roc::AbbDevice::UndefinedOpticPath),
00037    fBrdId(brdid),
00038    fHwType(hwtyp)
00039 {
00040    fContext = dev->fContext;
00041 
00042    fBufferSize = GetPort()->Cfg(dabc::xmlBufferSize, cmd).AsInt(16384);
00043    
00044    fFlushTime = GetPort()->Cfg(roc::xmlFlushTime, cmd).AsDouble(0.5);
00045    
00046    fMbsHeader = cmd.GetBool("WithMbsHeader", false);
00047 
00048    if (fMbsHeader) fManyRocs = cmd.GetBool("ManyRocs", false);
00049    
00050    fOpticPath = path;
00051 
00052 //   if (!cmd->GetBool("IndividualRoc", false)) fOpticPath = roc::AbbDevice::UndefinedOpticPath;
00053 
00054    DOUT2(("Create AbbTransport %p Buffer size %u", this, fBufferSize));
00055    
00056    fFormat = formatOptic2;
00057 }
00058 
00059 roc::AbbTransport::~AbbTransport()
00060 {
00061    // cleanup all registered memory
00062    DOUT2(("Destroy AbbTransport daemon = %p device = %p", fContext.daemon(), fDevice));
00063 
00064    ProcessPoolChanged(0);
00065 
00066    if (fDevice) { fDevice->fTransport = 0; fDevice = 0; }
00067    
00068    DOUT2(("Destroy AbbTransport done %p", this));
00069 }
00070 
00071 int roc::AbbTransport::ExecuteCommand(dabc::Command cmd)
00072 {
00073    if (cmd.IsName("StartABBTransport")) {
00074 
00075       if (fDaqRunning) {
00076          EOUT(("StartABBTransport - AbbTransport already running!!"));
00077          return dabc::cmd_true;
00078       }
00079       
00080       if (fDevice==0) return dabc::cmd_false;
00081       fLastDMAtime = dabc::Now();
00082       fDaqRunning = true;
00083       cmd.SetUInt(roc::OpticPathPar, fOpticPath);
00084       cmd.SetUInt("HwTyp",fHwType);
00085       fDevice->Submit(cmd);
00086       return dabc::cmd_postponed;
00087    } else
00088    if (cmd.IsName("StopABBTransport")) {
00089       if (fDevice==0) return dabc::cmd_false;
00090       fDaqRunning = false;
00091       cmd.SetUInt(roc::OpticPathPar, fOpticPath);
00092       cmd.SetUInt("HwTyp",fHwType);
00093       fDevice->Submit(cmd);
00094       return dabc::cmd_postponed;
00095    } else
00096    if (cmd.IsName("SetFlushTimeout")) {
00097       fFlushTime = cmd.GetDouble("Timeout", 0.1);
00098       return dabc::cmd_true;
00099    }
00100 
00101    return dabc::DataTransport::ExecuteCommand(cmd);
00102 }
00103 
00104 
00105 void roc::AbbTransport::ProcessPoolChanged(dabc::MemoryPool* pool)
00106 {
00107    DOUT2(("ProcessPoolChanged pool = %p daemon = %p!!", pool, fContext.daemon()));
00108 
00109    fMapError = false;
00110 
00111    if (fContext.daemon()==0) { fMapError = true; return; }
00112 
00113    try {
00114 
00115       for (unsigned n=0;n<fDMABuffers.size();n++)
00116          fContext.daemon()->unregisterBuffer(fDMABuffers[n]);
00117       fDMABuffers.clear();
00118 
00119       if (pool==0) { DOUT2(("Only unregister all buffers")); return; }
00120 
00121       std::vector<void*> bufs;
00122       std::vector<unsigned> sizes;
00123 
00124       pool->GetPoolInfo(bufs, sizes);
00125 
00126       for (unsigned n=0;n<bufs.size();n++) {
00127          
00128          void* dmabuf = 0;
00129          
00130          if (fMbsHeader) 
00131             dmabuf = fContext.daemon()->registerBuffer(sizes[n] - MbsShift, (char*) (bufs[n]) + MbsShift);   
00132          else
00133             dmabuf = fContext.daemon()->registerBuffer(sizes[n], bufs[n]);
00134 
00135          if (dmabuf==0) EOUT(("DMA handle == 0 !!!"));
00136 
00137          fDMABuffers.push_back(dmabuf);
00138       }
00139 
00140    } catch (abbdaemon::ABBexception e) {
00141       EOUT(("abbdaemon exception when registering DMA buffer: %s", e.what()));
00142       fMapError = true;
00143       return;
00144    } catch (mprace::Exception e) {
00145       EOUT(("mprace exception when registering DMA buffer : %s %d", e.what(), e.getParameter()));
00146       fMapError = true;
00147       return;
00148    } catch (mprace::Exception* e) {
00149       DOUT0(("mprace* exception when registering DMA buffer: %s par:%d", e->what(), e->getParameter()));
00150       fMapError = true;
00151       return;
00152    }
00153 
00154    DOUT3(("ABB MAP %u", fDMABuffers.size()));
00155 
00156    DOUT3(("Finish full map buffers"));
00157 }
00158 
00159 
00160 unsigned roc::AbbTransport::Read_Size()
00161 {
00162    if (!fDaqRunning || (fContext.daemon()==0)) return dabc::di_RepeatTimeOut;
00163 
00164    uint32_t read_size = fBufferSize / 4;
00165    if (fMbsHeader) read_size -= MbsShift/4;
00166       
00167 // if (read_size > 1000) read_size = 1000;
00168 
00169    uint32_t fifo_status = fContext.daemon()->getFIFOStatus() / 4;
00170 
00171    if (fifo_status < read_size) {
00172       double dist = fLastDMAtime.SpentTillNow();
00173       if ((dist < fFlushTime) || (fifo_status==0)) return dabc::di_RepeatTimeOut;
00174       DOUT2(("DO FLUSH with %u", fifo_status));
00175    }
00176 
00177    return fBufferSize;
00178 }
00179 
00180 unsigned roc::AbbTransport::Read_Complete(dabc::Buffer& buf)
00181 {
00182    if (!fDaqRunning || (fContext.daemon()==0)) return dabc::di_SkipBuffer;
00183 
00184    if (buf.NumSegments()!=1) {
00185       EOUT(("Segmented buffers are not supported by roc::AbbTransport - FAIL"));
00186       throw dabc::Exception("Segmented buffers are not supported by roc::AbbTransport - FAIL");
00187    }
00188 
00189    if (fDMABuffers.size()==0) ProcessPoolChanged(GetPool());
00190    
00191    if (fMapError) return dabc::di_Error;
00192 
00193    dabc::BufferSize_t len = buf.SegmentSize();
00194 
00195    uint32_t read_size = len / 4;
00196    if (fMbsHeader) read_size -= MbsShift/4;
00197    
00198    uint32_t fifo_status = fContext.daemon()->getFIFOStatus() / 4;
00199 
00200    if (fifo_status < read_size) {
00201       double dist = fLastDMAtime.SpentTillNow();
00202       if ((fifo_status==0) || (dist < fFlushTime)) return dabc::di_RepeatTimeOut;
00203       read_size = fifo_status;
00204    }
00205 
00206    void* handle = fDMABuffers[buf.SegmentId()];
00207 
00208 //   DOUT0(("Start DMA handle %p size %u", handle, read_size));
00209 
00210    try {
00211       
00212       fContext.daemon()->readDMAserialized( 0x0, handle, read_size, 0, false, true, 0.);
00213 
00214       fLastDMAtime.GetNow();
00215       
00216    } catch (abbdaemon::ABBexception e) {
00217       EOUT(("abbdaemon exception during DMA transfer: %s", e.what()));
00218       return dabc::di_Error;
00219    } catch (mprace::Exception e) {
00220       EOUT(("mprace exception during DMA transfer: %s %d", e.what(), e.getParameter()));
00221       return dabc::di_Error;
00222    } catch (mprace::Exception* e) {
00223       DOUT0(("mprace* exception during DMA transfer: %s par:%d", e->what(), e->getParameter()));
00224       return dabc::di_Error;
00225    }
00226 
00227    fBufCounter++;
00228 
00229 //   DOUT0(("Finish DMA handle %p size %u", handle, read_size));
00230    
00231    if (fMbsHeader) {
00232       
00233       buf.CutFromBegin(MbsShift - MbsHeaderSize);
00234 
00235       buf.SetTypeId(mbs::mbt_MbsEvents);
00236       buf.SetTotalSize(MbsHeaderSize + read_size*4);
00237 
00238       mbs::EventHeader* evhdr = (mbs::EventHeader*) buf.SegmentPtr();
00239       evhdr->Init(fBufCounter);
00240       evhdr->SetSubEventsSize(read_size*4 + sizeof(mbs::SubeventHeader));
00241       
00242       mbs::SubeventHeader* subhdr = evhdr->SubEvents();
00243       subhdr->Init(fManyRocs ? 0xff : fBrdId, roc::proc_RawData, fFormat);
00244       subhdr->SetRawDataSize(read_size*4);
00245 
00246    } else {
00247       buf.SetTypeId(roc::rbt_RawRocData + fFormat);
00248       buf.SetTotalSize(read_size*4);
00249    }
00250 
00251    return dabc::di_Ok;
00252 }
00253 
00254 
00255 void roc::AbbTransport::StartTransport()
00256 {
00257    DOUT2(("roc::AbbTransport::StartABBTransport %p", this));
00258    
00259    //Execute("StartABBTransport");
00260    Submit(dabc::Command("StartABBTransport"));
00261 
00262    dabc::DataTransport::StartTransport();
00263 }
00264 
00265 void roc::AbbTransport::StopTransport()
00266 {
00267 //   Execute("StopABBTransport");
00268 
00269    DOUT2(("roc::AbbTransport::StopABBTransport"));
00270 
00271    dabc::DataTransport::StopTransport();
00272 
00273    Submit(dabc::Command("StopABBTransport"));
00274 }
00275 
00276 int roc::AbbTransport::GetParameter(const char* name)
00277 {
00278    if (strcmp(name, roc::xmlRocNumber)==0) return fBrdId;
00279    if (strcmp(name, roc::xmlMsgFormat)==0) return fFormat;
00280    if (strcmp(name, roc::xmlTransportKind)==0) return roc::kind_ABB;
00281 
00282    return dabc::Transport::GetParameter(name);
00283 }

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