DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
WIB Class Reference

#include <WIB.hh>

Inheritance diagram for WIB:
[legend]
Collaboration diagram for WIB:
[legend]

Public Types

enum  WIB_DAQ_t { UNKNOWN , RCE , FELIX }
 

Public Member Functions

 WIB (std::string const &address, std::string const &WIBAddressTable="WIB.adt", std::string const &FEMBAddressTable="FEMB.adt", bool fullStart=true)
 
 ~WIB ()
 
void FullStart ()
 
void InitializeWIB ()
 
void ResetWIB (bool reset_udp=false)
 
void InitializeDTS (uint8_t PDTSsource=0, uint8_t clockSource=0, uint32_t PDTSAlignment_timeout=0)
 
void EnableDAQLink (uint8_t iDAQLink)
 
void EnableDAQLink_Lite (uint8_t iDAQLink, uint8_t enable)
 
void StartSyncDTS ()
 
void ResetWIBAndCfgDTS (uint8_t localClock, uint8_t PDTS_TGRP, uint8_t PDTSsource=0, uint32_t PDTSAlignment_timeout=0)
 
void CheckedResetWIBAndCfgDTS (uint8_t localClock, uint8_t PDTS_TGRP, uint8_t PDTSsource=0, uint32_t PDTSAlignment_timeout=0)
 
void StartStreamToDAQ (bool l1=true, bool l2=true, bool l3=false, bool l4=false)
 
void PDTSInRunningState ()
 
void EnableFEMBCNC ()
 
void DisableFEMBCNC ()
 
void FEMBPower (uint8_t iFEMB, bool turnOn)
 
void SourceFEMB (uint64_t iDAQLink, uint64_t real)
 
void StartEventBuilder (uint8_t mask=0xF)
 
void StopEventBuilder (uint8_t mask=0xF)
 
void WriteQSFP (uint16_t address, uint32_t value, uint8_t byte_count)
 
uint32_t ReadQSFP (uint16_t address, uint8_t byte_count)
 
void WriteDTS_CDS (uint16_t address, uint32_t value, uint8_t byte_count=4, bool ignore_error=false)
 
uint32_t ReadDTS_CDS (uint16_t address, uint8_t byte_count=4)
 
float ConfigureDTSCDS (uint8_t source=0)
 
void WriteDTS_SI5344 (uint16_t address, uint32_t value, uint8_t byte_count=4)
 
uint32_t ReadDTS_SI5344 (uint16_t address, uint8_t byte_count=4)
 
void SetDTS_SI5344Page (uint8_t page)
 
uint8_t GetDTS_SI5344Page ()
 
uint8_t GetDTS_SI5344AddressPage (uint16_t address)
 
void LoadConfigDTS_SI5344 (std::string const &fileName)
 
void ResetSi5344 ()
 
void SelectSI5344 (uint64_t input, bool enable)
 
void SelectSI5342 (uint64_t input, bool enable)
 
void WriteDAQ_SI5342 (uint16_t address, uint32_t value, uint8_t byte_count=4)
 
uint32_t ReadDAQ_SI5342 (uint16_t address, uint8_t byte_count=4)
 
void SetDAQ_SI5342Page (uint8_t page)
 
uint8_t GetDAQ_SI5342Page ()
 
uint8_t GetDAQ_SI5342AddressPage (uint16_t address)
 
void LoadConfigDAQ_SI5342 (std::string const &fileName)
 
void ResetSi5342 ()
 
std::vector< uint32_t > CaptureHistory (std::string const &address)
 
std::vector< uint128_tCaptureHistory (std::string const &address, size_t wordCount)
 
uint32_t ReadLocalFlash (uint16_t address)
 
std::vector< uint32_t > ReadLocalFlash (uint16_t address, size_t n)
 
void WriteLocalFlash (uint16_t address, uint32_t data)
 
void WriteLocalFlash (uint16_t address, std::vector< uint32_t > const &data)
 
void FlashCheckBusy ()
 
void ReadFlash (std::string const &fileName, uint8_t update_percentage=101)
 
void WriteFlash (std::vector< uint32_t > data, uint8_t update_percentage=101)
 
void ProgramFlash (std::string const &fileName, uint8_t update_percentage=101)
 
void EraseFlash (bool print_updates=false)
 
void CheckFlash (std::vector< uint32_t > data, uint8_t update_percentage=101)
 
std::vector< data_8b10b_tReadOutCDLinkSpyBuffer ()
 
std::vector< data_8b10b_tReadDAQLinkSpyBuffer (uint8_t iDAQLink, uint8_t trigger_mode=0)
 
void SetupFEMBExtClock (uint8_t iFEMB)
 Setup FEMB External Clock.
 
void WriteFEMBPhase (uint8_t iFEMB, uint16_t clk_phase_data)
 
bool TryFEMBPhases (uint8_t iFEMB, std::vector< uint16_t > phases)
 
bool HuntFEMBPhase (uint8_t iFEMB, uint16_t clk_phase_data_start)
 
void ConfigFEMB (uint8_t iFEMB, std::vector< uint32_t > fe_config, std::vector< uint16_t > clk_phases, uint8_t pls_mode=0, uint8_t pls_dac_val=0, uint8_t start_frame_mode_sel=1, uint8_t start_frame_swap=1)
 Setup FEMB in real or pulser data mode.
 
void ConfigFEMBFakeData (uint8_t iFEMB, uint8_t fake_mode, uint32_t fake_word, uint8_t femb_number, std::vector< uint32_t > fake_samples, uint8_t start_frame_mode_sel=1, uint8_t start_frame_swap=1)
 Setup FEMB in fake data mode.
 
void ConfigFEMBMode (uint8_t iFEMB, uint32_t pls_cs, uint32_t dac_sel, uint32_t fpga_dac, uint32_t asic_dac, uint32_t mon_cs)
 
uint16_t SetupFEMBASICs (uint8_t iFEMB, uint8_t gain, uint8_t shape, uint8_t highBaseline, bool highLeakage, bool leakagex10, bool acCoupling, bool buffer, bool useExtClock, uint8_t internalDACControl, uint8_t internalDACValue)
 Setup FEMB ASICs.
 
void SetupFPGAPulser (uint8_t iFEMB, uint8_t dac_val)
 
void SetupInternalPulser (uint8_t iFEMB)
 
uint16_t SetupASICPulserBits (uint8_t iFEMB)
 
uint16_t SetupFEMBASICs (uint8_t iFEMB, std::vector< uint32_t > registerList)
 Setup FEMB ASICs.
 
void ConfigWIBFakeData (bool enableFakeFEMB1, bool enableFakeFEMB2, bool enableFakeFEMB3, bool enableFakeFEMB4, bool counter)
 
void SetFEMBFakeCOLDATAMode (uint8_t iFEMB, uint8_t iCD, bool mode=0)
 
uint8_t GetFEMBFakeCOLDATAMode (uint8_t iFEMB, uint8_t iCD)
 
void SetFEMBStreamSource (uint8_t iFEMB, uint8_t iStream, bool real=true)
 
uint8_t GetFEMBStreamSource (uint8_t iFEMB, uint8_t iStream)
 
void SetEventBuilderDebugMode (uint8_t mask=0xF)
 
uint8_t GetEventBuilderDebugMode ()
 
char GetFEMBChar (uint8_t iFEMB)
 
char GetDAQLinkChar (uint8_t iDAQLink)
 
char GetFEMBCDChar (uint8_t iCD)
 
bool CheckDAQLinkInRange (uint8_t iDAQLink)
 
bool CheckFEMBInRange (uint8_t iFEMB)
 
bool CheckFEMBStreamInRange (uint8_t iStream)
 
bool CheckFEMBCDInRange (uint8_t iCD)
 
uint8_t GetFEMBCount ()
 
WIB_DAQ_t GetDAQMode ()
 
void SetContinueOnFEMBRegReadError (bool enable)
 
void SetContinueOnFEMBSPIError (bool enable)
 
void SetContinueOnFEMBSyncError (bool enable)
 
void SetContinueIfListOfFEMBClockPhasesDontSync (bool enable)
 
- Public Member Functions inherited from WIBBase
 WIBBase (std::string const &address, std::string const &WIBAddressTable, std::string const &FEMBAddressTable)
 
 ~WIBBase ()
 
std::string GetAddress ()
 
uint32_t Read (uint16_t address)
 
uint32_t ReadWithRetry (uint16_t address)
 
uint32_t Read (std::string const &address)
 
uint32_t ReadWithRetry (std::string const &address)
 
void Write (uint16_t address, uint32_t value)
 
void WriteWithRetry (uint16_t address, uint32_t value)
 
void Write (std::string const &address, uint32_t value)
 
void WriteWithRetry (std::string const &address, uint32_t value)
 
void Write (uint16_t address, std::vector< uint32_t > const &values)
 
void Write (std::string const &address, std::vector< uint32_t > const &values)
 
void Write (uint16_t address, uint32_t const *values, size_t word_count)
 
void Write (std::string const &address, uint32_t const *values, size_t word_count)
 
uint32_t ReadI2C (std::string const &base_address, uint16_t I2C_aaddress, uint8_t byte_count=4)
 
void WriteI2C (std::string const &base_address, uint16_t I2C_address, uint32_t data, uint8_t byte_count=4, bool ignore_error=false)
 
std::vector< std::string > GetNames (std::string const &regex)
 
std::vector< std::string > GetFEMBNames (std::string const &regex)
 
std::vector< std::string > GetAddresses (uint16_t lower, uint16_t upper)
 
std::vector< std::string > GetFEMBAddresses (uint16_t lower, uint16_t upper)
 
std::vector< std::string > GetTableNames (std::string const &regex)
 
std::vector< Item const * > GetTagged (std::string const &tag)
 
std::vector< Item const * > GetFEMBTagged (std::string const &tag)
 
uint32_t ReadFEMB (int iFEMB, uint16_t address)
 
uint32_t ReadFEMB (int iFEMB, std::string const &address)
 
void WriteFEMB (int iFEMB, uint16_t address, uint32_t value)
 
void WriteFEMB (int iFEMB, std::string const &address, uint32_t value)
 
void WriteFEMBBits (int iFEMB, uint16_t address, uint32_t pos, uint32_t mask, uint32_t value)
 
void EnableADC (uint64_t iFEMB, uint64_t enable)
 
Item const * GetItem (std::string const &)
 
Item const * GetFEMBItem (int iFEMB, std::string const &)
 
int GetSVNVersion ()
 

Public Attributes

bool started
 

Private Member Functions

 WIB ()
 
 WIB (const WIB &other)
 
WIBoperator= (const WIB &)
 

Private Attributes

WIB_DAQ_t DAQMode
 
uint8_t FEMBCount
 
uint8_t FEMBStreamCount
 
uint8_t FEMBCDACount
 
uint8_t DAQLinkCount
 
bool ContinueOnFEMBRegReadError
 
bool ContinueOnFEMBSPIError
 
bool ContinueOnFEMBSyncError
 
bool ContinueIfListOfFEMBClockPhasesDontSync
 

Detailed Description

Definition at line 26 of file WIB.hh.

Member Enumeration Documentation

◆ WIB_DAQ_t

Enumerator
UNKNOWN 
RCE 
FELIX 

Definition at line 208 of file WIB.hh.

@ UNKNOWN
Definition WIB.hh:208
@ FELIX
Definition WIB.hh:208
@ RCE
Definition WIB.hh:208

Constructor & Destructor Documentation

◆ WIB() [1/3]

WIB::WIB ( std::string const & address,
std::string const & WIBAddressTable = "WIB.adt",
std::string const & FEMBAddressTable = "FEMB.adt",
bool fullStart = true )

Definition at line 9 of file WIB.cpp.

9 :
10 WIBBase(address,WIBAddressTable,FEMBAddressTable),DAQMode(UNKNOWN),FEMBStreamCount(4),FEMBCDACount(2),
13
14
15 if(fullStart){
16 //Figure out what kind of WIB firmware we are dealing with
17 FEMBCount = Read("SYSTEM.FEMB_COUNT");
18 DAQLinkCount = Read("SYSTEM.DAQ_LINK_COUNT");
19 //Hardcoded lookup for RCE and FELIX
20 if((FEMBCount == 4) && (DAQLinkCount == 4)){
21 DAQMode = RCE;
22 }else if((FEMBCount == 4) && (DAQLinkCount == 2)){
23 DAQMode = FELIX;
24 }
25 //TODO check FEMBStreamCount and FEMCDACount from registers on the WIB
26 //TODO create those registers
27 Write("POWER.ENABLE.MASTER_BIAS",1);
28 started = true;
29 }
30}
uint32_t Read(uint16_t address)
Definition WIBBase.cpp:119
void Write(uint16_t address, uint32_t value)
Definition WIBBase.cpp:132
bool ContinueOnFEMBRegReadError
Definition WIB.hh:237
uint8_t FEMBCDACount
Definition WIB.hh:234
bool ContinueOnFEMBSyncError
Definition WIB.hh:239
bool ContinueOnFEMBSPIError
Definition WIB.hh:238
uint8_t FEMBStreamCount
Definition WIB.hh:233
WIB_DAQ_t DAQMode
Definition WIB.hh:231
bool ContinueIfListOfFEMBClockPhasesDontSync
Definition WIB.hh:240
bool started
Definition WIB.hh:33
uint8_t FEMBCount
Definition WIB.hh:232
uint8_t DAQLinkCount
Definition WIB.hh:235

◆ ~WIB()

WIB::~WIB ( )

Definition at line 32 of file WIB.cpp.

32 {
33}

◆ WIB() [2/3]

WIB::WIB ( )
private

◆ WIB() [3/3]

WIB::WIB ( const WIB & other)
private

Member Function Documentation

◆ CaptureHistory() [1/2]

std::vector< uint32_t > WIB::CaptureHistory ( std::string const & address)

Definition at line 3 of file WIB_History.cpp.

3 {
4 std::vector<uint32_t> ret;
5 uint32_t val;
6 while( (val = Read(address)) & 0x1){
7 ret.push_back(val);
8 }
9 return ret;
10}

◆ CaptureHistory() [2/2]

std::vector< uint128_t > WIB::CaptureHistory ( std::string const & address,
size_t wordCount )

Definition at line 12 of file WIB_History.cpp.

12 {
13 std::vector<uint128_t> ret;
14 bool capture = true;
15 uint16_t addr = GetItem(address)->address;
16 while(capture){
17 uint128_t val = 0;
18 //Read address last since it causes the incr.
19 for(size_t offset = wordCount;offset > 0;offset--){
20 val |= uint128_t(Read(addr+(offset-1)) << 32*(offset-1));
21 }
22 ret.push_back(val);
23 if(!(val & 0x1)){
24 break;
25 }
26 }
27 return ret;
28}
unsigned __int128 uint128_t
Definition WIB.hh:14
uint16_t address
Item const * GetItem(std::string const &)
Definition WIBBase.cpp:103
double offset

◆ CheckDAQLinkInRange()

bool WIB::CheckDAQLinkInRange ( uint8_t iDAQLink)

Definition at line 509 of file WIB.cpp.

509 {
510 if(!((iDAQLink > 0) && (iDAQLink <= DAQLinkCount))){
511 BUException::WIB_INDEX_OUT_OF_RANGE e;
512 e.Append("DAQ Link\n");
513 throw e;
514 }
515 return true;
516}

◆ CheckedResetWIBAndCfgDTS()

void WIB::CheckedResetWIBAndCfgDTS ( uint8_t localClock,
uint8_t PDTS_TGRP,
uint8_t PDTSsource = 0,
uint32_t PDTSAlignment_timeout = 0 )

Definition at line 272 of file WIB.cpp.

