работа с FT232, через библиотеку FTD2XX.dll

Обсуждаем цифровые устройства...
Ответить
svin
Родился
Сообщения: 14
Зарегистрирован: Пн авг 02, 2010 07:46:12
Контактная информация:

работа с FT232, через библиотеку FTD2XX.dll

Сообщение svin »

Второй день воюю над автоматическим определением своего девайса программой под винду.. Пришел к выводу, что либо я либо лыжи.. Вобщем есть устройство, состоящее из FT232R и МК. Программа под винду которую пишу в теневом режиме каждые 5 секунд проверяет подключен ли девайс к компу. Алгоритм определения именно моего устройства следующий: с помощью функций библиотеки ftd2xx.dll я определяю сколько FT устройств подключено, затем по их порядковым индексам получаю серийные номера всех этих устройств и начинаю поочереди их открывать с заданными параметрами обмена (скорость, стопы, четность, управление), при каждом открытии FT устройства я отправляю 2 байта 0x58, чтобы вывести МК моего устройства на рабочий режим, затем передергиваю вывод RTS ("1" -> "0" -> "1"), при этом передергивании МК отвечает 1 байтом 0x3E (МК переходит в режим настройки извне), затем снова отправляю 2 байта 0x58, чтобы вывести МК снова в рбочий режим. В итоге если после всех этих операций в приемном буфере остается принятый 0x3E, то я считаю что именно мое устройство подключено к компу и прерываю цикл проверки подключенных FT устройств и возвращаю в программу серийный номер FT устройства, определенного как мое устройство. Привожу ниже фрагмент кода функции, проделывающей эти операции с уже открытым FT устройством (после выполнения этой функции устройство закрывается в месте откуда эта функция была вызвана).

Код: Выделить всё

function getModemAnswer(FTHandle)
    --clear scanning flag
    RFMfound = false;
    --setting RX and TX timeouts, set latency timer
    result1 = modem:SetTimeouts(FTHandle,50,50);
    result2 = modem:SetLTimer(FTHandle,10);
    result3 = modem:SetRTS(FTHandle, false);
    if (result1 == 0 and result2 == 0 and result3 == 0) then
        --transmit 2 bytes (0x58,0x58) mean EXIT
        result1 = modem:WriteFrame(FTHandle,{88,88},2);
        if (result1 == 2) then
            Dialog.Message("Notice", FTLibraryVer, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1); -- delay 1
            --reset RX,TX buffers
            temptable3 = modem:FTReset(FTHandle,false,false,true,true);
            if (temptable3[3] == 0 and temptable3[4] == 0) then
                --enter RFM configure mode
                result1 = modem:SetRTS(FTHandle, true);
                result2 = modem:SetRTS(FTHandle, false);
                if (result1 == 0 and result2 == 0) then
                    --transmit 2 bytes (0x58,0x58) mean EXIT
                    result1 = modem:WriteFrame(FTHandle,{88,88},2);
                    if (result1 == 2) then
                        Dialog.Message("Notice", FTLibraryVer, MB_OK, MB_ICONINFORMATION, MB_DEFBUTTON1); -- delay 2
                        --reading answer (0x3E), if possible
                        temptable3 = modem:ReadFrame(FTHandle,1);
                        temptable4 = temptable3[3];
                        if (temptable3[1] == 0 and temptable3[2] > 0 and temptable4[1] == 62) then
                            RFMfound = true;
                        end
                    end
                end
            end
        end
    end
    return RFMfound
end
строки помеченные как delay 1 и delay 2 добавлены вынуждено как раз по причине "меня или лыж". Эти две строки являются своеобразными точками останова временно пока не разберусь, только так мое устройство определяется программой (т.е. байт 0x3E выуживается успешно). Попытки заменить эти диалоговые окошки на пассивные задержки (т.е. пустые циклы) только затормаживают работу программы и при этом все равно не получается отловить нужный байт. Главные вопросы и непонятки на данный момент: НА КОЙ ЧЕРТ в библиотеке ftd2xx.dll нужна функция установки таймаутов по приему и передачи? К примеру, я увеличиваю задержку по приему до 5000мс, чтобы избавиться от строки delay 2, но это не спасает и после вызова функции FT_Read и отработки интервала 5000 мне возвращается значение кол-ва принятых байт = 0! Я думал этот таймаут как раз и нужен для того чтобы допустим вызвать FT_Read с кол-вом байт которые должны быть приняты например 256 и ждать свой 1 байтик все 5 секунд пока он появится, на практике так не получается. Таймаут для передачи тож непонятно как работает, но я пока с ним особо не игрался.. Также есть еще установка времени запаздывания FT_SetLatencyTimer (от 2 до 255мс), это чиво еще такое? С библиотекой работаю через написанный свой ActiveX враппер, поэтому поясню приведенный код:

SetTimeouts(FTHandle,50,50) - эт я устанавливаю таймауты для RX и TX
SetLTimer(FTHandle,10) - эт равносильно FT_SetLatencyTimer
SetRTS(FTHandle, false), SetRTS(FTHandle, true) - сброс/установка сигнала RTS
WriteFrame(FTHandle,{88,88},2) - посылка массива из двух элементов
FTReset(FTHandle,false,false,true,true) - универсальная функция сброса, сброс: порта, устройства, RX буффера, TX буффера (в данном случае 2 последних сбрасываю)
ReadFrame(FTHandle,1) - функция чтения из буффера, возвращает массив, 1й элемент - код ошибки (если были), 2й - кол-во принятых байт, 3й - содержит массив, собственно полученные данные

Я конечно догадываюсь, что мой выход из ситуации - это работать по таймерам внутри своей программы под винду, НО. ЗАЧЕМ ВСЕ ЭТИ ТАЙМАУТЫ предоставляемые библиотекой ftd2xx.dll? Может я неправильно понимаю логику их работы?
Реклама
Аватара пользователя
asteroid7
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 18, 2009 21:12:49

Re: работа с FT232, через библиотеку FTD2XX.dll

Сообщение asteroid7 »

Вы все функции "обернули" своими. Не мудрите, используйте прототипные из dll - "FT_...".
Для очистки внутренних буферов м/с удобнее пользоваться FT_Purge.
С FT_SetLatencyTimer не заморачивайтесь и ставте в "1". Меньше 2-ух dll не даст, а меньше 16 - ОСь.

По основному вопросу - не хватает исходных данных.
Покажите функции WriteFrame, ReadFrame и FTReset.
Таймауты полезны. Работать можно без таймеров.
Реклама
svin
Родился
Сообщения: 14
Зарегистрирован: Пн авг 02, 2010 07:46:12
Контактная информация:

Re: работа с FT232, через библиотеку FTD2XX.dll

Сообщение svin »

не сердчайте, если кривовато написаны коды, эт был мой первый и пока единственный activex control, написанный в vb6

функция отправки данных:
*возвращает число фактически переданных байт

Код: Выделить всё

Public Function WriteFrame(ByVal vDHandle As Long, ByVal vFrame As Variant, ByVal vNewValue As Long) As Long
    If vNewValue > 128 Or vNewValue < 0 Then
        WriteFrame = 0
    Else
        ErrorVariable = 0
        For mycount = 0 To vNewValue - 1
            FTStatus = FT_WriteByte(vDHandle, CByte(vFrame(mycount + 1)), 1, TempVariable)
            If FTStatus = FT_OK Then
                ErrorVariable = ErrorVariable + TempVariable
            End If
        Next
        WriteFrame = ErrorVariable
    End If
End Function
функция чтения данных:
*возвращает массив из 3 элементов - 1.код ошибок (если были), 2.кол-во принятых байт, 3.массив, содержащий собсно данные

Код: Выделить всё

Public Function ReadFrame(ByVal vDHandle As Long, ByVal vBufferSize As Long) As Variant
    FTStatus = FT_GetStatus(vDHandle, TempVariable, TempVariable2, ErrorVariable)
    If FTStatus = FT_OK Then
        If TempVariable > 0 Then
            ReDim TempTable2(vBufferSize - 1)
            FTStatus = FT_Read(vDHandle, TempTable2(0), vBufferSize, TempVariable)
            If TempVariable > 0 Then
                ReDim TempTable(TempVariable - 1)
                If FTStatus = FT_OK Then
                    For mycount = 0 To TempVariable - 1
                        TempTable(mycount) = CLng(TempTable2(mycount))
                    Next
                End If
            End If
        End If
    End If
    ReDim TempTable3(2)
    TempTable3(0) = FTStatus
    TempTable3(1) = TempVariable
    TempTable3(2) = TempTable
    ReadFrame = TempTable3
End Function
функция сброса (универсальная):
*возвращает массив из 4 элементов, каждый из которых содержит код ошибок (если были) для каждой отдельной операции сброса
*1.сброс порта, 2.сброс FT устройства, 3.сброс буфера приема, 4.сброс буфера передачи

Код: Выделить всё

Public Function FTReset(ByVal vDHandle As Long, ByVal vRPort As Boolean, ByVal vRDevice As Boolean, ByVal vRRxBuf As Boolean, ByVal vRTxBuf As Boolean) As Variant
    ReDim TempTable(3) As Variant
    If vRPort Then
        FTStatus = FT_ResetPort(vDHandle)
        TempTable(0) = FTStatus
    Else
        TempTable(0) = FT_OK
    End If
    If vRDevice Then
        FTStatus = FT_ResetDevice(vDHandle)
        TempTable(1) = FTStatus
    Else
        TempTable(1) = FT_OK
    End If
    If vRRxBuf Then
        FTStatus = FT_Purge(vDHandle, FT_PURGE_RX)
        TempTable(2) = FTStatus
    Else
        TempTable(2) = FT_OK
    End If
    If vRTxBuf Then
        FTStatus = FT_Purge(vDHandle, FT_PURGE_TX)
        TempTable(3) = FTStatus
    Else
        TempTable(3) = FT_OK
    End If
    FTReset = TempTable
