//------------------------------------------------------------------------------ // Dark registers interface -- // (C) Piero Giubilato 2008-2010, Berkeley Lab -- //------------------------------------------------------------------------------ //______________________________________________________________________________ // {Trace} // [File name] "comm_Reg.cpp" // [Author] "Piero Giubilato" // [Version] "1.1" // [Modified by] "Piero Giubilato, Devis Contarato" // [Last revision] "17 Mar 2009" // [Language] "C++" // [Compiler] "Visual C++ 9.x" // [Member of] "Cool SEAL" // [Project] "SEAL" // [Description] "Provides meaningful access to DARK registers" // [Key documentation] // "Dark SEAL documentation, in particular mdl_Register.vhd" // "Visual C++ Reference Help" // {Trace} //______________________________________________________________________________ // Standard components #include // Application components #include "global.h" #include "comm_Master.h" #include "comm_Reg.h" //______________________________________________________________________________ // Static member instantiation // Singleton comm_Reg* comm_Reg::inst_Handle = 0; int comm_Reg::inst_Count = 0; // Registers storage unsigned int comm_Reg::reg_Word[32]; //______________________________________________________________________________ // Provides a safe self-destruction mechanism in case of missed destruction class RegCleaner { public: ~RegCleaner() {comm_Reg::instance_Destroy();} } RegCleanerInst; //______________________________________________________________________________ comm_Reg* comm_Reg::instance_Load() { // Loads one instance of the class dbg_Print("comm_Reg::instance_Load: singleton initializer called", DBG_LVL_ZERO); // Just loads one class instance if (inst_Count == 0) { inst_Handle = new comm_Reg(); inst_Count ++; } // Returns the instance handle return inst_Handle; } //______________________________________________________________________________ void comm_Reg::instance_Destroy() { // Kills the active instance dbg_Print("comm_Master::instance_Destroy: singleton destroyer called", DBG_LVL_ZERO); // Deletes the current class instance if (inst_Handle) { inst_Handle = 0; inst_Count = 0; } } //______________________________________________________________________________ comm_Reg::comm_Reg() { // Default constructor dbg_Print("comm_Reg::comm_Reg: constructor called", DBG_LVL_ZERO); // Here the update list of DARK registers // Register 0: General acquisition parameters // // word #0 (15 to 0) (1 to 0) -> Acquisition mode (2 bit) // (5 to 2) -> Data mode (4 bit) // (7 to 6) -> Internal trigger mode (2 bit) // (15 to 8) -> Driver selector (8 bit) // word #1 (31 to 16) (23 to 16) -> Driver delay (fine) (8 bit) // (31 to 24) -> Driver delay (raw) (8 bit) // word #2 (47 to 32) (47 to 32) -> Internal trigger period (16 bit) // word #3 (63 to 48) (55 to 48) -> Channel enabled (8 bit) // (63 to 56) -> Unused (8 bit) // word #4 (79 to 64) (79 to 64) -> Number of frames (16 bit) // word #5,6 (111 to 80) (103 to 80) -> Number of data points (24 bit) // (111 to 104)-> Unused (8 bit) // word #7 (127 to 112) (123 to 111)-> Dummy driver cols/rows (12 bit) // Register 1: Data trigger // // word #0 (15 to 0) (0 to 0) -> Trg Mode (1 bit) // (1 to 1) -> Trg Slope (1 bit) // (7 to 3) -> Unused (6 bit) // (15 to 8) -> Trg channels (8 bit) // word #1 (31 to 16) (31 to 16) -> Trg threshold (16 bit) // word #2,3 (55 to 32) (55 to 32) -> Trg delay (24 bit) // word #3 (63 to 56) (63 to 56) -> Unused (8 bit) // word #4,5 (87 to 64) (87 to 64) -> Trg count (24 bit) // word# 5,6,7 (127 to 88) (127 to 88) -> Unused (24 bit) // Register 2: ADCs input, Chip parameters, DDR2 controller parameter // // word #0 (15 to 0) (3 to 0) -> Clock channel (4 bit) // (7 to 4) -> Unused (4 bit) // (11 to 8) -> Clock divider (4 bit) // (15 to 12) -> Unused (4 bit) // word #1 (31 to 16) (18 to 16) -> Averages per sample (3 bit) // (31 to 19) -> Unused (13 bit) // word #2 (47 to 32) (47 to 32) -> Chip settings (16 bit) // word #3,4 (71 to 48) (63 to 48) -> DDR2 controller data (16 bit) // (71 to 64) -> DDR2 controller commands(8 bit) // all other words (127 to 72) -> Unused (56 bit) } //______________________________________________________________________________ comm_Reg::~comm_Reg() { // Default destructor dbg_Print("comm_Reg::~comm_Reg: destructor called", DBG_LVL_ZERO); } //______________________________________________________________________________ unsigned int comm_Reg::bit_Value(unsigned short *buffer, unsigned short buf_Len, unsigned short bit_Start, unsigned short bit_Stop) { // Extracts the bits between bit_Start and bit_Stop, boundaries included, // and returns them as an unsigned int (4 bytes) value dbg_Print("comm_Reg::bit_Value(short): retriving bit(s) value", DBG_LVL_ZERO); // Boundaries check if (bit_Start > bit_Stop) return 0; if (bit_Stop >= (buf_Len * 16)) return 0; // Extracts the value unsigned int result = 0; for (int i = bit_Stop; i >= bit_Start; i--) { result <<= 1; result |= (buffer[(i >> 4)] >> (i & 15) & 1); } // Give back the result return result; } //______________________________________________________________________________ unsigned int comm_Reg::bit_Value(unsigned short *buffer, unsigned short buf_Len, unsigned short bit_Start, unsigned short bit_Stop, unsigned int value) { // Sets the bits between bit_Start and bit_Stop, boundaries included dbg_Print("comm_Reg::bit_Value(short): setting bit(s) value", DBG_LVL_ZERO); // Boundaries check if (bit_Start > bit_Stop) return 0; if (bit_Stop >= (buf_Len * 16)) return 0; // Sets the value for (unsigned int i = bit_Start; i <= bit_Stop; i++) { // Erases the bit buffer[(i >> 4)] &= ~(1 << (i & 15)); // Add the new value buffer[(i >> 4)] |= ((value & 1) << (i & 15)); // Shifts the value value >>= 1; } // Give back the result return value; } //______________________________________________________________________________ unsigned int comm_Reg::reg_Value(unsigned short reg_Idx, unsigned short bit_Start, unsigned short bit_Stop) { // Extracts the bits between bit_Start and bit_Stop, boundaries included, // and returns them as an unsigned int (4 bytes) value dbg_Print("comm_Reg::reg_Value: retriving bit(s) value", DBG_LVL_ZERO); // Register check if (reg_Idx > 3) return 0; // Boundaries check if (bit_Start > bit_Stop) return 0; if (bit_Stop > 127) return 0; // Retrieves the register unsigned short buffer[8]; comm_Master::reg_Read(reg_Idx, buffer, 8); // Extracts the value return bit_Value(buffer, 8, bit_Start, bit_Stop); } //______________________________________________________________________________ unsigned int comm_Reg::reg_Value(unsigned short reg_Idx, unsigned short bit_Start, unsigned short bit_Stop, unsigned int value) { // Sets the bits between bit_Start and bit_Stop, boundaries included' dbg_Print("comm_Reg::reg_Value: setting bit(s) value", DBG_LVL_ZERO); // Register check if (reg_Idx > 3) return 0; // Boundaries check if (bit_Start > bit_Stop) return 0; if (bit_Stop > 127) return 0; // Retrieves the register unsigned short buffer[8]; comm_Master::reg_Read(reg_Idx, buffer, 8); // Sets the value bit_Value(buffer, 8, bit_Start, bit_Stop, value); // Saves the register comm_Master::reg_Write(reg_Idx, buffer, 8); // Exit return value; } // ----------------------------------------------------------------------------- // Acquisition // ----------------------------------------------------------------------------- //______________________________________________________________________________ unsigned int comm_Reg::acq_Mode() { // Gets the acquisition mode value return reg_Value(0, 0, 1); } //______________________________________________________________________________ unsigned int comm_Reg::acq_Mode(unsigned int mode) { // Sets the acquisition mode value return reg_Value(0, 0, 1, mode); } //______________________________________________________________________________ unsigned int comm_Reg::acq_data_Mode() { // Gets the acquisition data mode value return reg_Value(0, 2, 5); } //______________________________________________________________________________ unsigned int comm_Reg::acq_data_Mode(unsigned int mode) { // Sets the acquisition data mode value return reg_Value(0, 2, 5, mode); } //______________________________________________________________________________ unsigned int comm_Reg::acq_trg_Mode() { // Gets the acquisition trigger mode // 0 = internal, 1 = external return reg_Value(0, 6, 7); } //______________________________________________________________________________ unsigned int comm_Reg::acq_trg_Mode(unsigned int mode) { // Sets the acquisition trigger mode // 0 = internal, 1 = external return reg_Value(0, 6, 7, mode); } //______________________________________________________________________________ unsigned int comm_Reg::acq_trg_Period() { // Gets the acquisition trigger period return reg_Value(0, 32, 47); } //______________________________________________________________________________ unsigned int comm_Reg::acq_trg_Period(unsigned int period) { // Sets the acquisition trigger period return reg_Value(0, 32, 47, period); } //______________________________________________________________________________ unsigned int comm_Reg::acq_drv_Sel() { // Gets the currently selected driver // 0 = no driver return reg_Value(0, 8, 15); } //______________________________________________________________________________ unsigned int comm_Reg::acq_drv_Sel(unsigned int Idx) { // Sets the driver to enable // 0 = no driver return reg_Value(0, 8, 15, Idx); } //______________________________________________________________________________ unsigned int comm_Reg::acq_drv_Delay() { // Gets the driver synch delay return reg_Value(0, 16, 31); } //______________________________________________________________________________ unsigned int comm_Reg::acq_drv_Delay(unsigned int delay) { // The first LSB 8 bits (values from 0 to 255) drive the fine tuning, where // each step is about 78ps (standard DARK firmware implementation). // The 8 MSB bits control the raw tuning, where each step is about 1ns. // Sets the driver synch delay return reg_Value(0, 16, 31, delay); } //______________________________________________________________________________ unsigned int comm_Reg::acq_chn_Enable() { // Gets enabled channels (one hot encoding) return reg_Value(0, 48, 55); } //______________________________________________________________________________ unsigned int comm_Reg::acq_chn_Enable(unsigned int chns) { // Sets enabled channels (one hot encoding) return reg_Value(0, 48, 55, chns); } //______________________________________________________________________________ unsigned int comm_Reg::acq_frm_Count() { // Gets the number of frames to be acquired return reg_Value(0, 64, 79); } //______________________________________________________________________________ unsigned int comm_Reg::acq_frm_Count(unsigned int count) { // Sets the number of frame to be acquired return reg_Value(0, 64, 79, count); } //______________________________________________________________________________ unsigned int comm_Reg::acq_dp_Count() { // Gets the number of dp per channel return reg_Value(0, 80, 103); } //______________________________________________________________________________ unsigned int comm_Reg::acq_dp_Count(unsigned int count) { // Sets the number of dp per channel return reg_Value(0, 80, 103, count); } //______________________________________________________________________________ unsigned int comm_Reg::acq_dmy_Size() { // Gets the size (pixels) of the detector simulated by the dummy // driver inside the FPGA (cols = rows) return reg_Value(0, 112, 123); } //______________________________________________________________________________ unsigned int comm_Reg::acq_dmy_Size(unsigned int count) { // Sets the size (pixels) of the detector simulated by the dummy // driver inside the FPGA (cols = rows) return reg_Value(0, 112, 123, count); } // ----------------------------------------------------------------------------- // Data trigger // ----------------------------------------------------------------------------- //______________________________________________________________________________ unsigned int comm_Reg::data_trg_Mode() { // Gets the data triggering mode return reg_Value(1, 0, 0); } //______________________________________________________________________________ unsigned int comm_Reg::data_trg_Mode(unsigned int mode) { // Sets the data triggering mode // 0 = on data, 1 = external return reg_Value(1, 0, 0, mode); } //______________________________________________________________________________ unsigned int comm_Reg::data_trg_Slope() { // Gets the data triggering slope return reg_Value(1, 1, 1); } //______________________________________________________________________________ unsigned int comm_Reg::data_trg_Slope(unsigned int slope) { // Sets the data triggering slope return reg_Value(1, 1, 1, slope); } //______________________________________________________________________________ unsigned int comm_Reg::data_trg_Chn() { // Gets the channel enabled for data triggering return reg_Value(1, 8, 15); } //______________________________________________________________________________ unsigned int comm_Reg::data_trg_Chn(unsigned int channels) { // Sets the channel enabled for data triggering return reg_Value(1, 8, 15, channels); } //______________________________________________________________________________ unsigned int comm_Reg::data_trg_Thr() { // Gets the data triggering threshold return reg_Value(1, 16, 31); } //______________________________________________________________________________ unsigned int comm_Reg::data_trg_Thr(unsigned int threshold) { // Sets the data triggering threshold return reg_Value(1, 16, 31, threshold); } //______________________________________________________________________________ unsigned int comm_Reg::data_trg_Delay() { // Gets the data triggering delay return reg_Value(1, 32, 55); } //______________________________________________________________________________ unsigned int comm_Reg::data_trg_Delay(unsigned int delay) { // Sets the data triggering delay return reg_Value(1, 32, 55, delay); } //______________________________________________________________________________ unsigned int comm_Reg::data_trg_Count() { // Gets the data triggering count return reg_Value(1, 64, 87); } //______________________________________________________________________________ unsigned int comm_Reg::data_trg_Count(unsigned int count) { // Sets the data triggering count return reg_Value(1, 64, 87, count); } // ----------------------------------------------------------------------------- // ADCs // ----------------------------------------------------------------------------- //______________________________________________________________________________ unsigned int comm_Reg::adc_clk_Chn() { // Gets the number of frames to be acquired return reg_Value(2, 0, 3); } //______________________________________________________________________________ unsigned int comm_Reg::adc_clk_Chn(unsigned int chn) { // Sets the number of frame to be acquired return reg_Value(2, 0, 3, chn); } //______________________________________________________________________________ unsigned int comm_Reg::adc_clk_Div() { // Gets the number of frames to be acquired return reg_Value(2, 8, 11); } //______________________________________________________________________________ unsigned int comm_Reg::adc_clk_Div(unsigned int divider) { // Sets the number of frame to be acquired return reg_Value(2, 8, 11, divider); } //______________________________________________________________________________ unsigned int comm_Reg::adc_Avgs() { // Gets the number of frames to be acquired return reg_Value(2, 16, 18); } //______________________________________________________________________________ unsigned int comm_Reg::adc_Avgs(unsigned int avgs) { // Sets the number of frame to be acquired return reg_Value(2, 16, 18, avgs); } //______________________________________________________________________________ unsigned int comm_Reg::chp_Pars() { // Gets the chip specific settings return reg_Value(2, 32, 47); } //______________________________________________________________________________ unsigned int comm_Reg::chp_Pars(unsigned int pars) { // Sets the chip specific settings return reg_Value(2, 32, 47, pars); } //______________________________________________________________________________ unsigned int comm_Reg::ddr_Cmd() { // Gets the DDR2 command return reg_Value(2, 64, 71); } //______________________________________________________________________________ unsigned int comm_Reg::ddr_Cmd(unsigned int cmd) { // Sets the DDR2 command return reg_Value(2, 64, 71, cmd); } //______________________________________________________________________________ unsigned int comm_Reg::ddr_Data() { // Gets the DDR2 data return reg_Value(2, 48, 63); } //______________________________________________________________________________ unsigned int comm_Reg::ddr_Data(unsigned int data) { // Sets the DDR2 data return reg_Value(2, 48, 63, data); }