272 {
273 if(DAQMode == UNKNOWN){
274 BUException::WIB_DAQMODE_UNKNOWN e;
275 throw e;
276 }
277 if(localClock > 1){
278 BUException::WIB_BAD_ARGS e;
279 e.Append("localClock > 1; must be 0 (for DTS) or 1 (for local clock)\n");
280 throw e;
281 }
282 if(PDTSsource > 1){
283 BUException::WIB_BAD_ARGS e;
284 e.Append("PDTSsource > 1; must be 0 (for backplane) or 1 (for front panel)\n");
285 throw e;
286 }
287 if(16 <= PDTS_TGRP){
288 BUException::WIB_BAD_ARGS e;
289 e.Append("PDTS TGRP > 15; must be 0 to 15\n");
290 throw e;
291 }
292
293
294 bool reset_check = false;
295 // Check if we are already in a good state
296 if(localClock > 0){
297 printf("Checking if locked on local clock\n");
298 reset_check = ( (Read("DTS.CONVERT_CONTROL.EN_FAKE") != 1)
299 || (Read("DTS.CCONVERT_CONTROL.LOCAL_TIMESTAMP") != 1)
300 || (Read("FEMB_CNC.CNC_CLOCK_SELECT") != 1)
301 // || (Read("FEMB_CNC.ENABLE_DTS_CMDS") != 1)
302 || (Read("DTS.SI5344.INPUT_SELECT") != 1)
303 || (Read("DTS.SI5344.ENABLE") != 1) );
304 if(!reset_check){
305 printf("Already in a good state\n");
306 }
307 else{
308 printf("Need to reset for local clocking\n");
309 }
310 }
311 else{
312 printf("Checking if locked on PDTS\n");
313 reset_check = ( (Read("DTS.PDTS_TGRP") != PDTS_TGRP)
314 || (Read("FEMB_CNC.CNC_CLOCK_SELECT") != 1)
315 || (Read("DTS.PDTS_ENABLE") != 1)
316 || (Read("DTS.CDS.LOL") != 0)
317 || (Read("DTS.CDS.LOS") != 0)
318 || (ReadWithRetry("DTS.SI5344.INPUT_SELECT") != 0)
319 || (ReadWithRetry("DTS.SI5344.LOS") != 0)
320 || (ReadWithRetry("DTS.SI5344.LOL") != 0)
321 || (ReadWithRetry("DTS.SI5344.ENABLE") != 1)
322 || (ReadWithRetry("DTS.PDTS_STATE") != 0x8) );
323 if(!reset_check){
324 printf("Already in a good state\n");
325 }
326 else{
327 printf("Need to reset for PDTS\n");
328 }
329 }
330
331 //Check the SI5342 if we're attached to FELIX
332 if(DAQMode == FELIX){
333
334 if(
335 (Read("DAQ.SI5342.ENABLE") == 0)
336 || (Read("DAQ.SI5342.INPUT_SELECT") != 1)
337 || (Read("DAQ.SI5342.LOL") == 1)
338 || (Read("DAQ.SI5342.LOS_XAXB") == 1)
339 || (Read("DAQ.SI5342.LOS_2") == 1) ){
340 printf("Need to reset for SI5342\n");
341 reset_check = true;
342 }
343 else{
344 printf("SI5342 in good state\n");
345 }
346 }
347
348 if(reset_check){
349 // get this register so we can leave it in the state it started in
350 uint32_t slow_control_dnd = Read("SYSTEM.SLOW_CONTROL_DND");
351
352 ResetWIB();
353 Write("SYSTEM.SLOW_CONTROL_DND",1);
354
355 for (size_t iFEMB=1; iFEMB<=4; iFEMB++){
356 FEMBPower(iFEMB,0);
357 }
358
359 //make sure everything DTS is off
360 Write("DTS.CONVERT_CONTROL.HALT",1);
361 Write("DTS.CONVERT_CONTROL.ENABLE",0);
362 Write("DTS.CONVERT_CONTROL.START_SYNC",0);
363 sleep(1);
364
365 if(localClock > 0){
366 printf("Configuring local clock\n");
367 //Configure the SI5344 to use the local oscillator instead of the PDTS
368 LoadConfigDTS_SI5344("default");
369 sleep(1);
370 SelectSI5344(1,1);
371 sleep(1);
372 Write("DTS.CONVERT_CONTROL.EN_FAKE",1);
373 Write("DTS.CONVERT_CONTROL.LOCAL_TIMESTAMP",1);
374 Write("FEMB_CNC.CNC_CLOCK_SELECT",1);
375 // Write("FEMB_CNC.ENABLE_DTS_CMDS",1);
376 sleep(1);
377 }
378 else {
379 //Configure the clocking for the PDTS (assumes the PDTS is sending idle or something)
380 printf("Configuring DTS\n");
381 Write("DTS.PDTS_TGRP",PDTS_TGRP);
382 printf("Using timing group 0x%X\n",PDTS_TGRP);
383 InitializeDTS(PDTSsource,0,PDTSAlignment_timeout);
384 sleep(1);
385 Write("FEMB_CNC.CNC_CLOCK_SELECT",1);
386 sleep(1);
387 //We are ready for the PDTS, start searching
388 Write("DTS.PDTS_ENABLE",1);
389 sleep(1);
390 }
391
392
393 Write("SYSTEM.SLOW_CONTROL_DND",slow_control_dnd);
394 }
395 //Now we have the 128MHz clock
396 std::cout << "Resetting DAQ Links" << std::endl;
397 size_t nLinks = 4;
398 if(DAQMode == FELIX){ nLinks = 2; }
399 for (size_t iLink=1; iLink <= nLinks; ++iLink){
400 std::cout << iLink << std::endl;
401 EnableDAQLink_Lite(iLink, 0);
402 }
403
404 Write("FEMB1.DAQ.ENABLE",0);
405 Write("FEMB2.DAQ.ENABLE",0);
406 Write("FEMB3.DAQ.ENABLE",0);
407 Write("FEMB4.DAQ.ENABLE",0);
408
409}
#define sleep(x)
Definition WIB_FEMB.cpp:12
uint32_t ReadWithRetry(uint16_t address)
Definition WIBBase.cpp:116
void ResetWIB(bool reset_udp=false)
Definition WIB.cpp:138
void LoadConfigDTS_SI5344(std::string const &fileName)
void InitializeDTS(uint8_t PDTSsource=0, uint8_t clockSource=0, uint32_t PDTSAlignment_timeout=0)
Definition WIB_DTS.cpp:12
void EnableDAQLink_Lite(uint8_t iDAQLink, uint8_t enable)
Definition WIB.cpp:77
void SelectSI5344(uint64_t input, bool enable)
void FEMBPower(uint8_t iFEMB, bool turnOn)
Definition WIB.cpp:456

◆ CheckFEMBCDInRange()

bool WIB::CheckFEMBCDInRange ( uint8_t iCD)

Definition at line 594 of file WIB.cpp.

594 {
595 if(!((iCDA > 0) && (iCDA <= FEMBCDACount))){
596 BUException::WIB_INDEX_OUT_OF_RANGE e;
597 e.Append("FEMB CDA");
598 throw e;
599 }
600 return true;
601}

◆ CheckFEMBInRange()

bool WIB::CheckFEMBInRange ( uint8_t iFEMB)

Definition at line 547 of file WIB.cpp.

547 {
548 if(!((iFEMB > 0) && (iFEMB <= FEMBCount))){
549 BUException::WIB_INDEX_OUT_OF_RANGE e;
550 e.Append("FEMB\n");
551 throw e;
552 }
553 return true;
554}

◆ CheckFEMBStreamInRange()

bool WIB::CheckFEMBStreamInRange ( uint8_t iStream)

Definition at line 585 of file WIB.cpp.

585 {
586 if(!((iStream > 0) && (iStream <= FEMBStreamCount))){
587 BUException::WIB_INDEX_OUT_OF_RANGE e;
588 e.Append("FEMB Stream");
589 throw e;
590 }
591 return true;
592}

◆ CheckFlash()

void WIB::CheckFlash ( std::vector< uint32_t > data,
uint8_t update_percentage = 101 )

Definition at line 294 of file WIB_Flash.cpp.

294 {
295 bool print_updates = false;
296 if(update_percentage < 100){
297 print_updates = true;
298 }
299 size_t update_delta = (update_percentage * float(16*1024*1024/4))/100;
300 size_t next_update = update_delta;
301
302 if(print_updates){
303 fprintf(stderr," Checking flash\n");
304 fprintf(stderr," [");
305 for(size_t i = 0; i < 100.0/update_percentage;i++){
306 fprintf(stderr,"=");
307 }
308 fprintf(stderr,"]\n [");
309 }
310 //program flash in groups of 64 32bit words (256 bytes)
311 uint32_t flashAddress = 0;
312 uint32_t blockRegMapAddress = GetItem("FLASH.DATA00")->address;
313
314 for(size_t currentBlockStartIndex = 0; currentBlockStartIndex < 16*1024*1024/4;){
316
317 //Find size of this block to write (usually just 64 (256bytes)), but the last one might be smaller.
318 size_t blockSize = std::min(size_t(64),flashData.size()-currentBlockStartIndex);
319 //Set adddress
320 WriteWithRetry("FLASH.ADDRESS",flashAddress);
321 //set block size (in bytes and is 1 less than value; 0 means 1 byte, 255 means 256 bytes)
322 WriteWithRetry("FLASH.BYTE_COUNT",(blockSize*sizeof(uint32_t))-1);
323 //Start read
324 WriteWithRetry("FLASH.RUN_COMMAND",0x5);
325
327
328 //Check the data.
329 for(size_t iBlockWord = 0;iBlockWord < blockSize;iBlockWord++){
330 //flashData: Address in WIB register map of this 32bit word
331 //ReadWithRetry: Data from the flash for this word
332 uint32_t dataRead;
333 if((dataRead = ReadWithRetry(blockRegMapAddress + iBlockWord)) !=
334 flashData[currentBlockStartIndex + iBlockWord]){
335 BUException::WIB_FLASH_ERROR e;
336 char errorbuffer[] = "Error on index 0xXXXXXXXX: 0xXXXXXXXX != 0xXXXXXXXX";
337 snprintf(errorbuffer,
338 strlen(errorbuffer),
339 "Error on index 0x%08X: 0x%08X != 0x%08X",
340 flashAddress,
341 dataRead,
342 flashData[currentBlockStartIndex + iBlockWord]);
343 e.Append(errorbuffer);
344 throw e;
345 }
346 }
347 currentBlockStartIndex += blockSize;
348 flashAddress += blockSize*sizeof(uint32_t);
349
350 if(print_updates && (currentBlockStartIndex > next_update)){
351 fprintf(stderr,"=");
352 next_update += update_delta;
353 }
354 }
355 if(print_updates){
356 printf("]\n");
357 printf(" Check passed\n");
358 }
359}
void WriteWithRetry(uint16_t address, uint32_t value)
Definition WIBBase.cpp:129
void FlashCheckBusy()

◆ ConfigFEMB()

void WIB::ConfigFEMB ( uint8_t iFEMB,
std::vector< uint32_t > fe_config,
std::vector< uint16_t > clk_phases,
uint8_t pls_mode = 0,
uint8_t pls_dac_val = 0,
uint8_t start_frame_mode_sel = 1,
uint8_t start_frame_swap = 1 )

Setup FEMB in real or pulser data mode.

Sets up iFEMB (index from 1) fe_config: list of options to configure the FE ASICs: Gain: 0,1,2,3 for 4.7, 7.8, 14, 25 mV/fC, respectively Shaping Time: 0,1,2,3 for 0.5, 1, 2, 3 us, respectively High Baseline: 0 for 200 mV, 1 for 900 mV, 2 for 200 mV on collection and 900 mV on induction High Leakage: 0 for 100 pA, 1 for 500 pA Leakage x 10: if 1, multiply leakage times 10 AC Coupling : 0 for DC coupling, 1 for AC coupling (between FE and ADC) Buffer: 0 for disable and bypass, 1 for use (between FE and ADC) Use External Clock: 0 ADC use internal clock, 1 ADC use FPGA clocking (almost always want 1) clk_phases: a list of 16 bit values to try for the ADC clock phases. Tries these values until the sync check bits are all 0, and hunts for good values if these all fail. The most significant byte is ADC_ASIC_CLK_PHASE_SELECT (register 6) while the least significant byte is ADC_ASIC_CLK_PHASE_SELECT (register 15) pls_mode: pulser mode select: 0 off, 1 FE ASIC internal pulser, 2 FPGA pulser pls_dac_val: pulser DAC value (amplitude) 6-bits in ASIC test pulse mode, 5-bits in FPGA test pulse mode start_frame_mode_sel: 1 to make data frame start the way BU WIB firmware expects start_frame_swap: 1 to reverse the start bits

Definition at line 37 of file WIB_FEMB.cpp.

38 {
39
40 if (iFEMB < 1 || iFEMB > 4)
41 {
42 BUException::WIB_BAD_ARGS e;
43 std::stringstream expstr;
44 expstr << "ConfigFEMB: iFEMB should be between 1 and 4: "
45 << int(iFEMB);
46 e.Append(expstr.str().c_str());
47 throw e;
48 }
49 if (pls_mode > 2)
50 {
51 BUException::WIB_BAD_ARGS e;
52 std::stringstream expstr;
53 expstr << "ConfigFEMB: pls_dac_mode is allowed to be 0 (off), 1 (FPGA), 2 (internal), but is: "
54 << int(pls_mode);
55 e.Append(expstr.str().c_str());
56 throw e;
57 }
58 if (start_frame_mode_sel > 1 || start_frame_swap > 1)
59 {
60 BUException::WIB_BAD_ARGS e;
61 std::stringstream expstr;
62 expstr << "ConfigFEMB: start_frame_mode_sel and start_frame_swap must be 0 or 1";
63 e.Append(expstr.str().c_str());
64 throw e;
65 }
66
67 if(fe_config.size() != 8){
68
69 BUException::WIB_BAD_ARGS e;
70 std::stringstream expstr;
71 expstr << "Error: Expecting 9 Front End configuration options:" << std::endl <<
72 "\t0: Gain" << std::endl <<
73 "\t1: Shaping Time" << std::endl <<
74 "\t2: High Baseline" << std::endl <<
75 "\t3: High Leakage" << std::endl <<
76 "\t4: Leakage x 10" << std::endl <<
77 "\t5: AC Coupling" << std::endl <<
78 "\t6: Buffer" << std::endl <<
79 "\t7: Use External Clock" << std::endl;
80 e.Append(expstr.str().c_str());
81 throw e;
82 }
83 else{
84 std::cout << "Front End configuration options:" << std::endl <<
85 "\t0:" << std::setw(22) << std::setfill(' ') << "Gain " << fe_config[0] << std::endl <<
86 "\t1:" << std::setw(22) << std::setfill(' ') << "Shaping Time " << fe_config[1] << std::endl <<
87 "\t2:" << std::setw(22) << std::setfill(' ') << "High Baseline " << fe_config[2] << std::endl <<
88 "\t3:" << std::setw(22) << std::setfill(' ') << "High Leakage " << fe_config[3] << std::endl <<
89 "\t4:" << std::setw(22) << std::setfill(' ') << "Leakage x 10 " << fe_config[4] << std::endl <<
90 "\t5:" << std::setw(22) << std::setfill(' ') << "AC Coupling " << fe_config[5] << std::endl <<
91 "\t6:" << std::setw(22) << std::setfill(' ') << "Buffer " << fe_config[6] << std::endl <<
92 "\t8:" << std::setw(22) << std::setfill(' ') << "Use External Clock " << fe_config[7] << std::endl;
93 }
94
95 std::cout << "Pulser Mode: " << int(pls_mode) << " and DAC Value: " << int(pls_dac_val) << std::endl;
96
97 // get this register so we can leave it in the state it started in
98 uint32_t slow_control_dnd = Read("SYSTEM.SLOW_CONTROL_DND");
99 Write("SYSTEM.SLOW_CONTROL_DND",1);
100
101 if(ReadFEMB(iFEMB,"VERSION_ID") == ReadFEMB(iFEMB,"SYS_RESET")) { // can't read register if equal
103 std::cout << "Error: Can't read registers from FEMB " << int(iFEMB) << std::endl;
104 return;
105 }
106 BUException::FEMB_REG_READ_ERROR e;
107 std::stringstream expstr;
108 expstr << " for FEMB: " << int(iFEMB);
109 e.Append(expstr.str().c_str());
110 throw e;
111 }
112
113 WriteFEMB(iFEMB, "REG_RESET", 1);
114 sleep(1);
115
116 WriteFEMB(iFEMB, "START_FRAME_MODE_SELECT", start_frame_mode_sel);
117 sleep(1);
118 WriteFEMB(iFEMB, "START_FRAME_SWAP", start_frame_swap);
119
120 if(fe_config[7]){ // use external clock
121 SetupFEMBExtClock(iFEMB);
122 }
123 sleep(0.05);
124
125 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
126 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
127
128 // These are all Jack's WIB addresses, need to figure out Dan's addresses for functionality
130 //Write(1, 0);
131 //Write(1, 0);
132 //Write(1, 2);
133 //Write(1, 2);
134 //Write(1, 0);
135 //Write(1, 0);
136 //
138 //Write(18, 0x8000);
139 //Write(18, 0x8000);
140
141 //Reset SPI
142 //
143 sleep(0.005);
144 WriteFEMB(iFEMB, "ADC_ASIC_RESET", 0x1);
145 sleep(0.005);
146 WriteFEMB(iFEMB, "ADC_ASIC_RESET", 0x1);
147 sleep(0.005);
148 WriteFEMB(iFEMB, "FE_ASIC_RESET", 0x1);
149 sleep(0.005);
150 WriteFEMB(iFEMB, "FE_ASIC_RESET", 0x1);
151 sleep(0.005);
152
153 //Set ADC latch_loc
154 uint32_t REG_LATCHLOC1_4_data = 0x04040404;
155 uint32_t REG_LATCHLOC5_8_data = 0x04040404;
156
157 WriteFEMB(iFEMB, "ADC_LATCH_LOC_0TO3", REG_LATCHLOC1_4_data);
158 WriteFEMB(iFEMB, "ADC_LATCH_LOC_4TO7", REG_LATCHLOC5_8_data);
159
160 // Setup pulser
161 uint8_t internal_daq_value = 0;
162 if (pls_mode == 1) // internal, FE ASIC, 6 bits
163 {
164 if (pls_dac_val >= 63)
165 {
166 BUException::WIB_BAD_ARGS e;
167 std::stringstream expstr;
168 expstr << "ConfigFEMB: pls_dac_val is 6 bits for internal DAC, must be 0-63, but is: "
169 << int(pls_dac_val);
170 e.Append(expstr.str().c_str());
171 throw e;
172 }
173 internal_daq_value = pls_dac_val;
174 SetupInternalPulser(iFEMB);
175 }
176 else if (pls_mode == 2) // external, FPGA, 5 bits
177 {
178 if (pls_dac_val >= 32)
179 {
180 BUException::WIB_BAD_ARGS e;
181 std::stringstream expstr;
182 expstr << "ConfigFEMB: pls_dac_val is 5 bits for FPGA DAC, must be 0-31, but is: "
183 << int(pls_dac_val);
184 e.Append(expstr.str().c_str());
185 throw e;
186 }
187 SetupFPGAPulser(iFEMB,pls_dac_val);
188 }
189
190 // Setup ASICs
191 SetupFEMBASICs(iFEMB, fe_config[0], fe_config[1], fe_config[2], fe_config[3], fe_config[4], fe_config[5], fe_config[6], fe_config[7], pls_mode, internal_daq_value);
192 std::cout << "FEMB " << int(iFEMB) << " Successful SPI config" << std::endl;
193
194 // Try to sync ADCs
195 if (clk_phases.size() == 0)
196 {
197 clk_phases.push_back(0xFFFF);
198 }
199 if (!TryFEMBPhases(iFEMB,clk_phases)) {
201 std::cout << "Warning: FEMB " << int(iFEMB) << " ADC FIFO not synced from expected phases, trying to hunt for phases" << std::endl;
202 if (!HuntFEMBPhase(iFEMB,clk_phases.at(0))) {
204 std::cout << "Error: FEMB " << int(iFEMB) << " ADC FIFO could not be synced even after hunting" << std::endl;
205 }
206 else {
207 uint16_t adc_fifo_sync = ( ReadFEMB(iFEMB, 6) & 0xFFFF0000) >> 16;
208 BUException::FEMB_ADC_SYNC_ERROR e;
209 std::stringstream expstr;
210 expstr << " after hunting. ";
211 expstr << " FEMB: " << int(iFEMB);
212 expstr << " sync: " << std::bitset<16>(adc_fifo_sync);
213 expstr << " phases: ";
214 expstr << std::hex << std::setfill ('0') << std::setw(2) << ReadFEMB(iFEMB,"ADC_ASIC_CLK_PHASE_SELECT");
215 expstr << std::hex << std::setfill ('0') << std::setw(2) << ReadFEMB(iFEMB,"ADC_ASIC_CLK_PHASE_SELECT_2");
216 e.Append(expstr.str().c_str());
217 throw e;
218 }
219 } // if ! HuntFEMBPhase
220 } // if ContinueIfListOfFEMBClockPhasesDontSync
221 else // ContinueIfListOfFEMBClockPhasesDontSync
222 {
223 uint16_t adc_fifo_sync = ( ReadFEMB(iFEMB, 6) & 0xFFFF0000) >> 16;
224 BUException::FEMB_ADC_SYNC_ERROR e;
225 std::stringstream expstr;
226 expstr << " after trying all in list. ";
227 expstr << " FEMB: " << int(iFEMB);
228 expstr << " sync: " << std::bitset<16>(adc_fifo_sync);
229 expstr << " phases tried: " << std::endl;
230 for (size_t iclk_phase = 0;iclk_phase < clk_phases.size();iclk_phase++)
231 {
232 expstr << " "
233 << std::hex << std::setfill ('0') << std::setw(4) << clk_phases[iclk_phase] << std::endl;
234 }
235 e.Append(expstr.str().c_str());
236 throw e;
237 } // else ContinueIfListOfFEMBClockPhasesDontSync
238 } // if ! TryFEMBPhases
239 uint16_t adc_fifo_sync = ( ReadFEMB(iFEMB, 6) & 0xFFFF0000) >> 16;
240 std::cout << "FEMB " << int(iFEMB) << " Final ADC FIFO sync: " << std::bitset<16>(adc_fifo_sync) << std::endl;
241 std::cout << "FEMB " << int(iFEMB) << " Final Clock Phases: "
242 << std::hex << std::setfill ('0') << std::setw(2) << ReadFEMB(iFEMB,"ADC_ASIC_CLK_PHASE_SELECT")
243 << std::hex << std::setfill ('0') << std::setw(2) << ReadFEMB(iFEMB,"ADC_ASIC_CLK_PHASE_SELECT_2")
244 << std::endl;
245
246 //time stamp reset
247 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
248 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
249
250 // These are all Jack's WIB addresses, need to figure out Dan's addresses for functionality
252 //Write(1, 0);
253 //Write(1, 0);
254 //Write(1, 2);
255 //Write(1, 2);
256 //Write(1, 0);
257 //Write(1, 0);
258 //
260 //Write(18, 0x8000);
261 //Write(18, 0x8000);
262
263 Write("SYSTEM.SLOW_CONTROL_DND",slow_control_dnd);
264}
void WriteFEMB(int iFEMB, uint16_t address, uint32_t value)
Definition WIBBase.cpp:174
uint32_t ReadFEMB(int iFEMB, uint16_t address)
Definition WIBBase.cpp:155
bool TryFEMBPhases(uint8_t iFEMB, std::vector< uint16_t > phases)
void SetupFEMBExtClock(uint8_t iFEMB)
Setup FEMB External Clock.
Definition WIB_FEMB.cpp:375
bool HuntFEMBPhase(uint8_t iFEMB, uint16_t clk_phase_data_start)
void SetupInternalPulser(uint8_t iFEMB)
Definition WIB_FEMB.cpp:928
void SetupFPGAPulser(uint8_t iFEMB, uint8_t dac_val)
Definition WIB_FEMB.cpp:912
uint16_t SetupFEMBASICs(uint8_t iFEMB, uint8_t gain, uint8_t shape, uint8_t highBaseline, bool highLeakage, bool leakagex10, bool acCoupling, bool buffer, bool useExtClock, uint8_t internalDACControl, uint8_t internalDACValue)
Setup FEMB ASICs.
Definition WIB_FEMB.cpp:621

