//------------------------------------------------------------------------------ // Application task example -- // (C) Piero Giubilato 2008-2010, Berkeley Lab -- //------------------------------------------------------------------------------ //______________________________________________________________________________ // {Trace} // [File name] "task_Demo.cpp" // [Author] "Piero Giubilato" // [Version] "1.0" // [Modified by] "Piero Giubilato" // [Last revision] "09 Feb 2009" // [Language] "C++" // [Compiler] "Visual C++ 8.x 9.x" // [Member of] "Cool SEAL" // [Project] "SEAL" // [Description] "Application task example" // [Key documentation] // "Visual C++ Reference Help" // {Trace} //______________________________________________________________________________ // Standard components #include // Root components // Application components #include "global.h" #include "cool.h" #include "task_Demo.h" //______________________________________________________________________________ task_Demo::task_Demo() { // Standard constructor dbg_Print("task_Demo::task_Demo:()", DBG_LVL_ZERO); // Clears handles burst_Raw = 0; frame_Pedestal = 0; frame_Noise = 0; // Set up the detectors detector_Setup(); // Set up the data container(s) data_Setup(detector_List[0], 1); // Set up the interface gui_Setup(); } //______________________________________________________________________________ task_Demo::~task_Demo() { // Standard destructor dbg_Print("task_Demo::~task_Demo:()", DBG_LVL_ZERO); // Kill everything delete_All(); } //______________________________________________________________________________ UInt_t task_Demo::run() { // Debug dbg_Print("task_Demo::run: run called", DBG_LVL_MAKE); // Returns all ok return 0; } //______________________________________________________________________________ void task_Demo::delete_All() { // Delete the data dbg_Print("task_Demo::delete_All:()", DBG_LVL_FLOW); // Delete GUI cool::Gui->delete_All(); // Delete data structures delete burst_Raw; delete frame_Noise; delete frame_Pedestal; // Delete detectors for (UInt_t i = 0; i < detector_List.size(); i++) delete detector_List[i]; } //______________________________________________________________________________ void task_Demo::static_Evn(const int arg) { // Try the call to a static function (here just to give an example) dbg_Print("task_Demo::static_Evn: it works!", DBG_LVL_FLOW); } //****************************************************************************** //* * //* GUI initialization and destruction * //* * //****************************************************************************** //______________________________________________________________________________ void task_Demo::gui_Setup() { // Set up all the interface objects dbg_Print("task_Demo::gui_Setup: defining interface!", DBG_LVL_FLOW); // General appearance // ------------------ // Main window color cool::Gui->update_Auto(false); cool::Gui->color_Set(0x888888, cool::Gui->kc_Blue); // Buttons // ------- // Button Run btn_Run = new gui_CoolButton("Acquire", 16, 30, 100, 36, cool::Gui->kc_White, cool::Gui->kc_Green); //btn_Run->label_Set("Acquire 1 burst",gui_Const::align_Left + gui_Const::align_Top); btn_Run->task_Connect(this, &task_Demo::btn_run_Evn); // Button Quit btn_Quit = new gui_CoolButton("Quit", 16, 75, 100, 36, cool::Gui->kc_White, cool::Gui->kc_Red); btn_Quit->task_Connect(this, &task_Demo::btn_quit_Evn); // Comm buttons lbl_Desk.push_back(new gui_Label("Communication" ,160, 10)); lbl_Desk.back()->foreColor(cool::Gui->kc_White); lbl_Desk.back()->Transparent(true); btn_Comm.push_back(new gui_CoolButton("Open", 160, 30, 100, 36, cool::Gui->kc_White, cool::Gui->kc_Cyan)); btn_Comm.push_back(new gui_CoolButton("Reset", 160, 75, 100, 36, cool::Gui->kc_Red, cool::Gui->kc_Cyan)); btn_Comm.push_back(new gui_CoolButton("Close", 280, 30, 100, 36, cool::Gui->kc_Black, cool::Gui->kc_Cyan)); btn_Comm.push_back(new gui_CoolButton("Purge", 280, 75, 100, 36, cool::Gui->kc_Black, cool::Gui->kc_Cyan)); btn_Comm.push_back(new gui_CoolButton("Clear", 280, 120, 100, 36, cool::Gui->kc_Black, cool::Gui->kc_Cyan)); for (UInt_t i = 0; i < btn_Comm.size(); i++) btn_Comm[i]->task_Connect(this, &task_Demo::btn_comm_Evn); // Detector combos // --------------- // Detector type cmb_Det.push_back(new gui_Combo(0, 420, 35, 120, 24)); cmb_Det.back()->fontName("Calibri"); cmb_Det.back()->label_Set("Detector", 0); cmb_Det.back()->cbox_Entry("Test detector" , 0); cmb_Det.back()->cbox_Entry("LDRD2 Px + Ref" , 1); cmb_Det.back()->cbox_Val(0); // Dummy detector size cmb_Det.push_back(new gui_Combo(0, 420, 80, 120, 24)); cmb_Det.back()->fontName("Calibri"); cmb_Det.back()->label_Set("Dummy size", 0); cmb_Det.back()->cbox_Entry("2", 0); cmb_Det.back()->cbox_Entry("4", 1); cmb_Det.back()->cbox_Entry("8", 2); cmb_Det.back()->cbox_Entry("16", 3); cmb_Det.back()->cbox_Entry("32", 4); cmb_Det.back()->cbox_Entry("64", 5); cmb_Det.back()->cbox_Entry("128", 6); cmb_Det.back()->cbox_Entry("256", 7); cmb_Det.back()->cbox_Entry("512", 8); cmb_Det.back()->cbox_Entry("1024", 9); cmb_Det.back()->cbox_Entry("2048", 10); cmb_Det.back()->cbox_Entry("4096", 11); cmb_Det.back()->cbox_Val(0); // Detector clock divider cmb_Det.push_back(new gui_Combo(0, 420, 125, 120, 24)); cmb_Det.back()->fontName("Calibri"); cmb_Det.back()->label_Set("Clock speed", 0); cmb_Det.back()->cbox_Entry("50 Mhz", 0); cmb_Det.back()->cbox_Entry("25 MHz", 1); cmb_Det.back()->cbox_Entry("12.5 MHz", 2); cmb_Det.back()->cbox_Entry("6.25 Mhz", 3); cmb_Det.back()->cbox_Entry("3.12 MHz", 4); cmb_Det.back()->cbox_Entry("1.56 MHz", 5); cmb_Det.back()->cbox_Entry("781 KHz", 6); cmb_Det.back()->cbox_Entry("390 Khz", 7); cmb_Det.back()->cbox_Entry("195 KHz", 8); cmb_Det.back()->cbox_Val(1); // Maps // ---- // Palette UInt_t col[6] = {0xFF0000, 0xFFFF00, 0x00FF00, 0x00FFFF, 0x0000FF, 0xFF00FF}; // Signal data_Layer* sig = burst_Raw->frame(0)->layer(0); map_Signal = new gui_Map(20, 180, 512, 512); map_Signal->range_Color(col, 6); map_Signal->color_Set(cool::Gui->kc_White, 0x000000); // Reference /* data_Layer* ref = 0; if (burst_Raw->frame_Count() > 1) { ref = burst_Raw->frame(1)->layer(0); } else { ref = burst_Raw->frame(0)->layer(0); } map_Reference = new gui_Map(ref->dp_Front(), ref->dp_col_Count(), ref->dp_row_Count(), 420, 180, 256, 256); map_Reference->range_Color(col, 6); map_Signal->color_Set(cool::Gui->kc_White, 0x000000); */ // Refresh cool::Gui->Update(); } //****************************************************************************** //* * //* GUI Callback target functions * //* * //****************************************************************************** //______________________________________________________________________________ void task_Demo::btn_run_Evn(const int arg) { // Play button events handler dbg_Print("task_Demo::btn_run_Evn: run called", DBG_LVL_FLOW); // Acquire data_Acquire(); } //______________________________________________________________________________ void task_Demo::btn_quit_Evn(const int arg) { // Quit button events handler dbg_Print("task_Demo::btn_quit_Evn: quit called", DBG_LVL_FLOW); // Exits by self-quitting the class cool::Gui->Quit(); } //______________________________________________________________________________ void task_Demo::btn_comm_Evn(const int arg) { // Do some comm operation if (arg == btn_Comm[0]->obj_Id()) comm_Setup(burst_Raw); if (arg == btn_Comm[1]->obj_Id()) cool::Comm->Reset(); if (arg == btn_Comm[2]->obj_Id()) cool::Comm->Close(); if (arg == btn_Comm[3]->obj_Id()) cool::Comm->Purge(); if (arg == btn_Comm[4]->obj_Id()) cool::Comm->Clear(); } //****************************************************************************** //* * //* Data & Detector initialization and destruction * //* * //****************************************************************************** //______________________________________________________________________________ void task_Demo::detector_Setup(UInt_t dSize) { // Set up the data dbg_Print("task_Demo::data_Setup: defining data objects", DBG_LVL_FLOW); // Creates new detectors for (UInt_t i = 0; i < detector_List.size(); i++) delete detector_List[i]; detector_List.clear(); // TEST // ---- detector_List.push_back(new geom_Frame()); geom_Frame* test = detector_List.back(); // This is a test chip! // Hardware ID test->HrdID(1); // FPGA-encoded hardware ID // 1 Chip test->chip(0)->Name("Chip 0"); test->chip(0)->col_Count(dSize); test->chip(0)->row_Count(dSize); // 1 Layer test->layer(0)->Name("Layer 0"); test->layer(0)->dp_col_Count(dSize); test->layer(0)->dp_row_Count(dSize); // 1 Channel test->channel(0)->Name("Channel 0"); test->channel(0)->chip_Idx(0); test->channel(0)->layer_Idx(0); // Dummy linear geometry test->chip(0)->dp_all_Range(0, 1); // LDRD2 // ----- detector_List.push_back(new geom_Frame()); geom_Frame* ldrd2 = detector_List.back(); // Defines the hardware chips // Hardwrae ID ldrd2->HrdID(2); // FPGA-encoded hardware ID // LEFT LDRD2 sector ldrd2->chip(0)->Name("Left"); // LEFT side of LDRD2 ldrd2->chip(0)->col_Count(48); // 48 columns ldrd2->chip(0)->row_Count(96); // 96 rows ldrd2->chip(0)->col_Pitch(20); // Pixel column pitch ldrd2->chip(0)->row_Pitch(20); // Pixel row pitch // RIGHT LDRD2 sector ldrd2->chip_Add(); ldrd2->chip(1)->Name("Right"); // RIGHT side of LDRD2 ldrd2->chip(1)->col_Count(48); // 48 columns ldrd2->chip(1)->row_Count(96); // 96 rows ldrd2->chip(1)->col_Pitch(20); // Pixel column pitch ldrd2->chip(1)->row_Pitch(20); // Pixel row pitch // Defines the logic layers // First logical layer (SIGNAL) ldrd2->layer(0)->Name("Signal"); // The signal (abstracted) layer ldrd2->layer(0)->dp_col_Count(96); // Logical column count ldrd2->layer(0)->dp_row_Count(96); // Logical row count // Second logical layer (REFERENCE) ldrd2->layer_Add(); ldrd2->layer(1)->Name("Reference"); // The reference (abstracted) layer ldrd2->layer(1)->dp_col_Count(96); // 96 columns ldrd2->layer(1)->dp_row_Count(96); // 96 rows // Defines the chip/channel/layer connections // 1st output, left sector signal ldrd2->channel(0)->Name("Left signal"); // Chip/Layer connection ldrd2->channel(0)->chip_Idx(0); // Data are shaped as decribed by chip #0 ldrd2->channel(0)->layer_Idx(0); // Data are directed to layer #0 // 2nd output, left sector reference ldrd2->channel_Add(0, 1); // Chip #0 to layer #1 ldrd2->channel(1)->Name("Left reference"); // 3rd output, right sector signal ldrd2->channel_Add(1, 0); // Chip #1 to layer #0 ldrd2->channel(2)->Name("Right signal"); // 4th output, right sector reference ldrd2->channel_Add(1, 1); // Chip #1 to layer #1 ldrd2->channel(3)->Name("Right reference"); // Sets the chip geometry // Here we set the chip mapping respect to layer mapping. Basically, the // number of pixels contained into one chip is considered as a linear vector, // where for each pixel is stored the location where to place it into the // logical target layer defined by the channel association. // Chip #0 is on the left side of the logical frame, chip #1 (Right) // on the right side but mirrored, i.e. the first data to exit is the\ // last in the row. geom_Chip* chip_Left = ldrd2->chip(0); geom_Chip* chip_Right = ldrd2->chip(1); UInt_t l_Col = 0, r_Col = 0, lr_Row = 0; for (UInt_t i = 0; i < chip_Left->dp_Count(); i++) { // Left l_Col = i % 48; r_Col = 95 - i % 48; lr_Row = (UInt_t)(i / 48); // Put the address in linear style chip_Left->dp_Value(i) = l_Col + lr_Row * 96; chip_Right->dp_Value(i) = r_Col + lr_Row * 96; } } //______________________________________________________________________________ void task_Demo::data_Setup(geom_Frame* detector, UInt_t fr_Count) { // Setup data structures dbg_Print("task_Demo::data_Delete: releasing data objects", DBG_LVL_FLOW); // Raw data if (burst_Raw) { burst_Raw->frame_Fit(detector, fr_Count); } else { burst_Raw = new data_Burst(detector, fr_Count); } } //______________________________________________________________________________ void task_Demo::comm_Setup(data_Burst* burst) { // Comm setup dbg_Print("task_Demo::comm_Setup: setting up communication", DBG_LVL_FLOW); // Step if (!cool::Comm->isOpen()) cool::Comm->Open(); // Check comm status if (!cool::Comm->isOpen()) { cool::Out->Print("You need to open communication to set FPGA!\n", LYELLOW); return; } // Set the ADCs cool::Reg->adc_clk_Chn(0); // Reference ADC clock cool::Reg->adc_clk_Div(cmb_Det[2]->cbox_Val()); // Clock divider cool::Reg->adc_Avgs(0); // No averages // Set the data trigger cool::Reg->data_trg_Mode(0); // External triggering //cool::Reg->data_trg_Count(burst_Raw->dp_Count()); // Number of data point //cool::Reg->data_trg_Delay(0); // Trigger delay //cool::Reg->data_trg_Slope(0); // Positive slope //cool::Reg->data_trg_Chn(0); // Channel 0 //cool::Reg->data_trg_Thr(2000); // Trigger threshold // Set the dummy driver UInt_t dmy_Size = (UInt_t)sqrt((Double_t)burst->frame_Fit()->chip(0)->dp_Count()); cool::Reg->acq_dmy_Size(dmy_Size); // Set the acquisition mode cool::Reg->acq_Mode(0); // Software triggered cool::Reg->acq_data_Mode(1); // ADC mode (0), Fake data mode (1) cool::Reg->acq_drv_Delay(0); // No driving delay cool::Reg->acq_drv_Sel(burst->frame_Fit()->HrdID()); // Set the driver UInt_t chn_Mask = (UInt_t)(pow((double)2, (int)burst->frame_Fit()->channel_Count()) - 1); cool::Reg->acq_chn_Enable(chn_Mask); cool::Reg->acq_frm_Count(burst->frame_Count()); // Frame data count cool::Reg->acq_dp_Count(burst->frame_Fit()->chip(0)->dp_Count()); // Total data count // Set data triggering mode cool::Reg->acq_trg_Mode(0); // Internal trigger cool::Reg->acq_trg_Period(1000); // 10 Hz trigger period } //****************************************************************************** //* * //* Data acquisition functions * //* * //****************************************************************************** //______________________________________________________________________________ void task_Demo::data_Acquire() { // Acquire the data dbg_Print("task_Demo::data_Acquire: retriving data from DAQ", DBG_LVL_FLOW); // Updates the detector detector_Setup((UInt_t)pow((double)2,cmb_Det[1]->cbox_Val()+1)); // Fit data structures Int_t gfId = cmb_Det[0]->cbox_Val(); data_Setup(detector_List[gfId], 1); comm_Setup(burst_Raw); // Fit and Setup maps data_Layer* lRef = burst_Raw->frame(0)->layer(0); map_Signal->data_Set(lRef->dp_Front(), lRef->dp_col_Count(), lRef->dp_row_Count()); map_Signal->range_Auto(true); //if (burst_Raw->frame_Count() > 1) map_Reference->range_Auto(true); // Info cool::Out->Print("\nACQ started!\n", LWHITE); // Small test UInt_t burst_Count = 1; clock_t start = clock(); for (UInt_t i = 0 ; i < burst_Count; i++) { // This is the (strongly) suggested way get data from the firmware! // Here is implemented as cool::Comm->burst_Read(burst_Raw, true, 5000); // Show what it gets map_Signal->Refresh(); //if (burst_Raw->frame_Count() > 1) map_Reference->Refresh(); } // Timing Double_t elapsed = (double)(clock() - start) / CLOCKS_PER_SEC; cool::Out->Print(burst_Count); cool::Out->Print(" burst(s): "); cool::Out->Print(elapsed, LWHITE, true); cool::Out->Print("Speed: "); cool::Out->Print((burst_Count * burst_Raw->dp_Count() * 2) / (elapsed * 1024 * 1024)); //cool::Out-> << "MB/s\n"; // Shows data commitment std::cout << "Total allocated data: " << data_Object::stc_data_Size() / 1024 << " kBytes\n"; //std::cout << "raw_Burst data:" << burst_Raw->dp_Size() / 1024 << " kBytes\n"; }