#include "stdafx.h" #include "resource.h" #include "WfScanDlg.h" #include "Run.h" #include "Utils.h" #include "FileIO.h" #include "Probe.h" #include "ModuleControl.h" #include #include #include #include #include #include #ifdef RAL //SJM #include #endif #include "ReformatTV.h" extern Probe ProbeStation; CEvent *evtRun,*evtStop; CSingleLock *lckRun,*lckStop; static char msg[1024],obuf[1024]; static CBitmap *DigStatus[5]; static CBitmap theChip; static int iFirst; extern unsigned long ConfiG; enum digStatus { dgNone,dgDead,dgHalf,dgMedium,dgGood }; int cId[2] = { 0x3f,0x3f }; #define BUSY 0x10000 #define DAQ_OK 0 #define DAQ_STOPPED 1 #define DAQ_TIMEOUT 2 #define SCANtimeout 5 // wb: sec #define DIGtimeout 10 // wb: sec - not yet implemented.. bool stuck_low[MAXCHANNELS]; bool stuck_high[MAXCHANNELS]; int n_stuck_low, n_stuck_high, n_funny_dyn; ////////////////////////////////////////////////////////////////////////// // DefaultChipConfig // // Created: Wed Sep 20 12:05:54 2000 Author: Carlos // Purpose: Sets the chip in a default state // ////////////////////////////////////////////////////////////////////////// void DefaultChipConfig(int id) { long mask[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}; ABCDinit *h = &Config.hABCD; // Set the frequency gModuleControl->SetFreq(Config.freq); // For spacing between triggers, take the worst case: // -> one every 2 channels gives an output... gModuleControl->LoadTrigSpacing( 19 + 64*17 + 16 ); // Configuration register gModuleControl ->LoadConfigReg(id, POWER_ON | AS_END_CHIP | FEED_THR_DISABLE | (h->ROmode >0 ? 1 << h->ROmode : 0) | CAL0 << h->CalMode | TRIM_RANGE0<< h->trimrange | (h->EdgeDetect==0 ? LEVEL : EDGE ) | (h->MaskEnable==0 ? MASK_DISABLE : MASK_ENABLE) ); // Set the DACs gModuleControl->LoadBiasDAC_ABCD(id,h->pream,h->shaper); gModuleControl->LoadStrobeDelay(id,h->strbdelay); gModuleControl->LoadThreshCalibDAC(id,h->thrs,h->pulse); gModuleControl->LoadMaskReg(id, mask); gModuleControl->LoadStrobe2TrigDelay(h->delay); gModuleControl->EnableDataTaking(id); gModuleControl->EnableStrobe(); // Adjust Config.SetTesterDACs(Config.hABCD.vdd,Config.freq, true); //wb: changed last argument from 'false' to 'true'--^^^^ } ////////////////////////////////////////////////////////////////////////// // Run // // Created: Wed Apr 21 11:49:45 1999 Author: Carlos // Purpose: Makes the scan // ////////////////////////////////////////////////////////////////////////// UINT Run( LPVOID lparam) { WfScanDlg *dlg = (WfScanDlg *)lparam; float *vd = new float [ ScanPoint::nVar() ]; float *vv = new float [ ScanPoint::nVar() ]; float pWfPos[3],mWfPos[3],BeforeStop[3],AfterStart[3],PosDiff[3]; int i,ij,iok, n_dead_spipe=0, n_dead_dpipe=0; POSITION wc,pos; int npts,iPoint,nTry; char fnam[512],lin[512]; ostrstream Fnam(fnam,512); FileIO DataOut; //#ifdef RAL CString auxnam; // SJM CString CSfnam; // SJM CString CSbuffY; // SJM // char buff1[51],buff2[51],buffY[6]; // SJM to avoid stack overflow use new instead !!! FILE *fsjm; bool bCopyFile; // SJM char* buff1 = new char[512]; char* buff2 = new char[512]; char* buffY = new char[6]; //#endif HEADER_CONFIG Fheader(Config); ANALOG_BLOCK AnalogBlock,TrimBlock,TRangeBlock,TStrobeBlock; DIGITAL_BLOCK DigitalBlock; DAC_BLOCK DACBlock; POWERC_BLOCK PowerCBlock; PIPELINE_BLOCK StaticPipeBlock, DynamicPipeBlock; // read out the firmware version DataOut.SetFirmwareVersion( gModuleControl->ReadFirmwareDate() ); //--------------------------------------------------------------------- // Load the bitmaps for the status //--------------------------------------------------------------------- if ( !iFirst ) { iFirst++; theChip.LoadBitmap( IDB_Meassuring ); DigStatus[dgNone] =0; DigStatus[dgDead] = CopyBmp( dlg->m_DigStatusBtn[0],IDB_DigitalDead ); DigStatus[dgHalf] = CopyBmp( dlg->m_DigStatusBtn[0],IDB_DigitalAlmost ); DigStatus[dgMedium]= CopyBmp( dlg->m_DigStatusBtn[0],IDB_DigitalMedium ); DigStatus[dgGood] = CopyBmp( dlg->m_DigStatusBtn[0],IDB_DigitalGood ); } //--------------------------------------------------------------------- // Lock and set the Run event so that anybody interested can know what // we are doing //--------------------------------------------------------------------- evtRun->SetEvent(); lckRun->Lock(); dlg->SetStatus(WfScanDlg::StartingRun); //--------------------------------------------------------------------- // Clear histogram memory (Take Data relays on this clearing) //--------------------------------------------------------------------- gModuleControl->ClearHistoMem(); //--------------------------------------------------------------------- // Set Voltages and update the displays //--------------------------------------------------------------------- gModuleControl->SetChipVoltages(Config.hABCD.vcc,Config.hABCD.vdd); //wb: comment it out to not interfear with run PowerPC meas. //PostMessage(dlg->hWndMonV->m_hWnd,WM_UPDATEV,3,0); //--------------------------------------------------------------------- // Set initial values in the controls //--------------------------------------------------------------------- for ( i=0;iprgMonitor[i]->SetPos(vd[i]); } dlg->m_WfMap.SetRefBtm(&theChip,&theChip); //--------------------------------------------------------------------- // Prepare Data structures //--------------------------------------------------------------------- if ( Config.DoScan ) { // Analog scan // Get the number of points for the npts = ScPointList.GetCount(); // Create the block for the front-end tests AnalogBlock.Prepare(npts,ScanPoint::nVar(),vd,&Fheader); // Loop on Scan Points and get the total size needed pos = ScPointList.GetHeadPosition(); iPoint = 0; while( pos != NULL ) { ScanPoint *pt = ScPointList.GetNext(pos); // Add the point in the analog block AnalogBlock.Add(iPoint++,pt->nvar,pt->type,pt->values); } } //--------------------------------------------------------------------- // Set current status as running //--------------------------------------------------------------------- dlg->SetStatus(WfScanDlg::Running); //--------------------------------------------------------------------- // Ask for output directory //--------------------------------------------------------------------- if ( Config.OutDNeeded ) { int iok = AfxMessageBox( "Do you want to store the data on disk ?", MB_YESNO | MB_ICONQUESTION ); if ( iok==IDYES ) #ifdef RAL { char * args[4]; // SJM char prog[] ="c:/daq5/dirs.exe"; // SJM int mode = _P_WAIT; // SJM args[0] = prog; // SJM args[1] = "exec??"; // SJM args[2] = "two"; // SJM args[3] = NULL; // SJM _spawnv(mode,prog,args); // SJM fsjm = fopen("C:/Temp/sjmAuxFile.txt","r"); // SJM fscanf(fsjm,"%s\n",buff1); // SJM fscanf(fsjm,"%s\n",buffY); // SJM fscanf(fsjm,"%s\n",buff2); // SJM auxnam = buff2; // SJM CSbuffY = buffY; // SJM if (CSbuffY == "YES")bCopyFile = true; else bCopyFile = false;// SJM dlg->SendMessage(WM_COMMAND,(WPARAM)IDM_LogData,0); // if ( Config.OutDir ) delete [] Config.OutDir; // Config.OutDir = new char [ strlen( buff1 ) +1 ]; // strcpy(Config.OutDir,buff1); // // LogMessage( CString("Data files in directory: ")+Config.OutDir+"\n",TRUE); } #else dlg->SendMessage(WM_COMMAND,(WPARAM)IDM_LogData,0); #endif else { if ( Config.OutDir ) delete [] Config.OutDir; Config.OutDir=0; } } //--------------------------------------------------------------------- // Loop on Chips //--------------------------------------------------------------------- try { // Catch here probe panic exceptions ProbeStation.SetDevID( Config.GPIBprobe ); ProbeStation.SetStep(&Config.wfStepx); ProbeStation.SetProbeOrigin(Config.wfnx-Config.xRef-1,Config.yRef); ProbeStation.StartMotors(); wc = ChipList.GetHeadPosition(); while ( wc != NULL ) { if ( lckStop->IsLocked() ) goto END; ChipListItem *chip = ChipList.GetNext(wc); dlg->m_WfMap.UpdateReference(Config.wfnx-chip->GetIx()-1, chip->GetIy()); dlg->LogVMessage("Moving to chip %d.%d\n", chip->GetIx(),chip->GetIy()); #ifndef SCIPP #ifndef RAL // Check Vacuum if ( Config.GPIBprobe>0 && Config.GPIBvacuum>0 ) { float vVal = dlg->hWndMonV->DCsingle(Config.vpVacuum); if ( vValConfig.vacuumThres[2] ) throw ProbePanic( BAD_VACUUM ); } #endif #endif // Move to chip dlg->LogMessage("Moving the probe... "); ProbeStation.GotoChipNo(chip->GetIx(),chip->GetIy(), Config.wfRes,mWfPos,pWfPos); dlg->LogMessage("Waiting for probe to be ready\n"); Sleep(250); // And read from the prober the current position ProbeStation.ReadActualPosition(BeforeStop); // Update display with positions sprintf(lin,"%9.1f",BeforeStop[0]); dlg->m_ProbeX.SetWindowText(lin); dlg->m_ProbeX.UpdateWindow(); sprintf(lin,"%9.1f",BeforeStop[1]); dlg->m_ProbeY.SetWindowText(lin); dlg->m_ProbeY.UpdateWindow(); sprintf(lin,"%9.1f",BeforeStop[2]); dlg->m_ProbeZ.SetWindowText(lin); dlg->m_ProbeZ.UpdateWindow(); // Stop the motors ProbeStation.StopMotors(); //--------------------------------------------------------------------- // Build the Data File name //--------------------------------------------------------------------- if ( Config.OutDir ) { #ifdef RAL Fnam.clear(); Fnam.rdbuf()->seekoff(0,ios::beg,ios::out); Fnam << Config.Fname << setfill('0') << setw(2) << chip->GetIx() << setfill('0') << setw(2) << chip->GetIy() << setfill(' ') << ".dat" << ends; auxnam = buff2; // SJM if (auxnam.Right(1) != "\\" && auxnam.Right(1) != "/")auxnam += "\\"; // SJM should be && auxnam += fnam; #endif Fnam.clear(); Fnam.rdbuf()->seekoff(0,ios::beg,ios::out); Fnam << Config.OutDir << "/" << Config.Fname << setfill('0') << setw(2) << chip->GetIx() << setfill('0') << setw(2) << chip->GetIy() << setfill(' ') << ".dat" << ends; DataOut.NewFile(fnam,&Fheader); dlg->m_OutFile.SetWindowText(CString("Output File: ") + fnam); } else dlg->m_OutFile.SetWindowText("Output File:" " "); //--------------------------------------------------------------------- // Check that the chip is alive. If not: forget about the chip //--------------------------------------------------------------------- if ( TestSConfig(dlg) ) goto This_is_the_End; //--------------------------------------------------------------------- // Static test the digital pipeline; write the data anyway; exit iff they are bad //--------------------------------------------------------------------- if( Config.DoSPipeline ) { n_dead_spipe = TestDigiPipeline( dlg, &StaticPipeBlock, false ); DataOut.WritePipeline( &StaticPipeBlock, 0 ); if ( Config.SelectOnSPipe && n_dead_spipe != 0 ) { dlg->LogMessage("...skipping other tests\n"); goto This_is_the_End; } } //--------------------------------------------------------------------- // Dynamic test the digital pipeline; write the data anyway; exit iff they are bad //--------------------------------------------------------------------- if( Config.DoDPipeline ) { n_dead_dpipe = TestDigiPipeline( dlg, &DynamicPipeBlock, true ); DataOut.WritePipeline( &DynamicPipeBlock, 1 ); } //--------------------------------------------------------------------- // Meassure Power Consumption //--------------------------------------------------------------------- if ( Config.DoPower ) { iok = MeassurePC(dlg,&PowerCBlock); if ( iok==-99 ) goto END; DataOut.WritePowerC(&PowerCBlock); } //--------------------------------------------------------------------- // Set up the chip and meassure currents on Vcc and Vcc // This is done to wait until they are stabilized... //--------------------------------------------------------------------- DefaultChipConfig(0x3f); SendMessage(dlg->hWndMonV->m_hWnd,WM_UPDATEV,3,0); for (i=0;i<128;i++) { gModuleControl ->LoadTrimDAC_ABCD(0x3f, i, Config.hABCD.trim[i]); } //--------------------------------------------------------------------- // Real start of the scan //--------------------------------------------------------------------- dlg->LogMessage("Starting Scan\n"); //--------------------------------------------------------------------- // Loop on scan points for that chip //--------------------------------------------------------------------- pos = ScPointList.GetHeadPosition(); iPoint = 0; while( Config.DoScan && pos != NULL ) { ScanPoint *pt = ScPointList.GetNext(pos); nTry = 0; // Find how many parameters we are going to scan for (i=0;invar;i++) { vv[pt->type[i]] = pt->values[i]; dlg->prgMonitor[pt->type[i]]->SetPos(vv[pt->type[i]]); } /* Build the RO sequence set all var. params in the chip... CalibStrobe,Thrs etc.. */ pt->BuildSequence(vv); Another_Chance: nTry++; dlg->SetStatus(WfScanDlg::Running); // Issue a Software reset to set the chip in a proper state gModuleControl->SendSoftReset(); //PostMessage(dlg->hWndMonV->m_hWnd,WM_UPDATEV,1,0); // Loop on events dlg->nevt->SetPos(0); iok = TakeData(dlg,AnalogBlock.Get(iPoint++)); switch (iok) { case DAQ_STOPPED: goto END; case DAQ_TIMEOUT: goto Scan_DACs; default: break; } } // Write the analog block if ( Config.DoScan ) DataOut.WriteAnalog(&AnalogBlock,0); //--------------------------------------------------------------------- // Scan Trim DACs //--------------------------------------------------------------------- if ( Config.DoTrimDac ) { iok = TestTrimDacs(dlg,TrimBlock,TRangeBlock); if ( iok==-99 ) goto END; DataOut.WriteAnalog(&TrimBlock,1); DataOut.WriteAnalog(&TRangeBlock,2); } //--------------------------------------------------------------------- // Scan Strobe //--------------------------------------------------------------------- if ( Config.DoStrobe ) { iok = TestStrobe(dlg,TStrobeBlock); if ( iok==-99 ) goto END; DataOut.WriteAnalog(&TStrobeBlock,3); } //--------------------------------------------------------------------- // Scan DACS //--------------------------------------------------------------------- Scan_DACs: if ( Config.DoDACs ) { iok = ScanDACs(dlg,&DACBlock); if ( iok==-99 ) goto END; DataOut.WriteDAC(&DACBlock); } //--------------------------------------------------------------------- // Do Digital tests //--------------------------------------------------------------------- if ( Config.DoDigital ) { DigitalBlock.Prepare(&Fheader); bool worth_adapting = n_funny_dyn != 0 && n_funny_dyn == n_stuck_low+n_stuck_high; // cout << " we use adapted TVs ? " << worth_adapting // << " n_funny_dyn = " << n_funny_dyn << endl; bool fail_test; iok = TestDigital(dlg,&DigitalBlock, ( Config.UseAdaptedTVs && worth_adapting ), &fail_test ); if ( iok==-99 ) goto END; DataOut.WriteDigital(&DigitalBlock); DigitalBlock.Clear(); if( fail_test && Config.useTVselection ) { dlg->LogMessage("... failed TV, skipping other tests\n"); goto This_is_the_End; } } //--------------------------------------------------------------------- // Re start the motors and prepare for moving to the next chip //--------------------------------------------------------------------- This_is_the_End: // Write the Data on disk DataOut.WriteFile(); #ifdef RAL if (bCopyFile) CopyFile( fnam, (LPCTSTR)auxnam, false); // SJM #endif #ifndef SCIPP #ifndef RAL // Check Vacuum Again if ( Config.GPIBprobe>0 ) { float vVal = dlg->hWndMonV->DCsingle(Config.vpVacuum); if ( vValConfig.vacuumThres[2] ) throw ProbePanic( BAD_VACUUM ); } #endif #endif // Stop Motors ProbeStation.StartMotors(); dlg->LogMessage("Waiting for probe to be ready\n"); Sleep(250); // Get current position and compare with what we got before stopping ProbeStation.ReadActualPosition(AfterStart); for (ij=0;ij<3;ij++) PosDiff[ij]=BeforeStop[ij]-AfterStart[ij]; // Look for discrepancies according to the required resolution int err; for (ij=0,err=0;ij<3;ij++) { if ( fabs(PosDiff[ij])>Config.wfRes ) err++; } sprintf(lin,"%6.3f",PosDiff[0]); dlg->m_ProbeErrorX.SetWindowText(lin);dlg->m_ProbeErrorX.UpdateWindow(); sprintf(lin,"%6.3f",PosDiff[1]); dlg->m_ProbeErrorY.SetWindowText(lin);dlg->m_ProbeErrorY.UpdateWindow(); sprintf(lin,"%6.3f",PosDiff[2]); dlg->m_ProbeErrorZ.SetWindowText(lin);dlg->m_ProbeErrorZ.UpdateWindow(); // throw an exception if that is the case // if ( err ) // throw ProbePanic( NO_POSITION_AGREEMENT ); } // End of loop on chips } // end of try block //--------------------------------------------------------------------- // Catch exceptions here //--------------------------------------------------------------------- catch (ProbePanic Panic) { Panic.Thrown(); if ( ! Panic.DejaVu() ) { ostrstream ostr; ostr << Panic.ShowReason(); if ( Panic.Message() ) ostr << endl << Panic.Message(); ostr << ends; char *msg = ostr.str(); dlg->LogMessage(msg,TRUE); dlg->MessageBox(msg,"Bye bye ...",MB_ICONSTOP); ProbeStation.GoHome(); goto END; } } //--------------------------------------------------------------------- // This is the end //--------------------------------------------------------------------- dlg->LogMessage("Done\n",1); END: ProbeStation.GoHome(); dlg->nevt->SetPos(0); lckRun->Unlock(1); evtRun->ResetEvent(); if ( lckStop->IsLocked() ) { lckStop->Unlock(1); evtStop->ResetEvent(); } delete [] vv; dlg->SetStatus(WfScanDlg::Ready); #ifdef RAL delete buff1; delete buff2; delete buffY; #endif return 0; } ////////////////////////////////////////////////////////////////////////// // TestSConfig // // Created: Fri May 21 14:45:55 1999 Author: // Purpose: Fast check on Config. register I/O // ////////////////////////////////////////////////////////////////////////// int TestSConfig(WfScanDlg *dlg) { int i,nt; //--------------------------------------------------------------------- // Write a message in the log window //--------------------------------------------------------------------- dlg->LogMessage("Testing Conf. Reg. I/O..."); //--------------------------------------------------------------------- // Reset the chip //--------------------------------------------------------------------- // gModuleControl->EnableStrobe() // chose the select line // set up the right conditions ( F = 40 MHz, Vdd = 4.0 V ) // for this small TV gModuleControl->SetFreq( 40. ); Config.SetTesterDACs_vdd( 4.0, true ); gModuleControl->SetClockLatchDAC(40.); int dacVal = int((0xd2-0x28)*40.0/ 40.0 + 0x28); // dac for leading edge delay gModuleControl->SetDAC(CLK0_delay, dacVal); // dac for trailing edge delay gModuleControl->SetDAC(CLK0_width, dacVal); // dac for leading edge delay gModuleControl->SetDAC(CLK1_delay, dacVal); // dac for trailing edge delay gModuleControl->SetDAC(CLK1_width, dacVal); gModuleControl->SendSoftReset(); //--------------------------------------------------------------------- // Get Configuration register from the chip //--------------------------------------------------------------------- nt = gModuleControl->TestConfRegIO(100); if ( nt ) { cout << " DEAD because TV failed " << nt << " times " << endl; dlg->LogMessage(" DEAD\n"); return 1; } dlg->LogMessage( " ALIVE\n"); return 0; } ////////////////////////////////////////////////////////////////////////// // TestDigiPipeline // // Created: Thu Jun 28 18:18:16 PDT 2001 Author: vf // Purpose: a test of the digital pipeline (looking for the stuck channels) // ////////////////////////////////////////////////////////////////////////// int TestDigiPipeline(WfScanDlg *dlg, void * pTest, bool dynamic_test ) { unsigned int data; float *pdata,*ptr; time_t t0; // some necessary constants long maskF[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}; long mask0[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000}; long maskA[4] = {0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa}; long mask5[4] = {0x55555555, 0x55555555, 0x55555555, 0x55555555}; int numScans = 4; int id = ( Config.UseChipID ? Config.ChipID : 0x3f ); long trig2trigDelay = 2005; long numberTriggers = 144; long val_trim_dac = 0x0; ABCDinit *h = &Config.hABCD; PIPELINE_BLOCK *pDigi = (PIPELINE_BLOCK *)pTest; pdata = pDigi->data_mask; pDigi->ntrig[0] = (float)numberTriggers; //--------------------------------------------------------------------- // Write a message in the log window //--------------------------------------------------------------------- if( dynamic_test ) { dlg->LogMessage("Test of the Digital Pipeline (Dynamic)..."); // the only place in the code where this feature is used gModuleControl->EnableInpRegPulse(); }else{ dlg->LogMessage("Test of the Digital Pipeline (Static )..."); } //--------------------------------------------------------------------- // Place the chip in the right conditions //--------------------------------------------------------------------- // set up the right conditions ( F = 40 MHz, Vdd = 4.0 V ) gModuleControl->SetFreq( 40. ); Config.SetTesterDACs_vdd( 4.0, true ); gModuleControl->SetClockLatchDAC(40.); int dacVal = int((0xd2-0x28)*40.0/ 40.0 + 0x28); // dac for the clock edges delays gModuleControl->SetDAC(CLK0_delay, dacVal); gModuleControl->SetDAC(CLK0_width, dacVal); gModuleControl->SetDAC(CLK1_delay, dacVal); gModuleControl->SetDAC(CLK1_width, dacVal); gModuleControl->SendSoftReset(); //----------------------------------------------- // inital configuration // Set the DACs (max threshold to minimize the FE influence) gModuleControl->LoadBiasDAC_ABCD(id,h->pream,h->shaper); gModuleControl->LoadStrobeDelay(id, 0); if( dynamic_test ) { gModuleControl->LoadThreshCalibDAC(id, 0xff ,h->pulse); }else{ gModuleControl->LoadThreshCalibDAC(id, h->thrs ,h->pulse); } gModuleControl->LoadStrobe2TrigDelay( 0x9a ); gModuleControl->LoadTrigSpacing(trig2trigDelay); gModuleControl->LoadTriggerNum(numberTriggers); // setting trim DACs for all channels to zero for(int channel=0; channelLoadTrimDAC_ABCD( id, channel, val_trim_dac ); } // Load the Configuration register of the ABCD // with the mask data going into the input register if( dynamic_test ) { gModuleControl->LoadConfigReg( id, POWER_ON | AS_END_CHIP | FEED_THR_DISABLE | CAL0 | TRIM_RANGE0 | EDGE_DETECT | COMPRESS_LEVEL | MASK_DISABLE ); }else{ gModuleControl->LoadConfigReg( id, POWER_ON | AS_END_CHIP | FEED_THR_DISABLE | CAL0 | TRIM_RANGE0 | LEVEL | MASK_ENABLE ); } //--------------------------------------------------------------------- // do the digital pipeline test per se //--------------------------------------------------------------------- // starting scans // reset the histogramming module memory // pointer and clean up (initialize) the memory gModuleControl->LoadHistoBaseAddr(0); gModuleControl->ClearHistoMem(); // loop over different masks for( int nM=0; nMLoadMaskReg( id, mask0 ); }else if( nM==1 ) { gModuleControl->LoadMaskReg( id, mask5 ); }else if( nM==2 ) { gModuleControl->LoadMaskReg( id, maskA ); }else if( nM==3 ) { gModuleControl->LoadMaskReg( id, maskF ); } gModuleControl->SendSoftReset(); gModuleControl->EnableDataTaking( id ); // point to separate memory block at each threshold value gModuleControl->LoadHistoBaseAddr( nM ); // go get the data time(&t0); gModuleControl->SendTriggers(); int timeout = 0 ; do { timeout = (TElapsed(t0)LogMessage("Timeout during digi pipeline test.\n"); break; } } while( gModuleControl->QueryBoard(HST_BUSY) ) ; // pointer to the data memory location in the PIPELINE_BLOCK class ptr = pdata + MAXCHANNELS*nM; // point to the right block of memory on the VME board // and read it out sequentially gModuleControl->LoadHistoBaseAddr( nM ); for( int channel=0; channelReadHistoMem() ) >> 16; // write the datum to the data structure ptr[channel] = (float) data; } } // nM // now, check the number of unusual channels int n_funny = 0; for( int t3=0; t3ClearHistoMem(); // revert to the standard configuration gModuleControl->EnableStrobe(); ostrstream ostr; ostr << "found " << n_funny << " bad pipes; DONE\n" << ends; char *msg = ostr.str(); dlg->LogMessage(msg); return n_funny; } ////////////////////////////////////////////////////////////////////////// // TakeData // // Created: Mon Apr 26 08:09:21 1999 Author: Carlos // Purpose: Takes Data for a given ScanPoint // ////////////////////////////////////////////////////////////////////////// int TakeData(WfScanDlg *dlg,void *Vdata) { static char cCalAdd[10]; static int hst_add=-1; int iChan,iCalAdd,nCalAdd,wCalAdd[4],iHstAdd; int *nevt,*data,*ptr; int id; time_t t0,t1; unsigned int vdat; long mask[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}; ANALOG_TEST *Atest = (ANALOG_TEST *)Vdata; nevt = Atest->evt; data = Atest->evt+4; id = ( Config.UseChipID ? Config.ChipID : 0x3f ); //--------------------------------------------------------------------- // Clear data array //--------------------------------------------------------------------- for (iCalAdd=0;iCalAdd<4;iCalAdd++) { nevt[iCalAdd]=0; for (iChan=0;iChan<128;iChan++) data[iCalAdd*128+iChan]=0; } //--------------------------------------------------------------------- // Define the cal. addresses to be triggered //--------------------------------------------------------------------- if ( Config.hABCD.CalMode ) { nCalAdd=1; wCalAdd[0]= Config.hABCD.CalMode-1; } else { nCalAdd = 4; for (iCalAdd=0;iCalAdd<4;iCalAdd++) wCalAdd[iCalAdd]=iCalAdd; } //--------------------------------------------------------------------- // prepare histograming //--------------------------------------------------------------------- time(&t0); gModuleControl->ResetOutResyncFIFO(); gModuleControl->LoadHistoBaseAddr(0); // increment the base address of the histogram memory // Reset if we reach the maximum hst_add += 4; if ( hst_add >= 0xfc ) { gModuleControl->ClearHistoMem(); hst_add=0; } iHstAdd = hst_add; //--------------------------------------------------------------------- // Loop on calibration Addresses //--------------------------------------------------------------------- //cout << "Scan: #triggers: " << Config.nEvtPerPoint << " "; for (iCalAdd=0;iCalAddIsLocked() ) return DAQ_STOPPED; sprintf(cCalAdd,"%d",wCalAdd[iCalAdd]); // dlg->m_MonCalAdd.SetWindowText(cCalAdd); dlg->nevt->SetPos(0); gModuleControl->LoadConfigReg(id,CAL0 << iCalAdd); gModuleControl->LoadMaskReg(id, mask); gModuleControl->EnableDataTaking(id); //--------------------------------------------------------------------- // Send the triggers //--------------------------------------------------------------------- gModuleControl->LoadTriggerNum(Config.nEvtPerPoint); // triggers time(&t0); gModuleControl->LoadHistoBaseAddr(iHstAdd+iCalAdd); gModuleControl->SendTriggers(); //wb: elaborate on timeout... int timeout = 0 ; //wb: false do { timeout = (TElapsed(t0)LogMessage("Timeout on scan.\n"); break; } } while( gModuleControl->QueryBoard(HST_BUSY) ) ; //wb: OK nevt[iCalAdd] = Config.nEvtPerPoint ; // dlg->nevt->SetPos(nevt[iCalAdd]); } // Get the data for ( iCalAdd=0;iCalAddLoadHistoBaseAddr(iHstAdd+iCalAdd); for (iChan=0;iChan<128;iChan++) { vdat = gModuleControl->ReadHistoMem(); ptr[iChan] = (vdat>>16); } } return 0; } ////////////////////////////////////////////////////////////////////////// // TestStrobe // // Created: Wed Feb 14 19:42:27 2001 Author: // Purpose: // ////////////////////////////////////////////////////////////////////////// int TestStrobe(WfScanDlg *dlg, ANALOG_BLOCK &TStrobeBlock) { int i,nP,rc,id; HEADER_CONFIG Fheader(Config); ANALOG_TEST *aTest; float *vd = new float [ ScanPoint::nVar() ]; rc = 0; dlg->LogMessage("Scanning Strobe\n"); id = ( Config.UseChipID ? Config.ChipID : 0x3f ); //--------------------------------------------------------------------- // Get default parameters //--------------------------------------------------------------------- for ( i=0;iprgMonitor[i]->SetPos(vd[i]); } //--------------------------------------------------------------------- // Set up the chip. Full scan of strobe delay with nominal parameters //--------------------------------------------------------------------- int nvar = 1; int types[1] = { ScanPoint::strobe }; float vx = 0; vd[ScanPoint::pulse]=4.; nP = ScanPoint::Range[ScanPoint::strobe].y+1; dlg->prgMonitor[ScanPoint::pulse]->SetPos(vd[ScanPoint::pulse]); TStrobeBlock.Prepare(nP,ScanPoint::nVar(),vd,&Fheader); //--------------------------------------------------------------------- // Start the scan //--------------------------------------------------------------------- DefaultChipConfig(0x3f); // Program the TRIM dacs for ( i=0;i<128;i++) gModuleControl->LoadTrimDAC_ABCD(id,i,0); // Send a Soft Reset gModuleControl->SendSoftReset(); // Start for (i=0;iprgMonitor[ScanPoint::strobe]->SetPos(vx); aTest = TStrobeBlock.Get(i); TStrobeBlock.Add(i,nvar,types,&vx); gModuleControl->LoadStrobeDelay(id,vx); // Take data dlg->nevt->SetPos(0); rc = TakeData(dlg,aTest); switch (rc) { case DAQ_STOPPED: case DAQ_TIMEOUT: goto END; default: dlg->SetStatus(WfScanDlg::Running); break; } } //--------------------------------------------------------------------- // Write Data and quit //--------------------------------------------------------------------- END: delete [] vd; return rc; } ////////////////////////////////////////////////////////////////////////// // TestTrimDacs // // Created: Mon May 24 12:03:16 1999 Author: Carlos Lacasta // Purpose: scan the trim dacs // ////////////////////////////////////////////////////////////////////////// int TestTrimDacs(WfScanDlg *dlg, ANALOG_BLOCK &TrimBlock,ANALOG_BLOCK &TRangeBlock) { int saveCalSeq,saveCalMode; int i,j,k,id,iok,itrim,rc,trange[4]; float *vd = new float [ ScanPoint::nVar() ]; float *vv = new float [ ScanPoint::nVar() ]; HEADER_CONFIG Fheader(Config); ANALOG_TEST *aTest; rc = 0; dlg->LogMessage("Scanning Trim DACs\n"); id = ( Config.UseChipID ? Config.ChipID : 0x3f ); //--------------------------------------------------------------------- // Set up the Chip and set as calibration pulse that of the // 1st point in the Gain Scan. If the Gain scan is not defined, // set it at 2.5fC //--------------------------------------------------------------------- int nThrs; float frstValue; float sThrs; // find the step and limits on the threshold for (i=0;iprgMonitor[i]->SetPos(vd[i]); } // Prepare the analog block to be writen on file vd[ScanPoint::pulse]=pulse; dlg->prgMonitor[ScanPoint::pulse]->SetPos(vd[ScanPoint::pulse]); TrimBlock.Prepare(np,ScanPoint::nVar(),vd,&Fheader); vd[ScanPoint::trimdac]=(float)wTrim[wRange]; TRangeBlock.Prepare(4*nThrs,ScanPoint::nVar(),vd,&Fheader); int nvar = 2; int types[2] = { ScanPoint::trimdac, ScanPoint::threshold }; float vx[3]; int iPoint=0; int nTry = 0; //--------------------------------------------------------------------- // Scan the trim DAC and the threshold //--------------------------------------------------------------------- // ABCD_Select(sqs,Config.hABCD.SelectLine); DefaultChipConfig(0x3f); gModuleControl->SendSoftReset(); // Loop on the points for (i=0;iprgMonitor[types[0]]->SetPos(vx[0]); // Program the TRIM dacs for ( k=0;k<128;k++) gModuleControl ->LoadTrimDAC_ABCD(id,k,wTrim[i]); // Loop on Threshold for (j=0;jprgMonitor[types[1]]->SetPos(vx[1]); aTest = TrimBlock.Get(iPoint); TrimBlock.Add(iPoint++,nvar,types,vx); nTry = 0; Another_Chance: nTry++; // change the Threshold gModuleControl ->LoadThreshCalibDAC(id, vx[1], vd[ScanPoint::pulse] ); // pause untill the Vthreshold is stable gModuleControl->ReadDac(ADC_Vt); // Take Data dlg->nevt->SetPos(0); iok = TakeData(dlg,aTest); switch (iok) { case DAQ_STOPPED: case DAQ_TIMEOUT: goto END; default: dlg->SetStatus(WfScanDlg::Running); break; } } } //--------------------------------------------------------------------- // Scan the trim range //--------------------------------------------------------------------- types[0] = ScanPoint::trimrange; dlg->LogMessage("Scanning Trim DACs range\n"); // Program the TRIM dacs to the middle of the scale itrim = wTrim[wRange]; for ( k=0;k<128;k++) gModuleControl ->LoadTrimDAC_ABCD(id,k,itrim); dlg->prgMonitor[ScanPoint::trimdac]->SetPos(itrim); // Start looping for (i=0,iPoint=0;i<4;i++) { // Set the range vx[0] = (float)i; dlg->prgMonitor[types[0]]->SetPos(vx[0]); gModuleControl->LoadConfigReg(id,TRIM_RANGE0<prgMonitor[types[1]]->SetPos(vx[1]); aTest = TRangeBlock.Get(iPoint); TRangeBlock.Add(iPoint++,nvar,types,vx); // change the Threshold gModuleControl ->LoadThreshCalibDAC(id, vx[1], vd[ScanPoint::pulse] ); // pause untill the Vthreshold is stable gModuleControl->ReadDac(ADC_Vt); // Take Data dlg->nevt->SetPos(0); iok = TakeData(dlg,aTest); if ( iok==DAQ_STOPPED ) { rc = -99; goto END; } if ( iok==DAQ_TIMEOUT ) { rc = -99; goto END; } } // restore the original stuff Config.hABCD.CalMode = saveCalMode; } //--------------------------------------------------------------------- // Set back the chip in a "known" state //--------------------------------------------------------------------- DefaultChipConfig(0x3f); for (i=0;i<128;i++) gModuleControl ->LoadTrimDAC_ABCD(0x3f, i, Config.hABCD.trim[i]); //--------------------------------------------------------------------- // Write Data and quit //--------------------------------------------------------------------- END: delete [] vv; delete [] vd; return rc; } ////////////////////////////////////////////////////////////////////////// // Testdigital // // Created: Tue Apr 27 14:41:15 1999 Author: Carlos // Purpose: Makes the digital tests // ////////////////////////////////////////////////////////////////////////// int TestDigital(WfScanDlg *dlg, void *pDigB, bool adaptTVs, bool *failTV ) { int i,j,k,rc; int iTest,wTest,ievt; int dacVal; float nBad,nTot,eff; *failTV = false; DIGITAL_BLOCK *DigBlck = (DIGITAL_BLOCK *)pDigB; // Message dlg->LogMessage("Making Digital tests\n"); rc = 0; // Set the digital names DigBlck->SetNames((const char**) Config.tvector); // Loop on Vdd iTest = 0; // Clear Buttons for (k=0;km_DigStatusBtn[k % 8].SetBitmap( 0 ); int *iptr = Config.DoDigTests; for ( wTest=0;wTestLoadTestVector(Config.tvNam[wTest]); /* if( adaptTVs ) { ReformatTV newTV( Config.tsNam[wTest], stuck_high, stuck_low ); newTV.ProcessData(); long *SimData = long[MAX_N_LINES]; newTV.FillStream( SimData ); gModuleControl->LoadTunedSimVector( SimData, newTV.Length() ); delete SimData; }else{ */ gModuleControl->LoadSimVector(Config.tsNam[wTest]); // } for (j=0;j<((int *)Config.VddList)[0];j++) { sprintf(msg,"%.2f",Config.VddList[j+1]); // adjust DACs Config.SetTesterDACs_vdd( Config.VddList[j+1], true ); dlg->m_dgVdd.SetWindowText(msg); dlg->vvdd->SetValue(Config.VddList[j+1],TRUE); Sleep(20); // wb: sleep enough long to stab. Vdd //Loop on Clock frequency for ( i=0;i<((int *)Config.frqList)[0];i++) { sprintf(msg,"%f",Config.frqList[i+1]); dlg->m_dgFreq.SetWindowText(msg); gModuleControl->SetFreq( Config.frqList[i+1] ); // adjust DACs gModuleControl->SetClockLatchDAC(Config.frqList[i+1]); dacVal = int((0xd2-0x28)*40.0/ Config.frqList[i+1] + 0x28); // dac for leading edge delay gModuleControl->SetDAC(CLK0_delay, dacVal); // dac for trailing edge delay gModuleControl->SetDAC(CLK0_width, dacVal); // dac for leading edge delay gModuleControl->SetDAC(CLK1_delay, dacVal); // dac for trailing edge delay gModuleControl->SetDAC(CLK1_width, dacVal); Sleep(2); // Meassure Ivcc and Ivdd to be sure they are stable when the test // starts SendMessage(dlg->hWndMonV->m_hWnd,WM_UPDATEV,3,0); // Reset the chip since we have changed the clock frq. and Vdd gModuleControl->SendSoftReset(); //wb: 21.05.01 , stabilize chip : Sleep(10); nBad=nTot=0.; for (ievt=0;ievtSendTV(); if ( gModuleControl->QueryBoard(TVDIFF) ) nBad++; nTot++; } DIGITAL_TEST *dtst = DigBlck->Add(iTest,wTest, Config.frqList[i+1], Config.VddList[j+1] ); eff = (nTot-nBad)/nTot; dtst->eff=eff; iTest++; // new selection on the digital tests eff, to save the testing time: // at least some eff for all TVs at 40 MHz if( abs( Config.frqList[i+1] - 40.0 ) < 1.0 ) { if( eff < Config.failTVeff ) { *failTV = true; } } rc = ( eff < 0.25 ? dgDead : ( eff < 0.75 ? dgHalf : ( eff < 1.00 // wb: we want 100% chips good... :) //wb: was 0.99 ? dgMedium : dgGood ) ) ); dlg->m_DigStatusBtn[wTest % 8].SetBitmap( *DigStatus[rc] ); if ( lckStop->IsLocked() ) return DAQ_STOPPED; } } } END: dlg->LogMessage("...Done with Digital tests.\n"); return rc; } ////////////////////////////////////////////////////////////////////////// // ScanDACs // // Created: Wed May 05 08:00:32 1999 Author: Carlos // Purpose: Does a DAC scan // ////////////////////////////////////////////////////////////////////////// int ScanDACs(WfScanDlg *dlg, void *pPter) { float thstp = 2.5f; float prstp = 9.2f; float spstp = 1.2f; float thrs,pream,shaper; float tempVth,tempIp,tempIsh; //float fv[10]; DAC_BLOCK *pDAC = (DAC_BLOCK *)pPter; int i; ABCDinit *h = &Config.hABCD; int id = ( Config.UseChipID ? Config.ChipID : 0x3f ); dlg->LogMessage("Scanning DACs\n"); // Avoid MonitorV timer interfering dlg->hWndMonV->SendMessage(WM_STOPTIMER,0,0); //--------------------------------------------------------------------- // Loop on the sequences //--------------------------------------------------------------------- thrs=pream=shaper=0.f; pDAC->factor[0] = Config.slopeADC[ADC_Vt]; pDAC->factor[1] = 0.; pDAC->factor[2] = Config.slopeADC[ADC_Ip]; pDAC->factor[3] = Config.slopeADC[ADC_Ish]; //wb: measuring Ipr : //wb: defaults pream = h->pream; ; shaper = h->shaper ; thrs = h->thrs ; gModuleControl->LoadBiasDAC_ABCD(id, pream, shaper); gModuleControl->LoadThreshCalibDAC(id,thrs,0.); Sleep(10); // wb: stabilize Icc //wb: update display: tempVth = gModuleControl->ReadDac(ADC_Vt); tempIp = gModuleControl->ReadDac(ADC_Ip); tempIsh = gModuleControl->ReadDac(ADC_Ish); dlg->IPream->SetValue(tempIp,TRUE); dlg->IShaper->SetValue(tempIsh,TRUE); dlg->VThreshold->SetValue(tempVth,TRUE); pream = 0.0 ; for (i=0;i<32;i++,pream+=prstp) { float val = 0.0 ; if ( lckStop->IsLocked() ) { return -99; } //wb: set DAC values in chip: gModuleControl->LoadBiasDAC_ABCD(id, pream, shaper); gModuleControl->LoadThreshCalibDAC(id,thrs,0.); Sleep(10); // wb: stabilize Icc val = gModuleControl->ReadDac(ADC_Ip); pDAC->ipr[i] = val ; dlg->IPream->SetValue(val,TRUE); } //wb: measuring Ish : //wb: defaults pream = h->pream; ; shaper = h->shaper ; thrs = h->thrs ; //wb: load defaults: gModuleControl->LoadBiasDAC_ABCD(id, pream, shaper); gModuleControl->LoadThreshCalibDAC(id,thrs,0.); Sleep(10); // wb: stabilize Icc //wb: update display: tempVth = gModuleControl->ReadDac(ADC_Vt); tempIp = gModuleControl->ReadDac(ADC_Ip); tempIsh = gModuleControl->ReadDac(ADC_Ish); dlg->IPream->SetValue(tempIp,TRUE); dlg->IShaper->SetValue(tempIsh,TRUE); dlg->VThreshold->SetValue(tempVth,TRUE); shaper = 0.0 ; for (i=0;i<32;i++,shaper+=spstp) { float val = 0.0 ; if ( lckStop->IsLocked() ) { return -99; } //wb: set DAC values in chip: gModuleControl->LoadBiasDAC_ABCD(id, pream, shaper); gModuleControl->LoadThreshCalibDAC(id,thrs,0.); Sleep(10); // wb: stabilize Icc val = gModuleControl->ReadDac(ADC_Ish); pDAC->isp[i] = val ; dlg->IShaper->SetValue(val,TRUE); } //wb: measuring Vth : //wb: defaults pream = h->pream; ; shaper = h->shaper ; thrs = h->thrs ; //wb: load defaults: gModuleControl->LoadBiasDAC_ABCD(id, pream, shaper); gModuleControl->LoadThreshCalibDAC(id,thrs,0.); Sleep(10); // wb: stabilize Icc //wb: update display: tempVth = gModuleControl->ReadDac(ADC_Vt); tempIp = gModuleControl->ReadDac(ADC_Ip); tempIsh = gModuleControl->ReadDac(ADC_Ish); dlg->IPream->SetValue(tempIp,TRUE); dlg->IShaper->SetValue(tempIsh,TRUE); dlg->VThreshold->SetValue(tempVth,TRUE); thrs = 0.0 ; for (i=0;i<256;i++,thrs+=thstp) { float val = 0.0 ; if ( lckStop->IsLocked() ) { return -99; } //wb: set DAC values in chip: gModuleControl->LoadBiasDAC_ABCD(id, pream, shaper); gModuleControl->LoadThreshCalibDAC(id,thrs,0.); // wb: do not need to stabilize Icc, no Sleep() val = gModuleControl->ReadDac(ADC_Vt); pDAC->vthp[i] = val ; pDAC->vthn[i] = 0.0 ; dlg->VThreshold->SetValue(val,TRUE); } //for (i=0;i<256;i++,thrs+=thstp,pream+=prstp,shaper+=spstp) { //if ( lckStop->IsLocked() ) { // return -99; //} //if ( i && !(i%32) ) pream=shaper=0.; //gModuleControl->LoadBiasDAC_ABCD(id, pream, shaper); //gModuleControl->LoadThreshCalibDAC(id,thrs,0.); //fv[0] = gModuleControl->ReadDac(ADC_Vt); //fv[1] = 0.0; //wb: do not measure Ipr & Isp if i > 32 : //if (i<32) { //fv[2] = gModuleControl->ReadDac(ADC_Ip); //fv[3] = gModuleControl->ReadDac(ADC_Ish); //} else { //fv[2] = 0.0; //fv[3] = 0.0; //} //dlg->IPream->SetValue(fv[2],TRUE); //dlg->IShaper->SetValue(fv[3],TRUE); //dlg->VThreshold->SetValue((fv[0]-fv[1]),TRUE); //pDAC->vthp[i] = fv[0]; //pDAC->vthn[i] = fv[1]; //if ( i<32 ) { // pDAC->ipr[i] = fv[2]; // pDAC->isp[i] = fv[3]; //} //} return 0; } ////////////////////////////////////////////////////////////////////////// // MeassurePC // // Created: Wed May 05 08:00:32 1999 Author: Carlos // Purpose: Meassures power consumption // Update: hard reset and take Icc,Idd measurements w\o the 100 kHz trigger // 27/11/2001, VF // ////////////////////////////////////////////////////////////////////////// int MeassurePC(WfScanDlg *dlg, void *pPter) { int i; int prb; ABCDinit *h = &Config.hABCD; POWERC_BLOCK *pPC = ( POWERC_BLOCK * ) pPter; int id = ( Config.UseChipID ? Config.ChipID : 0x3f ); dlg->LogMessage("Meassuring PC\n"); //--------------------------------------------------------------------- // Set Voltages and update the displays //--------------------------------------------------------------------- gModuleControl->SetChipVoltages(Config.hABCD.vcc,Config.hABCD.vdd); //--------------------------------------------------------------------- // Configure the chip //--------------------------------------------------------------------- long Mask[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}; gModuleControl ->LoadConfigReg(id, POWER_ON | AS_MASTER | AS_END_CHIP | FEED_THR_DISABLE | LEVEL | CAL0 | TRIM_RANGE0<LoadBiasDAC_ABCD(id,h->pream,h->shaper); gModuleControl->LoadStrobeDelay(id,h->strbdelay); gModuleControl->LoadThreshCalibDAC(id,h->thrs,h->pulse); gModuleControl->LoadMaskReg(id,Mask); gModuleControl->EnableDataTaking(id); Sleep( 10 ); //--------------------------------------------------------------------- // issure the "hard reset" //--------------------------------------------------------------------- // gModuleControl->SendHardReset(); gModuleControl->ResetTVMem(); for (i=0;i<1000;i++) { gModuleControl->WriteTVMem(0); } for (i=0;i<200000;i++) { gModuleControl->WriteTVMem(0x40); } gModuleControl->WriteTVMem(0x20040); gModuleControl->SendTVnowait(); // Sleep long enough afterwards // Sleep( 50 ); //--------------------------------------------------------------------- // Measure //--------------------------------------------------------------------- // time_t t1, t2; // time( &t1 ); // wb: make it more precise, erase "byPassWait" flag : pPC->MasterIVcc = gModuleControl->ReadDac(ADC_Icc); pPC->MasterIVdd = gModuleControl->ReadDac(ADC_Idd); // wb: (21.05.2001) now we have Vcc,Vdd readout: pPC->MasterVVcc = gModuleControl->ReadDac(ADC_Vcc); pPC->MasterVVdd = gModuleControl->ReadDac(ADC_Vdd); // time( &t2 ); // Wait while the card is busy int bad=0; while(gModuleControl->QueryBoard(BUSY))bad++; // cout << " time spent = " << t2-t1 << endl; // cout << " nBUSY = " << bad << endl; // update display: dlg->avcc->SetValue(pPC->MasterIVcc,TRUE); dlg->avdd->SetValue(pPC->MasterIVdd,TRUE); dlg->vvcc->SetValue(pPC->MasterVVcc,TRUE); dlg->vvdd->SetValue(pPC->MasterVVdd,TRUE); //--------------------------------------------------------------------- // Do the same as slave //--------------------------------------------------------------------- gModuleControl ->LoadConfigReg(id, POWER_ON | AS_SLAVE | AS_END_CHIP | FEED_THR_DISABLE | LEVEL | CAL0 | TRIM_RANGE0<EnableDataTaking(id); //--------------------------------------------------------------------- // issure the "hard reset" //--------------------------------------------------------------------- // gModuleControl->SendHardReset(); gModuleControl->ResetTVMem(); for (i=0;i<1000;i++) { gModuleControl->WriteTVMem(0); } for (i=0;i<200000;i++) { gModuleControl->WriteTVMem(0x40); } gModuleControl->WriteTVMem(0x20040); gModuleControl->SendTVnowait(); // Sleep long enough afterwards // Sleep( 50 ); // wb: make it more precise: pPC->SlaveIVcc = gModuleControl->ReadDac(ADC_Icc); pPC->SlaveIVdd = gModuleControl->ReadDac(ADC_Idd); // wb: (17.04.2001) now we have Vcc,Vdd readout: pPC->SlaveVVcc = gModuleControl->ReadDac(ADC_Vcc); pPC->SlaveVVdd = gModuleControl->ReadDac(ADC_Vdd); // Wait while the card is busy bad=0; while(gModuleControl->QueryBoard(BUSY))bad++; // wb: (17.04.2001) update display values: dlg->avcc->SetValue(pPC->SlaveIVcc,TRUE); dlg->avdd->SetValue(pPC->SlaveIVdd,TRUE); dlg->vvcc->SetValue(pPC->SlaveVVcc,TRUE); dlg->vvdd->SetValue(pPC->SlaveVVdd,TRUE); // Leave the chip in a sane state DefaultChipConfig(id); return 0; }