◆ ConfigFEMBFakeData()

void WIB::ConfigFEMBFakeData ( uint8_t iFEMB,
uint8_t fake_mode,
uint32_t fake_word,
uint8_t femb_number,
std::vector< uint32_t > fake_samples,
uint8_t start_frame_mode_sel = 1,
uint8_t start_frame_swap = 1 )

Setup FEMB in fake data mode.

Sets up iFEMB (index from 1) in fake data mode fake_mode: 0 for real data, 1 for fake word, 2 for fake waveform, 3 for channel indicator (FEMB, chip, channel), 4 for channel indicator (counter, chip, channel) fake_word: 12 bit wrd to use when in fake word mode femb_number: femb number to use in fake_mode 3 fake_samples: vector of samples to use in fake_mode 2

Sets up iFEMB (index from 1) in fake data mode fake_mode: 0 for real data, 1 for fake word, 2 for fake waveform, 3 for channel indicator (FEMB, chip, channel), 4 for channel indicator (counter, chip, channel) fake_word: 12 bit wrd to use when in fake word mode femb_number: femb number to use in fake_mode 3, 4 bits fake_samples: vector of samples to use in fake_mode 2

Definition at line 275 of file WIB_FEMB.cpp.

276 {
277
278 if (iFEMB < 1 || iFEMB > 4)
279 {
280 BUException::WIB_BAD_ARGS e;
281 std::stringstream expstr;
282 expstr << "ConfigFEMBFakeData: iFEMB should be between 1 and 4: "
283 << int(iFEMB);
284 e.Append(expstr.str().c_str());
285 throw e;
286 }
287 if (start_frame_mode_sel > 1 || start_frame_swap > 1)
288 {
289 BUException::WIB_BAD_ARGS e;
290 std::stringstream expstr;
291 expstr << "ConfigFEMBFakeData: start_frame_mode_sel and start_frame_swap must be 0 or 1";
292 e.Append(expstr.str().c_str());
293 throw e;
294 }
295 if (fake_mode == 1 && fake_word > 0xFFF)
296 {
297 BUException::WIB_BAD_ARGS e;
298 std::stringstream expstr;
299 expstr << "ConfigFEMBFakeData: fake_word must be only 12 bits i.e. <= 4095, is: "
300 << fake_word;
301 e.Append(expstr.str().c_str());
302 throw e;
303 }
304 if (fake_mode == 2 && fake_samples.size() != 256)
305 {
306 BUException::WIB_BAD_ARGS e;
307 std::stringstream expstr;
308 expstr << "ConfigFEMBFakeData: femb_samples must be 255 long, is: "
309 << fake_samples.size();
310 e.Append(expstr.str().c_str());
311 throw e;
312 }
313 if (fake_mode == 3 && femb_number > 0xF)
314 {
315 BUException::WIB_BAD_ARGS e;
316 std::stringstream expstr;
317 expstr << "ConfigFEMBFakeData: femb_number must be only 4 bits i.e. <= 15, is: "
318 << int(femb_number);
319 e.Append(expstr.str().c_str());
320 throw e;
321 }
322
323 // get this register so we can leave it in the state it started in
324 uint32_t slow_control_dnd = Read("SYSTEM.SLOW_CONTROL_DND");
325 Write("SYSTEM.SLOW_CONTROL_DND",1);
326
327 WriteFEMB(iFEMB, "REG_RESET", 1);
328 sleep(1);
329
330 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 0);
331 sleep(1);
332
333 WriteFEMB(iFEMB, "START_FRAME_MODE_SELECT", start_frame_mode_sel);
334 sleep(1);
335 WriteFEMB(iFEMB, "START_FRAME_SWAP", start_frame_swap);
336 sleep(0.05);
337
338 //time stamp reset
339 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
340 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
341
342 // Now do the Fake data mode setup
343 if (fake_mode == 1)
344 {
345 WriteFEMB(iFEMB, "DATA_TEST_PATTERN", fake_word);
346 }
347 if (fake_mode == 2)
348 {
349 // Put waveform in FEMB registers
350 for (size_t iSample=0; iSample < 256; iSample++)
351 {
352 WriteFEMB(iFEMB,0x300+iSample,fake_samples.at(iSample));
353 sleep(0.005);
354 }
355 }
356 if (fake_mode == 3)
357 {
358 WriteFEMB(iFEMB, "FEMB_NUMBER", femb_number);
359 }
360 WriteFEMB(iFEMB, "FEMB_TST_SEL", fake_mode);
361
362 //time stamp reset
363 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
364 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
365
366 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 9);
367
368 Write("SYSTEM.SLOW_CONTROL_DND",slow_control_dnd);
369}

◆ ConfigFEMBMode()

void WIB::ConfigFEMBMode ( uint8_t iFEMB,
uint32_t pls_cs,
uint32_t dac_sel,
uint32_t fpga_dac,
uint32_t asic_dac,
uint32_t mon_cs = 0 )

Definition at line 1126 of file WIB_FEMB.cpp.

1126 {
1127 uint32_t tp_sel;
1128 if (mon_cs == 0){
1129 tp_sel = ((asic_dac & 0x01) << 1) + (fpga_dac & 0x01) + ((dac_sel&0x1)<<8);
1130 }
1131 else{
1132 tp_sel = 0x402;
1133 }
1134 WriteFEMB(iFEMB, 16, tp_sel & 0x0000FFFF);
1135 WriteFEMB(iFEMB, 18, 0x11);
1136 uint32_t pls_cs_value = 0x00;
1137 if (pls_cs == 0) pls_cs_value = 0x11;//disable all
1138 else if (pls_cs == 1) pls_cs_value = 0x10;//internal pls
1139 else if (pls_cs == 2) pls_cs_value = 0x01;//external pls
1140
1141 WriteFEMB(iFEMB, 18, pls_cs_value);
1142}

◆ ConfigureDTSCDS()

float WIB::ConfigureDTSCDS ( uint8_t source = 0)

Definition at line 24 of file WIB_CDS.cpp.

24 {
25 if(source > 1){
26 BUException::WIB_BAD_ARGS e;
27 e.Append("Bad DTS CDS clock source");
28 throw e;
29 }
30
31 //Set timing system source (FP:0 BP:1)
32 WriteWithRetry("DTS.CDS.INPUT_SELECT",source);
33
34 //Reset the I2C firmware
35 WriteWithRetry("DTS.CDS.I2C.RESET",1);
36 //Reset the CDS chip (ADN2814)
37 WriteDTS_CDS(0x9,0x20,1);
38 usleep(500000);
39
40 //Reset the I2C firmware
41 WriteWithRetry("DTS.CDS.I2C.RESET",1);
42 //Un reset
43 WriteDTS_CDS(0x9,0x00,1,true);
44 //Reset the I2C firmware
45 WriteWithRetry("DTS.CDS.I2C.RESET",1);
46 usleep(1000000);
47
48 //read bits 8 downto 1 from reg 3
49 uint16_t dataRateLookup = uint16_t(ReadDTS_CDS(0x3,1)) << 1;
50 //Read bit 0 from reg 4
51 dataRateLookup |= uint16_t(ReadDTS_CDS(0x4,1))&0x1;
52 if(dataRateLookup >=COURSE_DATARATE_SIZE){
53 return -1;
54 }
55 return courseDataRates[dataRateLookup];
56}
static float courseDataRates[COURSE_DATARATE_SIZE]
Definition WIB_CDS.cpp:7
#define COURSE_DATARATE_SIZE
Definition WIB_CDS.cpp:6
uint32_t ReadDTS_CDS(uint16_t address, uint8_t byte_count=4)
Definition WIB_CDS.cpp:20
void WriteDTS_CDS(uint16_t address, uint32_t value, uint8_t byte_count=4, bool ignore_error=false)
Definition WIB_CDS.cpp:17

◆ ConfigWIBFakeData()

void WIB::ConfigWIBFakeData ( bool enableFakeFEMB1,
bool enableFakeFEMB2,
bool enableFakeFEMB3,
bool enableFakeFEMB4,
bool counter )

Definition at line 4 of file WIB_FAKE_CD.cpp.

6 { // counter==true: counter instead of COLDATA frame, else samples in COLDATA frame
7
8 if(DAQMode == FELIX){
9 //Don't allow fake mode on only half of a FELIX link
10 if ((enableFakeFEMB1 ^ enableFakeFEMB2) || (enableFakeFEMB3 ^ enableFakeFEMB4)) {
11 BUException::WIB_FAKE_DATA_ON_HALF_FELIX_LINK e;
12 throw e;
13 }
14 }
15
16 //Setup the FEMBs/Links
17 for(size_t iFEMB = 1; iFEMB <= FEMBCount; iFEMB++){
18 for(size_t iCDA = 1; iCDA <= FEMBCDACount; iCDA++){
19 SetFEMBFakeCOLDATAMode(iFEMB, iCDA, counter);
20 }
21 }
22
23 for(size_t iStream = 1; iStream <= FEMBStreamCount; iStream++){
24 SetFEMBStreamSource(1, iStream, !enableFakeFEMB1);
25 SetFEMBStreamSource(2, iStream, !enableFakeFEMB2);
26 SetFEMBStreamSource(3, iStream, !enableFakeFEMB3);
27 SetFEMBStreamSource(4, iStream, !enableFakeFEMB4);
28 }
29
30 uint64_t enableWord1 = 0;
31 uint64_t enableWord2 = 0;
32 uint64_t enableWord3 = 0;
33 uint64_t enableWord4 = 0;
34 if (enableFakeFEMB1) enableWord1 = 0xF;
35 if (enableFakeFEMB2) enableWord2 = 0xF;
36 if (enableFakeFEMB3) enableWord3 = 0xF;
37 if (enableFakeFEMB4) enableWord4 = 0xF;
38 SourceFEMB(1,enableWord1);
39 SourceFEMB(2,enableWord2);
40 SourceFEMB(3,enableWord3);
41 SourceFEMB(4,enableWord4);
42}
void SetFEMBStreamSource(uint8_t iFEMB, uint8_t iStream, bool real=true)
void SourceFEMB(uint64_t iDAQLink, uint64_t real)
Definition WIB.cpp:626
void SetFEMBFakeCOLDATAMode(uint8_t iFEMB, uint8_t iCD, bool mode=0)

◆ DisableFEMBCNC()

void WIB::DisableFEMBCNC ( )

Definition at line 503 of file WIB.cpp.

503 {
504 //Enable the clock and control stream to the FEMBs
505 Write("FEMB_CNC.CNC_CLOCK_SELECT",0);
506 Write("FEMB_CNC.CNC_COMMAND_SELECT",0);
507}

◆ EnableDAQLink()

void WIB::EnableDAQLink ( uint8_t iDAQLink)

Definition at line 51 of file WIB.cpp.

51 {
52 //CHeck if we know how to dael with this firmware
53 if(!((DAQMode == RCE)||(DAQMode == FELIX))){
54 //Not RCE or FELIX firmware, return
55 BUException::WIB_FEATURE_NOT_SUPPORTED e;
56 e.Append("Automatic DAQLink configuration not supported with this firmware.\n");
57 throw e;
58 }
59
60 //Build the base string for this DAQLINK
61 std::string base("DAQ_LINK_");
62 base.push_back(GetDAQLinkChar(iDAQLink));
63 base.append(".CONTROL.");
64 printf("%s\n",base.c_str());
65
66 //set the CD stream enable mask from that
67 uint32_t enable_mask = 0;
68 for(size_t iStream = 0; iStream < (4 * FEMBCount/DAQLinkCount);iStream++){
69 enable_mask <<= 0x1;
70 }
71
72 Write(base+"ENABLE_CDA_STREAM",enable_mask);
73
74 Write(base+"ENABLE",0x1);
75}
char GetDAQLinkChar(uint8_t iDAQLink)
Definition WIB.cpp:518

◆ EnableDAQLink_Lite()

void WIB::EnableDAQLink_Lite ( uint8_t iDAQLink,
uint8_t enable )

Definition at line 77 of file WIB.cpp.

