Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds static readout buffer #85

Merged
merged 2 commits into from
Jan 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 19 additions & 42 deletions V1724.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ V1724::V1724(std::shared_ptr<MongoLog>& log, std::shared_ptr<Options>& opts, int
fPreTrigRegister = 0x8038;
fPreTrigChRegister = 0x1038;
fError = false;
fBufferSize = 0x800000; // 8 MB total memory

fSampleWidth = 10;
fClockCycle = 10;
Expand Down Expand Up @@ -76,6 +77,7 @@ int V1724::Init(int link, int crate) {

uint32_t word(0);
int my_bid(0);
fROBuffer.assign(fBufferSize*2, 0); // double buffer for safety

if (Reset()) {
fLog->Entry(MongoLog::Error, "Board %i unable to pre-load registers", fBID);
Expand Down Expand Up @@ -233,65 +235,40 @@ int V1724::Read(std::unique_ptr<data_packet>& outptr){
auto t_start = high_resolution_clock::now();
if ((GetAcquisitionStatus() & 0x8) == 0) return 0;
// Initialize
int blt_words=0, nb=0, ret=-5;
std::vector<std::pair<char32_t*, int>> xfer_buffers;
xfer_buffers.reserve(4);
int total_bytes=0, nb=0, ret=-5;

unsigned count = 0;
int alloc_bytes, request_bytes;
char32_t* thisBLT = nullptr;
do{
// each loop allocate more memory than the last one.
// there's a fine line to walk between making many small allocations for full digitizers
// and fewer, large allocations for empty digitizers. 16 19 20 23 seem to be optimal
// for the readers, but this depends heavily on specific machines.
if (count < fBLTalloc.size()) {
alloc_bytes = 1 << fBLTalloc[count];
} else {
alloc_bytes = 1 << (fBLTalloc.back() + count - fBLTalloc.size() + 1);
}
// Reserve space for this block transfer
thisBLT = new char32_t[alloc_bytes/sizeof(char32_t)];
request_bytes = alloc_bytes/fBLTSafety;
// we already allocated a readout buffer, we just read into it

ret = CAENVME_FIFOBLTReadCycle(fBoardHandle, fBaseAddress, thisBLT,
request_bytes, cvA32_U_MBLT, cvD64, &nb);
ret = CAENVME_FIFOBLTReadCycle(fBoardHandle, fBaseAddress, fROBuffer.data()+total_bytes,
fBufferSize, cvA32_U_MBLT, cvD64, &nb);
if( (ret != cvSuccess) && (ret != cvBusError) ){
fLog->Entry(MongoLog::Error,
"Board %i read error after %i reads: (%i) and transferred %i bytes this read",
fBID, count, ret, nb);
"Board %i read error %i, transferred %i bytes this read",
fBID, ret, nb);

// Delete all reserved data and fail
delete[] thisBLT;
for (auto& b : xfer_buffers) delete[] b.first;
return -1;
}
if (nb > request_bytes) fLog->Entry(alloc_bytes > nb ? MongoLog::Debug : MongoLog::Warning,
"Board %i got %x more bytes than asked for (headroom %i)",
fBID, nb-request_bytes, alloc_bytes-nb);

count++;
blt_words+=nb/sizeof(char32_t);
xfer_buffers.emplace_back(std::make_pair(thisBLT, nb/sizeof(char32_t)));
total_bytes += nb;
if (total_bytes > fBufferSize) fLog->Entry(MongoLog::Debug,
"Board %i got a lot of data (%x/%x)",
fBID, total_bytes, fBufferSize);

}while(ret != cvBusError);

// Now we have to concatenate all this data into a single continuous buffer
// because I'm too lazy to write a class that allows us to use fragmented
// buffers as if they were continuous
if(blt_words>0){
// copy from the digitizer's buffer into something we can send downstream
int words = total_bytes/sizeof(char32_t);
if(words>0){
std::u32string s;
s.reserve(blt_words);
for (auto& xfer : xfer_buffers) {
s.append(xfer.first, xfer.second);
}
fBLTCounter[int(std::ceil(std::log2(blt_words)))]++;
s.reserve(words);
s.append((char32_t*)fROBuffer.data(), words);
fBLTCounter[int(std::ceil(std::log2(words)))]++;
auto [ht, cc] = GetClockInfo(s);
outptr = std::make_unique<data_packet>(std::move(s), ht, cc);
}
for (auto b : xfer_buffers) delete[] b.first;
fTotReadTime += duration_cast<nanoseconds>(high_resolution_clock::now()-t_start);
return blt_words;
return words;
}

int V1724::LoadDAC(std::vector<uint16_t>& dac_values){
Expand Down
2 changes: 2 additions & 0 deletions V1724.hh
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,13 @@ protected:
unsigned int fInputDelayChRegister;
unsigned int fPreTrigRegister;
unsigned int fPreTrigChRegister;
int fBufferSize;

std::vector<int> fBLTalloc;
std::map<int, int> fBLTCounter;
std::vector<int> fDelayPerCh;
std::vector<int> fPreTrigPerCh;
std::vector<uint8_t> fROBuffer;

bool MonitorRegister(uint32_t reg, uint32_t mask, int ntries, int sleep, uint32_t val=1);
virtual std::tuple<uint32_t, long> GetClockInfo(std::u32string_view);
Expand Down
1 change: 1 addition & 0 deletions V1730.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ V1730::V1730(std::shared_ptr<MongoLog>& log, std::shared_ptr<Options>& options,
fArtificialDeadtimeChannel = 792;
fDefaultDelay = 2*fSampleWidth*0xA; // see register document
fDefaultPreTrig = 6*fSampleWidth; // undocumented value?
fBufferSize = 0x1400000; // 640 kS/ch
}

V1730::~V1730(){}
Expand Down