00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #define DMA_THRESHOLD 34*20*4 // Don't allow it to go DMA.
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #include <config.h>
00053 #include "CCAENChain.h"
00054 #include "CAENcard.h"
00055 #include <CVMEInterface.h>
00056 #ifdef HAVE_SBSVME_INTERFACE
00057 #include <SBSBit3API.h>
00058 #endif
00059
00060 #include <stdio.h>
00061
00062 #ifdef HAVE_STD_NAMESPACE
00063 using namespace std;
00064 #endif
00065
00066
00067 static const int QualifyingFirmware(0x0904);
00068
00069
00070 static int fwMajor(int firmware)
00071 {
00072 return (firmware >> 8) & 0xff;
00073 }
00074 static int fwMinor(int firmware)
00075 {
00076 return firmware & 0xff;
00077 }
00113 CCAENChain::CCAENChain(int nFirstSlot, int nLastSlot,
00114 vector<unsigned long>& vBases,
00115 int nCrate, bool geo) throw (string)
00116 : m_nCBLTAddress(0),
00117 m_nCrate(nCrate),
00118 m_pHandle(0),
00119 m_nMaxBytes(0)
00120 {
00121
00122
00123
00124 int nModules = (nLastSlot - nFirstSlot + 1);
00125 if(nModules < 2) {
00126 throw string("Chains must have at least two modules!!");
00127 }
00128
00129
00130 if(!geo & (vBases.size() != nModules)) {
00131 throw string("Insufficient module base addresses in CAENChain");
00132 }
00133
00134
00135
00136
00137 int i = 0;
00138 try {
00139 for(int slot = nFirstSlot; slot <= nLastSlot; slot++, i++) {
00140 m_vCards.push_back(new CAENcard(slot, nCrate, geo,
00141 geo ? 0 : vBases[i]));
00142 }
00143 }
00144 catch(...) {
00145 FreeModules();
00146 throw;
00147 }
00148
00149
00150
00151
00152
00153 try {
00154 for (int slot = 0; slot < m_vCards.size(); slot++) {
00155 if (m_vCards[slot]->getFirmware() < QualifyingFirmware) {
00156 unsigned long base = m_vCards[slot]->getBase();
00157 int fw = m_vCards[slot]->getFirmware();
00158 int major = fwMajor(fw);
00159 int minor = fwMinor(fw);
00160 int qmajor = fwMajor(QualifyingFirmware);
00161 int qminor = fwMinor(QualifyingFirmware);
00162 char errorMessage[1000];
00163 sprintf(errorMessage,
00164 "All modules in the chain must have firmware rev at least %d.%d, the module base address 0x%08x (slot %d) has firmware rev %d.%d",
00165 qmajor, qminor, base, m_vCards[slot]->getSlot(), major, minor);
00166 throw(string(errorMessage));
00167
00168 }
00169 }
00170 }
00171 catch (...) {
00172 FreeModules();
00173 throw;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182 m_nCBLTAddress = nFirstSlot << 24;
00183 for(i = 0; i < nModules; i++) {
00184 CAENcard::ChainMember where(CAENcard::IntermediateInChain);
00185 if(i == 0) where = CAENcard::FirstInChain;
00186 if(i == (nModules - 1)) where = CAENcard::LastInChain;
00187 m_vCards[i]->SetCBLTChainMembership(nFirstSlot, where);
00188 }
00189
00190
00191
00192
00193
00194
00195
00196 m_nMaxBytes = (nModules * 35 + 1) * sizeof(long);
00197
00198
00199
00200
00201 try {
00202 m_pHandle = CVMEInterface::Open(CVMEInterface::CBLT, nCrate);
00203 #ifdef HAVE_SBSVME_INTERFACE
00204 CSBSBit3VmeInterface::SetDMABlockTransfer(m_pHandle, true);
00205 CSBSBit3VmeInterface::SetDMAThreshold(m_pHandle, DMA_THRESHOLD);
00206 #endif
00207 }
00208 catch (...) {
00209 FreeModules();
00210 throw;
00211 }
00212
00213
00214 }
00220 CCAENChain::~CCAENChain()
00221 {
00222 FreeModules();
00223 CVMEInterface::Close(m_pHandle);
00224 }
00235 CAENcard*
00236 CCAENChain::operator[](int index) throw (CRangeError)
00237 {
00238 if( (index >= 0) && (index < m_vCards.size())) {
00239 return m_vCards[index];
00240 }
00241 else {
00242 throw CRangeError(0, m_vCards.size(), index,
00243 "Selecting a CAENcard from a chain");
00244 }
00245
00246 }
00281 int
00282 CCAENChain::ReadEvent(void* pBuffer)
00283 {
00284 int nCards = m_vCards.size();
00285 int nRead = 0;
00286 try {
00287 nRead = CVMEInterface::Read(m_pHandle,
00288 m_nCBLTAddress,
00289 pBuffer, m_nMaxBytes);
00290 }
00291 catch (... ) {
00292
00293 CVMEInterface::Close(m_pHandle);
00294 m_pHandle = CVMEInterface::Open(CVMEInterface::CBLT, m_nCrate);
00295 #ifdef HAVE_SBSVME_INTERFACE
00296 CSBSBit3VmeInterface::SetDMABlockTransfer(m_pHandle, true);
00297 CSBSBit3VmeInterface::SetDMAThreshold(m_pHandle, DMA_THRESHOLD);
00298 #endif
00299 throw;
00300 }
00301
00302 return nRead/sizeof(unsigned short);
00303 }
00307 void
00308 CCAENChain::ClearData()
00309 {
00310 int ncards = m_vCards.size();
00311 for(int i = 0; i < ncards; i++) {
00312 m_vCards[i]->clearData();
00313 }
00314 }
00315
00323 void
00324 CCAENChain::FreeModules()
00325 {
00326 for(int i=0; i < m_vCards.size(); i++ ) {
00327 delete m_vCards[i];
00328 }
00329 m_vCards.erase(m_vCards.begin(), m_vCards.end());
00330 }
00331
00350 void
00351 CCAENChain::lastModuleEmptyEnable()
00352 {
00353
00354 CAENcard* pCard = lastCard();
00355 pCard->emptyEnable();
00356 }
00357
00364 void
00365 CCAENChain::lastModuleEmptyDisable()
00366 {
00367 CAENcard* pCard = lastCard();
00368 pCard->emptyDisable();
00369 }
00370
00371
00372
00373
00374 CAENcard*
00375 CCAENChain::lastCard()
00376 {
00377
00378
00379 CAENcard* pCard = m_vCards.back();
00380 return pCard;
00381 }