77 {
78 //CHeck if we know how to dael with this firmware
79 if(!((DAQMode == RCE)||(DAQMode == FELIX))){
80 //Not RCE or FELIX firmware, return
81 BUException::WIB_FEATURE_NOT_SUPPORTED e;
82 e.Append("Automatic DAQLink configuration not supported with this firmware.\n");
83 throw e;
84 }
85
86 //Build the base string for this DAQLINK
87 std::string base("DAQ_LINK_");
88 base.push_back(GetDAQLinkChar(iDAQLink));
89 base.append(".CONTROL.");
90
91 uint8_t stream = 0;
92 if(enable){
93 if(DAQMode == RCE) stream = 0xF;
94 else stream = 0xFF;
95 }
96
97 Write(base+"ENABLE_CDA_STREAM",stream);
98 Write(base+"ENABLE",enable);
99}

◆ EnableFEMBCNC()

void WIB::EnableFEMBCNC ( )

Definition at line 498 of file WIB.cpp.

498 {
499 //Enable the clock and control stream to the FEMBs
500 Write("FEMB_CNC.CNC_CLOCK_SELECT",1);
501 Write("FEMB_CNC.CNC_COMMAND_SELECT",1);
502}

◆ EraseFlash()

void WIB::EraseFlash ( bool print_updates = false)

Definition at line 190 of file WIB_Flash.cpp.

190 {
191 if(print_updates){
192 fprintf(stderr," Erase flash\n");
193 }
194 WriteWithRetry("FLASH.RUN_COMMAND",0x7);
195 size_t iTimeout = FLASH_TIMEOUT;
196 while(ReadWithRetry("FLASH.BUSY") && (iTimeout != 0)){
197 iTimeout--;
198 usleep(100000);
199 }
200 if(iTimeout == 0){
201 BUException::WIB_FLASH_TIMEOUT e;
202 //throw an exception
203 e.Append("Program (erase): FLASH.BUSY");
204 throw e;
205 //throw an exception
206 }
207}
#define FLASH_TIMEOUT
Definition WIB_Flash.cpp:7

◆ FEMBPower()

void WIB::FEMBPower ( uint8_t iFEMB,
bool turnOn )

Definition at line 456 of file WIB.cpp.

456 {
457 std::string reg = "POWER.ENABLE.FEMB";
458 reg.push_back(GetFEMBChar(iFEMB));
459 if(turnOn){
460 Write(reg,0x1F);
461 }else{
462 Write(reg,0x0);
463 }
464}
char GetFEMBChar(uint8_t iFEMB)
Definition WIB.cpp:556

◆ FlashCheckBusy()

void WIB::FlashCheckBusy ( )

Definition at line 362 of file WIB_Flash.cpp.

362 {
363 size_t iTimeout = FLASH_TIMEOUT;
364 while(ReadWithRetry("FLASH.BUSY") && (iTimeout != 0)){
365 iTimeout--;
366 usleep(10000);
367 }
368 if(iTimeout == 0){
369 BUException::WIB_FLASH_TIMEOUT e;
370 //throw an exception
371 e.Append("Read: FLASH.BUSY");
372 throw e;
373 }
374}

◆ FullStart()

void WIB::FullStart ( )

Definition at line 35 of file WIB.cpp.

35 {
36 //Figure out what kind of WIB firmware we are dealing with
37 FEMBCount = Read("SYSTEM.FEMB_COUNT");
38 DAQLinkCount = Read("SYSTEM.DAQ_LINK_COUNT");
39 //Hardcoded lookup for RCE and FELIX
40 if((FEMBCount == 4) && (DAQLinkCount == 4)){
41 DAQMode = RCE;
42 }else if((FEMBCount == 4) && (DAQLinkCount == 2)){
43 DAQMode = FELIX;
44 }
45 //TODO check FEMBStreamCount and FEMCDACount from registers on the WIB
46 //TODO create those registers
47 Write("POWER.ENABLE.MASTER_BIAS",1);
48 started = true;
49}

◆ GetDAQ_SI5342AddressPage()

uint8_t WIB::GetDAQ_SI5342AddressPage ( uint16_t address)

Definition at line 30 of file WIB_SI5342.cpp.

30 {
31 return uint8_t((address >> 8)&0xFF);
32}

◆ GetDAQ_SI5342Page()

uint8_t WIB::GetDAQ_SI5342Page ( )

Definition at line 26 of file WIB_SI5342.cpp.

26 {
27 return uint8_t(ReadDAQ_SI5342(0x1,1)&0xFF);
28}
uint32_t ReadDAQ_SI5342(uint16_t address, uint8_t byte_count=4)

◆ GetDAQLinkChar()

char WIB::GetDAQLinkChar ( uint8_t iDAQLink)

Definition at line 518 of file WIB.cpp.

518 {
519 char c = '0';
520 //Check if the link is in range given DAQLinkCount (throws)
521 CheckDAQLinkInRange(iDAQLink);
522 //Convert the numeric daq link number to a char
523 switch (iDAQLink){
524 case 1:
525 c = '1';
526 break;
527 case 2:
528 c = '2';
529 break;
530 case 3:
531 c = '3';
532 break;
533 case 4:
534 c = '4';
535 break;
536 default:
537 BUException::WIB_INDEX_OUT_OF_RANGE e;
538 e.Append("DAQ Link\n");
539 char estr[] = "0";
540 estr[0] = c;
541 e.Append(estr);
542 throw e;
543 }
544 return c;
545}
bool CheckDAQLinkInRange(uint8_t iDAQLink)
Definition WIB.cpp:509

◆ GetDAQMode()

WIB_DAQ_t WIB::GetDAQMode ( )
inline

Definition at line 219 of file WIB.hh.

219{return DAQMode;}

◆ GetDTS_SI5344AddressPage()

uint8_t WIB::GetDTS_SI5344AddressPage ( uint16_t address)

Definition at line 30 of file WIB_SI5344.cpp.

30 {
31 return uint8_t((address >> 8)&0xFF);
32}

◆ GetDTS_SI5344Page()

uint8_t WIB::GetDTS_SI5344Page ( )

Definition at line 26 of file WIB_SI5344.cpp.

26 {
27 return uint8_t(ReadDTS_SI5344(0x1,1)&0xFF);
28}
uint32_t ReadDTS_SI5344(uint16_t address, uint8_t byte_count=4)

◆ GetEventBuilderDebugMode()

uint8_t WIB::GetEventBuilderDebugMode ( )

◆ GetFEMBCDChar()

char WIB::GetFEMBCDChar ( uint8_t iCD)

Definition at line 603 of file WIB.cpp.

603 {
604 char c = '0';
605 //Check if the link is in range given FEMBCount (throws)
607 //Convert the numeric daq link number to a char
608 switch (iCD){
609 case 1:
610 c = '1';
611 break;
612 case 2:
613 c = '2';
614 break;
615 default:
616 BUException::WIB_INDEX_OUT_OF_RANGE e;
617 e.Append("FEMB CDA\n");
618 char estr[] = "0";
619 estr[0] = c;
620 e.Append(estr);
621 throw e;
622 }
623 return c;
624}
bool CheckFEMBCDInRange(uint8_t iCD)
Definition WIB.cpp:594

◆ GetFEMBChar()

char WIB::GetFEMBChar ( uint8_t iFEMB)

Definition at line 556 of file WIB.cpp.

556 {
557 char c = '0';
558 //Check if the link is in range given FEMBCount (throws)
559 CheckFEMBInRange(iFEMB);
560 //Convert the numeric daq link number to a char
561 switch (iFEMB){
562 case 1:
563 c = '1';
564 break;
565 case 2:
566 c = '2';
567 break;
568 case 3:
569 c = '3';
570 break;
571 case 4:
572 c = '4';
573 break;
574 default:
575 BUException::WIB_INDEX_OUT_OF_RANGE e;
576 e.Append("FEMB\n");
577 char estr[] = "0";
578 estr[0] = c;
579 e.Append(estr);
580 throw e;
581 }
582 return c;
583}
bool CheckFEMBInRange(uint8_t iFEMB)
Definition WIB.cpp:547

◆ GetFEMBCount()

uint8_t WIB::GetFEMBCount ( )
inline

Definition at line 218 of file WIB.hh.

218{return FEMBCount;}

◆ GetFEMBFakeCOLDATAMode()

uint8_t WIB::GetFEMBFakeCOLDATAMode ( uint8_t iFEMB,
uint8_t iCD )

Definition at line 77 of file WIB_FAKE_CD.cpp.

77 {
78 std::string base("FEMB0.DAQ.FAKE_CD.CD0.");
79 base[4] = GetFEMBChar(iFEMB);
80 base[20] = GetFEMBCDChar(iCD);
81
82 return Read(base+"FAKE_MODE");
83}
char GetFEMBCDChar(uint8_t iCD)
Definition WIB.cpp:603

◆ GetFEMBStreamSource()

uint8_t WIB::GetFEMBStreamSource ( uint8_t iFEMB,
uint8_t iStream )

Definition at line 44 of file WIB_FAKE_CD.cpp.

44 {
46 std::string base = "FEMB0.DAQ.FAKE_CD.RX_DATA_SOURCE";
47 base[4] = GetFEMBChar(iFEMB);
48 //Read the current settings
49 uint32_t data = Read(base);
50 return (data >> (iStream -1))&0x1;
51}
bool CheckFEMBStreamInRange(uint8_t iStream)
Definition WIB.cpp:585

◆ HuntFEMBPhase()

bool WIB::HuntFEMBPhase ( uint8_t iFEMB,
uint16_t clk_phase_data_start )

Definition at line 1061 of file WIB_FEMB.cpp.

1061 {
1062 uint32_t clk_phase_data0 = (clk_phase_data_start >> 8) & 0xFF;
1063 uint32_t clk_phase_data1 = clk_phase_data_start & 0xFF;
1064 uint32_t adc_fifo_sync = 1;
1065
1066 uint32_t a_cs[8] = {
1067 0xc000, 0x3000, 0x0c00, 0x0300,
1068 0x00c0, 0x0030, 0x000c, 0x0003};
1069
1070 uint32_t a_mark[8] = {
1071 0x80, 0x40, 0x20, 0x10,
1072 0x08, 0x04, 0x02, 0x01};
1073
1074 uint32_t a_cnt[8] = {
1075 0,0,0,0,
1076 0,0,0,0};
1077
1078 while (adc_fifo_sync){
1079 sleep(0.001);
1080 adc_fifo_sync = (ReadFEMB(iFEMB, 6) & 0xFFFF0000) >> 16;
1081 sleep(0.001);
1082 adc_fifo_sync = (ReadFEMB(iFEMB, 6) & 0xFFFF0000) >> 16;
1083 sleep(0.001);
1084
1085 std::cout << "FEMB " << int(iFEMB) << " ADC FIFO sync: " << std::bitset<16>(adc_fifo_sync) << std::endl;
1086
1087 if (adc_fifo_sync == 0){
1088 std::cout << "FEMB " << int(iFEMB) << " Successful SPI config and ADC FIFO synced" << std::endl;
1089 //std::cout << " ADC_ASIC_CLK_PHASE_SELECT: " << std::hex << std::setw(2) << std::setfill('0') << clk_phase_data0 << std::endl;
1090 //std::cout << " ADC_ASIC_CLK_PHASE_SELECT_2: " << std::hex << std::setw(2) << std::setfill('0') << clk_phase_data1 << std::endl;
1091 std::cout << " phase: " << std::hex << std::setw(2) << std::setfill('0') << clk_phase_data0;
1092 std::cout << std::hex << std::setw(2) << std::setfill('0') << clk_phase_data1 << std::endl;
1093 return true;
1094 }
1095 else{
1096 std::cout << "ERROR: sync not zero: " << std::bitset<16>(adc_fifo_sync) << std::endl;
1097 for(int i = 0; i < 8; ++i){
1098 uint32_t a = adc_fifo_sync & a_cs[i];
1099 uint32_t a_mark_xor = 0;
1100 if (a != 0){
1101 a_cnt[i]++;
1102 a_mark_xor = a_mark[i] ^ 0xFF;
1103 if (a_cnt[i] == 1 || a_cnt[i] == 3){
1104 clk_phase_data0 = ((clk_phase_data0 & a_mark[i]) ^ a_mark[i]) + (clk_phase_data0 & a_mark_xor);
1105 }
1106 else if (a_cnt[i] == 2 || a_cnt[i] == 4){
1107 clk_phase_data1 = ((clk_phase_data1 & a_mark[i]) ^ a_mark[i]) + (clk_phase_data1 & a_mark_xor);
1108 }
1109 else if (a_cnt[i] >= 5){
1110 return false;
1111 }
1112 }
1113 else{
1114 continue;
1115 }
1116 }
1117 uint16_t clk_phase_to_write=0;
1118 clk_phase_to_write |= (clk_phase_data0 & 0xFF) << 8;
1119 clk_phase_to_write |= clk_phase_data1;
1120 WriteFEMBPhase(iFEMB,clk_phase_to_write);
1121 }
1122 }
1123 return false;
1124}
void WriteFEMBPhase(uint8_t iFEMB, uint16_t clk_phase_data)
Definition WIB_FEMB.cpp:943

◆ InitializeDTS()

void WIB::InitializeDTS ( uint8_t PDTSsource = 0,
uint8_t clockSource = 0,
uint32_t PDTSAlignment_timeout = 0 )

Definition at line 12 of file WIB_DTS.cpp.

12 {
13 //Disable the PDTS
14 WriteWithRetry("DTS.PDTS_ENABLE",0x0);
15
16 //Disable SI5344 outputs (fixed by SI5344 config)
17 WriteWithRetry("DTS.SI5344.ENABLE",0);
18 //Disable SI5344 (fixed by SI5344 config)
19 WriteWithRetry("DTS.SI5344.RESET",1);
20
21
22 //Reset the I2C firmware
23 WriteWithRetry("DTS.CDS.I2C.RESET",1);
24
25
26 if(0 == clockSource){
27 printf("Using PDTS for DUNE timing.\n\nConfiguring clock and data separator\n");
28 //Bring up the CDS
29 float frequency = 0;
30 try{
31 frequency = ConfigureDTSCDS(PDTSsource);
32 }catch(BUException::exBase & e){
33 frequency = 0;
34 e.Append("Failed to communicate with the DTS CDS via I2C\n");
35 throw;
36 }
37 uint32_t LOL = Read("DTS.CDS.LOL");
38 uint32_t LOS = Read("DTS.CDS.LOS");
39 printf("CDS frequency %f\n",frequency);
40 printf("CDS LOL=%d LOS=%d\n",LOL,LOS);
41
42 //Check for the correct frequency, not in LOS, and not in LOL
43 // if( (2.4136e+08 == frequency) &&
44 if(LOL || LOS){
45 BUException::WIB_DTS_ERROR e;
46 e.Append("Failed to configure CDS chip\n");
47 throw e;
48 }
49 }else{
50 printf("Using local OSC for DUNE timing\n");
51 }
52 //CDS is up
53
54
55 printf("\nConfiguring SI5344.\n");
56
57 //Set the SI5344 source
58 WriteWithRetry("DTS.SI5344.INPUT_SELECT",clockSource);
59 //Configure Si5344 with default config file
60 //Do the I2C configuration
61 try{
63 }catch(BUException::exBase & e){
64 //Disable SI5344 outputs
65 WriteWithRetry("DTS.SI5344.ENABLE",0);
66 //Disable SI5344
67 WriteWithRetry("DTS.SI5344.RESET",1);
68
69 e.Append("Error in LoadConfigDTS_SI5344\n");
70 throw;
71 }
72
73 usleep(100000);
74
75 //Check that SI5344 is locked on
76 if(ReadWithRetry("DTS.SI5344.LOS") ||
77 ReadWithRetry("DTS.SI5344.LOL")){
78 //Disable SI5344 outputs
79 WriteWithRetry("DTS.SI5344.ENABLE",0);
80 //Disable SI5344
81 WriteWithRetry("DTS.SI5344.RESET",1);
82
83 //Throw
84 BUException::WIB_DTS_ERROR e;
85 e.Append("Failed to configure the SI5344 chip correctly\n");
86 throw e;
87 }
88
89 //Enable the clock for FPGA
90 WriteWithRetry("DTS.SI5344.ENABLE",1);
91 usleep(100000);
92
93 char const * const PDTSStates[] = {"W_RST",
94 "W_LINK",
95 "W_FREQ",
96 "W_ADJUST",
97 "W_ALIGN",
98 "W_LOCK",
99 "W_PHASE",
100 "W_RDY",
101 "RUN",
102 "0x9",
103 "0xA",
104 "0xB",
105 "ERR_R",
106 "ERR_T",
107 "ERR_P",
108 "0xF"};
109
110
111 if(0 == clockSource){
112 printf("\nSetup PDTS.\n");
113 bool timeout_exists = true;
114 if (PDTSAlignment_timeout == 0)
115 timeout_exists = false;
116
117 auto start_time = std::chrono::high_resolution_clock::now();
118 bool timed_out = false;
119
120 while ((timeout_exists == false) || timed_out == false) {
121 //Using PDTS, set that up.
122 usleep(500000);
123 WriteWithRetry("DTS.PDTS_ENABLE",1);
124 usleep(500000); //needed in new PDTS system to get to a good state before giving up and trying a new phase.
125
126 //See if we've locked
127 uint32_t pdts_state = ReadWithRetry("DTS.PDTS_STATE");
128 printf("PDTS state: %s (0x%01X)\n",PDTSStates[pdts_state&0xF],pdts_state);
129 if ((pdts_state < 0x6) || (pdts_state > 0x8)) {
130 WriteWithRetry("DTS.PDTS_ENABLE",0);
131 //dynamic post-amble
132 Write("DTS.SI5344.I2C.RESET",1);
134 Write("DTS.SI5344.I2C.RESET",1);
135 WriteDTS_SI5344(0x1C,0x1,1);
136 }
137 else if(0x6 == pdts_state){
138 ers::info(dunedaq::wibmod::WaitingForAlignment(ERS_HERE));
139 }
140 else if(0x7 == pdts_state){
141 ers::info(dunedaq::wibmod::WaitingForTimestamp(ERS_HERE));
142 }
143 else {
144 return; //0x8 == pdts_state
145 }
146 auto now = std::chrono::high_resolution_clock::now();
147 auto duration = now - start_time;
148 if ( duration.count() > PDTSAlignment_timeout)
149 timed_out = true;
150 }
151 //If we get here something went wrong
152 Write("DTS.SI5344.I2C.RESET",1);
154 Write("DTS.SI5344.I2C.RESET",1);
155 WriteDTS_SI5344(0x1C,0x1,1);
156
157 BUException::WIB_DTS_ERROR e;
158 e.Append("Failed to configure the PDTS correctly within timeout\n");
159 throw e;
160 }
161}
#define ERS_HERE
void Append(const char *buffer)
void SetDTS_SI5344Page(uint8_t page)
void WriteDTS_SI5344(uint16_t address, uint32_t value, uint8_t byte_count=4)
Definition WIB_SI5344.cpp:8
float ConfigureDTSCDS(uint8_t source=0)
Definition WIB_CDS.cpp:24
static int64_t now()
Cannot add TPSet with start_time
void info(const Issue &issue)
Definition ers.hpp:95

◆ InitializeWIB()

void WIB::InitializeWIB ( )

Definition at line 130 of file WIB.cpp.

130 {
131 //run resets
132 Write("SYSTEM.RESET",0xFF);
133 //Set clock settings
134 Write("POWER.ENABLE.MASTER_BIAS",0x1);//Turn on DC/DC converter
135}

◆ LoadConfigDAQ_SI5342()

void WIB::LoadConfigDAQ_SI5342 ( std::string const & fileName)

Definition at line 34 of file WIB_SI5342.cpp.

34 {
35 std::ifstream confFile(fileName.c_str());
36 BUException::WIB_BAD_ARGS badFile;
37
38 if(confFile.fail()){
39 //Failed to topen filename, add it to the exception
40 badFile.Append("Bad SI5342 config file name:");
41 badFile.Append(fileName.c_str());
42
43 //Try the default
44 if(getenv("WIBMOD_SHARE") != NULL){
45 std::string envBasedFileName=getenv("WIBMOD_SHARE");
46 envBasedFileName+="/config/WIB1/config/";
47 envBasedFileName+=SI5342_CONFIG_FILENAME;
48 confFile.open(envBasedFileName.c_str());
49 if(confFile.fail()){
50 badFile.Append("Bad env based filename:");
51 badFile.Append(envBasedFileName.c_str());
52 }
53 }
54 }
55
56 if(confFile.fail()){
57 //We are still failing to open our file
58 throw badFile;
59 }
60
61 //Make sure the chip isn't in reset
62 if(Read("DAQ.SI5342.RESET") != 0){
63 Write("DAQ.SI5342.RESET",0x0);
64 usleep(50000);
65 }
66
67 //Reset the I2C firmware
68 Write("DAQ.SI5342.I2C.RESET",1);
69
70 std::vector<std::pair<uint16_t,uint8_t> > writes;
71 while(!confFile.eof()){
72 std::string line;
73 std::getline(confFile,line);
74 if(line.size() == 0){
75 continue;
76 }else if(line[0] == '#'){
77 continue;
78 }else if(line[0] == 'A'){
79 continue;
80 }else{
81 if( line.find(',') == std::string::npos ){
82 printf("Skipping bad line: \"%s\"\n",line.c_str());
83 continue;
84 }
85 uint16_t address = strtoul(line.substr(0,line.find(',')).c_str(),NULL,16);
86 uint8_t data = strtoul(line.substr(line.find(',')+1).c_str(),NULL,16);
87 writes.push_back(std::pair<uint16_t,uint8_t>(address,data));
88 }
89 }
90
91 //Disable the SI5342 output
92 Write("DAQ.SI5342.ENABLE",0x0);
93
94 uint8_t page = GetDAQ_SI5342Page();
95 unsigned int percentDone = 0;
96
97
98 printf("\n[==================================================]\n");
99 fprintf(stderr," ");
100 for(size_t iWrite = 0; iWrite < writes.size();iWrite++){
101
102 if(page != GetDAQ_SI5342AddressPage(writes[iWrite].first)){
103 page = GetDAQ_SI5342AddressPage(writes[iWrite].first);
104 SetDAQ_SI5342Page(page);
105 usleep(100000);
106 }
107
108
109 if(iWrite == 3){
110 usleep(300000);
111 }
112
113
114 uint8_t address = writes[iWrite].first & 0xFF;
115 uint32_t data = (writes[iWrite].second) & 0xFF;
116 uint8_t iData = 1;
117
118 for(size_t iTries = 10; iTries > 0;iTries--){
119 try{
120 WriteDAQ_SI5342(address ,data,iData);
121 }catch (BUException::WIB_ERROR & e){
122 //Reset the I2C firmware
123 Write("DAQ.SI5342.I2C.RESET",1);
124 if(iTries == 1){
125 e.Append("\nTried 3 times\n");
126 throw;
127 }
128 }
129 }
130 if((100*iWrite)/writes.size() > percentDone){
131 fprintf(stderr,"#");
132 percentDone+=2;
133 }
134 }
135 printf("\n");
136
137}
#define SI5342_CONFIG_FILENAME
Definition WIB_SI5342.cpp:6
uint8_t GetDAQ_SI5342Page()
uint8_t GetDAQ_SI5342AddressPage(uint16_t address)
void WriteDAQ_SI5342(uint16_t address, uint32_t value, uint8_t byte_count=4)
Definition WIB_SI5342.cpp:8
void SetDAQ_SI5342Page(uint8_t page)

◆ LoadConfigDTS_SI5344()

void WIB::LoadConfigDTS_SI5344 ( std::string const & fileName)

Definition at line 34 of file WIB_SI5344.cpp.

34 {
35 std::ifstream confFile(fileName.c_str());
36 BUException::WIB_BAD_ARGS badFile;
37
38 if(confFile.fail()){
39 //Failed to topen filename, add it to the exception
40 badFile.Append("Bad SI5344 config file name:");
41 badFile.Append(fileName.c_str());
42
43 //Try the default
44 if(getenv("WIBMOD_SHARE") != NULL){
45 std::string envBasedFileName=getenv("WIBMOD_SHARE");
46 envBasedFileName+="/config/WIB1/config/";
47 envBasedFileName+=SI5344_CONFIG_FILENAME;
48 confFile.open(envBasedFileName.c_str());
49 if(confFile.fail()){
50 badFile.Append("Bad env based filename:");
51 badFile.Append(envBasedFileName.c_str());
52 }
53 }
54 }
55
56 if(confFile.fail()){
57 //We are still failing to open our file
58 throw badFile;
59 }
60
61 //Make sure the chip isn't in reset
62 if(Read("DTS.SI5344.RESET") != 0){
63 Write("DTS.SI5344.RESET",0x0);
64 usleep(50000);
65 }
66
67 //Reset the I2C firmware
68 Write("DTS.SI5344.I2C.RESET",1);
69
70 std::vector<std::pair<uint16_t,uint8_t> > writes;
71 while(!confFile.eof()){
72 std::string line;
73 std::getline(confFile,line);
74 if(line.size() == 0){
75 continue;
76 }else if(line[0] == '#'){
77 continue;
78 }else if(line[0] == 'A'){
79 continue;
80 }else{
81 if( line.find(',') == std::string::npos ){
82 printf("Skipping bad line: \"%s\"\n",line.c_str());
83 continue;
84 }
85 uint16_t address = strtoul(line.substr(0,line.find(',')).c_str(),NULL,16);
86 uint8_t data = strtoul(line.substr(line.find(',')+1).c_str(),NULL,16);
87 writes.push_back(std::pair<uint16_t,uint8_t>(address,data));
88 }
89 }
90
91 //Disable the SI5344 output
92 Write("DTS.SI5344.ENABLE",0x0);
93
94 uint8_t page = GetDTS_SI5344Page();
95 unsigned int percentDone = 0;
96
97
98 printf("\n[==================================================]\n");
99 fprintf(stderr," ");
100 for(size_t iWrite = 0; iWrite < writes.size();iWrite++){
101
102 if(page != GetDTS_SI5344AddressPage(writes[iWrite].first)){
103 page = GetDTS_SI5344AddressPage(writes[iWrite].first);
104 SetDTS_SI5344Page(page);
105 usleep(100000);
106 }
107
108
109 if(iWrite == 3){
110 usleep(300000);
111 }
112
113
114 uint8_t address = writes[iWrite].first & 0xFF;
115 uint32_t data = (writes[iWrite].second) & 0xFF;
116 uint8_t iData = 1;
117
118 for(size_t iTries = 10; iTries > 0;iTries--){
119 try{
120 WriteDTS_SI5344(address ,data,iData);
121 }catch (BUException::WIB_ERROR & e){
122 //Reset the I2C firmware
123 Write("DTS.SI5344.I2C.RESET",1);
124 if(iTries == 1){
125 e.Append("\nTried 10 times\n");
126 throw;
127 }
128 }
129 }
130 if((100*iWrite)/writes.size() > percentDone){
131 fprintf(stderr,"#");
132 percentDone+=2;
133 }
134 }
135 printf("\n");
136}
#define SI5344_CONFIG_FILENAME
Definition WIB_SI5344.cpp:6
uint8_t GetDTS_SI5344AddressPage(uint16_t address)
uint8_t GetDTS_SI5344Page()

◆ operator=()

WIB & WIB::operator= ( const WIB & )
private

◆ PDTSInRunningState()

void WIB::PDTSInRunningState ( )

Definition at line 169 of file WIB_DTS.cpp.

169 {
170 if(Read("DTS.PDTS_STATE") != 0x8){
171 BUException::WIB_DTS_ERROR e;
172 e.Append("WIB is not in PDTS state RUN(0x8)\n");
173 throw e;
174 }
175}

◆ ProgramFlash()

void WIB::ProgramFlash ( std::string const & fileName,
uint8_t update_percentage = 101 )

Definition at line 209 of file WIB_Flash.cpp.

209 {
210 WriteWithRetry("SYSTEM.SLOW_CONTROL_DND",1);
211
212 bool print_updates = false;
213 if(update_percentage < 100){
214 print_updates = true;
215 }
216
217 //Load data and validate
218 if(print_updates){
219 fprintf(stderr," Reading file: %s\n",fileName.c_str());
220 }
221 // std::vector<uint32_t> flashData = firmwareFromDumpFile(fileName);
222 std::vector<uint32_t> flashData = firmwareFromIntelHexFile(fileName);
223
224 //erase flash
225 EraseFlash(print_updates);
226
227 //Load data into flash.
228 WriteFlash(flashData,update_percentage);
229
230
231 //Validate flash
232 CheckFlash(flashData,update_percentage);
233 WriteWithRetry("SYSTEM.SLOW_CONTROL_DND",0);
234}
static std::vector< uint32_t > firmwareFromIntelHexFile(std::string const &iHexFileName)
Definition WIB_Flash.cpp:93
void EraseFlash(bool print_updates=false)
void WriteFlash(std::vector< uint32_t > data, uint8_t update_percentage=101)
void CheckFlash(std::vector< uint32_t > data, uint8_t update_percentage=101)

◆ ReadDAQ_SI5342()

uint32_t WIB::ReadDAQ_SI5342 ( uint16_t address,
uint8_t byte_count = 4 )

Definition at line 11 of file WIB_SI5342.cpp.

11 {
12 return ReadI2C("DAQ.SI5342.I2C",address,byte_count);
13}
uint32_t ReadI2C(std::string const &base_address, uint16_t I2C_aaddress, uint8_t byte_count=4)
Definition WIBBase.cpp:39

◆ ReadDAQLinkSpyBuffer()

std::vector< data_8b10b_t > WIB::ReadDAQLinkSpyBuffer ( uint8_t iDAQLink,
uint8_t trigger_mode = 0 )

Definition at line 20 of file WIB_spybuffer.cpp.

20 {
21 //TODO read DAQ link count
22 std::string base("DAQ_LINK_");
23 base.push_back(GetDAQLinkChar(iDAQLink));
24 base.append(".SPY_BUFFER.");
25
26 //Check if there is an active capture
27 if(ReadWithRetry(base+"CAPTURING_DATA")){
28 BUException::WIB_BUSY e;
29 e.Append(base);
30 e.Append(" is busy\n");
31 throw e;
32 }
33 //The spy buffer isn't busy, so let's make sure the fifo is empty
34 while(!ReadWithRetry(base+"EMPTY")){
35 //Read out a workd from the fifo
36 WriteWithRetry(base+"DATA",0x0);
37 }
38
39 //write trigger mode
40 WriteWithRetry(base+"TRIGGER_MODE",trigger_mode & 0x1);
41
42 //Start the capture
43 Write(base+"START",0x1);
44
45 //Wait for capture to finish
46 while(ReadWithRetry(base+"CAPTURING_DATA")){
47 }
48
49 //Read out the data
50 std::vector<data_8b10b_t> ret;
51
52 while(!ReadWithRetry(base+"EMPTY")){
53 //read out the k-chars
54 uint32_t k_data = ReadWithRetry(base+"K_DATA");
55 //read out the data
56 uint32_t data = ReadWithRetry(base+"DATA");
57
58 // printf("0x%08X 0x%08X\n",k_data,data);
59
60 for(size_t iWord = 0; iWord < 4;iWord++){
61 ret.push_back( data_8b10b_t((k_data>>iWord)&0x1,
62 (data >>(iWord*8) &0xFF)));
63 }
64 //mark word as read
65 Write(base+"DATA",0x0);
66 }
67 return ret;
68}

◆ ReadDTS_CDS()

uint32_t WIB::ReadDTS_CDS ( uint16_t address,
uint8_t byte_count = 4 )

Definition at line 20 of file WIB_CDS.cpp.

20 {
21 return ReadI2C("DTS.CDS.I2C",address,byte_count);
22}

◆ ReadDTS_SI5344()

uint32_t WIB::ReadDTS_SI5344 ( uint16_t address,
uint8_t byte_count = 4 )

Definition at line 11 of file WIB_SI5344.cpp.

11 {
12 return ReadI2C("DTS.SI5344.I2C",address,byte_count);
13}

◆ ReadFlash()

void WIB::ReadFlash ( std::string const & fileName,
uint8_t update_percentage = 101 )

Definition at line 126 of file WIB_Flash.cpp.

126 {
127 bool print_updates = false;
128 if(update_percentage < 100){
129 print_updates = true;
130 }
131 size_t update_delta = (update_percentage * float(16*1024*1024/4))/100;
132 size_t next_update = update_delta;
133
134 FILE * outFile = fopen(fileName.c_str(),"w");
135 if(outFile == NULL){
136 BUException::WIB_BAD_ARGS e;
137 e.Append("Failed to create: ");
138 e.Append(fileName);
139 throw e;
140 }
141
142 if(print_updates){
143 fprintf(stderr," Reading flash\n");
144 fprintf(stderr," [");
145 for(size_t i = 0; i < 100.0/update_percentage;i++){
146 fprintf(stderr,"=");
147 }
148 fprintf(stderr,"]\n [");
149 }
150 //program flash in groups of 64 32bit words (256 bytes)
151 uint32_t address = 0;
152
153 uint32_t blockRegMapAddress = GetItem("FLASH.DATA00")->address;
154 size_t blockSize = 64;
155 //set block size
156 WriteWithRetry("FLASH.BYTE_COUNT",255);
157
158 for(size_t iWord = 0; iWord < 16*1024*1024/4;){
160
161 //Set adddress
162 WriteWithRetry("FLASH.ADDRESS",address);
163 //Start read
164 WriteWithRetry("FLASH.RUN_COMMAND",0x5);
165
167
168 //Readout the data
169 for(size_t iWordRead = 0;iWordRead < blockSize;iWordRead++){
170 fprintf(outFile,"0x%06X 0x%08X\n",uint32_t(iWord),ReadWithRetry(blockRegMapAddress+iWordRead));
171 iWord++;
172 }
173
174 // iWord+= blockSize;
175 address+=blockSize*4;
176
177 if(print_updates && (iWord > next_update)){
178 // printf(" % 3f%% done\n",float(iWord)/float(flashData.size()));
179 fprintf(stderr,"=");
180 next_update += update_delta;
181 }
182 }
183 if(print_updates){
184 printf("]\n");
185 printf(" done\n");
186 }
187 fclose(outFile);
188}

◆ ReadLocalFlash() [1/2]

uint32_t WIB::ReadLocalFlash ( uint16_t address)

Definition at line 4 of file WIB_localFlash.cpp.

4 {
5 //load the address
6 Write("SYSTEM.FLASH.ADDRESS",address);
7 //start the read transaction
8 Write("SYSTEM.FLASH.RW",1);
9 Write("SYSTEM.FLASH.RUN",1);
10
11 //Wait for transaction to finish
12 while(Read("SYSTEM.FLASH.DONE") == 0){
13 printf("busy\n");
14 //sleep for 1ms
15 usleep(1000);
16 }
17
18 return Read("SYSTEM.FLASH.RD_DATA");
19}

◆ ReadLocalFlash() [2/2]

std::vector< uint32_t > WIB::ReadLocalFlash ( uint16_t address,
size_t n )

