#c# #windows #ftdi
Вопрос:
Сценарий
Я пытаюсь открыть устройство FTDI, записать 1 байт и дождаться ответа в 1 байт. Я использую оболочку FTD2XXNative C# для FTDI в Windows 10 и использую следующий код для подключения к порту:
public PortFTDI test()
{
// devs count
int dev_count = 0;
var status = FTD2XXNative.FT_CreateDeviceInfoList(out dev_count);
Console.WriteLine($"create list status={status}");
Console.WriteLine($"dev_count={dev_count}");
if (0 == dev_count) {
return null;
}
// devs list
var devs_array = new FTD2XXNative.FT_DEVICE_LIST_INFO_NODE[dev_count];
status = FTD2XXNative.FT_GetDeviceInfoList(devs_array, ref dev_count);
Console.WriteLine($"get list status={status}");
// array of allowed VIDs
var VIDs_allowed_array = VIDs_allowed.ToUpper().Split(' ');
// filter in: devices with allowed VID
var node = devs_array.Where(d => VIDs_allowed_array.Any(VID_ok => VID_ok.Contains($"{d.ID >> 16:X4}"))).FirstOrDefault();
Console.WriteLine($"USBLoc={node.LocId}");
return new PortFTDI($"{node:X4}", node.ID, node.SerialNumber, node.LocId);
}
Проблема 1
Я заметил, что если я отключу и снова подключу устройство, а затем попытаюсь подключиться к нему (примерно через 2 секунды), устройство будет обнаружено (dev_count=1), но расположение USB равно 0 вместо 17. Таким образом, кажется, что устройство обнаружено FT_CreateDeviceInfoList, но не полностью заполнено в FT_GetDeviceInfoList. Есть ли какое-либо объяснение этому или есть какой-либо способ убедиться, что устройство полностью заполнено? (это может иметь отношение к проблеме 2)
Выход:
create list status=FT_OK
dev_count=1
get list status=FT_OK
USBLoc=0
get port after=8
open port after=9
!read=0 after=10
close after=10
Проблема 2
Если я отключу и снова подключу устройство, открою порт, а затем попытаюсь записать в него байт, иногда я не получу ответа от своего устройства, даже если USBLoc=17 (так что устройство, по крайней мере, частично заполнено). Я заметил, что добавление задержки около 200-300 мс между port.open() и port.write() приведет к успешному выполнению функции port.read() впоследствии, поэтому, похоже, возникают проблемы со временем, и, возможно, устройство снова не обнаружено. Есть ли какое-либо объяснение этим проблемам или какой-либо способ обеспечить более предсказуемое поведение, помимо добавления задержек?
var watch = new Stopwatch();
watch.Start();
var mgr = new PortManagerFTDI();
var port = mgr.test();
Console.WriteLine($"get port after={watch.ElapsedMilliseconds}");
port.Open();
Console.WriteLine($"open port after={watch.ElapsedMilliseconds}");
//Thread.Sleep(1000);
// attempt ack
bool ok = false;
port.Write(0x09);
if (1 != port.Read(out byte data)) {
Console.WriteLine($"!read=0 after={watch.ElapsedMilliseconds}");
}
else if (data != 0x20) {
Console.WriteLine($"!BAD ACK after={watch.ElapsedMilliseconds}");
}
else {
Console.WriteLine($"ACK after={watch.ElapsedMilliseconds}");
ok = true;
}
port.Close();
Console.WriteLine($"close after={watch.ElapsedMilliseconds}");
Assert.IsTrue(ok);
Output:
create list status=FT_OK
dev_count=1
get list status=FT_OK
USBLoc=17
get port after=160
open port after=179
!read=0 after=203
close after=485