178void Flx::Card::read(
const uint32_t aAddr,
const uint32_t aNrWords, std::vector<uint32_t>& aValues) {
183 flxcard_bar2_regs_t *bar2 = (flxcard_bar2_regs_t *) mFlxCard.openBackDoor( 2 );
186 uint32_t lNrReads64b = (aNrWords+1)/2;
187 uint32_t lAddr = aAddr/2;
189 for ( uint32_t i(0); i<lNrReads64b; i++) {
191 bar2->IPBUS_READ_ADDRESS = lAddr+i;
193 uint64_t lDataWord = bar2->IPBUS_READ_DATA;
195 aValues.push_back(lDataWord & 0xffffffff);
196 if ( 2*i+1 < aNrWords )
197 aValues.push_back(lDataWord >> 32);
200 log(uhal::Debug(),
"Flx::Card::read, ", aNrWords,
" requested, ", aValues.size(),
" read");
206void Flx::Card::write(
const uint32_t aAddr,
const std::vector<std::pair<const uint8_t*, size_t> >& aData)
212 flxcard_bar2_regs_t *bar2 = (flxcard_bar2_regs_t *) mFlxCard.openBackDoor( 2 );
215 for (
size_t i = 0; i < aData.size(); i++)
216 lNrBytes += aData.at(i).second;
218 assert((lNrBytes % 4) == 0);
220 char *allocated = NULL;
221 posix_memalign((
void **)&allocated, 4096, lNrBytes + 4096);
222 if (allocated == NULL) {
223 exception::FlxCommunicationError lExc;
224 log(lExc,
"Failed to allocate ", uhal::Integer(lNrBytes + 4096),
" bytes in File::write/2 function");
229 char* buffer = allocated;
230 size_t lNrBytesCopied = 0;
231 for (
size_t i = 0; i < aData.size(); i++) {
232 memcpy(buffer + lNrBytesCopied, aData.at(i).first, aData.at(i).second);
233 lNrBytesCopied += aData.at(i).second;
237 uint32_t lAddr = aAddr/2;
239 while (lNrBytesCopied < lNrBytes) {
240 bar2->IPBUS_WRITE_ADDRESS = lAddr;
241 char* lSrcPtr = buffer + lNrBytesCopied;
242 if ((lNrBytes - lNrBytesCopied) >= 8) {
243 bar2->IPBUS_WRITE_DATA.DATA = *(uint64_t*) lSrcPtr;
246 else if ((lNrBytes - lNrBytesCopied) >= 4) {
247 bar2->IPBUS_WRITE_DATA.DATA = uint64_t(*(uint32_t*) lSrcPtr);
289Flx::Flx (
const std::string& aId,
const uhal::URI& aUri ) :
290 IPbus< 2 , 0 > ( aId , aUri ),
303 for (uhal::NameValuePairVectorType::const_iterator lIt = aUri.mArguments.begin(); lIt != aUri.mArguments.end(); lIt++) {
304 if (lIt->first ==
"sleep") {
305 mSleepDuration = std::chrono::microseconds(std::stoul(lIt->second));
306 log (uhal::Notice() ,
"flx client with URI ", uhal::Quote (uri()),
" : Inter-poll-/-interrupt sleep duration set to ", std::stoul(lIt->second),
" us by URI 'sleep' attribute");
315 log (uhal::Warning() ,
"Unknown attribute ", uhal::Quote (lIt->first),
" used in URI ", uhal::Quote(uri()));
401 log ( uhal::Debug() ,
"flx client is opening device file " , uhal::Quote (
mDeviceFile.
getPath() ) );
402 std::vector<uint32_t> lValues;
404 log (uhal::Debug(),
"Read status info from addr 0 (", uhal::Integer(lValues.at(0)),
", ", uhal::Integer(lValues.at(1)),
", ", uhal::Integer(lValues.at(2)),
", ", uhal::Integer(lValues.at(3)),
"): ",
PacketFmt((
const uint8_t*)lValues.data(), 4 * lValues.size()));
414 if (lValues.at(1) > 0xFFFF) {
415 exception::FlxInitialisationError lExc;
416 log (lExc,
"Invalid page size, ", uhal::Integer(lValues.at(1)),
", reported in device file ", uhal::Quote(
mDeviceFile.
getPath()));
421 exception::FlxInitialisationError lExc;
427 log ( uhal::Info() ,
"flx client connected to device at ", uhal::Quote(
mDeviceFile.
getPath()),
"; FPGA has ", uhal::Integer(
mNumberOfPages),
" pages, each of size ", uhal::Integer(
mPageSize),
" words, index ", uhal::Integer(
mIndexNextPage),
" should be filled next" );
439void Flx::write(
const std::shared_ptr<uhal::Buffers>& aBuffers)
453 log (uhal::Info(),
"flx client ", uhal::Quote(
id()),
" (URI: ", uhal::Quote(uri()),
") : writing ", uhal::Integer(aBuffers->sendCounter() / 4),
"-word packet to page ", uhal::Integer(
mIndexNextPage),
" in ", uhal::Quote(
mDeviceFile.
getPath()));
455 const uint32_t lHeaderWord = (0x10000 | (((aBuffers->sendCounter() / 4) - 1) & 0xFFFF));
456 std::vector<std::pair<const uint8_t*, size_t> > lDataToWrite;
457 lDataToWrite.push_back( std::make_pair(
reinterpret_cast<const uint8_t*
>(&lHeaderWord),
sizeof lHeaderWord) );
458 lDataToWrite.push_back( std::make_pair(aBuffers->getSendBuffer(), aBuffers->sendCounter()) );
462 log (uhal::Debug(),
"Wrote " , uhal::Integer((aBuffers->sendCounter() / 4) + 1),
" 32-bit words at address " , uhal::Integer(
mIndexNextPage * 4 *
mPageSize),
" ... ",
PacketFmt(lDataToWrite));
472 SteadyClock_t::time_point lStartTime = SteadyClock_t::now();
476 uint32_t lHwPublishedPageCount = 0x0;
478 std::vector<uint32_t> lValues;
483 lHwPublishedPageCount = lValues.at(3);
485 log (uhal::Debug(),
"Read status info from addr 0 (", uhal::Integer(lValues.at(0)),
", ", uhal::Integer(lValues.at(1)),
", ", uhal::Integer(lValues.at(2)),
", ", uhal::Integer(lValues.at(3)),
"): ",
PacketFmt((
const uint8_t*)lValues.data(), 4 * lValues.size()));
493 if (SteadyClock_t::now() - lStartTime > std::chrono::microseconds(getBoostTimeoutPeriod().total_microseconds())) {
494 exception::FlxTimeout lExc;
499 log(uhal::Debug(),
"flx client ", uhal::Quote(
id()),
" (URI: ", uhal::Quote(uri()),
") : Trying to read page index ", uhal::Integer(lPageIndexToRead),
" = count ", uhal::Integer(
mReadReplyPageCount+1),
"; published page count is ", uhal::Integer(lHwPublishedPageCount),
"; sleeping for ",
mSleepDuration.count(),
"us");
505 log(uhal::Info(),
"flx client ", uhal::Quote(
id()),
" (URI: ", uhal::Quote(uri()),
") : Reading page ", uhal::Integer(lPageIndexToRead),
" (published count ", uhal::Integer(lHwPublishedPageCount),
", surpasses required, ", uhal::Integer(
mReadReplyPageCount + 1),
")");
510 std::shared_ptr<uhal::Buffers> lBuffers =
mReplyQueue.front();
513 uint32_t lNrWordsToRead(lBuffers->replyCounter() >> 2);
516 std::vector<uint32_t> lPageContents;
520 log (uhal::Debug(),
"Read " , uhal::Integer(lNrWordsToRead),
" 32-bit words from address " , uhal::Integer(4 + lPageIndexToRead * 4 *
mPageSize),
" ... ",
PacketFmt((
const uint8_t*)lPageContents.data(), 4 * lPageContents.size()));
523 const std::deque< std::pair< uint8_t* , uint32_t > >& lReplyBuffers ( lBuffers->getReplyBuffer() );
524 size_t lNrWordsInPacket = (lPageContents.at(0) >> 16) + (lPageContents.at(0) & 0xFFFF);
525 if (lNrWordsInPacket != (lBuffers->replyCounter() >> 2))
526 log (uhal::Warning(),
"Expected reply packet to contain ", uhal::Integer(lBuffers->replyCounter() >> 2),
" words, but it actually contains ", uhal::Integer(lNrWordsInPacket),
" words");
528 size_t lNrBytesCopied = 0;
529 for ( std::deque< std::pair< uint8_t* , uint32_t > >::const_iterator lIt = lReplyBuffers.begin() ; lIt != lReplyBuffers.end() ; ++lIt )
532 if ( lNrBytesCopied >= 4*lNrWordsInPacket)
535 size_t lNrBytesToCopy = std::min( lIt->second , uint32_t(4*lNrWordsInPacket - lNrBytesCopied) );
536 memcpy ( lIt->first, &lPageContents.at(1 + (lNrBytesCopied / 4)), lNrBytesToCopy );
537 lNrBytesCopied += lNrBytesToCopy;
544 if ( uhal::exception::exception* lExc = ClientInterface::validate ( lBuffers ) )
549 catch ( uhal::exception::exception& aExc )
552 log ( *
mAsynchronousException ,
"Exception caught during reply validation for flx device with URI " , uhal::Quote ( this->uri() ) ,
"; what returned: " , uhal::Quote ( aExc.what() ) );