UInt16 m_nUpperBound = 0; //Max value for index with available data void InitializeCollection() { m_arrScreenContainer = new RFEScreenData[MAX_ELEMENTS]; RFEScreenData objFirst = new RFEScreenData(128, 8); Add(objFirst); m_nUpperBound = 0; }
public void Add(RFEScreenData ScreenData) { if (IsFull()) { return; } m_nUpperBound++; m_arrScreenContainer[m_nUpperBound] = ScreenData; }
/// <summary> /// Will load a RFS standard file from disk. If the file format is incorrect (unknown) will return false but will not invalidate the internal container /// If there are file exceptions, will be received by the caller so should react with appropriate error control /// If file is successfully loaded, all previous container data is lost and replaced by data from file /// </summary> /// <param name="sFile"></param> /// <returns></returns> public bool LoadFile(string sFile) { FileStream myFile = null; try { myFile = new FileStream(sFile, FileMode.Open); using (BinaryReader binStream = new BinaryReader(myFile)) { myFile = null; string sHeader = binStream.ReadString(); if ((sHeader != FileHeaderVersioned()) && (sHeader != FileHeaderVersioned_001())) { return(false); } CleanAll(); m_nUpperBound = binStream.ReadUInt16(); //We start at page 1, page 0 is always null for (UInt16 nPageInd = 1; nPageInd <= m_nUpperBound; nPageInd++) { binStream.ReadUInt16(); //page number, can be ignored here RFEScreenData objScreen = new RFEScreenData(128, 8); m_arrScreenContainer[nPageInd] = objScreen; if (sHeader == FileHeaderVersioned_001()) { objScreen.CaptureTime = new DateTime(2000, 1, 1); //year 2000 means no actual valid date-time was captured } else { //Starting in version 002, load sweep capture time too int nLength = (int)binStream.ReadInt32(); string sTime = (string)binStream.ReadString(); if ((sTime.Length == nLength) && (nLength > 0)) { objScreen.CaptureTime = DateTime.Parse(sTime); } objScreen.Model = (RFECommunicator.eModel)binStream.ReadByte(); } for (int nIndY = 0; nIndY < 8; nIndY++) { for (int nIndX = 0; nIndX < 128; nIndX++) { byte nData = binStream.ReadByte(); objScreen.m_arrRemoteScreenData[nIndX + 128 * nIndY] = nData; } } } } } finally { if (myFile != null) { myFile.Dispose(); } } return(true); }
/// <summary> /// The secondary thread used to get data from USB/RS232 COM port /// </summary> private void ReceiveThreadfunc() { //this is the object used to keep current configuration data RFEConfiguration objCurrentConfiguration = null; RFESweepData objSweepTracking = null; m_bThreadTrackingEnabled = false; int nTrackingStepRetry = 0; while (m_bRunReceiveThread) { string strReceived = ""; #if SUPPORT_EXPERIMENTAL while (m_bPortConnected && !m_bModeAPI) #else while (m_bPortConnected && m_bRunReceiveThread) #endif { string sNewText = ""; try { Monitor.Enter(m_serialPortObj); if (m_serialPortObj.IsOpen && m_serialPortObj.BytesToRead > 0) { sNewText = m_serialPortObj.ReadExisting(); } } catch (IOException) { } catch (TimeoutException) { } catch (Exception obExeption) { Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue(obExeption); Monitor.Exit(m_arrReceivedData); } finally { Monitor.Exit(m_serialPortObj); } if (sNewText.Length > 0) { if (m_bDebugTraces) { //Debug only, do not enable this in production m_ReceivedBytesMutex.WaitOne(); m_sAllReceivedBytes += sNewText; m_ReceivedBytesMutex.ReleaseMutex(); } strReceived += sNewText; sNewText = ""; } if (strReceived.Length > 25240) { //Safety code, some error prevented the string from being processed in several loop cycles. Reset it. if (m_bDebugTraces) { Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue("Received string truncated (" + strReceived.Length + ")"); Monitor.Exit(m_arrReceivedData); } strReceived = ""; } if (strReceived.Length > 0) { if (strReceived[0] == '#') { int nEndPos = strReceived.IndexOf("\r\n"); if (nEndPos >= 0) { string sNewLine = strReceived.Substring(0, nEndPos); string sLeftOver = strReceived.Substring(nEndPos + 2); strReceived = sLeftOver; RFEConfiguration objNewConfiguration = null; if ((sNewLine.Length > 2) && (sNewLine.Substring(0, 3) == "#K1")) { if (m_bThreadTrackingEnabled==false) { //if we are starting tracking here, send the request for first step right away m_objRFEGen.SendCommand_TrackingStep(0); SendCommand_TrackingStep(0); } m_bThreadTrackingEnabled=true; nTrackingStepRetry = 0; Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue(sNewLine); Monitor.Exit(m_arrReceivedData); } if ((sNewLine.Length > 2) && (sNewLine.Substring(0, 3) == "#K0")) { m_bThreadTrackingEnabled = false; Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue(sNewLine); Monitor.Exit(m_arrReceivedData); } else if ((sNewLine.Length > 5) && ((sNewLine.Substring(0, 6) == "#C2-F:") || (sNewLine.Substring(0, 6) == "#C3-G:"))) { m_bThreadTrackingEnabled=false; if (m_bDebugTraces) { Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue("Received Config:" + strReceived.Length.ToString("D5")); Monitor.Exit(m_arrReceivedData); } //Standard configuration expected objNewConfiguration = new RFEConfiguration(); if (objNewConfiguration.ProcessReceivedString(sNewLine)) { objCurrentConfiguration = new RFEConfiguration(objNewConfiguration); Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue(objNewConfiguration); Monitor.Exit(m_arrReceivedData); } } else { Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue(sNewLine); Monitor.Exit(m_arrReceivedData); } } } else if (strReceived[0] == '$') { if ((strReceived.Length > 4) && (strReceived[1] == 'C')) { UInt16 nSize = 2; //account for CR+LF switch (strReceived[2]) { case 'c': { //Calibration data nSize += (byte)(Convert.ToByte(strReceived[3]) + 4); break; } case 'b': { //Memory data dump nSize += (UInt16)((Convert.ToByte(strReceived[4]) + 1) * 16 + 10); break; } } //This is standard for all 'C' data dumps if ((nSize > 2) && (strReceived.Length >= nSize)) { string sNewLine = strReceived.Substring(0, nSize); string sLeftOver = strReceived.Substring(nSize); strReceived = sLeftOver; Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue(sNewLine); Monitor.Exit(m_arrReceivedData); } } else if ((strReceived.Length > 1) && (strReceived[1] == 'q')) { //this is internal calibration data dump ushort nReceivedLength = (byte)strReceived[2]; bool bLengthOK = (strReceived.Length >= (3 + nReceivedLength + 2)); if (bLengthOK) { Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue(strReceived); Monitor.Exit(m_arrReceivedData); strReceived = strReceived.Substring(3 + nReceivedLength + 2); } } else if ((strReceived.Length > 1) && (strReceived[1] == 'D')) { //This is dump screen data if (m_bDebugTraces) { Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue("Received $D" + strReceived.Length.ToString("D5")); Monitor.Exit(m_arrReceivedData); } if (strReceived.Length >= (4 + 128 * 8)) { string sNewLine = "$D" + strReceived.Substring(2, 128 * 8); string sLeftOver = strReceived.Substring(4 + 128 * 8); strReceived = sLeftOver; RFEScreenData objData = new RFEScreenData(); if (objData.ProcessReceivedString(sNewLine)) { Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue(objData); Monitor.Exit(m_arrReceivedData); } else { Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue(sNewLine); Monitor.Exit(m_arrReceivedData); } } } else if ((strReceived.Length > 2) && (strReceived[1] == 'S')) { //Standard spectrum analyzer data ushort nReceivedLength = (byte)strReceived[2]; if (m_bDebugTraces) { Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue("Received $S" + nReceivedLength.ToString("D5")); Monitor.Exit(m_arrReceivedData); } bool bLengthOK = (strReceived.Length >= (3 + nReceivedLength + 2)); bool bFullStringOK = false; if (bLengthOK && (strReceived.Substring(3 + nReceivedLength, 2) == "\r\n")) { bFullStringOK = true; } if (bFullStringOK) { //So we are here because received the full set of chars expected, and all them are apparently of valid characters if (nReceivedLength <= MAX_SPECTRUM_STEPS) { string sNewLine = "$S" + strReceived.Substring(3, nReceivedLength); if (objCurrentConfiguration != null) { UInt16 nSweepSteps = objCurrentConfiguration.nFreqSpectrumSteps; if (m_bThreadTrackingEnabled) { nSweepSteps = nReceivedLength; } RFESweepData objSweep = new RFESweepData(objCurrentConfiguration.fStartMHZ, objCurrentConfiguration.fStepMHZ, nSweepSteps); if (objSweep.ProcessReceivedString(sNewLine, objCurrentConfiguration.fOffset_dB)) { if (!m_bThreadTrackingEnabled) { //Normal spectrum analyzer sweep data Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue(objSweep); Monitor.Exit(m_arrReceivedData); } else { //tracking generator sweep data, we capture a sweep point every time to build a new full objSweepTracking if (m_nRFGenTracking_CurrentSweepStep == 0) { objSweepTracking = new RFESweepData(m_objRFEGen.RFGenStartFrequencyMHZ, m_objRFEGen.RFGenStepFrequencyMHZ, m_objRFEGen.RFGenSweepSteps); } float fMaxDB = objSweep.GetAmplitudeDBM(objSweep.GetPeakStep()); objSweepTracking.SetAmplitudeDBM(m_nRFGenTracking_CurrentSweepStep, fMaxDB); if (!m_bTrackingNormalizing || (fMaxDB > MIN_AMPLITUDE_TRACKING_NORMALIZE) || !m_bTrackingAllowed) { //if we are normalizing, make sure the value read is correct or either do not increase step m_nRFGenTracking_CurrentSweepStep++; } else { nTrackingStepRetry++; if (m_bTrackingNormalizing && nTrackingStepRetry > (m_objRFEGen.RFGenSweepSteps / 5)) { //if we retried about the same number of steps the sweep have, then something is really wrong m_objRFEGen.SendCommand_GeneratorRFPowerOFF(); m_bThreadTrackingEnabled = false; //be done with thread tracking activity, so main thread knows Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue("Too many retries normalizing data. Review your setup and restart Spectrum Analyzer"); Monitor.Exit(m_arrReceivedData); Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue(objSweepTracking); //send whatever we have, we will detect it outside the thread Monitor.Exit(m_arrReceivedData); } } if (m_bThreadTrackingEnabled) { if (m_nRFGenTracking_CurrentSweepStep <= m_objRFEGen.RFGenSweepSteps) { m_objRFEGen.SendCommand_TrackingStep(m_nRFGenTracking_CurrentSweepStep); SendCommand_TrackingStep(m_nRFGenTracking_CurrentSweepStep); } else { //we are done with a tracking sweep capture objSweepTracking, make it available m_nTrackingNormalizingPass++; m_nTrackingPass++; Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue(objSweepTracking); Monitor.Exit(m_arrReceivedData); //If we need to restart, do it from first step m_nRFGenTracking_CurrentSweepStep = 0; if ( (m_bTrackingNormalizing && (m_nTrackingNormalizingPass > m_nAutoStopSNATrackingCounter)) || !m_bTrackingAllowed || (!m_bTrackingNormalizing && ((m_nAutoStopSNATrackingCounter!=0) && (m_nTrackingPass > m_nAutoStopSNATrackingCounter))) ) { //if normalizing is completed, or if we have finished tracking manually or automatically, we are done with RF power m_objRFEGen.SendCommand_GeneratorRFPowerOFF(); m_bThreadTrackingEnabled = false; //be done with thread tracking activity, so main thread knows } else { //start all over again a full new sweep m_objRFEGen.SendCommand_TrackingStep(m_nRFGenTracking_CurrentSweepStep); SendCommand_TrackingStep(m_nRFGenTracking_CurrentSweepStep); } } } } } else { Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue(sNewLine); Monitor.Exit(m_arrReceivedData); } } } else { Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue("Ignored $S of size " + nReceivedLength.ToString() + " expected " + FreqSpectrumSteps.ToString()); Monitor.Exit(m_arrReceivedData); } strReceived = strReceived.Substring(3 + nReceivedLength + 2); } else if (bLengthOK) { //So we are here because the string doesn't end with the expected chars, but has the right length. //The most likely cause is a truncated string was received, and some chars are from next string, not this one //therefore we truncate the line to avoid being much larger, and start over again next time. int nPosNextLine = strReceived.IndexOf("\r\n"); if (nPosNextLine >= 0) { strReceived = strReceived.Substring(nPosNextLine + 2); } } } else if ((strReceived.Length > 3) && (strReceived[1] == 's')) { //Extended API spectrum analyzer data ushort nReceivedLength = (byte)strReceived[2]; nReceivedLength = (ushort)(nReceivedLength * 0x100 + (byte)strReceived[3]); if (strReceived.Length >= (4 + nReceivedLength + 2)) { if (nReceivedLength <= MAX_SPECTRUM_STEPS) { string sNewLine = "$S" + strReceived.Substring(4, nReceivedLength); Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue(sNewLine); Monitor.Exit(m_arrReceivedData); } else { Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue("Ignored $S of size " + nReceivedLength.ToString() + " expected " + FreqSpectrumSteps.ToString()); Monitor.Exit(m_arrReceivedData); } string sLeftOver = strReceived.Substring(4 + nReceivedLength + 2); strReceived = sLeftOver; } } else if ((strReceived.Length > 10) && (strReceived[1] == 'R')) { //Raw data int nPos = strReceived.IndexOf('-'); if ((nPos > 2) && (nPos < 10)) { int nSize = Convert.ToInt32(strReceived.Substring(2, nPos - 2)); if (strReceived.Length > (nSize + nPos + 2)) { Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue("Received RAW data " + nSize.ToString()); m_arrReceivedData.Enqueue("$R" + strReceived.Substring(nPos + 1, nSize)); Monitor.Exit(m_arrReceivedData); strReceived = strReceived.Substring(nSize + nPos + 1 + 2); } } } } else { int nEndPos = strReceived.IndexOf("\r\n"); if (nEndPos >= 0) { string sNewLine = strReceived.Substring(0, nEndPos); string sLeftOver = strReceived.Substring(nEndPos + 2); strReceived = sLeftOver; Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue(sNewLine); Monitor.Exit(m_arrReceivedData); } else { //diagnosis only if (m_bDebugTraces) { Monitor.Enter(m_arrReceivedData); m_arrReceivedData.Enqueue("DEBUG partial:" + strReceived); Monitor.Exit(m_arrReceivedData); } } } } if (m_eMode!=eMode.MODE_TRACKING) Thread.Sleep(10); else Thread.Sleep(2); //in tracking mode we want to be as fast as possible } Thread.Sleep(500); } }
/// <summary> /// Will load a RFS standard file from disk. If the file format is incorrect (unknown) will return false but will not invalidate the internal container /// If there are file exceptions, will be received by the caller so should react with appropriate error control /// If file is successfully loaded, all previous container data is lost and replaced by data from file /// </summary> /// <param name="sFile"></param> /// <returns></returns> public bool LoadFile(string sFile) { FileStream myFile = null; try { myFile = new FileStream(sFile, FileMode.Open); using (BinaryReader binStream = new BinaryReader(myFile)) { myFile = null; string sHeader = binStream.ReadString(); if ((sHeader != FileHeaderVersioned()) && (sHeader != FileHeaderVersioned_001())) { return false; } CleanAll(); m_nUpperBound = binStream.ReadUInt16(); //We start at page 1, page 0 is always null for (UInt16 nPageInd = 1; nPageInd <= m_nUpperBound; nPageInd++) { binStream.ReadUInt16(); //page number, can be ignored here RFEScreenData objScreen = new RFEScreenData(128, 8); m_arrScreenContainer[nPageInd] = objScreen; if (sHeader == FileHeaderVersioned_001()) { objScreen.CaptureTime = new DateTime(2000, 1, 1); //year 2000 means no actual valid date-time was captured } else { //Starting in version 002, load sweep capture time too int nLength = (int)binStream.ReadInt32(); string sTime = (string)binStream.ReadString(); if ((sTime.Length == nLength) && (nLength > 0)) { objScreen.CaptureTime = DateTime.Parse(sTime); } objScreen.Model = (RFECommunicator.eModel)binStream.ReadByte(); } for (int nIndY = 0; nIndY < 8; nIndY++) { for (int nIndX = 0; nIndX < 128; nIndX++) { byte nData = binStream.ReadByte(); objScreen.m_arrRemoteScreenData[nIndX + 128 * nIndY] = nData; } } } } } finally { if (myFile != null) myFile.Dispose(); } return true; }
public void Add(RFEScreenData ScreenData) { if (IsFull()) return; m_nUpperBound++; m_arrScreenContainer[m_nUpperBound] = ScreenData; }