⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 streamer.h

📁 Cypress Suite USB 3.4.6
💻 H
📖 第 1 页 / 共 2 页
字号:
			if (XferThread->ThreadState == System::Threading::ThreadState::Running)
				XferThread->Join(10);
		 }

		
		void StartBtn_Click(System::Object *  sender, System::EventArgs *  e)
		{
			Decimal db;
			
			if(!Decimal::TryParse(this->TimeOutBox->Text, &db))
			{
				::MessageBox(NULL,"Invalid Input : TimeOut Per Xfer(ms)","Streamer",0);				
				this->TimeOutBox->Text = "";
				return;
			}
		    if (XferThread) {
				switch (XferThread->ThreadState)
				{
				case System::Threading::ThreadState::Stopped:
				case System::Threading::ThreadState::Unstarted:

					EnforceValidPPX();

					StartBtn->Text = "Stop";
					StartBtn->BackColor = Color::MistyRose;
					StartBtn->Refresh();

					bStreaming = true;

					// Start-over, initializing counters, etc.
					if ((XferThread->ThreadState) == System::Threading::ThreadState::Stopped)
						XferThread = new Thread(new ThreadStart(0,&XferLoop));

					PPX = Convert::ToInt32(PacketsPerXferBox->Text);

					QueueSize = Convert::ToInt32(QueueLenBox->Text);
					TimeOut = Convert::ToInt32(TimeOutBox->Text);
					bShowData = ShowDataBox->Checked;

					EndPointsBox->Enabled		= false;
					PacketsPerXferBox->Enabled	= false;
					QueueLenBox->Enabled		= false;
					TimeOutBox->Enabled			= false;
					ShowDataBox->Enabled		= false;

					XferThread->Start();
					break;
				case System::Threading::ThreadState::Running:
					StartBtn->Text = "Start";
					StartBtn->BackColor = Color::Aquamarine;
					StartBtn->Refresh();
					
					bStreaming = false;  // Stop the thread's xfer loop
					XferThread->Join(10);

					EndPointsBox->Enabled		= true;
					PacketsPerXferBox->Enabled	= true;
					QueueLenBox->Enabled		= true;
					TimeOutBox->Enabled			= true;
					ShowDataBox->Enabled		= true;

					break;
				}

			} 

		 }
			
		void EndPointsBox_SelectedIndexChanged(System::Object *  sender, System::EventArgs *  e)
		{
			// Parse the alt setting and endpoint address from the EndPointsBox->Text
			String *tmp = EndPointsBox->Text->Substring(EndPointsBox->Text->IndexOf("("),10);
			int  alt = Convert::ToInt32(tmp->Substring(1,1));

			String *addr = tmp->Substring(7,2);
			//changed int to __int64 to avoid data loss
			__int64 eptAddr = HexToInt(addr);

			int clrAlt = (USBDevice->AltIntfc() == 0) ? 1 : 0;

			// Attempt to set the selected Alt setting and get the endpoint
			if (! USBDevice->SetAltIntfc(alt))
			{
				MessageBox::Show("Alt interface could not be selected.","USB Exception",MessageBoxButtons::OK,MessageBoxIcon::Hand);
				StartBtn->Enabled = false;
				USBDevice->SetAltIntfc(clrAlt); // Cleans-up
				return;
			}
			
			
			EndPt = USBDevice->EndPointOf((UCHAR)eptAddr);

			StartBtn->Enabled = true;


			if (EndPt->Attributes == 1)
			{
				SuccessLabel->Text = "Good Pkts";
				FailureLabel->Text = "Bad Pkts";
			}
			else
			{
				SuccessLabel->Text = "Successes";
				FailureLabel->Text = "Failures";
			}

			EnforceValidPPX();
		}

	
		void EnforceValidPPX()
		{
			PPX = Convert::ToInt32(PacketsPerXferBox->Text);

			// Limit total transfer length to 64K
			int len = ((EndPt->MaxPktSize) * PPX);
			int maxLen = 0x10000; 
			if (len > maxLen)
			{
				PPX = maxLen / EndPt->MaxPktSize;
				DataBox->Text = String::Concat(DataBox->Text,"Total xfer length limited to 64K.\r\n");
				DataBox->Text = String::Concat(DataBox->Text,"Packets per Xfer has been adjusted.\r\n");
				DataBox->SelectionStart = DataBox->Text->Length;
				DataBox->ScrollToCaret();
			}

			if (bHighSpeedDevice && (EndPt->Attributes == 1))  // HS ISOC Xfers must use PPX >= 8
			{
				if (PPX < 8)
				{
					PPX = 8;
					Display("ISOC xfers require at least 8 Packets per Xfer.");
					Display("Packets per Xfer has been adjusted.");
				}

				PPX = (PPX / 8) * 8;
			}

			PacketsPerXferBox->Text = PPX.ToString();			
		}

	
		static UInt64 HexToInt(String *hexString)
		{
			String *HexChars = "0123456789abcdef";

			String *s = hexString->ToLower();

			// Trim off the 0x prefix
			if (s->Length > 2)
				if (s->Substring(0,2)->Equals("0x"))
					s = s->Substring(2,s->Length-2);

			
			String *_s = "";
			int len = s->Length;

			// Reverse the digits
			for (int i=len-1; i>=0; i--) _s  = String::Concat(_s,s->Substring(i,1));

			UInt64 sum = 0;
			UInt64 pwrF = 1;
			for (int i=0; i<len; i++)
			{
				UInt32 ordinal = (UInt32) HexChars->IndexOf(_s->Substring(i,1));
				sum += (i==0) ? ordinal : pwrF*ordinal;
				pwrF *= 16;
			}


			return sum;
		}


		
		static void ShowCpuLoad(Object* state) 
		{
			Form1 *form = dynamic_cast<Form1 *>(state);

			if (form->CPUCounter != NULL)
			{
				//thread safe-commented
				CheckForIllegalCrossThreadCalls = false;

				float load = form->CPUCounter->NextValue();
				int a = Convert::ToInt32(load);
				form->CPUBar->Value = a;
				form->CPULabel->Text = String::Concat(a.ToString()," %"); 
			}
		}

	
		static void Display(String *s)
		 {
			DataBox->Text = String::Concat(DataBox->Text, s, "\r\n");
			DataBox->SelectionStart = DataBox->Text->Length;
			DataBox->ScrollToCaret();
		 }
	
		static void Display16Bytes(PUCHAR data)
		{
			String *xData = "";

			for (int i=0; i<16; i++) 
				xData = String::Concat(xData,data[i].ToString("X02"), " ");

			Display(xData);
		} 


			
		
		// This method executes in it's own thread.  The thread gets re-launched each time the
		// Start button is clicked (and the thread isn't already running).
		static void XferLoop()
		{
			long BytesXferred = 0;
			unsigned long Successes = 0;
			unsigned long Failures = 0;
			int i = 0;

			// Allocate the arrays needed for queueing
			PUCHAR			*buffers		= new PUCHAR[QueueSize];
			CCyIsoPktInfo	**isoPktInfos	= new CCyIsoPktInfo*[QueueSize];
			PUCHAR			*contexts		= new PUCHAR[QueueSize];
			OVERLAPPED		inOvLap[MAX_QUEUE_SZ];

			long len = EndPt->MaxPktSize * PPX; // Each xfer request will get PPX isoc packets

			EndPt->SetXferSize(len);
			
			// Allocate all the buffers for the queues
			for (i=0; i< QueueSize; i++) 
			{ 
				buffers[i]        = new UCHAR[len];
				isoPktInfos[i]    = new CCyIsoPktInfo[PPX];
				inOvLap[i].hEvent = CreateEvent(NULL, false, false, NULL);

				memset(buffers[i],0,len);
			}
			
			DateTime t1 = DateTime::Now;	// For calculating xfer rate
			
			// Queue-up the first batch of transfer requests
			for (i=0; i< QueueSize; i++)	
			{
				contexts[i] = EndPt->BeginDataXfer(buffers[i], len, &inOvLap[i]);
				if (EndPt->NtStatus || EndPt->UsbdStatus) // BeginDataXfer failed
				{
					Display(String::Concat("Xfer request rejected. NTSTATUS = ",EndPt->NtStatus.ToString("x")));
					AbortXferLoop(i+1, buffers,isoPktInfos,contexts,inOvLap);
					return;
				}
			}

			i=0;	

			// The infinite xfer loop.
			for (;bStreaming;)		
			{
				long rLen = len;	// Reset this each time through because
									// FinishDataXfer may modify it

				if (!EndPt->WaitForXfer(&inOvLap[i], TimeOut))
				{
					EndPt->Abort();
					if (EndPt->LastError == ERROR_IO_PENDING)
						WaitForSingleObject(inOvLap[i].hEvent,2000);
				}

				if (EndPt->Attributes == 1) // ISOC Endpoint
				{	
					if (EndPt->FinishDataXfer(buffers[i], rLen, &inOvLap[i], contexts[i], isoPktInfos[i])) 
					{			
	  					CCyIsoPktInfo *pkts = isoPktInfos[i];
						for (int j=0; j< PPX; j++) 
						{
							if (pkts[j].Status == 0) 
							{
								BytesXferred += pkts[j].Length;

								if (bShowData)
									Display16Bytes(buffers[i]);

								Successes++;
							}
							else
								Failures++;

							pkts[j].Length = 0;	// Reset to zero for re-use.
						}

					} 
					else
						Failures++; 
			
				} 

				else // BULK Endpoint
				{
					if (EndPt->FinishDataXfer(buffers[i], rLen, &inOvLap[i], contexts[i])) 
					{			
						Successes++;
						BytesXferred += len;

						if (bShowData)
							Display16Bytes(buffers[i]);
					} 
					else
						Failures++; 
				}


				if (BytesXferred < 0) // Rollover - reset counters
				{
					BytesXferred = 0;
					t1 = DateTime::Now;
				}

				// Re-submit this queue element to keep the queue full
				contexts[i] = EndPt->BeginDataXfer(buffers[i], len, &inOvLap[i]);
				if (EndPt->NtStatus || EndPt->UsbdStatus) // BeginDataXfer failed
				{
					Display(String::Concat("Xfer request rejected. NTSTATUS = ",EndPt->NtStatus.ToString("x")));
					AbortXferLoop(QueueSize,buffers,isoPktInfos,contexts,inOvLap);
					return;
				}

				i++;

				if (i == QueueSize) //Only update the display once each time through the Queue
				{
					i=0;
					ShowStats(t1, BytesXferred, Successes, Failures);					
				}

			}  // End of the infinite loop

			// Memory clean-up
			AbortXferLoop(QueueSize,buffers,isoPktInfos,contexts,inOvLap);
		}

	
		static void AbortXferLoop(int pending, PUCHAR *buffers, CCyIsoPktInfo **isoPktInfos, PUCHAR *contexts, OVERLAPPED inOvLap __nogc [])
		 {
			EndPt->Abort();
			long len = EndPt->MaxPktSize * PPX;

			for (int j=0; j< QueueSize; j++) 
			{ 
				if (j<pending)
				{
					if (!EndPt->WaitForXfer(&inOvLap[j], TimeOut)) 
					{
						EndPt->Abort();
						if (EndPt->LastError == ERROR_IO_PENDING)
							WaitForSingleObject(inOvLap[j].hEvent,2000);
					}

					EndPt->FinishDataXfer(buffers[j], len, &inOvLap[j], contexts[j]);
				}

				CloseHandle(inOvLap[j].hEvent);

				delete [] buffers[j];
				delete [] isoPktInfos[j];
			}

			delete [] buffers;
			delete [] isoPktInfos;
			delete [] contexts;

					
			bStreaming = false;

			StartButton->Text = "Start";
			StartButton->BackColor = Color::Aquamarine;
			StartButton->Refresh();

			EptsBox->Enabled	= true;
			PpxBox->Enabled		= true;
			QueueBox->Enabled	= true;
			TimeoutBox->Enabled	= true;
			ShowBox->Enabled	= true;
		 }


		
	    static void ShowStats(DateTime t, long bytesXferred, unsigned long successes, unsigned long failures)
		{
			TimeSpan elapsed = DateTime::Now.Subtract(t);

			long totMS = (long)elapsed.TotalMilliseconds;
			if (totMS <= 0)	return;

			long XferRate = bytesXferred / totMS;

			// Convert to KB/s
			XferRate = XferRate * 1000 / 1024;

			// Truncate last 1 or 2 digits
			int rounder = (XferRate > 2000) ? 100 : 10;
			XferRate = XferRate / rounder * rounder;  

			//thread safe-commented
			CheckForIllegalCrossThreadCalls = false;

			if (XferRate > XferRateBar->Maximum) 
				XferRate = XferRateBar->Maximum;


			XferRateBar->Value = XferRate;
			XferRateLabel->Text = XferRate.ToString();

			SuccessBox->Text = successes.ToString();
			FailureBox->Text = failures.ToString();

		}



	
