Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: FTDI 232
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Danis
Приветствую коллеги по цеху!

Такая задача у меня: Имеется некий софт для ПК, который принимает данные от «железки», последняя отправляет данные в ПК через FTDI(FT232). Между ПК и железкой есть свой простой протокол обмена. Вопрос в том, что после посылки сообщения железка ждет подтверждения от ПК, которое приходит с задержкой 5-25 ms, что сильно напрягает и делает пропускную способность канала 25% при скорости 115200 (сообщения короткие 24-50 байт). Предполагаю что это связанно с задержками самого драйвера FTDI. Для работы с FTDI со стороны ПК пользовался D2XX Programmer's Guide.

клик

Данные с FTDI вычитываю каждую 1 ms с использованием мультимедийного таймера (разрешение - 1ms точно). Передаю также с разрешением 1ms, но увы, идут задержки. Прошу совета как выйти из положения. Писать свой драйвер под Windows могу но нет желания. Отказаться от FTDI нет возможности.

Прилагаю листинг инициализации FTDI.

Заголовок для класса FTDI

Код
#ifndef __FTDI_H
#define __FTDI_H

  #include "ftd2xx.h"
  #include <Mmsystem.h>

  class My_FTDI
  {
  public:  My_FTDI(void);
  public: ~My_FTDI(void);

  int Multimedia_Timer_Init(void);
  static int Get_number_D2XX_devices(void);
  static int Write_FTDI(BYTE *sours, WORD len);
  static int Read_FTDI(BYTE *RxBuffer);
  static int Find_FTDI_Connect(void);
  void static __stdcall TimeProc(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);

  FT_HANDLE ftHandle;
  DWORD NumDevs;
  DWORD Monitor_Timer;
  int Timer_Resolution;  

  };

  extern My_FTDI My_FTDI_Dev;

#endif


Вырезка из метода поиска/инициализации/подключения к FTDI

Код
Метод  инициализации FTDI
int My_FTDI::Find_FTDI_Connect(void)    // Пробую подлючиться к железке
{
    FT_STATUS ftStatus;
    BYTE sours[2]      = {0x01, 0x03};    // START, STOP
    static BYTE Rx_Buff[1024] = {0};
    WORD BytesWritten =  0;


   cout << " Connect to FTDI " << endl;

  for ( int i = 0; i < (int)My_FTDI_Dev.NumDevs; i++ )
  {

   ftStatus = FT_Open (i, &My_FTDI_Dev.ftHandle );
   if (ftStatus != FT_OK)
   FT_Close(My_FTDI_Dev.ftHandle); // Закрыть в случае ошибки;

   ftStatus = FT_SetTimeouts( My_FTDI_Dev.ftHandle, 1, 1 );  //  Timeout
   if (ftStatus != FT_OK)
   {
    cout << " Fail timeout " << i << endl;
    FT_Close(My_FTDI_Dev.ftHandle); // Закрыть в случае ошибки
   }


   ftStatus = FT_SetBaudRate(My_FTDI_Dev.ftHandle, 115200); // Set baud rate to 115200
   if (ftStatus != FT_OK)
   FT_Close(My_FTDI_Dev.ftHandle); // Закрыть в случае ошибки

   // Set 8 data bits, 1 stop bit and no parity
   ftStatus = FT_SetDataCharacteristics(My_FTDI_Dev.ftHandle, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE);
   if (ftStatus != FT_OK)
   FT_Close(My_FTDI_Dev.ftHandle); // Закрыть в случае ошибки

  } //  for ( int i = 0; i < (int)My_FTDI_Dev.NumDevs; i++ )


   return 0;

}



Спасибо!
V_G
Возможно, не по делу.
Но под винду писать приложения, для которых критичны задержки 5-25 мс, не есть правильно.
Оттестируйте свой софт на другой машине, где памяти побольше, а софта - поменьше (лучше всего на чистой винде). Сохранятся ли там задержки?
Ваш софт не проверял, сам пользуюсь для FT232 виртуальными компортами. Даже на 460800 особых проблем не видел. Мой софт, правда, особо комовским трафиком машину не грузит.
ReAl
Цитата(Danis @ Jul 5 2011, 12:08) *
сообщения короткие 24-50 байт
Т.е. меньше размера пакета обмена для FTDI. И не отправлются из микросхемы в комп до тех пор, пока не отработает Latency Timer, по умолчанию 16 мс (собственно, для длинных пакетов та же беда с остатком в конце пакета). Надо или крутить в свойствах данного ком-порта, или (на мой взгляд, лучше) устанавливать через FT_SetLatencyTimer().
Ещё лучше в пакетах иметь флаговый байт конца пакета (типа того, как в SLIP сделно) и назначить его для ком-порта как EventChar (вероятно, через FT_SetChars(), я этим делом пользовался и с обычным ком-портом через поле в DCB). Это для любого ком-порта полезно, чтобы в Win через WaitObject не за каждым символом из ком-порта дёргаться, а только по приходу всего пакета.
А в случае FTDI это ещё и приводит к немедленной отправке неполного буфера по приходу данного символа. Даже минимальный LatencyTimer не отсчитывается, его настройка не влияет вообще.
zltigo
QUOTE (Danis @ Jul 5 2011, 12:08) *
есть свой простой протокол обмена.

В данном случае правильный выход только один - протокол должен стать сложнее и не требовать немедленного подтверждения каждого фрейма. Посмотрите как подобное делается в классических протоколах, например, LAPB. TCP тоже годится для ознакомления с принципами.
QUOTE (Danis @ Jul 5 2011, 12:08) *
Данные с FTDI вычитываю каждую 1 ms с использованием мультимедийного таймера...

Сканирование это моветон sad.gif
Danis
Цитата(ReAl @ Jul 5 2011, 15:47) *
(на мой взгляд, лучше) устанавливать через FT_SetLatencyTimer().


Да, помогло. Установил минимальное значение LatencyTimer – 2 ms, повесил на RX и TX осциллограф, замерил, действительно 2-2,5 ms. Работает! Этого мне достаточно.
Большое спасибо cool.gif .



Цитата(zltigo @ Jul 5 2011, 16:53) *
В данном случае правильный выход только один - протокол должен стать сложнее и не требовать немедленного подтверждения каждого фрейма. Посмотрите как подобное делается в классических протоколах, например, LAPB. TCP тоже годится для ознакомления с принципами.


Согласен, дело в том, что это не мой софт, он написан давно и «устаканен», человек который его написал не «железячник», менять кардинально ничего нельзя, вот перед ним встала проблема, я ее помог решить. На счет сканирования, я завел его в отдельный паток Windows в котором идет обработка мультимедийного таймера, загрузка процессора от него не более 0,7% при max трафике, сам проверял, так что для ПК это сойдет. Вот подготовил класс С++ пусть вставляет и живет счастливо. Отозвавшимся спасибо, тему можно закрывать.

Цитата(zltigo @ Jul 5 2011, 16:53) *
Сканирование это моветон sad.gif

Программирование микроконтроллеров меня конечно воспитало но не на столько.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.