Definition at line 21 of file WIB_localFlash.cpp.

21 {
22 std::vector<uint32_t> readData;
23 size_t current_address = address;
24 size_t end_address = current_address + n;
25 for(;current_address < end_address;current_address++){
26 readData.push_back(ReadLocalFlash(current_address));
27 }
28 return readData;
29}
uint32_t ReadLocalFlash(uint16_t address)

◆ ReadOutCDLinkSpyBuffer()

std::vector< data_8b10b_t > WIB::ReadOutCDLinkSpyBuffer ( )

Definition at line 4 of file WIB_spybuffer.cpp.

4 {
5 if(Read("FEMB_SPY.FIFO_EMPTY")){
6 BUException::WIB_ERROR e;
7 e.Append("CD Spy fifo is empty!");
8 throw e;
9 }
10
11 std::vector<data_8b10b_t> data;
12 while(!Read("FEMB_SPY.FIFO_EMPTY")){
13 uint32_t val = Read("FEMB_SPY.DATA");
14 data.push_back( data_8b10b_t((val>>8)&0x1,uint8_t(val&0xff)));
15 }
16 return data;
17}

◆ ReadQSFP()

uint32_t WIB::ReadQSFP ( uint16_t address,
uint8_t byte_count )

Definition at line 10 of file WIB_QSFP.cpp.

10 {
11 return ReadI2C("DAQ.QSFP.I2C",address,byte_count);
12}

◆ ResetSi5342()

void WIB::ResetSi5342 ( )

Definition at line 16 of file WIB_SI5342.cpp.

16 {
17 Write("DAQ.SI5342.RESET",0x1);
18 Write("DAQ.SI5342.RESET",0x0);
19 usleep(100000);
20}

◆ ResetSi5344()

void WIB::ResetSi5344 ( )

Definition at line 16 of file WIB_SI5344.cpp.

16 {
17 Write("DTS.SI5344.RESET",0x1);
18 Write("DTS.SI5344.RESET",0x0);
19 usleep(100000);
20}

◆ ResetWIB()

void WIB::ResetWIB ( bool reset_udp = false)

Definition at line 138 of file WIB.cpp.

138 {
139
140 if(reset_udp){
141 //Resetting the UDP will stop the reply packet which will cause an error.
142 try{
143 Write("SYSTEM.RESET.UDP_RESET",1);
144 }catch(BUException::BAD_REPLY & e){
145 //do nothing
146 }
147 //Since we don't know this happened since we lack a udp response, do it again.
148 //This could be extended to read register REG
149 usleep(10000);
150 try{
151 Write("SYSTEM.RESET.UDP_RESET",1);
152 }catch(BUException::BAD_REPLY & e){
153 //do nothing
154 }
155 usleep(10000);
156 }
157
158
159 //Reset the control register
160 WriteWithRetry("SYSTEM.RESET.CONTROL_REGISTER_RESET",1);
161 usleep(1000);
162
163 //If this is felix, make sure we configure the SI5342
164 if(DAQMode == FELIX){
165 Write("DAQ.SI5342.RESET",1);
166 usleep(10000);
167 Write("DAQ.SI5342.RESET",0);
168 usleep(10000);
169 printf("Configuring SI5342 for FELIX\n");
170 LoadConfigDAQ_SI5342("default"); //use the default config file for the SI5342
171 usleep(10000); // Wait for
172 SelectSI5342(1, // Set input to be local oscillator for FELIX clock
173 1); // enable the output of the SI5342
174 }
175
176 //Reset the Eventbuilder PLL
177 Write("SYSTEM.RESET.EB_PLL_RESET",1);
178 usleep(10000);
179
180 //Reset the DAQ path
181 Write("SYSTEM.RESET.DAQ_PATH_RESET",1);
182
183 usleep(10000);
184
185 //Set clock settings
186 Write("DTS.CMD_COUNT_RESET", 0xFFFFFFFF);
187 Write("DTS.CMD_COUNT_RESET", 0);
188
189 //Halt signals
190 Write("DTS.CONVERT_CONTROL.HALT", 1);
191 Write("DTS.CONVERT_CONTROL.ENABLE", 0);
192
193 //Make sure DC/DC is on
194 Write("POWER.ENABLE.MASTER_BIAS",1);
195}
void SelectSI5342(uint64_t input, bool enable)
void LoadConfigDAQ_SI5342(std::string const &fileName)

◆ ResetWIBAndCfgDTS()

void WIB::ResetWIBAndCfgDTS ( uint8_t localClock,
uint8_t PDTS_TGRP,
uint8_t PDTSsource = 0,
uint32_t PDTSAlignment_timeout = 0 )

Definition at line 197 of file WIB.cpp.

197 {
198 if(DAQMode == UNKNOWN){
199 BUException::WIB_DAQMODE_UNKNOWN e;
200 throw e;
201 }
202 if(localClock > 1){
203 BUException::WIB_BAD_ARGS e;
204 e.Append("localClock > 1; must be 0 (for DTS) or 1 (for local clock)\n");
205 throw e;
206 }
207 if(PDTSsource > 1){
208 BUException::WIB_BAD_ARGS e;
209 e.Append("PDTSsource > 1; must be 0 (for backplane) or 1 (for front panel)\n");
210 throw e;
211 }
212 if(16 <= PDTS_TGRP){
213 BUException::WIB_BAD_ARGS e;
214 e.Append("PDTS TGRP > 15; must be 0 to 15\n");
215 throw e;
216 }
217
218 // get this register so we can leave it in the state it started in
219 uint32_t slow_control_dnd = Read("SYSTEM.SLOW_CONTROL_DND");
220
221 ResetWIB();
222 Write("SYSTEM.SLOW_CONTROL_DND",1);
223 sleep(1);
224
225 for (size_t iFEMB=1; iFEMB<=4; iFEMB++){
226 FEMBPower(iFEMB,0);
227 }
228
229 //make sure everything DTS is off
230 Write("DTS.CONVERT_CONTROL.HALT",1);
231 Write("DTS.CONVERT_CONTROL.ENABLE",0);
232 Write("DTS.CONVERT_CONTROL.START_SYNC",0);
233 sleep(1);
234
235 if(localClock > 0){
236 printf("Configuring local clock\n");
237 //Configure the SI5344 to use the local oscillator instead of the PDTS
238 LoadConfigDTS_SI5344("default");
239 sleep(1);
240 SelectSI5344(1,1);
241 sleep(1);
242 Write("DTS.CONVERT_CONTROL.EN_FAKE",1);
243 Write("DTS.CONVERT_CONTROL.LOCAL_TIMESTAMP",1);
244 Write("FEMB_CNC.CNC_CLOCK_SELECT",1);
245 // Write("FEMB_CNC.ENABLE_DTS_CMDS",1);
246 sleep(1);
247 }
248 else {
249 //Configure the clocking for the PDTS (assumes the PDTS is sending idle or something)
250 printf("Configuring DTS\n");
251 Write("DTS.PDTS_TGRP",PDTS_TGRP);
252 printf("Using timing group 0x%X\n",PDTS_TGRP);
253 InitializeDTS(PDTSsource,0,PDTSAlignment_timeout);
254 sleep(1);
255 Write("FEMB_CNC.CNC_CLOCK_SELECT",1);
256 sleep(1);
257 //We are ready for the PDTS, start searching
258 Write("DTS.PDTS_ENABLE",1);
259 sleep(1);
260 }
261
262 //Now we have the 128MHz clock
263 Write("FEMB1.DAQ.ENABLE",0);
264 Write("FEMB2.DAQ.ENABLE",0);
265 Write("FEMB3.DAQ.ENABLE",0);
266 Write("FEMB4.DAQ.ENABLE",0);
267
268 Write("SYSTEM.SLOW_CONTROL_DND",slow_control_dnd);
269
270}

◆ SelectSI5342()

void WIB::SelectSI5342 ( uint64_t input,
bool enable )

Definition at line 139 of file WIB_SI5342.cpp.

139 {
140 Write("DAQ.SI5342.INPUT_SELECT", input);
141 Write("DAQ.SI5342.ENABLE", uint64_t(enable));
142}

◆ SelectSI5344()

void WIB::SelectSI5344 ( uint64_t input,
bool enable )

Definition at line 138 of file WIB_SI5344.cpp.

138 {
139 Write("DTS.SI5344.INPUT_SELECT", input);
140 Write("DTS.SI5344.ENABLE", uint64_t(enable));
141}

◆ SetContinueIfListOfFEMBClockPhasesDontSync()

void WIB::SetContinueIfListOfFEMBClockPhasesDontSync ( bool enable)

Definition at line 1156 of file WIB_FEMB.cpp.

◆ SetContinueOnFEMBRegReadError()

void WIB::SetContinueOnFEMBRegReadError ( bool enable)

Definition at line 1144 of file WIB_FEMB.cpp.

1144 {
1146}

◆ SetContinueOnFEMBSPIError()

void WIB::SetContinueOnFEMBSPIError ( bool enable)

Definition at line 1148 of file WIB_FEMB.cpp.

1148 {
1150}

◆ SetContinueOnFEMBSyncError()

void WIB::SetContinueOnFEMBSyncError ( bool enable)

Definition at line 1152 of file WIB_FEMB.cpp.

1152 {
1154}

◆ SetDAQ_SI5342Page()

void WIB::SetDAQ_SI5342Page ( uint8_t page)

Definition at line 22 of file WIB_SI5342.cpp.

22 {
23 WriteDAQ_SI5342(0x1,page,1);
24}

◆ SetDTS_SI5344Page()

void WIB::SetDTS_SI5344Page ( uint8_t page)

Definition at line 22 of file WIB_SI5344.cpp.

22 {
23 WriteDTS_SI5344(0x1,page,1);
24}

◆ SetEventBuilderDebugMode()

void WIB::SetEventBuilderDebugMode ( uint8_t mask = 0xF)

◆ SetFEMBFakeCOLDATAMode()

void WIB::SetFEMBFakeCOLDATAMode ( uint8_t iFEMB,
uint8_t iCD,
bool mode = 0 )

Definition at line 68 of file WIB_FAKE_CD.cpp.

68 {
69 std::string base("FEMB0.DAQ.FAKE_CD.CD0.");
70 base[4] = GetFEMBChar(iFEMB);
71 base[20] = GetFEMBCDChar(iCD);
72
73 //Set this COLDATA ASIC
74 Write(base+"FAKE_MODE",uint32_t(mode));
75}

◆ SetFEMBStreamSource()

void WIB::SetFEMBStreamSource ( uint8_t iFEMB,
uint8_t iStream,
bool real = true )

Definition at line 52 of file WIB_FAKE_CD.cpp.

52 {
54 std::string base = "FEMB0.DAQ.FAKE_CD.RX_DATA_SOURCE";
55 base[4] = GetFEMBChar(iFEMB);
56 //Read the current settings
57 uint32_t data = Read(base);
58 //update the mask
59 iStream--; // iStream is 1-4, but we want bits 0 to 3
60 if(real){
61 data &= ~(0x1<<iStream);
62 }else{
63 data |= 0x1<<iStream;
64 }
65 Write(base,data);
66}

◆ SetupASICPulserBits()

uint16_t WIB::SetupASICPulserBits ( uint8_t iFEMB)

Definition at line 809 of file WIB_FEMB.cpp.

809 {
810
811 const uint32_t REG_SPI_BASE_WRITE = 0x200; // 512
812 const uint32_t REG_SPI_BASE_READ = 0x250; // 592
813 uint16_t adc_sync_status = 0xFFFF;
814
815
816
817 size_t nASICs = 8;
818 unsigned nTries = 3;
819 for(unsigned iSPIWrite=0; iSPIWrite < nTries; iSPIWrite++)
820 {
821 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 0 ); // Turn off STREAM_EN and ADC_DATA_EN
822 sleep(0.1);
823
824 std::cout << "ASIC SPI Write Registers..." << std::endl;
825
826 uint8_t value = 0x2;
827 uint8_t mask = 0x3;
828 uint8_t pos = 24;
829 std::vector<uint32_t> vals(nASICs);
830 for (size_t iASIC=0; iASIC<nASICs; iASIC++)
831 {
832 uint32_t address = (REG_SPI_BASE_WRITE + 9*iASIC + 8);
833 std::cout <<"Writing address " << std::hex << std::setfill ('0') << std::setw(8) << address << std::endl;
834 //WriteFEMBBits(iFEMB, address, pos, mask, value);
835
836 //Bit-wise calculation of register val
837 uint32_t shiftVal = value & mask;
838 uint32_t regMask = (mask << pos);
839 uint32_t initVal = ReadFEMB(iFEMB,address);
840 uint32_t newVal = ( (initVal & ~(regMask)) | (shiftVal << pos) );
841 vals[iASIC] = newVal;
842 WriteFEMB(iFEMB,address,newVal);
843
844 sleep(0.01);
845 }
846
847
848
849 //run the SPI programming
850 sleep(0.1);
851 WriteFEMB(iFEMB, "WRITE_ASIC_SPI", 1);
852 sleep(0.1);
853
854 if (iSPIWrite == nTries - 1)
855 {
856 // Now check readback
857 bool spi_mismatch = false;
858 for (unsigned iSPIRead = 0; iSPIRead < 2; iSPIRead++)
859 {
860 std::cout << "ASIC SPI Readback..." << std::endl;
861 std::vector<uint32_t> regsReadback(nASICs);
862 for (size_t iASIC=0; iASIC<nASICs; iASIC++)
863 {
864 uint32_t regReadback = ReadFEMB(iFEMB, (REG_SPI_BASE_READ + 9*iASIC + 8));
865 regsReadback[iASIC] = regReadback;
866 sleep(0.01);
867 }
868
869 std::cout << "ASIC SPI register number, write val, read val:" << std::endl;
870 spi_mismatch = false;
871 for (size_t iASIC=0; iASIC<nASICs; iASIC++)
872 {
873 std::cout << std::dec << std::setfill (' ') << std::setw(3) << iASIC
874 << " "
875 << std::hex << std::setfill ('0') << std::setw(8) << vals[iASIC]
876 << " "
877 << std::hex << std::setfill ('0') << std::setw(8) << regsReadback[iASIC]
878 << std::endl;
879 if (vals[iASIC] != regsReadback[iASIC])
880 {
881 spi_mismatch = true;
882 size_t asicFailNum = 0;
883 if (iASIC > 0) asicFailNum = (iASIC-1);
884 std::cout << "FE-ADC ASIC " << asicFailNum << " SPI faled" << std::endl;
885 } // if regs don't match
886 } // for iReg
887 if (!spi_mismatch) break;
888 } // for iSPIRead
889 if(spi_mismatch)
890 {
891 BUException::WIB_ERROR e;
892 e.Append("SPI programming failure");
893 throw e;
894 } // if spi_mismatch
895 } // if iSPIWrite == 1
896 sleep(0.1);
897
898 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 9 ); // STREAM_EN and ADC_DATA_EN
899 sleep(0.05);
900 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 9 ); // STREAM_EN and ADC_DATA_EN
901 sleep(0.1);
902
903 adc_sync_status = (uint16_t) ReadFEMB(iFEMB, "ADC_ASIC_SYNC_STATUS");
904
905 // The real sync check can happen here in Shanshan's code
906
907 } // for iSPIWrite
908
909 return adc_sync_status;
910}

◆ SetupFEMBASICs() [1/2]

uint16_t WIB::SetupFEMBASICs ( uint8_t iFEMB,
std::vector< uint32_t > registerList )

Setup FEMB ASICs.

Sets up iFEMB (index from 1) ASICs

registerList is a list of 71 32bit registers to program the FE and ADC ASICs

returns adc sync status 16 bits, one for each serial link between ADC and FPGA. There are 2 per ADC

Definition at line 550 of file WIB_FEMB.cpp.

550 {
551
552 const size_t REG_SPI_BASE = 512;
553 const size_t NREGS = 71;
554
555 if (registerList.size() != NREGS)
556 {
557 BUException::FEMB_FIRMWARE_VERSION_MISMATCH e;
558 std::stringstream expstr;
559 expstr << "SetupFEMBASICs expects : "
560 << NREGS
561 << " argument is: "
562 << registerList.size();
563 e.Append(expstr.str().c_str());
564 throw e;
565 }
566
567 //turn off HS data before register writes
568 WriteFEMB(iFEMB, "STREAM_EN", 0 );
569 sleep(2);
570
571 for (size_t iReg=0; iReg < NREGS; iReg++)
572 {
573 WriteFEMB(iFEMB, REG_SPI_BASE + iReg, registerList[iReg]);
574 }
575
577 //run the SPI programming
579
580 WriteFEMB(iFEMB, "ADC_ASIC_RESET", 1);
581 sleep(0.01);
582 WriteFEMB(iFEMB, "FE_ASIC_RESET", 1);
583 sleep(0.01);
584 WriteFEMB(iFEMB, "WRITE_ADC_ASIC_SPI", 1);
585 sleep(0.01);
586 WriteFEMB(iFEMB, "WRITE_ADC_ASIC_SPI", 1);
587 sleep(0.01);
588 WriteFEMB(iFEMB, "WRITE_FE_ASIC_SPI", 1);
589 sleep(0.01);
590 WriteFEMB(iFEMB, "WRITE_FE_ASIC_SPI", 1);
591 sleep(0.01);
592
593 uint16_t adc_sync_status = (uint16_t) ReadFEMB(iFEMB, "ADC_ASIC_SYNC_STATUS");
596
597 //turn HS link back on
598 sleep(2);
599 WriteFEMB(iFEMB, "STREAM_EN", 1 );
600
601 return adc_sync_status;
602}