protected:	

		[System::Security::Permissions::PermissionSet(System::Security::Permissions::SecurityAction::Demand, Name="FullTrust")]
		virtual void WndProc(Message *m)
		{	
			if (m->Msg == WM_DEVICECHANGE) 
			{
				// Tracks DBT_DEVNODES_CHANGED followed by DBT_DEVICEREMOVECOMPLETE
				if (m->WParam == DBT_DEVNODES_CHANGED) 
				{
					bPnP_DevNodeChange = true;
					bPnP_Removal = false;
				}

				// Tracks DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED
				if (m->WParam == DBT_DEVICEARRIVAL) 
				{
					bPnP_Arrival = true;
					bPnP_DevNodeChange = false;
				}

				if (m->WParam == DBT_DEVICEREMOVECOMPLETE) 
					bPnP_Removal = true;

				// If DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED
				if (bPnP_DevNodeChange && bPnP_Removal) 
				{
					bPnP_Removal = false;
					bPnP_DevNodeChange = false;
					bStreaming = false;
					GetStreamerDevice();
				}

				// If DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED
				if (bPnP_DevNodeChange && bPnP_Arrival) 
				{
					bPnP_Arrival = false;
					bPnP_DevNodeChange = false;
					GetStreamerDevice();
				}

			}

			Form::WndProc(m);
		}






	 
		void Dispose(Boolean disposing)
		{
			if (disposing && components)
			{
				components->Dispose();
			}
			__super::Dispose(disposing);
		}


};

}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -