#ifndef ABI_FUNCTIONS_H #define ABI_FUNCTIONS_H #include #include #include #include #include #include "rbm_functions.h" #include "rcu2_addr_map.h" /* ============================================================= ALTRO access functions ============================================================= */ #define CMD_ALTRO_RD 0x1100 // READ #define CMD_ALTRO_WR 0x1200 // WRITE #define CMD_ALTRO_BC 0x1400 // BROADCAST unsigned int parity( unsigned int val ) { // // Calculate parity // val ^= val >> 16; val ^= val >> 8; val ^= val >> 4; val ^= val >> 2; val ^= val >> 1; val &= 0x01; return val; }; unsigned int genAltroAddrHwAddr( int bcast, int hwaddr, int reg ) { // // Generate the address including parity // unsigned int res = reg & 0x1F; res |= (hwaddr & 0x7FF) << 5; // Dont use branch bit res |= (bcast & 0x01) << 18; res |= parity(res) << 19; return res; } unsigned int genAltroAddr( int bcast, int fec, int altro, int channel, int reg ) { // // Generate the address including parity // unsigned int res = reg & 0x1F; res |= (channel & 0x0F) << 5; res |= (altro & 0x07) << 9; res |= (fec & 0x0F) << 12; // Dont use branch bit res |= (bcast & 0x01) << 18; res |= parity(res) << 19; return res; } int check_ABI_CSR_Error( int branch, int verbose ) { // // check for transaction errors // int error_code = 0; if (rbm_read(get_Address_ABI_CSR(branch), &error_code, verbose)) { printf("check_ABI_CSR_Error: Error when reading ABI_CSR register\n"); return 1; } return (error_code&0xFF); } int check_ABI_CSR_Status( int branch , int verbose ) { // // Check transaction status. Return 0 when transaction done // int status = 0; rbm_read(get_Address_ABI_CSR(branch), &status, verbose); return status&0x1000; } int altro_write( int branch, unsigned int addr, unsigned int value, int verbose ) { // // write to the ABI TRX registers // unsigned int status = 0; unsigned int timer = 0; if (rbm_write(get_Address_ABI_TX_L(branch), value, verbose)) { // write data value to ABI register printf("altro_write: Error when writing to ABI_TX_L register\n"); return 1; } if (rbm_write(get_Address_ABI_TX_H(branch), addr, verbose)) { // write address value to ABI register printf("altro_write: Error when writing to ABI_TX_H register\n"); return 1; } if (rbm_write(get_Address_ABI_CSR(branch) , CMD_ALTRO_WR, verbose)) { // and send the write command to the ABI printf("altro_write: Error when writing to ABI_CSR register\n"); } do { timer++; status = check_ABI_CSR_Status(branch, verbose); if (timer > 1000) { printf("altro_write: ERROR in ALTRO_WRITE: TIMEOUT!\n"); return 2; } } while ( status ); if (verbose>5) printf("ALTRO_WRITE Timer : %d\n",timer); return (check_ABI_CSR_Error(branch, verbose)); // return error code } int altro_read( int branch, unsigned int addr, unsigned int *value, int verbose ) { // // write to the ABI TRX registers // unsigned int status = 0; unsigned int timer = 0; if (rbm_write(get_Address_ABI_TX_H(branch), addr, verbose)) { // write address value to ABI register printf("altro_read: Error when writing to ABI_TX_H register\n"); return 1; } if (rbm_write(get_Address_ABI_CSR(branch), CMD_ALTRO_RD, verbose)) { // and send the write command to the ABI printf("altro_read: Error when writing to ABI_CSR register\n"); return 1; } do { timer++; status = check_ABI_CSR_Status(branch, verbose); if (timer > 1000) { printf("ERROR in ALTRO_READ: TIMEOUT!\n"); return 2; } } while ( status ); if (verbose>5) printf("ALTRO_READ Timer : %d\n",timer); unsigned int result = 0; if (rbm_read(get_Address_ABI_RX_L(branch), &result, verbose)) { // read back the value from the TRX register printf("altro_read: Error when reading ABI_RX_L register\n"); return 1; } if (verbose>5) printf("Value read from ABI_RX_L register: 0x%X\n", result); *value = result; return 0; }; int altro_bcast( int branch, unsigned int addr, unsigned int value, int verbose ) { // // write to the ABI TRX registers // unsigned int status = 0; unsigned int timer = 0; if (rbm_write(get_Address_ABI_TX_L(branch), value, verbose)) { // write data value to ABI register printf("altro_bcast: Error when writing to ABI_TX_L register\n"); return 1; } if (rbm_write(get_Address_ABI_TX_H(branch), addr, verbose)) { // write address value to ABI register printf("altro_bcast: Error when writing to ABI_TX_H register\n"); } if (rbm_write(get_Address_ABI_CSR(branch) , CMD_ALTRO_BC, verbose)) { // and send the broadcast command to the ABI printf("altro_bcast: Error when writing to ABI_CSR register\n"); return 1; } do { timer++; status = check_ABI_CSR_Status(branch, verbose); if (timer > 1000) { printf("ERROR in ALTRO_BCAST: TIMEOUT!\n"); return 2; } } while ( status ); if (verbose>5) printf("ALTRO_BCAST Timer : %d\n",timer); return (check_ABI_CSR_Error(branch, verbose)); // return error code }; //======================================================================== // Dump RCU2 ALTRO Bus Optimization registers //======================================================================== //======================================================================== int Dump_ABI_CHRDO_PHASE(int verbose) { // // Dump the values from the CHRDO PHASE register // int branch; unsigned int data = 0; for (branch=0; branch<4; branch++){ if (rbm_read(get_Address_ABI_CHRDO_PHASE(branch), &data, verbose)) { printf("ERROR: Could not read ABI_CHRDO_PHASE\n"); return 1; } printf("ABI_CHRDO_PHASE (Branch %d)= 0x%X\n",branch, data); printf(" => Bit 11..0 (Low level signal control) = 0x%X (MUST BE 0x3B9)\n", data&0xFFF); if ( (data&0xFFF) != 0x3B9 ) printf(" VALUE IS NOT 0x3B9!!!\n"); printf(" => Bit 15..12 (Sequence of bus control phases) = 0x%X => ", (data>>12)&0xF); switch ( (data>>12)&0xF ) { case 0x0: printf("using 3 phases\n"); printf(" (1. Enable FPGA Output Buffer, 2. Enable GTL, 3. Assert CSTB. Original RCU1 setting.)\n"); break; case 0x1: printf("using 2 phases\n"); printf(" (1. Enable FPGA Output Buffer and GTL, 2. Assert CSTB)\n"); break; case 0x2: printf("using 1 phase (default)\n"); printf(" (Enable FPGA Output Buffer and GTL and assert CSTB all at once.)\n"); break; default: printf(" undefined\n"); break; } printf(" => Bit 31..16 (CSTB Control. CSTB Assert time) = 0x%X\n", (data>>16)&0xF); if ( ((data>>16)&0xFFFF) < 8 ) printf(" VALUE SHOULD BE > 8! OTHERWISE ERRORS POSSIBLE\n"); } return 0; } //======================================================================== // ALTRO Dump functions //======================================================================== //======================================================================== int Dump_FECERR(unsigned int branch, int verbose) { // // Dump the content of RCU2 FECERR register for this branch // unsigned int data = 0; rbm_read(get_Address_ABI_FECERR(branch), &data, verbose); printf("FECERR content for branch %d (", branch); if (branch == 0) printf("AI)"); else if (branch == 1) printf("AO)"); else if (branch == 2) printf("BI)"); else if (branch == 3) printf("BO)"); printf(" = 0x%X\n", data&0xFFFFF); if ( (data>>0)&0x1) printf(" => Bit 0 (ACK not asserted during read transaction (time-out))\n"); if ( (data>>1)&0x1) printf(" => Bit 1 (ACK not released during read transaction (time-out))\n"); if ( (data>>2)&0x1) printf(" => Bit 2 (ACK not asserted during write transaction (time-out))\n"); if ( (data>>3)&0x1) printf(" => Bit 3 (ACK not released during write transaction (time-out))\n"); if ( (data>>4)&0x1) printf(" => Bit 4 (TRSF not asserted during CHRDO transaction (time-out))\n"); if ( (data>>5)&0x1) printf(" => Bit 5 (TRSF not released during CHDRO transaction (time-out))\n"); if ( (data>>6)&0x1) printf(" => Bit 6 (DSTB never asserted during CHDRO (no data received from ALTRO))\n"); if ( (data>>7)&0x1) printf(" => Bit 7 (ACK asserted outside of transaction (stuck))\n"); if ( (data>>8)&0x1) printf(" => Bit 8 (TRSF asserted outside of transaction (stuck))\n"); if ( (data>>9)&0x1) printf(" => Bit 9 (DSTB asserted outside of transaction (stuck))\n"); if ( (data>>15)&0x1) { printf(" => Bit 15 (ALTRO ERROR asserted)\n"); printf(" => Bit 14 - 10 = 0x%X : FSM Error code in case ERR is asserted during any transaction\n"); } return 0; }; //======================================================================== int Dump_ALTRO_ZSTHR(unsigned int branch, unsigned int fec, unsigned int altro, int verbose) { // // Dump the content of ALTRO global register ZSTHR // unsigned int data = 0; if ( altro_read(branch, genAltroAddr(0, fec, altro, 0, 0x8), &data, verbose) ) { printf("ERROR: Could not read ZSTHR register!\n"); return 1; } printf("ZSTHR = 0x%X\n", data&0xFFFFF); printf(" => Bit 9..0 (ZS_THR) = 0x%X = %d\n", data&0x3FF, data&0x3FF); printf(" => Bit 19..10 (OFFSET) = 0x%X = %d\n", (data>>10)&0x3FF, (data>>10)&0x3FF); return 0; }; //======================================================================== int Dump_ALTRO_BCTHR(unsigned int branch, unsigned int fec, unsigned int altro, int verbose) { // // Dump the content of ALTRO global register BCTHR // unsigned int data = 0; if ( altro_read(branch, genAltroAddr(0, fec, altro, 0, 0x9), &data, verbose) ) { printf("ERROR: Could not read BCTHR register!\n"); return 1; } printf("BCTHR = 0x%X\n", data&0xFFFFF); printf(" => Bit 9..0 (THR_LO) = 0x%X = %d\n", data&0x3FF, data&0x3FF); printf(" => Bit 19..10 (THR_HI) = 0x%X = %d\n", (data>>10)&0x3FF, (data>>10)&0x3FF); return 0; }; //======================================================================== int Dump_ALTRO_TRCFG(unsigned int branch, unsigned int fec, unsigned int altro, int verbose) { // // Dump the content of ALTRO global register TRCFG // unsigned int data = 0; if ( altro_read(branch, genAltroAddr(0, fec, altro, 0, 0xA), &data, verbose) ) { printf("ERROR: Could not read TRCFG register!\n"); return 1; } printf("TRCFG = 0x%X\n", data&0xFFFFF); printf(" => Bit 9..0 (ACQ_END) = 0x%X = %d\n", data&0x3FF, data&0x3FF); printf(" => Bit 19..10 (ACQ_START) = 0x%X = %d\n", (data>>10)&0x3FF, (data>>10)&0x3FF); return 0; }; //======================================================================== int Dump_ALTRO_DPCFG(unsigned int branch, unsigned int fec, unsigned int altro, int verbose) { // // Dump the content of ALTRO global register DPCFG // unsigned int data = 0; if ( altro_read(branch, genAltroAddr(0, fec, altro, 0, 0xB), &data, verbose) ) { printf("ERROR: Could not read DPCFG register!\n"); return 1; } printf("DPCFG = 0x%X\n", data&0xFFFFF); printf(" => Bit 4..0 (BC1_CFG) = 0x%X\n", data&0x1F); printf(" Bit 3..0 => First Baseline Correction Mode: 0x%X => ", data&0xF); switch (data&0xF) { case 0x0: printf("DIN-FPD\n"); break; case 0x1: printf("DIN-PEDMEM\n"); break; case 0x2: printf("DIN-f(DIN)\n"); break; case 0x3: printf("DIN-f(DIN-VPD)\n"); break; case 0x4: printf("DIN-VPD-FPD\n"); break; case 0x5: printf("DIN-VPD-PEDMEM\n"); break; case 0x6: printf("DIN-VPD-f(DIN)\n"); break; case 0x7: printf("DIN-VPD-f(DIN-VPD)\n"); break; case 0x8: printf("f(DIN)-FPD\n"); break; case 0x9: printf("f(DIN-VPD)-FPD\n"); break; case 0xA: printf("PEDMEM-FPD\n"); break; case 0xB: printf("PEDMEM-PEDMEM\n"); break; case 0xC: printf("f(DIN)-f(DIN)\n"); break; case 0xD: printf("f(DIN-VPD)–f(DIN-VPD)"); break; case 0xE: printf("DIN-FPD\n"); break; case 0xF: printf("DIN-FPD\n"); break; default: printf("UNDEFINED?\n"); break; } printf(" Bit 4 => Polarity: %d => ", (data>>4)&0x1); if ( ((data>>4)&0x1) ) printf("ADC data is inverted\n"); else printf("ADC data is sent as is\n"); printf(" => Bit 11..5 (BC2_CFG) = 0x%X\n", (data>>5)&0x7F); printf(" Bit 6..5 => Number of presamples excluded from BC2: %d\n", (data>>5)&0x3); printf(" Bit 10..7 => Number of postsamples excluded from BC2: %d\n", (data>>7)&0xF); printf(" Bit 11 => Enable BC2: %d\n", (data>>11)&0x1); printf(" => Bit 19..12 (ZS_CFG) = 0x%X\n", (data>>12)&0xFF); printf(" Bit 13..12 => Glitch filter configuration: %d\n", (data>>12)&0x3); printf(" Bit 16..14 => Number of postsamples excluded from ZS: %d\n", (data>>14)&0x7); printf(" Bit 18..17 => Number of presamples excluded from ZS: %d\n", (data>>17)&0x3); printf(" Bit 19 => Enable ZS: %d\n", (data>>19)&0x1); return 0; }; //======================================================================== int Dump_ALTRO_DPCF2(unsigned int branch, unsigned int fec, unsigned int altro, int verbose) { // // Dump the content of ALTRO global register DPCF2 // unsigned int data = 0; if ( altro_read(branch, genAltroAddr(0, fec, altro, 0, 0xC), &data, verbose) ) { printf("ERROR: Could not read DPCF2 register!\n"); return 1; } printf("DPCF2 = 0x%X\n", data&0x7F); printf(" => Bit 3..0 (PTRG) = %d\n", data&0xF); printf(" => Bit 4 (NBUF) = %d => ", (data>>4)&0x1); if ( ((data>>4)&0x1) ) printf("8 buffers\n"); else printf("4 buffers\n"); printf(" => Bit 5 (FLT_EN) = %d\n", (data>>5)&0x1); printf(" => Bit 6 (PWSV) = %d\n", (data>>6)&0x1); return 0; }; //======================================================================== int Dump_ALTRO_ERSTR(unsigned int branch, unsigned int fec, unsigned int altro, int verbose) { // // Dump the content of ALTRO global register ERSTR // unsigned int data = 0; if ( altro_read(branch, genAltroAddr(0, fec, altro, 0, 0x10), &data, verbose) ) { printf("EROR: Could not read ERSTR register!\n"); return 1; } printf("ERSTR = 0x%X\n", data&0xFFFFF); printf(" => Bit 2..0 (Read Pointer) = 0x%X\n", data&0x7); printf(" => Bit 5..3 (Write Pointer) = 0x%X\n", (data>>3)&0x7); printf(" => Bit 9..6 (Remaining buffers) = %d\n", (data>>6)&0xF); printf(" => Bit 10 (FULL) = %d\n", (data>>10)&0x1); printf(" => Bit 11 (EMPTY) = %d\n", (data>>11)&0x1); printf(" => Bit 12 (Parity Error) = %d\n", (data>>12)&0x1); printf(" => Bit 13 (Instruction Error) = %d\n", (data>>13)&0x1); printf(" => Bit 14 (Trigger Overlap) = %d\n", (data>>14)&0x1); printf(" => Bit 15 (MMU 1 SEU) = %d\n", (data>>15)&0x1); printf(" => Bit 16 (MMU 2 SEU) = %d\n", (data>>16)&0x1); printf(" => Bit 17 (INT 1 SEU) = %d\n", (data>>17)&0x1); printf(" => Bit 18 (INT 2 SEU) = %d\n", (data>>18)&0x1); printf(" => Bit 19 (RDO Error) = %d\n", (data>>19)&0x1); return 0; }; //======================================================================== int Dump_ALTRO_TRCNT(unsigned int branch, unsigned int fec, unsigned int altro, int verbose) { // // Dump the content of ALTRO global register TRCNT // unsigned int data = 0; if ( altro_read(branch, genAltroAddr(0, fec, altro, 0, 0x12), &data, verbose) ) { printf("ERROR: Could not read TRCNT register!\n"); return 1; } printf("TRCNT = 0x%X = %d\n", data&0xFFFF, data&0xFFFF); return 0; }; //======================================================================== int Dump_ALTRO_Channel_Registers(unsigned int branch, unsigned int fec, unsigned int altro, int channel, int verbose) { // // Dump the content of the ALTRO channel registers // unsigned int data = 0; if ( altro_read(branch, genAltroAddr(0, fec, altro, channel, 0x0), &data, verbose) ) { printf("ERROR: Could not read K1 register for channel %d\n", channel); return 1; } printf("Ch%02i: K1=0x%X ", channel, data&0xFFFF); if ( altro_read(branch, genAltroAddr(0, fec, altro, channel, 0x1), &data, verbose) ) { printf("ERROR: Could not read K2 register for channel %d\n", channel); return 1; } printf("K2=0x%X ", data&0xFFFF); if ( altro_read(branch, genAltroAddr(0, fec, altro, channel, 0x2), &data, verbose) ) { printf("ERROR: Could not read K3 register for channel %d\n", channel); return 1; } printf("K3=0x%X ", data&0xFFFF); if ( altro_read(branch, genAltroAddr(0, fec, altro, channel, 0x3), &data, verbose) ) { printf("ERROR: Could not read L1 register for channel %d\n", channel); return 1; } printf("L1=0x%X ", data&0xFFFF); if ( altro_read(branch, genAltroAddr(0, fec, altro, channel, 0x4), &data, verbose) ) { printf("ERROR: Could not read L2 register for channel %d\n", channel); return 1; } printf("L2=0x%X ", data&0xFFFF); if ( altro_read(branch, genAltroAddr(0, fec, altro, channel, 0x5), &data, verbose) ) { printf("ERROR: Could not read L3 register for channel %d\n", channel); return 1; } printf("L3=0x%X ", data&0xFFFF); if ( altro_read(branch, genAltroAddr(0, fec, altro, channel, 0x6), &data, verbose) ) { printf("ERROR: Could not read VFPED register for channel %d\n", channel); return 1; } printf("FPED=%d VPED=%d ", data&0x3FF, (data>>10)&0x3FF); if ( altro_read(branch, genAltroAddr(0, fec, altro, channel, 0x11), &data, verbose) ) { printf("ERROR: Could not read ADEVL register for channel %d\n", channel); return 1; } printf("EVL=0x%X HwADD=0x%X\n", data&0xFF, (data>>8)&0xFF); return 0; }; #endif // ABI_FUNCTIONS_H