Нашел хороший пример, но перевести на Builder пока не смог)
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using CyUSB;
namespace BulkLoop
{
public partial class Form1 : Form
{
CyUSBDevice myDevice = null; // Create a USB device for our application called myDevice
USBDeviceList usbDevices = null; // Find all USBDevice objects that represent all USB devices
CyBulkEndPoint BulkInEndPt = null; // We need one Bulk IN endpoint
CyBulkEndPoint BulkOutEndPt = null; // We need one Bulk OUT endpoint
Thread tXfers;
bool bRunning = false;
int value,value1,value2,value3;
int byteCount = 0;
long outCount, inCount;
const int XFERSIZE = 512;
byte[] outData = new byte[XFERSIZE];
byte[] inData = new byte[XFERSIZE];
//bool bres;
// These 2 needed for TransfersThread to update the UI
delegate void UpdateUICallback();
UpdateUICallback updateUI;
protected override void OnPaint(PaintEventArgs e)
{
Bitmap bitmap = new Bitmap(80, 60);// может ещё захочешь куда пиксел сунтуть поэтому 10 на 10;
for (int i = 0; i < 80; i++)
for (int j = 0; j < 60; j++)
bitmap.SetPixel(i, j, Color.Black);
e.Graphics.DrawImage(bitmap, new Point(30, 450));
base.OnPaint(e);
}
public Form1()
{
InitializeComponent(); // All components of the form are initialized
// Setup the callback routine for updating the UI
updateUI = new UpdateUICallback(StatusUpdate); // Setup the callback routine for updating the UI
tXfers = new Thread(new ThreadStart(TransfersThread));
tXfers.IsBackground = true;
tXfers.Priority = ThreadPriority.Highest;
//Create a list of CYUSB devices
usbDevices = new USBDeviceList(CyConst.DEVICES_CYUSB); // All devices served by CyUSB.sys is added to the list usbDevices
GetDevice(); //This function gets the device with particular VID and PId
//and assign EP2 as BulkoutEP, EP6 as BilkInEP
//Adding event handlers for device attachment and device removal
usbDevices.DeviceAttached += new EventHandler(usbDevices_DeviceAttached); // Eventhandler assigned to DeviceAttached
// to handle the event when a device is attached
usbDevices.DeviceRemoved += new EventHandler(usbDevices_DeviceRemoved); // Eventhandler assigned to DeviceRemoved
// to handle the event when a device is removed
}
/* Summary
This is the event handler for Device Attachment event.
*/
public void usbDevices_DeviceAttached(object sender, EventArgs e) // Eventhandler assigned to DeviceAttached
{
GetDevice(); //This function gets the device with particular VID and PId
//and assign EP2 as BulkoutEP, EP6 as BilkInEP
}
/* Summary
This is the event handler for Device removal event.
*/
public void usbDevices_DeviceRemoved(object sender, EventArgs e) // Eventhandler assigned to DeviceRemoved
{
//if (tXfers.IsAlive)
//{
// tXfers.Abort();
// tXfers.Join();
// tXfers = null;
// MessageBox.Show("thread alive");
//}
//BulkInEndPt.Abort();
//BulkOutEndPt.Abort();
myDevice = usbDevices[0x04b4, 0x1004] as CyUSBDevice; // Assign all devices with VID/PID of 0x04B4/0x1004 to myDevice
if (myDevice == null) // If myDevice doesnt exist
{
bRunning = false;
StartBtn.Text = "Start";
StartBtn.BackColor = Color.Aquamarine;
//if (tXfers.IsAlive)
//{
// tXfers.Abort();
// tXfers.Join();
// tXfers = null;
// if (myDevice != null) myDevice.Dispose();
// MessageBox.Show("BulkLoop Device Not connected");
//}
label1.Text = "BulkLoop Device Not Connected";
StartBtn.Enabled = false;
}
}
/* Summary
The function gets the device, as the one having VID=04b4 and PID=1004
This will detect only the devices with the above VID,PID combinations
*/
public void GetDevice()
{
myDevice = usbDevices[0x04b4, 0x1004] as CyUSBDevice; // Assign all devices with VID/PID of 0x04B4/0x1004 to myDevice
if (myDevice != null) // If myDevice exists
{
BulkOutEndPt = myDevice.EndPointOf(0x02) as CyBulkEndPoint; //Assign EP2 as BulkOutEP and EP6 as BulkInEP
BulkInEndPt = myDevice.EndPointOf(0x86) as CyBulkEndPoint;
label1.Text = "Bulkloop Device connected";
StartBtn.Enabled = true;
}
else
label1.Text = "No Bulkloop Device Detected";
}
/* Summary
Executes on Start button click
*/
private void StartBtn_Click(object sender, EventArgs e)
{
if (!bRunning)
{
if (ValBox.Text != "")
{
byte[] byteArray = Encoding.ASCII.GetBytes(ValBox.Text);
byteCount = Encoding.ASCII.GetByteCount(ValBox.Text);
value = value1 = value2 = value3 = 0;
if(byteCount >= 1) value = Convert.ToInt32(Encoding.ASCII.GetString(byteArray, 0, 1), 16);
if(byteCount >= 2) value = Convert.ToInt32(Encoding.ASCII.GetString(byteArray, 0, 2), 16);
if(byteCount >= 3) value1 = Convert.ToInt32(Encoding.ASCII.GetString(byteArray, 2, 1), 16);
if(byteCount >= 4) value1 = Convert.ToInt32(Encoding.ASCII.GetString(byteArray, 2, 2), 16);
if(byteCount >= 5) value2 = Convert.ToInt32(Encoding.ASCII.GetString(byteArray, 4, 1), 16);
if(byteCount >= 6) value2 = Convert.ToInt32(Encoding.ASCII.GetString(byteArray, 4, 2), 16);
if(byteCount >= 7) value3 = Convert.ToInt32(Encoding.ASCII.GetString(byteArray, 6, 1), 16);
if(byteCount >= 8) value3 = Convert.ToInt32(Encoding.ASCII.GetString(byteArray, 6, 2), 16);
}
else
//tell user that he need to put correct value. -- open
outCount = 0;
inCount = 0;
OutdataBox.Text = "";
InDataBox.Text = "";
bRunning = true;
StartBtn.Text = "Stop";
StartBtn.BackColor = Color.Pink;
//creates new thread
tXfers = new Thread(new ThreadStart(TransfersThread));
tXfers.IsBackground = true;
tXfers.Priority = ThreadPriority.Highest;
//Starts the new thread
tXfers.Start();
}
else
{
//Makes the thread stop and aborts the thread
bRunning = false;
StartBtn.Text = "Start";
StartBtn.BackColor = Color.Aquamarine;
if (tXfers == null) return;
if (tXfers.IsAlive)
{
tXfers.Abort();
tXfers.Join();
tXfers = null;
}
}
}
/* Summary
Called from TransfersThread().When you click on start button, it will create and start a new thread named 'TransfersThread'.
The function outputs the bytes transfered to outData[] buffer.
*/
private void SetOutputData()
{
for (int i = 0; i < XFERSIZE; i++)
{
if((byteCount >= 1) && (i < XFERSIZE)) outData = (byte)value;
if((byteCount >= 3) && (++i < XFERSIZE)) outData = (byte)value1;
if((byteCount >= 5) && (++i < XFERSIZE)) outData = (byte)value2;
if((byteCount >= 7) && (++i < XFERSIZE)) outData = (byte)value3;
}
}
/* Summary
This thread is initiated on start button click.Run the thread and executes the transfer and invokes the StatusUpdate to update the UI
*/
public void TransfersThread()
{
int xferLen = XFERSIZE;
bool bResult = true;
// Loop stops if either an IN or OUT transfer fails
for (; bRunning && bResult; )
{
SetOutputData(); //this function sets the bytes in outData to be transferred to OUT EP
xferLen = XFERSIZE;
//calls the XferData function for bulk transfer(OUT) in the cyusb.dll
bResult = BulkOutEndPt.XferData(ref outData, ref xferLen);
outCount += xferLen;
if (bResult)
{
//calls the XferData function for bulk transfer(IN) in the cyusb.dll
bResult = BulkInEndPt.XferData(ref inData, ref xferLen);
inCount += xferLen;
}
// Call StatusUpdate() in the main thread
this.Invoke(updateUI);
//bres = bResult;
}
bRunning = false;
// Call StatusUpdate() in the main thread
this.Invoke(updateUI);
}
/* Summary
This is the call back function for updating the UI(user interface) and is called from TransfersThread. This updates the OutdataBox,InDataBox
with the Bytes transferred; and NumBytesOut,NumBytesIn with the number of Bytes transferred.
*/
public void StatusUpdate()
{
StringBuilder dataStrOut = new StringBuilder();
StringBuilder dataStrIn = new StringBuilder();
if (bRunning)
{
for (int i = 0; i < XFERSIZE; i++)
{
if ((i % 16) == 0) dataStrOut.Append(string.Format("\r\n{0:X4}", i));
dataStrOut.Append(string.Format(" {0:X2}", outData));
}
dataStrOut.Append(string.Format("\r\n"));
OutdataBox.Text += dataStrOut.ToString(); //This updates the OutdataBox with bytes transferred OUT
for (int i = 0; i < XFERSIZE; i++)
{
if ((i % 16) == 0) dataStrIn.Append(string.Format("\r\n{0:X4}", i));
dataStrIn.Append(string.Format(" {0:X2}", inData));
}
dataStrIn.Append(string.Format("\r\n"));
InDataBox.Text += dataStrIn.ToString(); //This updates the InDataBox with bytes transferred IN
}
NumBytesOut.Text = outCount.ToString(); //This updates the NumBytesOut with number of bytes transferred OUT
NumBytesIn.Text = inCount.ToString(); //This updates the NumBytesIn with number of bytes transferred IN
Refresh();
StartBtn.Text = bRunning ? "Stop" : "Start";
StartBtn.BackColor = bRunning ? Color.Pink : Color.Aquamarine;
//Text = bres.ToString();
}
/* Summary
closing the open form
*/
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// If close was selected while running the loopback, shut it down.
if (bRunning)
StartBtn_Click(this, null);
if (usbDevices != null) usbDevices.Dispose();
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
Тут ещё появляется небольшая разница в библиотеках CyUSB.dll и CyAPI.lib
Поставить вместо USBDevice CyUSBDevice я догадался, но вот USBDeviceList в CyAPI.lib нету, правда сразу нашел описание класса:
#region Сборка CyUSB.dll, v2.0.50727
// D:\Programming\CYPRESS_USB\Cypress\AN70983\Bulkloop\Application\Source\BulkLoop\bin\Debug\CyUSB.dll
#endregion
using System;
using System.Collections;
using System.Reflection;
namespace CyUSB
{
public class USBDeviceList : IDisposable, IEnumerable
{
public USBDeviceList(byte DeviceMask);
public USBDeviceList(byte DeviceMask, App_PnP_Callback fnCallBack);
public int Count { get; }
public USBDevice this[int index] { get; set; }
public USBDevice this[string infName] { get; }
public USBDevice this[int VID, int PID] { get; }
public CyHidDevice this[string sMfg, string sProd] { get; }
public CyHidDevice this[int VID, int PID, int UsagePg, int Usage] { get; }
public CyHidDevice this[string sMfg, string sProd, int UsagePg, int Usage] { get; }
public event EventHandler DeviceAttached;
public event EventHandler DeviceRemoved;
public USBDevice Add();
public byte DeviceIndex(USBDevice dev);
public void Dispose();
protected virtual void Dispose(bool isDisposing);
public IEnumerator GetEnumerator();
public void Remove(CySafeFileHandle hDev);
public void Remove(IntPtr hDev, USBEventArgs e);
}
}
Этого я пока не пробовал, но с другой стороны всегда можно определить устройство банально открывая все USB и сравнивая VID и PID...
Аналогичная проблема с Thread:
#region Сборка mscorlib.dll, v2.0.50727
// C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll
#endregion
using System;
using System.Globalization;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Contexts;
using System.Security.Principal;
namespace System.Threading
{
// Сводка:
// Создает и контролирует поток, задает приоритет и возвращает статус.
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
[ComDefaultInterface(typeof(_Thread))]
public sealed class Thread : CriticalFinalizerObject, _Thread
{
public Thread(ParameterizedThreadStart start);
public Thread(ThreadStart start);
public Thread(ParameterizedThreadStart start, int maxStackSize);
public Thread(ThreadStart start, int maxStackSize);
[Obsolete("The ApartmentState property has been deprecated. Use GetApartmentState, SetApartmentState or TrySetApartmentState instead.", false)]
public ApartmentState ApartmentState { get; set; }
public static Context CurrentContext { get; }
public CultureInfo CurrentCulture { get; set; }
public static IPrincipal CurrentPrincipal { get; set; }
public static Thread CurrentThread { get; }
public CultureInfo CurrentUICulture { get; set; }
public ExecutionContext ExecutionContext { get; }
public bool IsAlive { get; }
public bool IsBackground { get; set; }
public bool IsThreadPoolThread { get; }
public int ManagedThreadId { get; }
public string Name { get; set; }
public ThreadPriority Priority { get; set; }
public ThreadState ThreadState { get; }
public void Abort();
public void Abort(object stateInfo);
public static LocalDataStoreSlot AllocateDataSlot();
public static LocalDataStoreSlot AllocateNamedDataSlot(string name);
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static void BeginCriticalRegion();
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static void BeginThreadAffinity();
public static void EndCriticalRegion();
public static void EndThreadAffinity();
public static void FreeNamedDataSlot(string name);
public ApartmentState GetApartmentState();
[Obsolete("Thread.GetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")]
public CompressedStack GetCompressedStack();
public static object GetData(LocalDataStoreSlot slot);
public static AppDomain GetDomain();
public static int GetDomainID();
[ComVisible(false)]
public override int GetHashCode();
public void Interrupt();
public void Join();
public bool Join(int millisecondsTimeout);
public bool Join(TimeSpan timeout);
public static void MemoryBarrier();
public static void ResetAbort();
System.Security.Permissions.SecurityPermission.
[Obsolete("Thread.Resume has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202", false)]
public void Resume();
public void SetApartmentState(ApartmentState state);
[Obsolete("Thread.SetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")]
public void SetCompressedStack(CompressedStack stack);
public static void SetData(LocalDataStoreSlot slot, object data);
public static void Sleep(int millisecondsTimeout);
public static void Sleep(TimeSpan timeout);
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static void SpinWait(int iterations);
public void Start();
public void Start(object parameter);
System.Security.Permissions.SecurityPermission.
[Obsolete("Thread.Suspend has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202", false)]
public void Suspend();
public bool TrySetApartmentState(ApartmentState state);
public static byte VolatileRead(ref byte address);
public static double VolatileRead(ref double address);
public static float VolatileRead(ref float address);
public static int VolatileRead(ref int address);
public static IntPtr VolatileRead(ref IntPtr address);
public static long VolatileRead(ref long address);
public static object VolatileRead(ref object address);
[CLSCompliant(false)]
public static sbyte VolatileRead(ref sbyte address);
public static short VolatileRead(ref short address);
[CLSCompliant(false)]
public static uint VolatileRead(ref uint address);
[CLSCompliant(false)]
public static UIntPtr VolatileRead(ref UIntPtr address);
[CLSCompliant(false)]
public static ulong VolatileRead(ref ulong address);
[CLSCompliant(false)]
public static ushort VolatileRead(ref ushort address);
public static void VolatileWrite(ref byte address, byte value);
public static void VolatileWrite(ref double address, double value);
public static void VolatileWrite(ref float address, float value);
public static void VolatileWrite(ref int address, int value);
public static void VolatileWrite(ref IntPtr address, IntPtr value);
public static void VolatileWrite(ref long address, long value);
public static void VolatileWrite(ref object address, object value);
[CLSCompliant(false)]
public static void VolatileWrite(ref sbyte address, sbyte value);
public static void VolatileWrite(ref short address, short value);
[CLSCompliant(false)]
public static void VolatileWrite(ref uint address, uint value);
[CLSCompliant(false)]
public static void VolatileWrite(ref UIntPtr address, UIntPtr value);
[CLSCompliant(false)]
public static void VolatileWrite(ref ulong address, ulong value);
[CLSCompliant(false)]
public static void VolatileWrite(ref ushort address, ushort value);
}
}
С этим потоком совсем непонятно, честно говоря. Чем его можно заменить или переправить в Builder?
Столкнулся я с другой проблемой - delegate, я так понял тут можно вызывать какую-нибудь функции взамен.