Jump to content

    

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.

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

 

Share this post


Link to post
Share on other sites

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

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

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

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

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

 

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

TIMEOUT = 1000

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

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

Share this post


Link to post
Share on other sites
В общем удалось частично решить проблему.

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

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

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

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

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

Share this post


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

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

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

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

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

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

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this