End Function
svin
Родился
Сообщения: 14
Зарегистрирован: Пн авг 02, 2010 07:46:12
Контактная информация:

Re: работа с FT232, через библиотеку FTD2XX.dll

Сообщение svin »

короче заработало вот так:

Код: Выделить всё

function getModemAnswer(FTHandle)
	--clear scanning flag
	RFMfound = false;
	--setting RX and TX timeouts, set latency timer
	result1 = modem:SetTimeouts(FTHandle,500,0);
	result2 = modem:SetLTimer(FTHandle,2);
	result3 = modem:SetRTS(FTHandle, false);
	if (result1 == 0 and result2 == 0 and result3 == 0) then
		--transmit 2 bytes (0x58,0x58) mean EXIT
		result1 = modem:WriteFrame(FTHandle,{88,88},2);
		if (result1 == 2) then
			passDelay(50000); --delay 1
			--reset RX,TX buffers
			temptable3 = modem:FTReset(FTHandle,false,false,true,true);
			if (temptable3[3] == 0 and temptable3[4] == 0) then
				--enter RFM configure mode
				result1 = modem:SetRTS(FTHandle, true);
				result2 = modem:SetRTS(FTHandle, false);
				if (result1 == 0 and result2 == 0) then
					--transmit 2 bytes (0x58,0x58) mean EXIT
					result1 = modem:WriteFrame(FTHandle,{88,88},2);
					if (result1 == 2) then
						passDelay(50000); --delay 2
						--reading answer (0x3E), if possible
						temptable3 = modem:ReadFrame(FTHandle,1);
						temptable4 = temptable3[3];
						if (temptable3[1] == 0 and temptable3[2] > 0 and temptable4[1] == 62) then
							RFMfound = true;
						end
					end
				end
			end
		end
	end
	return RFMfound
end
--passive delay function
function passDelay(pDelay)
	for passcount = 0, pDelay do
		-- empty cycle
	end
end
но это не оч хороший способ.. все таки хотелось бы от просвященных людей услышать вразумительное объяснение как работают эти таймауты FT_SetTimeouts, если честно как я понял таймаут по приему начинает отсчет когда возникает условие что принимается байт, т.е. этот таймаут просто не сработает если например задат его равным 5 секундам в момент когда фактически устройству FT ничего не передается из вне, грубо говоря таймаут начнет отрабатывать когда принят хотяб 1 байт, а если ничо не принято то и таймаут не запускается при вызове функции FT_Read. Из этого можно сделать вывод - таймауты эти эффективны только тогда, когда ты гарантированно знаешь что данные уже принимаются. А если ты оправил посылку устройству и ждешь ответа например миллисекунд так через 10-20, то этот таймаут по приему из библиотеки не сработает вообще.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
asteroid7
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 18, 2009 21:12:49

Re: работа с FT232, через библиотеку FTD2XX.dll

Сообщение asteroid7 »

Очень жаль. Вчера ответил не просмотрев тематические форумы.
А жаль мне вот за это...

Нет брат. Так не пойдёт. Продолжай дальше там спрашивать.

Из филантропических побуждений, прислушайтесь к посту lvbnhbq. Он только перевёл. Немного некорректно, но твоя проблема именно в этом.

Удачи! :)
Реклама
O_l_e_g
Нашел транзистор. Понюхал.
Сообщения: 191
Зарегистрирован: Вт дек 27, 2011 01:13:21

Re: работа с FT232, через библиотеку FTD2XX.dll

Сообщение O_l_e_g »

Добрый день, помогите разобраться в режиме BitBand для FT245R.
1. Когда я использую функцию FT_write, то как мне представляется буфер данных заданного размера передается микросхеме FT и эти байты сразу появляются на выводах D0...D7, а сигналы RD и WR в этом случае не требуются. Но если я посылаю большой массив байт то с какой скоростью будут эти данные выталкиваться на шину D0...D7, и что будет на шине данных когда будет вытолкнут на шину последний байт из пакета, не перейдет ли это шина в третье состояние. Хотелось бы узнать также как в это время ведут себя выводы RXF и TXE
2. Хотелось бы узнать какой тип передачи используют при своем обмене ХОСТ и FT245.
С уважением Олег
Реклама
Ответить

Вернуться в «Цифровая техника»