/* ------------------------------------------------------------------------------ | APPGenMon | | Author : Terry Leach | Revision: 2/22/03 Initial creation Purpose : A Tone generator and monitor. Generates tones on all 8 channels of Layla Measures the corresponding channels. */ #include #include #include extern "C" { #include "APP.h" #include "misctyps.h" } #include "ERROR.hpp" #include "MATRIX.hpp" #include "BINLIST.hpp" #include "WAVES2.hpp" #include "CHANNEL.hpp" #define SLEEP(msToSleep) _sleep(msToSleep) // Test with 1 and 5 chans now we go the max #define _ALLCHAN static ERR errApp; static char szMsg[ 80 ]; static BINLIST binCH1; static BINLIST binCH2; static BINLIST binCH3; static BINLIST binCH4; static BINLIST binCH5; #ifdef _ALLCHAN static BINLIST binCH6; static BINLIST binCH7; static BINLIST binCH8; #endif typedef long WVFORM[ FAST_FFT_SZ ]; WVFORM wvfrmCH1; WVFORM wvfrmCH2; WVFORM wvfrmCH3; WVFORM wvfrmCH4; WVFORM wvfrmCH5; #ifdef _ALLCHAN WVFORM wvfrmCH6; WVFORM wvfrmCH7; WVFORM wvfrmCH8; #endif WAVE wvCH1 ( wvfrmCH1 ); WAVE wvCH2 ( wvfrmCH2 ); WAVE wvCH3 ( wvfrmCH3 ); WAVE wvCH4 ( wvfrmCH4 ); WAVE wvCH5 ( wvfrmCH5 ); #ifdef _ALLCHAN WAVE wvCH6 ( wvfrmCH6 ); WAVE wvCH7 ( wvfrmCH7 ); WAVE wvCH8 ( wvfrmCH8 ); #endif // LAYLA channel definitions CHANNEL chMaster; // Master channel control... just for readability // Output channels CHANNEL ch1 ( &wvCH1 ,1 ); CHANNEL ch2 ( &wvCH2 ,2 ); CHANNEL ch3 ( &wvCH3 ,3 ); CHANNEL ch4 ( &wvCH4 ,4 ); CHANNEL ch5 ( &wvCH5 ,5 ); #ifdef _ALLCHAN CHANNEL ch6 ( &wvCH6 ,6 ); CHANNEL ch7 ( &wvCH7 ,7 ); CHANNEL ch8 ( &wvCH8 ,8 ); #endif // Input channels static long meas1[ FFT_SZ ]; // Memory to hold incomming waveforms static long meas2[ FFT_SZ ]; static long meas3[ FFT_SZ ]; static long meas4[ FFT_SZ ]; static long meas5[ FFT_SZ ]; #ifdef _ALLCHAN static long meas6[ FFT_SZ ]; static long meas7[ FFT_SZ ]; static long meas8[ FFT_SZ ]; #endif static CHANNEL ch_1 ( &meas1[0] ,FFT_SZ ,1 ); // We will measure on channel 1 static CHANNEL ch_2 ( &meas2[0] ,FFT_SZ ,2 ); static CHANNEL ch_3 ( &meas3[0] ,FFT_SZ ,3 ); static CHANNEL ch_4 ( &meas4[0] ,FFT_SZ ,4 ); static CHANNEL ch_5 ( &meas5[0] ,FFT_SZ ,5 ); #ifdef _ALLCHAN static CHANNEL ch_6 ( &meas6[0] ,FFT_SZ ,6 ); static CHANNEL ch_7 ( &meas7[0] ,FFT_SZ ,7 ); static CHANNEL ch_8 ( &meas8[0] ,FFT_SZ ,8 ); #endif static uint Status = 0; // -------------------- VECTOR APP_useVec( TONELIST *pTone ); // APP for GenMon // --------------------------------------------------------------------------- void APP_load( ) /* | Purpose: Starts the ASIO sound driver. */ { errApp.Display( "APP_load: " ); chMaster.go(); } // --------------------------------------------------------------------------- void APP_close ( void ) /* | Purpose: Shuts down the ASIO sound driver... this is done when all the instantiated CHANNEL objects go out of scope. */ { errApp.Display( "APP_close:" ); } // --------------------------------------------------------------------------- void APP_TXonly( TONELIST *pCH1 ,TONELIST *pCH2 ,TONELIST *pCH3 ,TONELIST *pCH4 ,TONELIST *pCH5 ,TONELIST *pCH6 ,TONELIST *pCH7 ,TONELIST *pCH8 ) /* | Purpose: Ramps the system up to full power signals. Nulling is used for each entry in the pSteps list. In this way TX and REF balance against one another as they are ramped. INPUTS: pCntl Control structure containing bit packed control word as well as thresholds and iteration limits for nulling operations pTX A list of tones (frequency,complex component) describing the TX waveform. pREF The reference waveform tone description pCAL The Calibration waveform tone description pSteps A list of multiplication factors used to "Ramp" up the TX and REF waveforms. */ { errApp.Display( "APP_SysStart: " ); binCH1.binlist ( (*(pCH1-> freqLIST))-> Freqs ,(uint)(*(pCH1-> freqLIST))-> numFreqs ); binCH2.binlist ( (*(pCH2-> freqLIST))-> Freqs ,(uint)(*(pCH2-> freqLIST))-> numFreqs ); binCH3.binlist ( (*(pCH3-> freqLIST))-> Freqs ,(uint)(*(pCH3-> freqLIST))-> numFreqs ); binCH4.binlist ( (*(pCH4-> freqLIST))-> Freqs ,(uint)(*(pCH4-> freqLIST))-> numFreqs ); binCH5.binlist ( (*(pCH5-> freqLIST))-> Freqs ,(uint)(*(pCH5-> freqLIST))-> numFreqs ); #ifdef _ALLCHAN binCH6.binlist ( (*(pCH6-> freqLIST))-> Freqs ,(uint)(*(pCH6-> freqLIST))-> numFreqs ); binCH7.binlist ( (*(pCH7-> freqLIST))-> Freqs ,(uint)(*(pCH7-> freqLIST))-> numFreqs ); binCH8.binlist ( (*(pCH8-> freqLIST))-> Freqs ,(uint)(*(pCH8-> freqLIST))-> numFreqs ); #endif binCH1.convert( BINS ,FAST_FFT_SZ ); binCH2.convert( BINS ,FAST_FFT_SZ ); binCH3.convert( BINS ,FAST_FFT_SZ ); binCH4.convert( BINS ,FAST_FFT_SZ ); binCH5.convert( BINS ,FAST_FFT_SZ ); #ifdef _ALLCHAN binCH6.convert( BINS ,FAST_FFT_SZ ); binCH7.convert( BINS ,FAST_FFT_SZ ); binCH8.convert( BINS ,FAST_FFT_SZ ); #endif wvCH1.modify ( APP_useVec(pCH1) ,binCH1.m_pBins ); wvCH2.modify ( APP_useVec(pCH2) ,binCH2.m_pBins ); wvCH3.modify ( APP_useVec(pCH3) ,binCH3.m_pBins ); wvCH4.modify ( APP_useVec(pCH4) ,binCH4.m_pBins ); wvCH5.modify ( APP_useVec(pCH5) ,binCH5.m_pBins ); #ifdef _ALLCHAN wvCH6.modify ( APP_useVec(pCH6) ,binCH6.m_pBins ); wvCH7.modify ( APP_useVec(pCH7) ,binCH7.m_pBins ); wvCH8.modify ( APP_useVec(pCH8) ,binCH8.m_pBins ); #endif ch1.change(); ch2.change(); ch3.change(); ch4.change(); ch5.change(); #ifdef _ALLCHAN ch6.change(); ch7.change(); ch8.change(); #endif } // --------------------------------------------------------------------------- void APP_Measure( RTWAVE *pWV1 ,RTWAVE *pWV2 ,RTWAVE *pWV3 ,RTWAVE *pWV4 ,RTWAVE *pWV5 ,RTWAVE *pWV6 ,RTWAVE *pWV7 ,RTWAVE *pWV8 ) /* | Purpose: Takes a measurement each channel on the Layla. The entire real time waveform is sent back to LabView. INPUTS: pWV1 Pointer to the channel 1 real time waveform within LabView. This will be loaded with a single precision floating point representation of the sampled waveform. */ { WAVEPTR wvp; long pt; // ------------ ch1.GetNew(); while( ch1.busy() ) { // Now wait for whole waveform SLEEP( 100 ); } ch_1.lock(); ch_2.lock(); ch_3.lock(); ch_4.lock(); ch_5.lock(); #ifdef _ALLCHAN ch_6.lock(); ch_7.lock(); ch_8.lock(); #endif ch_1.convert(); ch_2.convert(); ch_3.convert(); ch_4.convert(); ch_5.convert(); #ifdef _ALLCHAN ch_6.convert(); ch_7.convert(); ch_8.convert(); #endif for( wvp.pv = &meas1[0] ,pt = pWV1-> NumPts; pt--; pWV1-> wave[pt] = wvp.pf[pt] ); for( wvp.pv = &meas2[0] ,pt = pWV2-> NumPts; pt--; pWV2-> wave[pt] = wvp.pf[pt] ); for( wvp.pv = &meas3[0] ,pt = pWV3-> NumPts; pt--; pWV3-> wave[pt] = wvp.pf[pt] ); for( wvp.pv = &meas4[0] ,pt = pWV4-> NumPts; pt--; pWV4-> wave[pt] = wvp.pf[pt] ); for( wvp.pv = &meas5[0] ,pt = pWV5-> NumPts; pt--; pWV5-> wave[pt] = wvp.pf[pt] ); #ifdef _ALLCHAN for( wvp.pv = &meas6[0] ,pt = pWV6-> NumPts; pt--; pWV6-> wave[pt] = wvp.pf[pt] ); for( wvp.pv = &meas7[0] ,pt = pWV7-> NumPts; pt--; pWV7-> wave[pt] = wvp.pf[pt] ); for( wvp.pv = &meas8[0] ,pt = pWV8-> NumPts; pt--; pWV8-> wave[pt] = wvp.pf[pt] ); #endif ch_1.unlock(); ch_2.unlock(); ch_3.unlock(); ch_4.unlock(); ch_5.unlock(); #ifdef _ALLCHAN ch_6.unlock(); ch_7.unlock(); ch_8.unlock(); #endif } // ========================================================================================= // Internal utilities // --------------------------------------------------------------------------- VECTOR APP_useVec( TONELIST *pTone ) /* | Purpose: INPUTS: */ { int vecLen; // ----------- vecLen = (*(pTone-> cxLIST))->LstLen; if( vecLen < 1 ) return VECTOR( 1 ); return VECTOR( &(*(pTone-> cxLIST))->cxVal[0] ,vecLen ); }