//******************************************************************* //* * //* Riadenie zostavy meracich pristrojov cez GPIB rozhranie * //* (c) 2005, MPsoft * //* Layout.cpp * //* 26.januara 2005 * //* * //* Ukážka plne komentovaného zdrojového textu * //* * //******************************************************************* #include #include "CmnHdr.H" #include #include "resource.h" #include "ccerr.h" #include "ismerr.h" #include "ism.h" #include #include #include #include #include #include "animbox.h" #include "x76f.h" #include #include "protpoi.h" #include "ccard.h" #include "audit.h" #define FD_CC_SHELL // vylucenie chybovych hlaseni ISM modulu #include "classapi.h" #include "ni488.h" #include "chamel.h" // tieto definicie pouzit len pri ladeni pre vypis do message boxov a zaznam do specialnych // udalosti v audite //#define ME_DBG TRUE // ladenie (vypis do message boxu) //#define AUD_DBG TRUE // ladenie (zaznam do specialnych udalosti auditu) //#define ERR_DBG TRUE // ladenie (vypis chyby z error latche do message boxu) #define LAYOUT_CHECK_TIME 2000 // perioda dalsieho testu zostavy #define TIME_OF_SWEEP 100 // vyskyt zariadeni DWORD AnalyzerEngineIndex = 0; DWORD GeneratorEngineIndex = 0; DWORD AmplifierEngineIndex = 0; DWORD PmeterEngineIndex = 0; DWORD ht14; // handle threadu DWORD ht15; // handle threadu DWORD ht16; // handle threadu DWORD ht17; // handle threadu extern BOOL GeneratorInitDevice(); extern BOOL AnalyzerSetupInstrument(); extern ULONG MeasureConfig; // premenna testu enginu extern int image; // ID obrazka pre prekreslenie extern CRITICAL_SECTION g_CriticalSectionICL; // kriticka sekcia pre ochranu pristupu extern void SpecialAuditEntry(HWND hwndDlg, LPSTR msg); // zaznam specialnych udalosti extern void SpecialAuditEntryError(HWND hwndDlg, LPSTR msg, int status); // zaznam specialnych udalosti extern LPTSTR LoadResString(SHORT IDs); extern int MessageBoxAudit(HWND hWnd, LPCSTR lpszText, LPCSTR lpszTitle, UINT uStyle); // messagebox so vstupom do auditu extern void RMreadThreadPacket(PVOID hwndDlg); extern BOOL GeneratorMeasureLevelOnSetfrequencyEngin(HWND hwndDlg, int Frequency, double Rlevel); extern void SendGeneratorStatement(HWND hWnd, LPCSTR Statement); void LayoutTestThread(PVOID hwndDlg); // Komunikacia pozostava z troch zakladnych casti: // 1. Inicializacia // 2. Telo // 3. Cistenie // Inicializacna davka pozostava z inicializacie zbernice a GPIB inteface karty tak, ze GPIB karta // je Hlavny kontrolor "CIC". Nasledovne najde vsetkych adresatov a potom vymaze vsetky zariadenia // na zbernici. // V hlavnom tele, tato aplikacia si pyta od vsetkych zariadeni ich identifikacne kody vydanim *IDM? prikazu. // Mnoho nastrojov odpoveda na tento povel ich identifikacnym retazcom. // Poznamka, 488.2 prislusne zariadenia odpovedaju odozvou na tento prikaz. // Posledny krok, Cistenie, prepne kartu do offline. #define ARRAYSIZE 100 // Velkost citacieho buffera #define GPIB0 0 // Handle karty (boardID%) = 0 int loop, // Pocitadlo slucky Num_Listeners; // Pocet posluchacov na GPIB Addr4882_t Instruments[32], // Pole primarnych adries Result[31]; // Pole zaznamenanych adries char ReadBuffer[ARRAYSIZE + 1]; // Citaci datovy buffer char SendBuffer[ARRAYSIZE + 1]; // Zapisovy datovy buffer // pole chybovej mnemoniky (podla "iberr") char ErrorMnemonic[21][5] = {"EDVR", "ECIC", "ENOL", "EADR", "EARG", "ESAC", "EABO", "ENEB", "EDMA", "", "EOIP", "ECAP", "EFSO", "", "EBUS", "ESTB", "ESRQ", "", "", "", "ETAB"}; int analyzer; // ID analyzatora int boardId; // ID karty kontrolera int iecaddress; void GPIBCleanup(int ud, char* ErrorMsg); BOOL AnalyzerIBWRT(LPSTR SendBuffer); BOOL AnalyzerIBRD(LPSTR ReadBuffer); BOOL AnalyzerInitController(); BOOL AnalyzerWrite(LPSTR SendBuffer); BOOL AnalyzerRead(LPSTR ReadBuffer); BOOL TestMeasure(HWND hWnd); BOOL GetToOffline(); BOOL GetToOnline(); BOOL AnalyzerInitDevice(); BOOL AnalyzerDisplayOn(); BOOL AnalyzerDisplayOff(); void AnalyzerMeasureLevelOnSetfrequency(PVOID hwndDlg); BOOL AnalyzerMeasureLevelOnSetfrequencyEngin(HWND hwndDlg, int Frequency, int Span, double Rlevel, LPTSTR Result); BOOL AnalyzerWriteT(LPSTR SendBuffer); BOOL WaitopAnalyzer(); BOOL StartOfSweepMeasurement(HWND hWnd); BOOL StartOfRmReadThreadAnalyzator(HWND hWnd); BOOL StartOfRmWriteThreadText(HWND hWnd); // *************************************************** // ******** Funkcie PRE PRISTUP DO GPIB-32.DLL ****** // *************************************************** // Funkcia "DevClearList" posiela Selected Device Clear (SDC) GPIB spravu pre vsetky adresy zariadeni // popisane v adresliste. Ak adreslist obsahuje len konstantu NOADDR, Universal Device Clear (DCL) // sprava je vyslana do vsetkych zariadeni na zbernici. // Funkcia "FindLstn" testuje vsetky primarne adresy: // Ak je zariadenie pritomne na primarnej adrese, tato primarna adresa je ulozena // do "resultlistu". Inaksie vsetky sekundarne adresy su tiez testovane // a tiez ukladane do "resultlistu". Ale pocet je limitovany. Funkcia "ibcntl" vracia // aktualny pocet adries ulozenych v "resultliste". // Funkcia "ibonl" resetuje kartu alebo zariadenie a nastavuje parametre softverovej // konfiguracie do predkonfigurovaneho stavu. // Ak je parameter "0", zariadenie alebo inretfejs prepina do offline stavu. // Ak je parameter nenulovy, zariadenie alebo inretfejs zostava v operacnom stave // alebo v stave online. // Ak je zariadenie alebo inretfejs nastaveny do stavu "offline", deskriptor karty // alebo deskriptor (ud) je uz dalej neplatny. Je potrebne vykonat funkciu "ibdev" // alebo "ibfind" pre pristup ku karte alebo zariadeniu. // Funkcia "Receive" adresuje zariadenie popisane adresou a nacita limitom zadany pocet bajtov // do buffra. Bajty udajov su citane az do zadaneho pocetu bajtov, // alebo kym nie je detekovany koniec. // Ak je zadana ukoncovacia podmienka "STOPend", citanie je stopnute ked je najdeny // bajt EOI. Inaksie je citanie zastavene ked je detekovany 8-bitovy znak EOS. // Aktualny pocet nacitanych znakov je vrateny funkciou "ibcntl". // Funkcia "SendList" adresuje zariadenia popisane v adresliste a zadany pocet // bajtov posiela do vsetkych zariadeni. Posledny zaslany bajt EOI vytvara predpoklad // ze pre ukoncenie je pouzity DABend. Ak je poslednym bajtom nie EOI, // ukoncovaci mod je NULLend. Ak je to NLend, znak ('\n') je vyslany s EOI. // Aktualny pocet prenesenych bajtov je vrateny funkciou "ibcntl". // Funkcia "SendIFC" je pouzita ako prvok GPIB inicializacie. Vnucuje interface // do stavu "Controller-In-Charge" GPIB. Taktiez zabezpecuje ze pripojene zariadenia // su vsetky deadresovane a ze interfejsove volania zariadeni su v cakacom stave. static void (__stdcall *PDevClearList)(int boardID, Addr4882_t * addrlist); static void (__stdcall *PFindLstn)(int boardID, Addr4882_t * addrlist, PSHORT results, int limit); static int (__stdcall *Pibonl)(int ud, int v); void (__stdcall *PReceive)(int boardID, Addr4882_t addr, PVOID buffer, LONG cnt, int Termination); void (__stdcall *PSend)(int boardID, Addr4882_t addr, PVOID buffer, LONG cnt, int Termination); static void (__stdcall *PSendList)(int boardID, Addr4882_t * addrlist, PVOID databuf, LONG datacnt, int eotMode); static void (__stdcall *PSendIFC)(int boardID); static int (__stdcall *IBWRT)(int ud, void *wrtbuf, long count); static int (__stdcall *IBRD)(int ud, void *rdbuf, long count); static int (__stdcall *IBFIND)(char *udname); static int (__stdcall *IBPAD)(int ud, int v); static int (__stdcall *IBTMO)(int ud, int v); static int (__stdcall *IBLOC)(int ud); // Toto su privatne data len pre jazykovy interface, // takze su definovane ako 'staticke' static HINSTANCE Gpib32Lib = NULL; // handle kniznice pre GPIB int *Pibsta; // smernik na funkciu navratu statusu operacie static int *Piberr; // smernik na funkciu navratu chyboveho statusu static long *Pibcntl; // smernik na funkciu navratu poctu //*** Zavedenie kniznice pre GPIB *** BOOL LoadDll (void) { // Volanie LoadLibrary pre zavedenie 32-bitovej GPIB DLL. Ulozi handle // do globalnej premennej 'Gpib32Lib' Gpib32Lib = LoadLibrary ("GPIB-32.DLL"); if (!Gpib32Lib) { // Volanie LoadLibrary zlyhalo, vrati sa chyba return FALSE; } // Ok, GPIB kniznica je nahrata. Dostaneme ukazovatele do pozadovanych funkcii. // Ak volanie GetProcAddress zlyha, potom sa vrati chyba. Pibsta = (int *) GetProcAddress(Gpib32Lib, (LPCSTR)"user_ibsta"); Piberr = (int *) GetProcAddress(Gpib32Lib, (LPCSTR)"user_iberr"); Pibcntl = (long *)GetProcAddress(Gpib32Lib, (LPCSTR)"user_ibcnt"); PDevClearList = (void (__stdcall *)(int, Addr4882_t *))GetProcAddress(Gpib32Lib, (LPCSTR)"DevClearList"); PFindLstn = (void (__stdcall *)(int, Addr4882_t *, PSHORT, int))GetProcAddress(Gpib32Lib, (LPCSTR)"FindLstn"); Pibonl = (int (__stdcall *)(int, int))GetProcAddress(Gpib32Lib, (LPCSTR)"ibonl"); PReceive = (void (__stdcall *)(int, Addr4882_t, PVOID, LONG, int))GetProcAddress(Gpib32Lib, (LPCSTR)"Receive"); PSend = (void (__stdcall *)(int, Addr4882_t, PVOID, LONG, int))GetProcAddress(Gpib32Lib, (LPCSTR)"Send"); PSendList = (void (__stdcall *)(int, Addr4882_t *, PVOID, LONG, int))GetProcAddress(Gpib32Lib, (LPCSTR)"SendList"); PSendIFC = (void (__stdcall *)(int))GetProcAddress(Gpib32Lib, (LPCSTR)"SendIFC"); IBWRT = (int (__stdcall *)(int ud, void *wrtbuf, long count))GetProcAddress(Gpib32Lib, (LPCSTR)"ibwrt"); IBRD = (int (__stdcall *)(int ud, void *rdbuf, long count))GetProcAddress(Gpib32Lib, (LPCSTR)"ibrd"); IBFIND = (int (__stdcall *)(char *udname))GetProcAddress(Gpib32Lib, (LPCSTR)"ibfindA"); IBPAD = (int (__stdcall *)(int ud, int v))GetProcAddress(Gpib32Lib, (LPCSTR)"ibpad"); IBTMO = (int (__stdcall *)(int ud, int v))GetProcAddress(Gpib32Lib, (LPCSTR)"ibtmo"); IBLOC = (int (__stdcall *)(int ud))GetProcAddress(Gpib32Lib, (LPCSTR)"ibloc"); if ((Pibsta == NULL) || (Piberr == NULL) || (Pibcntl == NULL) || (PDevClearList == NULL) || (PFindLstn == NULL) || (Pibonl == NULL) || (PReceive == NULL) || (PSend == NULL) || (PSendList == NULL) || (IBWRT == NULL) || (IBRD == NULL) || (IBFIND == NULL) || (IBPAD == NULL) || (IBTMO == NULL) || (IBLOC == NULL) || (PSendIFC == NULL)) { FreeLibrary (Gpib32Lib); Gpib32Lib = NULL; return FALSE; } else { return TRUE; } } //*** Uvolnenie kniznice pre GPIB *** void FreeDll() { FreeLibrary (Gpib32Lib); Gpib32Lib = NULL; return; } //*** Otestovanie pripojenej zostavy meracich pristrojov *** BOOL TestMeasureEngine(HWND hWnd, PULONG MeasureConfig) { char msg[256]; BOOL suc; EnterCriticalSection(&g_CriticalSectionICL); // ochrana pre vylucenie pristupu ineho threadu // indexy vyskytu zariadeni na zbernici AnalyzerEngineIndex = 0; GeneratorEngineIndex = 0; AmplifierEngineIndex = 0; PmeterEngineIndex = 0; // Vasa karta musi byt hlavnym kontrolerom na to aby nasla vsetkych posluchacov // na GPIB. Na dosiahnutie tohoto je volana funkcia "SendIFC". Ak chybny bit ERR je // nastaveny v "ibsta", vola sa "GPIBcleanup" s chybovou spravou. (*PSendIFC)(GPIB0); // (boardID) if ((*Pibsta) & ERR) // ak je chyba { GPIBCleanup(GPIB0, "Unable to open board"); LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return FALSE; } // Vytvori pole obsahujuce vsetky platne GPIB primarne adresy, okrem // primarnej adresy 0. GPIB interface karta je na adrese 0 ako default. // Toto pole "Instruments" bude zadane do funkcie "FindLstn" na najdenie vsetkych // adresatov. Konstanta "NOADDR", definovana v NT488.H, oznacuje koniec pola. for (loop = 0; loop < 30; loop++) { Instruments[loop] = (Addr4882_t)(loop + 1); } Instruments[30] = NOADDR; // Zaznamena spravu pre informovanie pouzivatela o tom, ze progaram hlada vsetkych // aktivnych posluchacov. Najde vsetkych aktivnych posluchacov na zbernici. Ulozi // zaznamenane adresy v poli Result. Ak je chybovy bit ERR je anstaveny v ibsta, vola sa // "GPIBCleanup" s chybovou spravou. wsprintf(msg, "Finding all listeners on the bus...\n\n"); #ifdef AUD_DBG SpecialAuditEntry(NULL, msg); // zapis oznamu o specialnej udalosti do auditu #endif #ifdef ME_DBG MessageBoxAudit(NULL, msg, LoadResString(IDS_TX567), MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TASKMODAL); #endif (*PFindLstn)(GPIB0, Instruments, Result, 31); if((*Pibsta) & ERR) // ak je chyba { GPIBCleanup(GPIB0, "Unable to issue FindLstn call"); LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return FALSE; } // "ibcntl" vracia skutocny pocet adries ulozenych v poli Result. // Priradi hodnotu z "ibcntl" funkcie premennej "Num_Listeners". Zanamena sa pocet najdenych // posluchacov. Num_Listeners = (short)(*Pibcntl); // ulozi sa pocet najdenych adries wsprintf(msg, "Number of instruments found = %d\n\n", Num_Listeners); #ifdef AUD_DBG SpecialAuditEntry(NULL, msg); // zapis oznamu o specialnej udalosti do auditu #endif #ifdef ME_DBG MessageBoxAudit(NULL, msg, LoadResString(IDS_TX567), MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TASKMODAL); #endif // Vysledkove pole [Result] obsahuje adresy vsetkych zaznamenanych // zariadeni najdenych "FindLstn" funkciou. Pouzije sa konstanta NOADDR, ak je definovane // v NI488.H, na oznacenie konca pola. Result[Num_Listeners] = NOADDR; // "DevClearList" zasle do GPIB "Selected Device Clear (SDC)" spravu vsetkym zariadeniam // na zbernici. Ak chybovy bit ERR je nastaveny v "ibsta", vola sa "GPIBCleanup" s chybovou // spravou. (*PDevClearList)(GPIB0, Result); if((*Pibsta) & ERR) // ak je chyba { GPIBCleanup(GPIB0, "Unable to clear devices"); LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return FALSE; } // Zasle identifikacnu otazku kazdej zaznamenanej adrese v poli // (Result) pouzitim "SendList". Konstanta NLend, definovana v NI488.H, // instruuje funkciu "SendList" pripojit riadkovy znak s EOI potrvdenim na konci // spravy. Ak je vrateny chybovy bit ERR funkciou "ibsta", vola sa "GPIBCleanup" // s chybovou spravou. (*PSendList)(GPIB0, Result, "*IDN?", 5L, NLend); if((*Pibsta) & ERR) // ak je chyba { GPIBCleanup(GPIB0, "Unable to write to devices"); LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return FALSE; } // Precita identifikacny kod kazdeho zariadenia, kazdy v jednom cykle // Ustanovenim FOR slucky na precitanie kazdeho jedneho identifikacneho // kodu zariadenia. Premenna LOOP bude sluzit ako pociatadlo pre FOR slucku // a ako index pre pole Result. for (loop = 0; loop < Num_Listeners; loop++) { // Precita odozvu na identifikaciu mena vratenu z kazdeho zariadenia. Ulozi // odozvu v poli ReadBuffer. Konstatnta "STOPend", definovana v NI488.H, prikazuje funkcii // "Recieve" ukoncit citanie ked END je detekovany. Ak chybovy bit ERR je nastaveny // v "ibsta", volanie "GPIBCleanup" s chybovym hlasenim (*PReceive)(GPIB0, Result[loop], ReadBuffer, ARRAYSIZE, STOPend); if((*Pibsta) & ERR) // ak je chyba { GPIBCleanup(GPIB0, "Unable to read from a device"); LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return FALSE; } // Predpoklada sa, ze vrateny retazec obsahuje ASCII data. NULL // ukonci retezec pouzitim hodnoty z "ibcntl" funkcie, co je pocet nacitanych bajtov. ReadBuffer[(*Pibcntl)] = '\0'; wsprintf(msg, "Returned string: %s", ReadBuffer); #ifdef AUD_DBG SpecialAuditEntry(NULL, msg); // zapis oznamu o specialnej udalosti do auditu #endif #ifdef ME_DBG MessageBoxAudit(NULL, msg, LoadResString(IDS_TX567), MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TASKMODAL); #endif // analyza pripojenych zariadeni ReadBuffer[20] = 0; // skratenie retazca if(!strcmp(ReadBuffer, "Rohde&Schwarz,FSP-40")) { if(!*MeasureConfig) { // len prvy krat po detekcii analyzatora } *MeasureConfig = 1; // je to analyzator StartOfRmReadThreadAnalyzator(hWnd); // start citacieho threadu na strane analyzatora } if(!strcmp(ReadBuffer, "ROHDE&SCHWARZ,SMR40,")) { if(!*MeasureConfig) { // len prvy krat po detekcii generatora // reset a zakladne nastavenie generatora MessageBeep(MB_OK); // beep pre upozornenie, ze nie je nic pripojene MessageBeep(MB_OK); // beep pre upozornenie, ze nie je nic pripojene MessageBeep(MB_OK); // beep pre upozornenie, ze nie je nic pripojene MessageBeep(MB_OK); // beep pre upozornenie, ze nie je nic pripojene } *MeasureConfig = 2; // je to zostava vysielaca (test len na generator) StartOfRmReadThreadAnalyzator(hWnd); // start citacieho threadu na strane analyzatora } // test vyskytu zariadeni a zapamatanie indexov if(!strcmp(ReadBuffer, "Rohde&Schwarz,FSP-40")) AnalyzerEngineIndex = loop; // je to analyzator (ulozi sa index vo vysledkovom poli) if(!strcmp(ReadBuffer, "ROHDE&SCHWARZ,SMR40,")) { GeneratorEngineIndex = loop; // je to generator (ulozi sa index vo vysledkovom poli) if(IsDlgButtonChecked(hWnd, IDC_CHECK2 ) == 1) // sweep ak je zaskrtnuty { if(IsDlgButtonChecked(hWnd, IDC_CHECK1 ) == 1) GeneratorInitDevice(); // reset generatora GeneratorMeasureLevelOnSetfrequencyEngin(hWnd, 100, -3); } } if(!strcmp(ReadBuffer, "BLWA 0140-5/0.5/0.1D")) AmplifierEngineIndex = loop; // je to vykonovy zosilnovac (ulozi sa index vo vysledkovom poli) if(!strcmp(ReadBuffer, "ROHDE&SCHWARZ,NRVD, ")) PmeterEngineIndex = loop; // je to power meter (ulozi sa index vo vysledkovom poli) // zaznamy o konfiguracii if(*MeasureConfig == 1) { wsprintf(msg, "---> Control center [Analyzator]: %d", *MeasureConfig); #ifdef AUD_DBG SpecialAuditEntry(NULL, msg); // zapis oznamu o specialnej udalosti do auditu #endif #ifdef ME_DBG MessageBoxAudit(NULL, msg, LoadResString(IDS_TX567), MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TASKMODAL); #endif } if(*MeasureConfig == 2) { wsprintf(msg, "---> Listener [Generator]: %d", *MeasureConfig); #ifdef AUD_DBG SpecialAuditEntry(NULL, msg); // zapis oznamu o specialnej udalosti do auditu #endif #ifdef ME_DBG MessageBoxAudit(NULL, msg, LoadResString(IDS_TX567), MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TASKMODAL); #endif } if(*MeasureConfig == 1) // len pre analyzator { suc = AnalyzerWrite("*CLS"); // reset status registrov (aj error latche analyzatora) suc = AnalyzerWrite("SYST:DISP:UPD ON"); // pocas merani nezhasat obrazovku } } LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return TRUE; } //*** Po kazdom volani GPIB, aplikacia skontroluje ci volanie uspelo. Ak volanie NI-488.2 *** // zlyha, GPIB ovladac nastavi zodpovedajuci bit v premennej globalneho statusu. Ak volanie zlyhalo // tato procedura vypise spravu o chybe, odstavi kartu a ukonci aplikaciu. void GPIBCleanup(int ud, char* ErrorMsg) { char msg[256]; char msg1[256]; wsprintf(msg, "Error : %s; ibsta = 0x%x iberr = %d (%s); ", ErrorMsg, *Pibsta, *Piberr, ErrorMnemonic[(*Piberr)]); wsprintf(msg1, "Cleanup: Taking board offline!"); strcat(msg, msg1); SpecialAuditEntryError(NULL, msg, 0xffff); // zapis oznamu o specialnej chybe do auditu // zaznamenava sa vzdy! #ifdef ME_DBG MessageBoxAudit(NULL, msg, LoadResString(IDS_TX567), MB_OK | MB_ICONSTOP | MB_SETFOREGROUND | MB_TASKMODAL); #endif (*Pibonl) (ud, 0); // reset karty a zariadeni a prepnutie do offline stavu return; } //*** Kontrola meracej zostavy *** BOOL LayoutTest(HWND hWnd) { DWORD retv; // ochrana pred viacnasobnym spustenim threadu retv = WaitForSingleObject((PVOID)ht14, 10); // test na trvanie prvej kopiie thredu if(retv == WAIT_TIMEOUT) // ak thread este bezi { return FALSE; // nespustat dalsiu kopiu } ht14 = _beginthread(LayoutTestThread, 0, hWnd); // start threadu pre test zostavy return TRUE; } //*** Start threadu kontroly meracej zostavy *** void LayoutTestThread(PVOID hwndDlg) { BOOL suc = FALSE; KillTimer((HWND)hwndDlg, TIMER1); // zrusenie casovaca TestMeasureEngine((HWND)hwndDlg, &MeasureConfig); // test pripojenej zostavy meracich pristrojov // ak je zostava nedefinovana (nepripojene pristroje) if(MeasureConfig == 0) { image = IDB_BITMAP66; // ID obrazka pre WM_PAINT (chameleon) SendMessage((HWND)hwndDlg, WM_PAINT, 0, 0L); // vyslanie spravy pre prekreslenie suc = FALSE; // nie je nic pripojene } // ak je zostava analyzatora if(MeasureConfig == 1) { image = IDB_BITMAP67; // ID obrazka pre WM_PAINT (analyzator) SendMessage((HWND)hwndDlg, WM_PAINT, 0, 0L); // vyslanie spravy pre prekreslenie suc = TRUE; // analyzator je pripojeny } // ak je zostava generatora if(MeasureConfig == 2) { image = IDB_BITMAP68; // ID obrazka pre WM_PAINT (zostava vysielaca) SendMessage((HWND)hwndDlg, WM_PAINT, 0, 0L); // vyslanie spravy pre prekreslenie suc = TRUE; // generator je pripojeny } if(!suc) MessageBeep(MB_OK); // beep pre upozornenie, ze nie je nic pripojene SetTimer((HWND)hwndDlg, TIMER1, LAYOUT_CHECK_TIME, NULL); // nastavenie casovaca ExitThread(0); } //*** Prepnutie interfejsu alebo zariadenia do OFFLINE rezimu *** BOOL GetToOffline() { (*Pibonl) (GPIB0, 0); if((*Pibsta) & ERR) // ak je chyba { GPIBCleanup(GPIB0, "Unable switch device to OFFLINE state!"); return FALSE; } return TRUE; } //*** Prepnutie interfejsu alebo zariadenia do ONLINE rezimu *** BOOL GetToOnline() { (*Pibonl) (GPIB0, 1); if((*Pibsta) & ERR) // ak je chyba { GPIBCleanup(GPIB0, "Unable switch device to ONLINE state!"); return FALSE; } return TRUE; } //*** Inicializacia kontrolera pre nizkourovnovu komunikaciu *** BOOL AnalyzerInitController() { int iecaddress; // adresa zariadenia EnterCriticalSection(&g_CriticalSectionICL); // ochrana pre vylucenie pristupu ineho threadu // inicializacia kontrolera boardId = IBFIND("GPIB0"); // otvorenie portu kontrolera analyzer = IBFIND("DEV1"); // otvorenie portu analyzatora iecaddress = Result[AnalyzerEngineIndex]; // adresa zariadenia IBPAD(analyzer, iecaddress); // informacia kontrolera o adrese zariadenia IBTMO(analyzer, 11); // timeout 1 sekunda (podla tabulky!) LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return TRUE; } //*** Zapis riadiaceho retazca do analyzatora cez GPIB nizkourovnovo *** BOOL AnalyzerIBWRT(LPSTR SendBuffer) { char SendBufferForAnalyzer[ARRAYSIZE + 1]; // zapisovy datovy buffer if(MeasureConfig != 1) // ak to nie je zostava analyzatora return FALSE; EnterCriticalSection(&g_CriticalSectionICL); // ochrana pre vylucenie pristupu ineho threadu // vyslanie retazca memset(SendBufferForAnalyzer, 0, sizeof(SendBufferForAnalyzer)); strcpy(SendBufferForAnalyzer, SendBuffer); IBWRT(analyzer, SendBufferForAnalyzer, strlen(SendBufferForAnalyzer)); // zapis do zariadenia if((*Pibsta) & ERR) // ak je chyba { GPIBCleanup(GPIB0, "Unable send to a device - IBWRT"); LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return FALSE; } // prepnutie karty do offline rezimu (*Pibonl) (GPIB0, 0); LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return TRUE; } //*** Citanie odozvy z analyzatora cez GPIB nizkourovnovo *** BOOL AnalyzerIBRD(LPSTR ReadBuffer) { char ReadBufferForAnalyzer[ARRAYSIZE + 1]; // zapisovy datovy buffer if(MeasureConfig != 1) // ak to nie je zostava analyzatora return FALSE; EnterCriticalSection(&g_CriticalSectionICL); // ochrana pre vylucenie pristupu ineho threadu // nacitanie retazca memset(ReadBufferForAnalyzer, 0, sizeof(ReadBufferForAnalyzer)); IBRD(analyzer, ReadBufferForAnalyzer, sizeof(ReadBufferForAnalyzer)); // nacitanie zo zariadenia if((*Pibsta) & ERR) // ak je chyba { GPIBCleanup(GPIB0, "Unable read from a device - IBRD"); LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return FALSE; } strcpy(ReadBuffer, ReadBufferForAnalyzer); // nakopirovanie odozvy do buffra // prepnutie karty do offline rezimu (*Pibonl) (GPIB0, 0); LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return TRUE; } //*** Zapis riadiaceho retazca do analyzatora cez GPIB *** BOOL AnalyzerWrite(LPSTR SendBuffer) { #define WDELAY 1 // 1 mS int count = 15000; // pre 15 sekund char SendBufferForAnalyzer[ARRAYSIZE + 1]; // zapisovy datovy buffer #ifdef ERR_DBG // len ak je ladenie char ErrLatche[256]; BOOL suc; char NoError[14] = {0x30, 0x2C, 0x22, 0x4E, 0x6F, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x22, 0x0A, 0x00}; // vracany retazec #endif if(MeasureConfig != 1) // ak to nie je zostava analyzatora return FALSE; EnterCriticalSection(&g_CriticalSectionICL); // ochrana pre vylucenie pristupu ineho threadu // vyslanie retazca memset(SendBufferForAnalyzer, 0, sizeof(SendBufferForAnalyzer)); strcpy(SendBufferForAnalyzer, SendBuffer); wstring: (*PSend)(GPIB0, Result[AnalyzerEngineIndex], SendBufferForAnalyzer, strlen(SendBufferForAnalyzer), NLend); if((*Pibsta) & ERR) // ak je chyba { if(!count) { GPIBCleanup(GPIB0, "Unable send to a device"); LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return FALSE; } count--; Sleep(WDELAY); goto wstring; // este opakovat } #ifdef ERR_DBG // len ak je ladenie suc = AnalyzerWriteT("SYSTEM:ERROR?"); if(!suc) // ak je chyba { LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return suc; } suc = AnalyzerRead(ErrLatche); // nacitanie parametrov (nacita uroven) if(!suc) // ak je chyba { LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return suc; } if(strcmp(ErrLatche, NoError)) // ak je chyba (nie je to "0, "No error"") { MessageBoxAudit(NULL, ErrLatche, LoadResString(IDS_TX568), MB_OK | MB_ICONSTOP | MB_SETFOREGROUND | MB_TASKMODAL); } #endif LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return TRUE; } //*** Zapis riadiaceho retazca do analyzatora cez GPIB pre nacitanie chyboveho latche analyzatora *** // Bez ochrany kritickou sekciou - vznikol by deadlock BOOL AnalyzerWriteT(LPSTR SendBuffer) { char SendBufferForAnalyzer[ARRAYSIZE + 1]; // zapisovy datovy buffer if(MeasureConfig != 1) // ak to nie je zostava analyzatora return FALSE; // vyslanie retazca memset(SendBufferForAnalyzer, 0, sizeof(SendBufferForAnalyzer)); strcpy(SendBufferForAnalyzer, SendBuffer); (*PSend)(GPIB0, Result[AnalyzerEngineIndex], SendBufferForAnalyzer, strlen(SendBufferForAnalyzer), NLend); if((*Pibsta) & ERR) // ak je chyba { GPIBCleanup(GPIB0, "Unable send to a device"); return FALSE; } return TRUE; } //*** Citanie odozvy z analyzatora cez GPIB *** BOOL AnalyzerRead(LPSTR ReadBuffer) { #define RDELAY 1 // 1 mS int count = 15000; // pre 15 sekund char ReadBufferForAnalyzer[ARRAYSIZE + 1]; // zapisovy datovy buffer if(MeasureConfig != 1) // ak to nie je zostava analyzatora return FALSE; EnterCriticalSection(&g_CriticalSectionICL); // ochrana pre vylucenie pristupu ineho threadu // nacitanie retazca rstring: memset(ReadBufferForAnalyzer, 0, sizeof(ReadBufferForAnalyzer)); (*PReceive)(GPIB0, Result[AnalyzerEngineIndex], ReadBufferForAnalyzer, sizeof(ReadBufferForAnalyzer), STOPend); // nacitanie zo zariadenia if((*Pibsta) & ERR) // ak je chyba { if(!count) { GPIBCleanup(GPIB0, "Unable read from a device"); LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return FALSE; } count--; Sleep(RDELAY); goto rstring; // este opakovat } strcpy(ReadBuffer, ReadBufferForAnalyzer); // nakopirovanie odozvy do buffra LeaveCriticalSection(&g_CriticalSectionICL); // zrusenie ochrany vyhradneho pristupu return TRUE; } //*** Inicializacia zariadeni zresetovanim *** BOOL AnalyzerInitDevice() { BOOL suc; WaitopAnalyzer(); // cakanie na ready suc = AnalyzerWrite("*CLS"); // reset status registrov if(!suc) // ak je chyba return suc; WaitopAnalyzer(); // cakanie na ready suc = AnalyzerWrite("*RST"); // reset zariadeni (prozor, nastavuje frekvenciu na 20 GHz s span 40 GHz) return suc; } //*** Display bude pri merani zapnuty *** BOOL AnalyzerDisplayOn() { BOOL suc; WaitopAnalyzer(); // cakanie na ready suc = AnalyzerWrite("SYST:DISP:UPD ON"); // zapis return suc; } //*** Display bude pri merani vypnuty *** BOOL AnalyzerDisplayOff() { BOOL suc; WaitopAnalyzer(); // cakanie na ready suc = AnalyzerWrite("SYST:DISP:UPD OFF"); // zapis return suc; } //*** Power saver - ON *** BOOL AnalyzerPowerSaveON() { BOOL suc; WaitopAnalyzer(); // cakanie na ready suc = AnalyzerWrite("SYST:PSAV:HOLD 1"); // zapis casu if(!suc) // ak je chyba return suc; WaitopAnalyzer(); // cakanie na ready suc = AnalyzerWrite("SYST:PSAV ON"); // zapnutie return suc; } //*** Power saver - OFF *** BOOL AnalyzerPowerSaveOFF() { BOOL suc; suc = AnalyzerWrite("SYST:PSAV OFF"); // vypnutie return suc; } //*** Start merania na analyzatore *** BOOL TestMeasure(HWND hwndDlg) { StartOfSweepMeasurement(hwndDlg); // start threadu merania return TRUE; } //*** Meranie urovne na nastavenej frekvencii *** BOOL AnalyzerMeasureLevelOnSetfrequencyEngin(HWND hwndDlg, int Frequency, int Span, double Rlevel, LPTSTR Result) { BOOL suc; char freq[256]; char span[256]; char rlevel[256]; char msg[256]; char msg1[256]; wsprintf(freq, "FREQUENCY:CENTER %dMHz", Frequency); WaitopAnalyzer(); // cakanie na ready suc = AnalyzerWrite(freq); // stredna frekvencia if(!suc) // ak je chyba return suc; // nastavenie strednej frekvencie wsprintf(span, "FREQUENCY:SPAN %dMHz", Span); WaitopAnalyzer(); // cakanie na ready suc = AnalyzerWrite(span); // rozsah if(!suc) // ak je chyba return suc; // nastavenie referencnej urovne sprintf(rlevel, "DISPLAY:TRACE:Y:RLEVEL %lfdbm", Rlevel); WaitopAnalyzer(); // cakanie na ready suc = AnalyzerWrite(rlevel); // referencna uroven if(!suc) // ak je chyba return suc; // nastavenie markera na maximum priebehu WaitopAnalyzer(); // cakanie na ready suc = AnalyzerWrite(":CALC:MARKER:MAX"); // nastavenie markera 1 na maximum if(!suc) // ak je chyba return suc; // vycitanie urovne markera 1 WaitopAnalyzer(); // cakanie na ready suc = AnalyzerWrite(":CALC:MARKER:Y?"); // vycitanie hodnoty z markera if(!suc) // ak je chyba return suc; // vycitanie vysledku z latche analyzatora suc = AnalyzerRead(Result); // nacitanie parametrov (nacita uroven) // zaznam nameranych hodnot do auditu memset(msg1, 0, sizeof(msg1)); wsprintf(msg1, Result); for(int i = 0; i < 255; i++) // zamena "LF" { if(msg1[i] == 0xa) { msg1[i] = 0; break; } } strcat(msg1, " dBm"); wsprintf(msg, "*** Test frequency: %dMHz, Background level: %s", Frequency, msg1); SpecialAuditEntry(NULL, msg); // zapis oznamu o specialnej udalosti do auditu // priebezny vypis hodnot do edit boxov wsprintf(msg, "%d", Frequency); SetDlgItemText(hwndDlg, IDC_EDIT1, msg); SetDlgItemText(hwndDlg, IDC_EDIT2, msg1); sprintf(rlevel, "%lfdbm", Rlevel); SetDlgItemText(hwndDlg, IDC_EDIT3, rlevel); return suc; } //*** Thread merania urovne na pevne nastavenych frekvenciach *** void AnalyzerMeasureLevelOnSetfrequency(PVOID hwndDlg) { BOOL suc; int Frequency; // frekvencia v MHz int Span; // rozsah double Rlevel; // referencna uroven char Result[256]; char msg[256]; KillTimer((HWND)hwndDlg, TIMER1); // zrusenie casovaca WaitopAnalyzer(); // cakanie na ready suc = AnalyzerWrite("*CLS"); // reset status registrov WaitopAnalyzer(); // cakanie na ready suc = AnalyzerWrite("*RST"); // reset zariadeni (prozor, nastavuje frekvenciu na 20 GHz s span 40 GHz) suc = AnalyzerWrite(":CALC:MARKER ON;MARKER:MAX"); // zapnutie markera 1 a nastavenie na maximum wsprintf(msg, "*********** Measurement of background levels ***********"); SpecialAuditEntry(NULL, msg); // zapis oznamu o specialnej udalosti do auditu SendGeneratorStatement((HWND)hwndDlg, "*RST"); // vyslanie prikazu pre generator SendGeneratorStatement((HWND)hwndDlg, "*CLS"); // vyslanie prikazu pre generator SendGeneratorStatement((HWND)hwndDlg, "OUTP:STAT ON"); // vyslanie prikazu pre generator Sleep(600); SendGeneratorStatement((HWND)hwndDlg, "FREQ 10MHz"); // vyslanie prikazu pre generator Sleep(600); Frequency = 10; // 10 MHz Span = 1; Rlevel = -19; suc = AnalyzerMeasureLevelOnSetfrequencyEngin((HWND)hwndDlg, Frequency, Span, Rlevel, Result); SendGeneratorStatement((HWND)hwndDlg, "FREQ 20MHz"); // vyslanie prikazu pre generator Sleep(600); Frequency = 20; // 20 MHz Span = 1; Rlevel = -19; suc = AnalyzerMeasureLevelOnSetfrequencyEngin((HWND)hwndDlg, Frequency, Span, Rlevel, Result); SendGeneratorStatement((HWND)hwndDlg, "FREQ 30MHz"); // vyslanie prikazu pre generator Sleep(600); Frequency = 30; // 30 MHz Span = 1; Rlevel = -19; suc = AnalyzerMeasureLevelOnSetfrequencyEngin((HWND)hwndDlg, Frequency, Span, Rlevel, Result); SendGeneratorStatement((HWND)hwndDlg, "FREQ 40MHz"); // vyslanie prikazu pre generator Sleep(600); Frequency = 40; // 40 MHz Span = 1; Rlevel = -19; suc = AnalyzerMeasureLevelOnSetfrequencyEngin((HWND)hwndDlg, Frequency, Span, Rlevel, Result); SendGeneratorStatement((HWND)hwndDlg, "FREQ 50MHz"); // vyslanie prikazu pre generator Sleep(600); Frequency = 50; // 50 MHz Span = 1; Rlevel = -19; suc = AnalyzerMeasureLevelOnSetfrequencyEngin((HWND)hwndDlg, Frequency, Span, Rlevel, Result); SendGeneratorStatement((HWND)hwndDlg, "FREQ 60MHz"); // vyslanie prikazu pre generator Sleep(600); Frequency = 60; // 60 MHz Span = 1; Rlevel = -19; suc = AnalyzerMeasureLevelOnSetfrequencyEngin((HWND)hwndDlg, Frequency, Span, Rlevel, Result); SendGeneratorStatement((HWND)hwndDlg, "FREQ 70MHz"); // vyslanie prikazu pre generator Sleep(600); Frequency = 70; // 70 MHz Span = 1; Rlevel = -19; suc = AnalyzerMeasureLevelOnSetfrequencyEngin((HWND)hwndDlg, Frequency, Span, Rlevel, Result); SendGeneratorStatement((HWND)hwndDlg, "FREQ 80MHz"); // vyslanie prikazu pre generator Sleep(600); Frequency = 80; // 80 MHz Span = 1; Rlevel = -19; suc = AnalyzerMeasureLevelOnSetfrequencyEngin((HWND)hwndDlg, Frequency, Span, Rlevel, Result); SendGeneratorStatement((HWND)hwndDlg, "FREQ 90MHz"); // vyslanie prikazu pre generator Sleep(600); Frequency = 90; // 90 MHz Span = 1; Rlevel = -19; suc = AnalyzerMeasureLevelOnSetfrequencyEngin((HWND)hwndDlg, Frequency, Span, Rlevel, Result); SendGeneratorStatement((HWND)hwndDlg, "FREQ 100MHz"); // vyslanie prikazu pre generator Sleep(600); Frequency = 100; // 100 MHz Span = 1; Rlevel = -19; suc = AnalyzerMeasureLevelOnSetfrequencyEngin((HWND)hwndDlg, Frequency, Span, Rlevel, Result); wsprintf(msg, "************** End of levels measurement ***************"); SpecialAuditEntry(NULL, msg); // zapis oznamu o specialnej udalosti do auditu GetToOffline(); SetTimer((HWND)hwndDlg, TIMER1, LAYOUT_CHECK_TIME, NULL); // nastavenie casovaca ExitThread(0); } //*** Cakanie na cakanie na dokoncenie operacie analyzatora *** BOOL WaitopAnalyzer() { BOOL wsuc; BOOL suc; int csuc; // vysledok porovnania char result[10]; char one[] = "1"; wsuc = TRUE; Sleep(TIME_OF_SWEEP); tst: suc = AnalyzerWrite(":ABOR;INIT:IMM; *OPC?"); // vycitanie hodnoty z markera if(!suc) // ak je chyba return suc; suc = AnalyzerRead(result); // nacitanie parametrov (nacita uroven) csuc = memcmp(one, result, 1); // test na "1" if(!csuc) { // ak je zhoda return TRUE; } goto tst; return wsuc; } //*** Start threadu merania *** BOOL StartOfSweepMeasurement(HWND hWnd) { DWORD retv; // ochrana pred viacnasobnym spustenim threadu retv = WaitForSingleObject((PVOID)ht15, 10); // test na trvanie prvej kopie threadu if(retv == WAIT_TIMEOUT) // ak thread este bezi { return FALSE; // nespustat dalsiu kopiu } ht15 = _beginthread(AnalyzerMeasureLevelOnSetfrequency, 0, hWnd); // start threadu pre meranie return TRUE; } //*** Start hreadu prijmu paketu z radiomodemu *** BOOL StartOfRmReadThreadAnalyzator(HWND hWnd) { DWORD retv; // ochrana pred viacnasobnym spustenim threadu retv = WaitForSingleObject((PVOID)ht16, 10); // test na trvanie prvej kopie threadu if(retv == WAIT_TIMEOUT) // ak thread este bezi { return FALSE; // nespustat dalsiu kopiu } ht16 = _beginthread(RMreadThreadPacket, 0, hWnd); // start threadu pre citanie return TRUE; }