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
00053
00054 DOUT2(("Create AbbTransport %p Buffer size %u", this, fBufferSize));
00055
00056 fFormat = formatOptic2;
00057 }
00058
00059 roc::AbbTransport::~AbbTransport()
00060 {
00061
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
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
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
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
00260 Submit(dabc::Command("StartABBTransport"));
00261
00262 dabc::DataTransport::StartTransport();
00263 }
00264
00265 void roc::AbbTransport::StopTransport()
00266 {
00267
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 }