◆ SetupFEMBASICs() [2/2]

uint16_t WIB::SetupFEMBASICs ( uint8_t iFEMB,
uint8_t gain,
uint8_t shape,
uint8_t highBaseline,
bool highLeakage,
bool leakagex10,
bool acCoupling,
bool buffer,
bool useExtClock,
uint8_t internalDACControl,
uint8_t internalDACValue )

Setup FEMB ASICs.

Sets up iFEMB (index from 1) ASICs

gain: 0,1,2,3 for 4.7, 7.8, 14, 25 mV/fC, respectively shaping time: 0,1,2,3 for 0.5, 1, 2, 3 us, respectively highBaseline is 900mV for 1, 200mV for 0, and appropriately for each plane for 2 highLeakage is 500pA for true, 100pA for false leakagex10 multiplies leakage x10 if true acCoupling: FE is AC coupled to ADC if true, DC if false buffer: FE to ADC buffer on if true, off and bypassed if false useExtClock: ADC uses external (FPGA) clock if true, internal if false internalDACControl: 0 for disabled, 1 for internal FE ASIC pulser, 2 for external FPGA pulser internalDACValue: 6 bit value for amplitude to use with internal pulser

returns adc sync status 16 bits, one for each serial link between ADC and FPGA. There are 2 per ADC

Definition at line 621 of file WIB_FEMB.cpp.

623 {
624
625 (void) buffer; // to make compiler not complain about unused arguments
626
627 if (gain > 3)
628 {
629 BUException::WIB_BAD_ARGS e;
630 std::stringstream expstr;
631 expstr << "gain should be between 0 and 3, but is: "
632 << int(gain);
633 e.Append(expstr.str().c_str());
634 throw e;
635 }
636 if (shape > 3)
637 {
638 BUException::WIB_BAD_ARGS e;
639 std::stringstream expstr;
640 expstr << "shape should be between 0 and 3, but is: "
641 << int(shape);
642 e.Append(expstr.str().c_str());
643 throw e;
644 }
645
646 const size_t REG_SPI_BASE_WRITE = 0x200; // 512
647 const size_t REG_SPI_BASE_READ = 0x250; // 592
648 // 0x48 registers total, 72 in hex
649
650 bool bypassOutputBuffer=true; // if false might blow up protoDUNE
651 bool useOutputMonitor=false; // if true might blow up protoDUNE
652 bool useCh16HighPassFilter=false;
653 bool monitorBandgapNotTemp=false;
654 bool monitorTempBandgapNotSignal=false;
655 bool useTestCapacitance = (bool) internalDACControl;
656
657 // Flip bits of gain
658 if (gain == 0x1) gain = 0x2;
659 else if (gain== 0x2) gain = 0x1;
660
661 // Shape
662 if (shape == 0x0) shape = 0x2; // 0.5 us
663 else if (shape == 0x1) shape = 0x0; // 1 us
664 else if (shape == 0x2) shape = 0x3; // 2 us
665 else if (shape == 0x3) shape = 0x1; // 3 us
666
667 FE_ASIC_reg_mapping fe_map;
668 if (highBaseline > 1)
669 {
670 // Set them all to high baseline
671 fe_map.set_board(useTestCapacitance,0,gain,shape,
672 useOutputMonitor,!bypassOutputBuffer,!highLeakage,
673 monitorBandgapNotTemp,monitorTempBandgapNotSignal,useCh16HighPassFilter,
674 leakagex10,acCoupling,internalDACControl,internalDACValue
675 );
676 // Now just set collection channels to low baseline
677 fe_map.set_collection_baseline(1);
678 }
679 else
680 {
681 fe_map.set_board(useTestCapacitance,~highBaseline,gain,shape,
682 useOutputMonitor,!bypassOutputBuffer,!highLeakage,
683 monitorBandgapNotTemp,monitorTempBandgapNotSignal,useCh16HighPassFilter,
684 leakagex10,acCoupling,internalDACControl,internalDACValue
685 );
686 }
687 ADC_ASIC_reg_mapping adc_map;
688 uint8_t offsetCurrentValue=0;
689 bool pcsr=0;
690 bool pdsr=0;
691 bool adcSleep=0;
692 bool useADCTestInput=0;
693 bool f4=0;
694 bool f5=0;
695 bool lsbCurrentStearingPartialNotFull=0;
696 bool clk0=0;
697 if (useExtClock) clk0=1;
698 bool clk1=0;
699 bool freq=0;
700 bool enableOffsetCurrent=0;
701 bool f0=0;
702 bool f1=0;
703 bool f2=0;
704 bool f3=0;
705 adc_map.set_board(offsetCurrentValue, pcsr, pdsr,
706 adcSleep, useADCTestInput, f4, f5,
707 lsbCurrentStearingPartialNotFull,0,0,
708 0,0,0,
709 clk0,clk1,freq,
710 enableOffsetCurrent,f0,f1,
711 f2,f3);
713 map.set_board(fe_map,adc_map);
714 map.get_regs();
715 const std::vector<uint32_t> regs = map.get_regs();
716 const size_t nRegs = regs.size();
717
718 uint16_t adc_sync_status = 0xFFFF;
719
720 for(unsigned iSPIWrite=0; iSPIWrite < 2; iSPIWrite++)
721 {
722 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 0 ); // Turn off STREAM_EN and ADC_DATA_EN
723 sleep(0.1);
724
725 std::cout << "ASIC SPI Write Registers..." << std::endl;
726 for (size_t iReg=0; iReg<nRegs; iReg++)
727 {
728 WriteFEMB(iFEMB,REG_SPI_BASE_WRITE+iReg,regs[iReg]);
729 sleep(0.01);
730 }
731
732
733 //run the SPI programming
734 sleep(0.1);
735 WriteFEMB(iFEMB, "WRITE_ASIC_SPI", 1);
736 sleep(0.1);
737
738 if (iSPIWrite == 1)
739 {
740 // Now check readback
741 bool spi_mismatch = false;
742 for (unsigned iSPIRead = 0; iSPIRead < 2; iSPIRead++)
743 {
744 std::cout << "ASIC SPI Readback..." << std::endl;
745 std::vector<uint32_t> regsReadback(nRegs);
746 for (size_t iReg=0; iReg<nRegs; iReg++)
747 {
748 uint32_t regReadback = ReadFEMB(iFEMB,REG_SPI_BASE_READ+iReg);
749 regsReadback[iReg] = regReadback;
750 sleep(0.01);
751 }
752
753 bool verbose = false;
754 if (verbose) std::cout << "ASIC SPI register number, write val, read val:" << std::endl;
755 spi_mismatch = false;
756 for (size_t iReg=0; iReg<nRegs; iReg++)
757 {
758 if (verbose)
759 {
760 std::cout << std::dec << std::setfill (' ') << std::setw(3) << iReg
761 << " "
762 << std::hex << std::setfill ('0') << std::setw(8) << regs[iReg]
763 << " "
764 << std::hex << std::setfill ('0') << std::setw(8) << regsReadback[iReg]
765 << std::endl;
766 } // if verbose
767 if (regs[iReg] != regsReadback[iReg])
768 {
769 spi_mismatch = true;
770 size_t asicFailNum = 0;
771 if (iReg > 0) asicFailNum = (iReg-1) / 9;
772 std::cout << "FE-ADC ASIC " << asicFailNum << " SPI faled" << std::endl;
773 } // if regs don't match
774 } // for iReg
775 if (!spi_mismatch) break;
776 } // for iSPIRead
777 if(spi_mismatch)
778 {
780 {
781 std::cout << "FEMB ASIC SPI readback mismatch--problems communicating with ASICs for FEMB: " << int(iFEMB) << std::endl;
782 }
783 else
784 {
785 BUException::FEMB_SPI_READBACK_MISMATCH e;
786 std::stringstream expstr;
787 expstr << " for FEMB: " << int(iFEMB);
788 e.Append(expstr.str().c_str());
789 throw e;
790 }
791 } // if spi_mismatch
792 } // if iSPIWrite == 1
793 sleep(0.1);
794
795 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 9 ); // STREAM_EN and ADC_DATA_EN
796 sleep(0.05);
797 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 9 ); // STREAM_EN and ADC_DATA_EN
798 sleep(0.1);
799
800 adc_sync_status = (uint16_t) ReadFEMB(iFEMB, "ADC_ASIC_SYNC_STATUS");
801
802 // The real sync check can happen here in Shanshan's code
803
804 } // for iSPIWrite
805
806 return adc_sync_status;
807}
void set_board(uint8_t d=0, uint8_t pcsr=0, uint8_t pdsr=0, uint8_t slp=0, uint8_t tstin=0, uint8_t f4=0, uint8_t f5=0, uint8_t slsb=0, uint8_t res4=0, uint8_t res3=0, uint8_t res2=0, uint8_t res1=0, uint8_t res0=0, uint8_t clk0=0, uint8_t clk1=0, uint8_t frqc=0, uint8_t engr=0, uint8_t f0=0, uint8_t f1=0, uint8_t f2=0, uint8_t f3=0)
std::vector< uint32_t > get_regs() const
void set_board(const FE_ASIC_reg_mapping &fe_map, const ADC_ASIC_reg_mapping &adc_map)
void set_collection_baseline(uint8_t snc)
void set_board(uint8_t sts=0, uint8_t snc=0, uint8_t sg=0, uint8_t st=0, uint8_t smn=0, uint8_t sdf=0, uint8_t slk0=0, uint8_t stb1=0, uint8_t stb=0, uint8_t s16=0, uint8_t slk1=0, uint8_t sdc=0, uint8_t swdac=0, uint8_t dac=0)

◆ SetupFEMBExtClock()

void WIB::SetupFEMBExtClock ( uint8_t iFEMB)

Setup FEMB External Clock.

Sets up iFEMB (index from 1) external clock parameters

Definition at line 375 of file WIB_FEMB.cpp.

375 {
376
377 //EXTERNAL CLOCK VARIABLES
378 uint32_t clk_period = 5; //ns
379 uint32_t clk_dis = 0; //0 --> enable, 1 disable
380 uint32_t d14_rst_oft = 0 / clk_period;
381 uint32_t d14_rst_wdt = (45 / clk_period ) ;
382 uint32_t d14_rst_inv = 1;
383 uint32_t d14_read_oft = 480 / clk_period;
384 uint32_t d14_read_wdt = 20 / clk_period;
385 uint32_t d14_read_inv = 1;
386 uint32_t d14_idxm_oft = 230 / clk_period;
387 uint32_t d14_idxm_wdt = 270 / clk_period;
388 uint32_t d14_idxm_inv = 0;
389 uint32_t d14_idxl_oft = 480 / clk_period;
390 uint32_t d14_idxl_wdt = 20 / clk_period;
391 uint32_t d14_idxl_inv = 0;
392 uint32_t d14_idl0_oft = 50 / clk_period;
393 uint32_t d14_idl0_wdt = (190 / clk_period ) -1;
394 uint32_t d14_idl1_oft = 480 / clk_period;
395 uint32_t d14_idl1_wdt = 20 / clk_period;
396 uint32_t d14_idl_inv = 0;
397
398 uint32_t d58_rst_oft = 0 / clk_period;
399 uint32_t d58_rst_wdt = (45 / clk_period );
400 uint32_t d58_rst_inv = 1;
401 uint32_t d58_read_oft = 480 / clk_period;
402 uint32_t d58_read_wdt = 20 / clk_period;
403 uint32_t d58_read_inv = 1;
404 uint32_t d58_idxm_oft = 230 / clk_period;
405 uint32_t d58_idxm_wdt = 270 / clk_period;
406 uint32_t d58_idxm_inv = 0;
407 uint32_t d58_idxl_oft = 480 / clk_period;
408 uint32_t d58_idxl_wdt = 20 / clk_period;
409 uint32_t d58_idxl_inv = 0;
410 uint32_t d58_idl0_oft = 50 / clk_period;
411 uint32_t d58_idl0_wdt = (190 / clk_period ) -1;
412 uint32_t d58_idl1_oft = 480 / clk_period;
413 uint32_t d58_idl1_wdt = 20 / clk_period;
414 uint32_t d58_idl_inv = 0;
415
416 //external clock phase -- Version 320
417 /*uint32_t d14_read_step = 7;
418 uint32_t d14_read_ud = 0;
419 uint32_t d14_idxm_step = 3;
420 uint32_t d14_idxm_ud = 0;
421 uint32_t d14_idxl_step = 1;
422 uint32_t d14_idxl_ud = 1;
423 uint32_t d14_idl0_step = 5;
424 uint32_t d14_idl0_ud = 0;
425 uint32_t d14_idl1_step = 2;
426 uint32_t d14_idl1_ud = 0;
427 uint32_t d14_phase_en = 1;
428
429 uint32_t d58_read_step = 1;
430 uint32_t d58_read_ud = 1;
431 uint32_t d58_idxm_step = 0;
432 uint32_t d58_idxm_ud = 0;
433 uint32_t d58_idxl_step = 5;
434 uint32_t d58_idxl_ud = 1;
435 uint32_t d58_idl0_step = 6;
436 uint32_t d58_idl0_ud = 0;
437 uint32_t d58_idl1_step = 5;
438 uint32_t d58_idl1_ud = 0;
439 uint32_t d58_phase_en = 1;*/
440 //Version 323
441 uint32_t d14_read_step = 11;
442 uint32_t d14_read_ud = 0;
443 uint32_t d14_idxm_step = 9;
444 uint32_t d14_idxm_ud = 0;
445 uint32_t d14_idxl_step = 7;
446 uint32_t d14_idxl_ud = 0;
447 uint32_t d14_idl0_step = 12;
448 uint32_t d14_idl0_ud = 0;
449 uint32_t d14_idl1_step = 10;
450 uint32_t d14_idl1_ud = 0;
451 uint32_t d14_phase_en = 1;
452
453 uint32_t d58_read_step = 0;
454 uint32_t d58_read_ud = 0;
455 uint32_t d58_idxm_step = 5;
456 uint32_t d58_idxm_ud = 0;
457 uint32_t d58_idxl_step = 4;
458 uint32_t d58_idxl_ud = 1;
459 uint32_t d58_idl0_step = 3;
460 uint32_t d58_idl0_ud = 0;
461 uint32_t d58_idl1_step = 4;
462 uint32_t d58_idl1_ud = 0;
463 uint32_t d58_phase_en = 1;
464
465 //END EXTERNAL CLOCK VARIABLES
466
467 //config timing
468 uint32_t d14_inv = (d14_rst_inv<<0) + (d14_read_inv<<1)+ (d14_idxm_inv<<2)+ (d14_idxl_inv<<3)+ (d14_idl_inv<<4);
469 uint32_t d58_inv = (d58_rst_inv<<0) + (d58_read_inv<<1)+ (d58_idxm_inv<<2)+ (d58_idxl_inv<<3)+ (d58_idl_inv<<4);
470 uint32_t d_inv = d58_inv + ( d14_inv<<5);
471
472 uint32_t addr_data;
473
474 addr_data = clk_dis + (d_inv << 16);
475 WriteFEMB(iFEMB, 21, addr_data);
476
477 addr_data = d58_rst_oft + (d14_rst_oft << 16);
478 WriteFEMB(iFEMB, 22, addr_data);
479
480 addr_data = d58_rst_wdt + (d14_rst_wdt << 16);
481 WriteFEMB(iFEMB, 23, addr_data);
482
483 addr_data = d58_read_oft + (d14_read_oft << 16);
484 WriteFEMB(iFEMB, 24, addr_data);
485
486 addr_data = d58_read_wdt + (d14_read_wdt << 16);
487 WriteFEMB(iFEMB, 25, addr_data);
488
489 addr_data = d58_idxm_oft + (d14_idxm_oft << 16);
490 WriteFEMB(iFEMB, 26, addr_data);
491
492 addr_data = d58_idxm_wdt + (d14_idxm_wdt << 16);
493 WriteFEMB(iFEMB, 27, addr_data);
494
495 addr_data = d58_idxl_oft + (d14_idxl_oft << 16);
496 WriteFEMB(iFEMB, 28, addr_data);
497
498 addr_data = d58_idxl_wdt + (d14_idxl_wdt << 16);
499 WriteFEMB(iFEMB, 29, addr_data);
500
501 addr_data = d58_idl0_oft + (d14_idl0_oft << 16);
502 WriteFEMB(iFEMB, 30, addr_data);
503
504 addr_data = d58_idl0_wdt + (d14_idl0_wdt << 16);
505 WriteFEMB(iFEMB, 31, addr_data);
506
507 addr_data = d58_idl1_oft + (d14_idl1_oft << 16);
508 WriteFEMB(iFEMB, 32, addr_data);
509
510 addr_data = d58_idl1_wdt + (d14_idl1_wdt << 16);
511 WriteFEMB(iFEMB, 33, addr_data);
512
513 //config phase
514 for(size_t i=0; i<4; i++)
515 {
516 addr_data = d14_read_step + (d14_idxm_step <<16);
517 WriteFEMB(iFEMB, 35, addr_data);
518
519 addr_data = d14_idxl_step + (d14_idl0_step <<16);
520 WriteFEMB(iFEMB, 36, addr_data);
521
522 d14_phase_en = d14_phase_en ^ 1;
523 uint32_t d14_ud = d14_read_ud + (d14_idxm_ud<<1) + (d14_idxl_ud<<2)+ (d14_idl0_ud<<3)+ (d14_idl1_ud<<4) + (d14_phase_en <<15);
524 addr_data = d14_idl1_step + (d14_ud<<16);
525 WriteFEMB(iFEMB, 37, addr_data);
526
527 addr_data = d58_read_step + (d58_idxm_step <<16);
528 WriteFEMB(iFEMB, 38, addr_data);
529
530 addr_data = d58_idxl_step + (d58_idl0_step <<16);
531 WriteFEMB(iFEMB, 39, addr_data);
532
533 d58_phase_en = d58_phase_en ^ 1;
534 uint32_t d58_ud = d58_read_ud + (d58_idxm_ud<<1) + (d58_idxl_ud<<2)+ (d58_idl0_ud<<3)+ (d58_idl1_ud<<4) + (d58_phase_en <<15);
535 addr_data = d58_idl1_step + (d58_ud <<16);
536 WriteFEMB(iFEMB, 40, addr_data);
537 }
538 sleep(0.05);
539}

