Перейти к содержанию
    

FT_Write глючит в Linux

Пишу кроссплатформенную программу на Qt.

Столкнулся с весьма необычным поведением FTDI под Linux.

При частом обращении к FTDI иногда не срабатывает функция FT_Write.

Функция для настройки FTDI:

bool MainWindow::OpenPort(int nPort, bool msgbox)
{
   if(ftPort != 0)
   {
       FT_Purge(ftPort, FT_PURGE_RX | FT_PURGE_TX);
       FT_Close(ftPort);

       ftPort = 0;
   }

   if(FT_Open(nDevIndex[nPort], &ftPort) != FT_OK)
   {
       ftPort = 0;

       if(msgbox)
           QMessageBox::critical(0, "Ошибка!", "Ошибка при открытии USB порта.");

       return false;
   }

   FT_ResetDevice(ftPort);

   FT_SetBitMode(ftPort, 0, FT_BITMODE_RESET);
   FT_SetDtr(ftPort);
   FT_SetRts(ftPort);
   FT_Purge(ftPort, FT_PURGE_RX | FT_PURGE_TX);
   FT_SetUSBParameters(ftPort, 65535, 0);
   FT_SetTimeouts(ftPort, TIMEOUT + 10, TIMEOUT + 10);
   FT_SetLatencyTimer(ftPort, 1);
   FT_SetDivisor(ftPort, FTDIVISOR);
   FT_SetDataCharacteristics(ftPort, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE);
   FT_SetFlowControl(ftPort, FT_FLOW_NONE, NULL, NULL);

   FT_Purge(ftPort, FT_PURGE_RX | FT_PURGE_TX);

   return true;
}

Код для записи в FTDI:

nb = 0;
ftStatus = FT_Write(*ftPort, ft_data, i, &nb);
if(ftStatus != FT_OK)
{
    emit ft_msg("ftStatus FT_Write() != FT_OK");
    continue;
}
if(i != ((uint32_t)nb))
{
    char st[256];
    sprintf(st, "Ошибка при записи данных.\nЗаписано %u bytes, передано %u bytes.", i, ((uint32_t)nb));
    emit ft_msg(st);
    continue;
}

Причём при возникновении ошибки функция всегда возвращает ftStatus == FT_OK и nb == 0.

На Windows (XP x32, Win7 x64) такая ошибка не возникает никогда.

Пробовал разные версии Linux.

На Red Hat вываливается раз в пол минуты.

На Gentoo почти сразу.

На Debian запись работает нормально, а вот чтение всегда возвращает неправильные данные.

Драйвер самый последний с ftdichip.com.

Кто-нибудь сталкивался с подобной проблемой?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В общем удалось частично решить проблему.

Если не вызывать FT_SetUSBParameters и FT_SetLatencyTimer, то FT_Write перестаёт глючить.

Правда не везде.

На Red Hat работает стабильно.

На Debian всё равно иногда подглючивает.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообще, это признак таймаута, что данных передано меньше, чем хотелось, а ошибки нет. Так что, смотрите, что Вы там назадавали по этому поводу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

TIMEOUT = 1000

Неужели за 1 секунду не успевает передаться пакет размером 11 байт на скорости 125000?

Период посылки пакетов > 10 мс. Пока не придёт ответ на предыдущий пакет, программа не отсылает новый.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В общем удалось частично решить проблему.

Если не вызывать FT_SetUSBParameters и FT_SetLatencyTimer, то FT_Write перестаёт глючить.

Правда не везде.

На Red Hat работает стабильно.

На Debian всё равно иногда подглючивает.

Под виндой тоже наблюдается подобное. Было экспериментально установлено, что для стабильной работы при непрерывном чтении SPI потока через MPSSE на скорости 33мб/с требуется ставить LatencyTimer не менее примерно 10(точную цифру не помню), иначе данные чтения иногда теряются без сообщения об ошибке. По умолчанию LatencyTimer не менее 8, а вы его переставляли на 1. Возможно, для Debian нужно поставить ещё больше, чем для Red Hat :).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Под виндой тоже наблюдается подобное. Было экспериментально установлено, что для стабильной работы при непрерывном чтении SPI потока через MPSSE на скорости 33мб/с требуется ставить LatencyTimer не менее примерно 10(точную цифру не помню), иначе данные чтения иногда теряются без сообщения об ошибке. По умолчанию LatencyTimer не менее 8, а вы его переставляли на 1. Возможно, для Debian нужно поставить ещё больше, чем для Red Hat :).

Что интересно, такое поведение наблюдается только под VirtualBox.

На живой машине работает стабильно.

Насколько я помню, LatencyTimer по умолчанию вроде равен 16.

Похоже, правильнее всего будет сделать отдельный пункт в меню для настройки LatencyTimer.

Если VirtualBox, то ставить побольше, если живая система, то поменьше :).

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...