Устройство FTDI D2XX обнаружено неполно

#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