◆ SetupFPGAPulser()

void WIB::SetupFPGAPulser ( uint8_t iFEMB,
uint8_t dac_val )

Definition at line 912 of file WIB_FEMB.cpp.

912 {
913 std::cout << "FEMB " << int(iFEMB) << " Configuring FPGA pulser with DAC value: " << int(dac_val) << std::endl;
914
915 WriteFEMB(iFEMB, "ASIC_TP_EN", 0 );
916 WriteFEMB(iFEMB, "FPGA_TP_EN", 1 );
917
918 WriteFEMB(iFEMB, "DAC_SELECT", 1 );
919 WriteFEMB(iFEMB, "TEST_PULSE_AMPLITUDE", dac_val );
920 WriteFEMB(iFEMB, "TEST_PULSE_DELAY", 219 );
921 WriteFEMB(iFEMB, "TEST_PULSE_PERIOD", 497 );
922
923 WriteFEMB(iFEMB, "INT_TP_EN", 0 );
924 WriteFEMB(iFEMB, "EXT_TP_EN", 1 );
925
926}

◆ SetupInternalPulser()

void WIB::SetupInternalPulser ( uint8_t iFEMB)

Definition at line 928 of file WIB_FEMB.cpp.

928 {
929 std::cout << "FEMB " << int(iFEMB) << " Configuring internal pulser" << std::endl;
930
931 WriteFEMB(iFEMB, "DAC_SELECT", 0 );
932 WriteFEMB(iFEMB, "TEST_PULSE_AMPLITUDE", 0 );
933 WriteFEMB(iFEMB, "TEST_PULSE_DELAY", 219 );
934 WriteFEMB(iFEMB, "TEST_PULSE_PERIOD", 497 );
935
936 WriteFEMB(iFEMB, "INT_TP_EN", 0 );
937 WriteFEMB(iFEMB, "EXT_TP_EN", 1 );
938
939 WriteFEMB(iFEMB, "FPGA_TP_EN", 0 );
940 WriteFEMB(iFEMB, "ASIC_TP_EN", 1 );
941}

◆ SourceFEMB()

void WIB::SourceFEMB ( uint64_t iDAQLink,
uint64_t real )

Definition at line 626 of file WIB.cpp.

626 {
627 if(iFEMB < 1){
628 printf("FEMB index out of range < 1\n");
629 return;
630 }
631
632/* if(DAQMode == RCE && iFEMB > 4){
633 printf("FEMB index out of range > 4 (RCE) \n");
634 return;}
635 if(DAQMode == FELIX && iFEMB > 2){
636 printf("FEMB index out of range > 2 (FELIX) \n");
637 return;}
638 */
639 std::string address("FEMB");
640 address.push_back(GetFEMBChar(iFEMB));
641 address.append(".DAQ.FAKE_CD.FAKE_SOURCE");
642 Write(address,real);
643}

◆ StartEventBuilder()

void WIB::StartEventBuilder ( uint8_t mask = 0xF)

◆ StartStreamToDAQ()

void WIB::StartStreamToDAQ ( bool l1 = true,
bool l2 = true,
bool l3 = false,
bool l4 = false )

Definition at line 411 of file WIB.cpp.

411 {
412 if(DAQMode == UNKNOWN){
413 BUException::WIB_DAQMODE_UNKNOWN e;
414 throw e;
415 }
416 WriteWithRetry("DTS.CONVERT_CONTROL.HALT",1);
417 WriteWithRetry("DTS.CONVERT_CONTROL.ENABLE",0);
418
419
420 // get this register so we can leave it in the state it started in
421 uint32_t slow_control_dnd = Read("SYSTEM.SLOW_CONTROL_DND");
422 Write("SYSTEM.SLOW_CONTROL_DND",1);
423
424 sleep(1);
425 Write("FEMB_CNC.FEMB_STOP",1);
426 sleep(1);
427 Write("SYSTEM.RESET.DAQ_PATH_RESET",1);
428 sleep(1);
429
430 // Enable DAQ links
431 if (DAQMode == FELIX){
432 if(link1_enabled) EnableDAQLink_Lite(1,1);
433 if(link2_enabled) EnableDAQLink_Lite(2,1);
434 }
435 else {
436 if(link3_enabled) EnableDAQLink_Lite(3,1);
437 if(link4_enabled) EnableDAQLink_Lite(4,1);
438 }
439
440 // Enable the FEMB to align to idle and wait for convert
441 Write("FEMB1.DAQ.ENABLE",0xF);
442 Write("FEMB2.DAQ.ENABLE",0xF);
443 Write("FEMB3.DAQ.ENABLE",0xF);
444 Write("FEMB4.DAQ.ENABLE",0xF);
445
446 // Start sending characters from the FEMB
447 Write("FEMB_CNC.ENABLE_DTS_CMDS",1);
448 StartSyncDTS();
449 // Write("FEMB_CNC.TIMESTAMP_RESET",1);
450 //Write("FEMB_CNC.FEMB_START",1);
451 // Write("SYSTEM.RESET.FEMB_COUNTER_RESET",1);
452
453 Write("SYSTEM.SLOW_CONTROL_DND",slow_control_dnd);
454}
void StartSyncDTS()
Definition WIB_DTS.cpp:163

◆ StartSyncDTS()

void WIB::StartSyncDTS ( )

Definition at line 163 of file WIB_DTS.cpp.

163 {
164 WriteWithRetry("DTS.CONVERT_CONTROL.HALT",0);
165 WriteWithRetry("DTS.CONVERT_CONTROL.ENABLE",1);
166 WriteWithRetry("DTS.CONVERT_CONTROL.START_SYNC",1);
167}

◆ StopEventBuilder()

void WIB::StopEventBuilder ( uint8_t mask = 0xF)

◆ TryFEMBPhases()

bool WIB::TryFEMBPhases ( uint8_t iFEMB,
std::vector< uint16_t > phases )

Definition at line 1031 of file WIB_FEMB.cpp.

1031 {
1032
1033 size_t nPhases = phases.size();
1034 std::cout << "Searching " << nPhases << " sets of phases:" << std::endl;
1035 for(size_t ip = 0; ip < nPhases; ++ip){
1036 uint16_t phase = phases.at(ip);
1037 std::cout << "Set " << ip << std::endl;
1038 std::cout << "\t Phase: " << std::hex << std::setw(4) << phase << std::endl;
1039
1040 WriteFEMBPhase(iFEMB,phase);
1041 //If it made it this far, it found the correct readback val
1042 sleep(0.001);
1043 uint32_t adc_fifo_sync = (ReadFEMB(iFEMB, 6) & 0xFFFF0000) >> 16;
1044 sleep(0.001);
1045 adc_fifo_sync = (ReadFEMB(iFEMB, 6) & 0xFFFF0000) >> 16;
1046 sleep(0.001);
1047
1048 std::cout << "FEMB " << int(iFEMB) << " ADC FIFO sync: " << std::bitset<16>(adc_fifo_sync) << std::endl;
1049
1050 if (adc_fifo_sync == 0){
1051 std::cout << "FEMB " << int(iFEMB) << " ADC FIFO synced" << std::endl;
1052 std::cout << " phase: " << std::hex << std::setw(4) << std::setfill('0') << (uint32_t) phase << std::endl;
1053 return true;
1054 }
1055 }
1056
1057 //std::cout << "Could not find successful phase" << std::endl;
1058 return false;
1059}

◆ WriteDAQ_SI5342()

void WIB::WriteDAQ_SI5342 ( uint16_t address,
uint32_t value,
uint8_t byte_count = 4 )

Definition at line 8 of file WIB_SI5342.cpp.

8 {
9 WriteI2C("DAQ.SI5342.I2C",address,value,byte_count);
10}
void WriteI2C(std::string const &base_address, uint16_t I2C_address, uint32_t data, uint8_t byte_count=4, bool ignore_error=false)
Definition WIBBase.cpp:69

◆ WriteDTS_CDS()

void WIB::WriteDTS_CDS ( uint16_t address,
uint32_t value,
uint8_t byte_count = 4,
bool ignore_error = false )

Definition at line 17 of file WIB_CDS.cpp.

17 {
18 WriteI2C("DTS.CDS.I2C",address,value,byte_count,ignore_error);
19}

◆ WriteDTS_SI5344()

void WIB::WriteDTS_SI5344 ( uint16_t address,
uint32_t value,
uint8_t byte_count = 4 )

Definition at line 8 of file WIB_SI5344.cpp.

8 {
9 WriteI2C("DTS.SI5344.I2C",address,value,byte_count);
10}

◆ WriteFEMBPhase()

void WIB::WriteFEMBPhase ( uint8_t iFEMB,
uint16_t clk_phase_data )

Definition at line 943 of file WIB_FEMB.cpp.

943 {
944
945 uint32_t clk_phase_data0 = (clk_phase_data >> 8) & 0xFF;
946 uint32_t clk_phase_data1 = clk_phase_data & 0xFF;
947
948 uint32_t data;
949 uint32_t read_back;
950 int count = 0;
951 sleep(0.001);
952 for(int i = 0; i < 10; ++i){
953
954 data = (~(clk_phase_data0)) & 0xFF;
955 WriteFEMB(iFEMB, 6, data);
956 sleep(0.001);
957 read_back = ReadFEMB(iFEMB, 6);
958 sleep(0.001);
959 if ( (read_back & 0xFF) == ((~(clk_phase_data0)) & 0xFF) ){
960 break;
961 }
962 else{
963 count++;
964 }
965 }
966 if( count >= 10){
967 std::cout << "readback val for 0 is different from written data "<< std::endl;
968 //Put in system exit?
969 }
970 count = 0;
971 for(int i = 0; i < 10; ++i){
972
973 data = (~(clk_phase_data1)) & 0xFF;
974 WriteFEMB(iFEMB, 15, data);
975 sleep(0.001);
976 read_back = ReadFEMB(iFEMB, 15);
977 sleep(0.001);
978 if ( (read_back & 0xFF) == ((~(clk_phase_data1)) & 0xFF) ){
979 break;
980 }
981 else{
982 count++;
983 }
984 }
985 if( count >= 10){
986 std::cout << "readback val for 1 is different from written data "<< std::endl;
987 //Put in system exit?
988 }
989 count = 0;
990 for(int i = 0; i < 10; ++i){
991
992 data = clk_phase_data0;
993 WriteFEMB(iFEMB, 6, data);
994 sleep(0.001);
995
996 read_back = ReadFEMB(iFEMB,6);
997 sleep(0.001);
998 if( (read_back & 0xFF) == ((clk_phase_data0) & 0xFF) ){
999 break;
1000 }
1001 else{
1002 count++;
1003 }
1004 }
1005 if( count >= 10){
1006 std::cout << "readback val for 2 is different from written data "<< std::endl;
1007 //Put in system exit?
1008 }
1009 count = 0;
1010 for(int i = 0; i < 10; ++i){
1011
1012 data = clk_phase_data1;
1013 WriteFEMB(iFEMB, 15, data);
1014 sleep(0.001);
1015
1016 read_back = ReadFEMB(iFEMB,6);
1017 sleep(0.001);
1018 if( (read_back & 0xFF) == ((clk_phase_data1) & 0xFF) ){
1019 break;
1020 }
1021 else{
1022 count++;
1023 }
1024 }
1025 if( count >= 10){
1026 std::cout << "readback val for 3 is different from written data "<< std::endl;
1027 //Put in system exit?
1028 }
1029}

◆ WriteFlash()

void WIB::WriteFlash ( std::vector< uint32_t > data,
uint8_t update_percentage = 101 )

Definition at line 236 of file WIB_Flash.cpp.

236 {
237 //Setup display if needed
238 bool print_updates = false;
239 if(update_percentage < 100){
240 print_updates = true;
241 }
242 size_t update_delta = (update_percentage * float(flashData.size()))/100;
243 size_t next_update = update_delta;
244 if(print_updates){
245 fprintf(stderr," Programming flash\n");
246 fprintf(stderr," [");
247 for(size_t i = 0; i < 100.0/update_percentage;i++){
248 fprintf(stderr,"=");
249 }
250 fprintf(stderr,"]\n [");
251 }
252
253
254 //program flash in groups of 64 32bit words (256 bytes)
255 uint32_t blockRegMapAddress = GetItem("FLASH.DATA00")->address; //Address of first of 64 32bit words
256 uint32_t flashAddress = 0; //Address in flash that we are writing to.
257
258 for(size_t currentBlockStartIndex = 0; currentBlockStartIndex < flashData.size();){
260
261 //Find size of this block to write (usually just 64 (256bytes)), but the last one might be smaller.
262 size_t blockSize = std::min(size_t(64),flashData.size()-currentBlockStartIndex);
263 //Set adddress
264 WriteWithRetry("FLASH.ADDRESS",flashAddress);
265 //set block size (in bytes and is 1 less than value; 0 means 1 byte, 255 means 256 bytes)
266 WriteWithRetry("FLASH.BYTE_COUNT",(blockSize*sizeof(uint32_t))-1);
267
268 //Write block of data
269 for(size_t iBlockWord = 0; iBlockWord < blockSize;iBlockWord++){
270 //arg1: Address in WIB register map of this 32bit word
271 //arg2: Data for this 32bit word reg map address in data vector
272 WriteWithRetry(blockRegMapAddress + iBlockWord,
273 flashData[currentBlockStartIndex + iBlockWord]);
274 }
275 //Do the block write
276 WriteWithRetry("FLASH.RUN_COMMAND",0x1);
277 currentBlockStartIndex += blockSize;
278 flashAddress += blockSize*sizeof(uint32_t);
279
280 //Update the screen if needed
281 if(print_updates && (currentBlockStartIndex > next_update)){
282 fprintf(stderr,"=");
283 next_update += update_delta;
284 }
285 }
286 //Update the screen if needed
287 if(print_updates){
288 fprintf(stderr,"]\n");
289 fprintf(stderr," done\n");
290 }
291
292}

◆ WriteLocalFlash() [1/2]

void WIB::WriteLocalFlash ( uint16_t address,
std::vector< uint32_t > const & data )

Definition at line 49 of file WIB_localFlash.cpp.

49 {
50 for(size_t iWord = 0; iWord < data.size();iWord++){
51 WriteLocalFlash(address,data[iWord]);
52 address++;
53 }
54}
void WriteLocalFlash(uint16_t address, uint32_t data)

◆ WriteLocalFlash() [2/2]

void WIB::WriteLocalFlash ( uint16_t address,
uint32_t data )

Definition at line 32 of file WIB_localFlash.cpp.

32 {
33 //load the address
34 Write("SYSTEM.FLASH.ADDRESS",address);
35 //load the data to write
36 Write("SYSTEM.FLASH.WR_DATA",data);
37
38 //start the read transaction
39 Write("SYSTEM.FLASH.RW",0);
40 Write("SYSTEM.FLASH.RUN",1);
41 //Wait for finish
42 while(Read("SYSTEM.FLASH.DONE") == 0){
43 //sleep for 1ms
44 usleep(1000);
45 }
46}

◆ WriteQSFP()

void WIB::WriteQSFP ( uint16_t address,
uint32_t value,
uint8_t byte_count )

Definition at line 7 of file WIB_QSFP.cpp.

7 {
8 WriteI2C("DAQ.QSFP.I2C",address,value,byte_count);
9}

Member Data Documentation

◆ ContinueIfListOfFEMBClockPhasesDontSync

bool WIB::ContinueIfListOfFEMBClockPhasesDontSync
private

Definition at line 240 of file WIB.hh.

◆ ContinueOnFEMBRegReadError

bool WIB::ContinueOnFEMBRegReadError
private

Definition at line 237 of file WIB.hh.

◆ ContinueOnFEMBSPIError

bool WIB::ContinueOnFEMBSPIError
private

Definition at line 238 of file WIB.hh.

◆ ContinueOnFEMBSyncError

bool WIB::ContinueOnFEMBSyncError
private

Definition at line 239 of file WIB.hh.

◆ DAQLinkCount

uint8_t WIB::DAQLinkCount
private

Definition at line 235 of file WIB.hh.

◆ DAQMode

WIB_DAQ_t WIB::DAQMode
private

Definition at line 231 of file WIB.hh.

◆ FEMBCDACount

uint8_t WIB::FEMBCDACount
private

Definition at line 234 of file WIB.hh.

◆ FEMBCount

uint8_t WIB::FEMBCount
private

Definition at line 232 of file WIB.hh.

◆ FEMBStreamCount

uint8_t WIB::FEMBStreamCount
private

Definition at line 233 of file WIB.hh.

◆ started

bool WIB::started

Definition at line 33 of file WIB.hh.


The documentation for this class was generated from the following files: