Forum: Mikrocontroller und Digitale Elektronik kein Zugriff auf FTDI FT245 nach SW-Abbruch


von TImo (Gast)


Lesenswert?

Hallo,

ich setzte einen FT245RL von FTDI ein und habe folgendes Problem in 
meinem Anwendungsporgramm (VB6) (ist sicher bei allen FTxxx das selbe) :

Sobald das Device einmal geöffnet ist (FT_GetNumDevices - 
FT_ListDevices-FT_Open) und die Software abbricht bevor der Port wieder 
ordentlich geschlossen werden kann (FT_Close), habe ich softwareseitig 
keine Chance auf einen neuen Zugriff. Ich muss dann erst das Gerät vom 
Bus abziehen und wieder einstecken.

Sicher ist das Problem nicht neu - kann jemand helfen?



Ach ja: FTDI-Support empfahl mir folgendes (leider ohne Erfolg)
1
Set the ResetPipeRetryCount to 100. This can be done in the drivers or in the application by using the function FT_SetResetPipeRetryCount. To change the driver by edit the INF file by following the instructions on page 11 of the following document http://www.ftdichip.com/Documents/AppNotes/AN232B-10_Advanced_Driver_Options.pdf 
2
3
 
4
5
Set the Dead mans timeout to 10000. This can be done in the driver or in the application by using the function FT_SetDeadmansTimeout. To change the driver by edit the INF file by following the instructions on page 17 of the following document http://www.ftdichip.com/Documents/AppNotes/AN232B-10_Advanced_Driver_Options.pdf  
6
7
 
8
9
There are also functions in the new driver that will try and recover the device programmatically. These functions are called FT_Rescan and FT_Reload.

Der Sourcecode sieht etwa so aus
1
Public Function USBOpen() As Boolean
2
Dim strDescription As String * 256
3
Dim strSerialNumber As String * 256
4
5
 
6
7
If FT_GetNumDevices(lngNumDevices, vbNullString, FT_LIST_BY_NUMBER_ONLY) <> FT_OK Then
8
    ' do Failoption
9
10
    Exit Function
11
End If
12
13
 
14
15
If FT_ListDevices(0, strDescription, FT_LIST_BY_INDEX Or FT_OPEN_BY_DESCRIPTION) <> FT_OK Then
16
    ' do Failoption
17
18
    Exit Function
19
End If
20
21
  
22
23
If FT_Open(0, lngNumDevices) <> FT_OK Then
24
    ' do Failoption
25
26
    Exit Function
27
End If
28
29
 
30
31
End Function
32
33
 
34
35
Public Function USBclose() As Boolean
36
If FT_Close(lngNumDevices) <> FT_OK Then
37
    ' do Failoption
38
39
End If
40
41
End Function



Danke,


Timo

von MM (Gast)


Lesenswert?

Das ist leider so - dafür gibt es keine universelle Lösung.

Am einfachsten einen Shutdown Handler programmieren der die offenen
Verbindungen schließt wenn das Programm beendet wird.

Gruß, Marcus

von Ralf (Gast)


Lesenswert?

Hallo,

@MM:
> Am einfachsten einen Shutdown Handler programmieren der die offenen
> Verbindungen schließt wenn das Programm beendet wird.

Timo hat geschrieben:

> ...und die Software abbricht bevor der Port wieder ordentlich geschlossen
> werden kann (FT_Close)

Wird denn dann ein Shutdown-Handler wirklich noch angesprungen? Sicher 
ist so ein Handler hilfreich, aber ich frag mich eben, ob der dann 
wirklich noch zum Zug kommt.

Ralf

von Andre T. (oldgrumpy)


Lesenswert?

Ralf wrote:
>
> Wird denn dann ein Shutdown-Handler wirklich noch angesprungen? Sicher
> ist so ein Handler hilfreich, aber ich frag mich eben, ob der dann
> wirklich noch zum Zug kommt.
>
> Ralf

Nein, wird er nicht. Wenn ein Prozess gekillt wird, dann wird er 
gekillt, das hat nichts mit einem kontrollierten Shutdown zu tun. Ich 
hatte vor einiger Zeit praktisch das gleiche Problem, je nachdem wie 
rabiat man die eigene Software implementieren will, kann man allerdings 
mittels der vom FTDI Support angesprochenen Funktionen FT_Rescan bzw. 
FT_Reload einen Reload des USB-Treibers erzwingen. Da der aber unter 
Umständen nicht nur die eigene Hardware befeuert (die FTDI-Chips sind ja 
sehr verbreitet), könnte man damit eine breite Palette an 
Kollateralschäden verursachen...

von Ralf (Gast)


Lesenswert?

Hi Andre,

ja, das könnte ein Problem geben. Bzgl. der FTDI Chips und einem 
gekillten Prozess müsste man aber mal probieren, ob man trotz geöffneter 
Devices diese nicht bei einem erneuten Programmstart einfach mittels der 
LocationID schliessen kann. Ich meine, dass man zumindest auch 
Informationen über alle angeschlossenen FTDIs bekommen kann, egal ob 
geschlossen oder geöffnet.

Ralf

von Andre T. (oldgrumpy)


Lesenswert?

Ralf wrote:
> ja, das könnte ein Problem geben. Bzgl. der FTDI Chips und einem
> gekillten Prozess müsste man aber mal probieren, ob man trotz geöffneter
> Devices diese nicht bei einem erneuten Programmstart einfach mittels der
> LocationID schliessen kann. Ich meine, dass man zumindest auch
> Informationen über alle angeschlossenen FTDIs bekommen kann, egal ob
> geschlossen oder geöffnet.

Ja, und genau das ist auch das einzige was geht - zumindest zum 
Zeitpunkt meiner letzten Tests, das war die Treiberversion vor der 
momentan aktuellen, hab die Nummer gerade nicht parat. Wenn die Jungs 
von FTDI da nix geändert haben, dann bekommt man gerade noch die Anzahl 
der angeschlossenen Devices, aber kaum mehr - ist alles vom vorherigen 
FT_Open gesperrt. :( Habe momentan leider ganz andere Sorgen (siehe mein 
Posting in Sachen M16C und CrossView von gestern abend) so dass ich 
keine Zeit zum Ausprobieren habe, ich wäre aber durchaus an den 
Testresultaten interessiert :)

von TImo (Gast)


Lesenswert?

Ich habe jetzt einen langen Mailverkehr mit der FTDI-Hotline, leider 
führt das aber auch nicht zum Erfolg bei mir.
Letzlich wird im oben beschriebenen Fehlerfall folgendes vorgeschlagen, 
wodurch der Handle wieder hergestellt werden soll.


Vielleicht kann das jemand mal gegenprüfen.....

Timo



1
// FTDI.cpp : Defines the entry point for the console application.
2
3
//
4
5
 
6
7
//#include "stdafx.h"
8
9
#include <windows.h>
10
11
#include <stdio.h>
12
13
#include "ftd2xx.h"
14
15
 
16
17
FT_HANDLE fthandle;
18
19
FT_STATUS status;
20
21
 
22
23
void Reload()
24
25
{     
26
27
FT_Reload(0403,6010);
28
29
FT_Rescan();
30
31
Sleep(1000);
32
33
 
34
35
status = FT_Open(0, &fthandle);
36
37
 
38
39
while(status!=0)
40
41
{
42
43
status = FT_Open(0, &fthandle);
44
45
 
46
47
}
48
49
printf("Device Open %d\n", status);
50
51
}
52
53
 
54
55
int main(int argc, char* argv[])
56
57
{
58
59
 
60
61
      
62
63
Reload();
64
65
 
66
67
 
68
69
 
70
71
 status = FT_ResetDevice(fthandle);
72
73
              if(status != FT_OK)
74
75
 {
76
77
              printf("reset status not ok %d\n", status);
78
79
                    //Reload();
80
81
 }
82
83
 
84
85
/************************************************************/                  
86
87
                   
88
89
 
90
91
 status = FT_SetTimeouts(fthandle,500,500);
92
93
 
94
95
                   if(status != FT_OK) 
96
97
 {
98
99
               printf("timeout status not ok %d\n", status); 
100
101
                     //Reload();
102
103
}
104
105
 
106
107
/************************************************************/                  
108
109
 
110
111
 
112
113
 status = FT_SetBaudRate(fthandle,38400);
114
115
 
116
117
                   if(status != FT_OK)
118
119
 { 
120
121
               printf("baud status not ok %d\n", status);
122
123
                     //Reload();
124
125
 }
126
127
/************************************************************/                  
128
129
printf("Program paused.... Press return to Start Again!\n");
130
131
getchar();
132
133
 
134
135
//CBUS BITBANG
136
137
                     
138
139
UCHAR MaskA = 0xFF;
140
141
UCHAR modeA = 0;
142
143
 
144
145
 
146
147
 status = FT_SetBitMode(fthandle, MaskA, modeA);
148
149
 
150
151
                     if(status != FT_OK) 
152
153
               printf("mode A status not ok %d\n", status);
154
155
                    
156
157
 
158
159
                    
160
161
MaskA = 0x00;
162
163
modeA = 0x20;
164
165
 
166
167
 
168
169
 status = FT_SetBitMode(fthandle, MaskA, modeA);
170
171
 
172
173
                     if(status != FT_OK) 
174
175
                              printf("mode A status not ok %d\n", status);
176
177
 
178
179
UCHAR Bitmode;
180
181
UCHAR KeyChar;
182
183
 
184
185
KeyChar = 0x6F;
186
187
 
188
189
do
190
191
{
192
193
 
194
195
 status = FT_GetBitMode(fthandle, &Bitmode);
196
197
 
198
199
                     if(status != FT_OK) 
200
201
               printf("data read failed\n", status);
202
203
}
204
205
while (Bitmode != KeyChar);
206
207
 
208
209
 printf("Key Press detected\n");
210
211
 
212
213
 status = FT_Close(fthandle);
214
215
 
216
217
               return 0;
218
219
 
220
221
}

von Lutz (Gast)


Lesenswert?

Hat das inzwischen jemand ausprobiert?
Es würde mich auch interessieren. Ich habe es versucht und bisher nicht 
geschafft das ganze in VB6 erfolgreich umzustezen, habe aber auch nur 
ein so ähnliche Problem.

Also beim Software-Crash ist die Sache einfach. Ich stöpsel den 
USB-Adapter einfach aus und wieder ein und schon funktionert der handle 
wieder.
Ausserdem kann ich einen Software-Crash ja verhindern.

Mein Problem ist folgendes, wenn ich meine Schreibtischlampe ein- oder 
ausschalte, stört das die USB-Kommunikation und ich bekomme Fehler 4 
(allgemeiner I/O error).
Wie kann ich diesen Fehler zurücksetzen ohne danach (zB bei FT_close) 
Fehler 1 zu bekommen (invalid handle)? Den ich dann wie oben für den 
Programm-Crash beschrieben nicht weg bekomme.
Stöpsel ich den USB-Port dann aus und ein, kann ich danach auch 
problemlos den alten handle benutzen. Der erzeugte Zustand ist also 
einem Crash sehr ähnlich

Ich bräuchte also eine Funktion, mit der ich den Fehler 4 zurücksetzen 
kann, ohne dass der Treiber vergisst, dass man die Berechtigung hat, den 
handle zu benutzen. Denn nach dem ein- und ausstöpseln funktioniert ja 
genau dieser falsche handle wieder und wird als richtig erkannt. Der 
handle ist also gar nicht falsch. Der CDM-Treiber hat nur vergessen, 
dass man das Recht hat, ihn zu benutzen.

Wie kommt man da softwaremässig raus, ohne ein und auszstöpseln?
Oder wie kann man Fehler 4 zurücksetzen ohne Fehler 1 zu erhalten.

Weiss jemand eine Lösung?

Vielen Dank
Lutz





Weiss jemand eine Lösung?

von NLB (Gast)


Lesenswert?

Wie sich die Fehler gleichen. Das ist nun gut 1,5 Jahre her. Ich 
versuche genau diesen Fehler auf Vorstads-Ebene mit FTDI zu klären. 
Falls ich was herausbekomme gibt es ein FeedBack

mfg NLB

von Lutz (Gast)


Lesenswert?

Hab mal wieder vorbei geschaut. Ja es ist schon über 1.5 Jahre her.

Das Problem habe ich immer noch. Und noch immer gibt es keine Lösung.
Schade.

Wie schaffen es alle anderen FTDI-Chip Nutzer den EMV-Test zu bestehen, 
wenn sie Fehler 4 nach eine elektrischen Störung nicht rücksetzen 
können?

Was mache ich falsch?

Alle von FTDI vorgeschlagenen Lösungen z.B. FT_SetResetPipeRetryCount, 
Schaltungsverbesserung... verringern nur die Fehlerquote, aber lösen das 
Problem nicht. Wenn ich Fehler 4 zurücksetzen könnte, ohne Fehler 1 zu 
erhalten, hätte ich das Problem komplett vom Tisch.
Warum kann ich das nicht? Wie machen das alle anderen Nutzer?
Ich will das die USB-Verbindung monatelang problemlos funktioniert.
Ist das zuviel verlangt?

Lutz

von Edefix (Boss vom BugFix) (Gast)


Lesenswert?

Nun ja. Auch ich kämpfe mit dem Problem bei einer Automatenkassa, wo die 
ccTalk-Komponentne via seriellem USB angesprochen werden, alle 2 bis 3 
Tage ist der USB-Device weg, also ausstöpseln, einstöpseln, wunderbar 
8-(

Habe nun eine Geschichte in VB6 herausgefunden: Der Handle, welchen man 
beim Öffnen des Devices erhält, wird ja auch wieder zum Schließen 
benötigt. Es gibt da allerdings eine mir mittlerweile bekannte Funktion, 
die diesen Handle zerstört: FT_EE_Read(lngHandle, EEData). Diese 
Funktion liest diue Seriennummer, Hersteller, etc. Der dabei übergebene 
Handle lngHandle wird bei der Ausführung auf 0 gesetzt, wobei das 
Schließen des Devices logischerweise schief geht. Also unbedingt den 
Device-Handle zwischenspeichern, weiß ja nicht wo das sonst noch 
passiert.

Aber jetzt kommt es dicker. Nachdem der Device geöffnet ist, kann er 
nicht wieder geöffnet werden >> Error. Schließen kannst Du ihn auch 
nicht mehr, hast ja keinen Handle mehr. Gut. Also zyklisch prüfen und 
dann resetten.

1. Versuch: Den Device resetten
FT_ResetDevice(lngHandle) ->> kein Ergebnis

2. Versuch: Den USB-seriellen FTDI-Device mit der internen Funktion 
reloaden
FT_Reload(&H403, &H6001) ->> kein Ergebnis

3. Versuch: Alle FTDI-Devices reloden
FT_Reload(&H0, &H0) ->> kein Ergebnis
(ausser daß wirklich alle betroffene Treiber aus der 
Hardwarekomponenten-Liste rausfliegen und dann auch wieder schön brav 
eingelesen werden)
Kann also den Device wieder auflisten, aber NICHT ÖFFNEN. Musst Du 
einfach ausstöpseln, einstöpseln, geht doch.

Kann doch nicht sein, oder?

Hat da irgend wer noch ne echt gute Idee?


Ed

von ab (Gast)


Lesenswert?

Auch wenn der Thread uralt ist, bin ich heute auch auf das gleiche 
Problem gestoßen..!! Hat es einer von euch irgendwie lösen können? Das 
manuelle raus und wieder reinstecken des USB Steckers kommt bei mir gar 
nicht in Frage, da das FTDI Device zum Zwecke einer Automatisierung 
eingesetzt wird. Daher muss ich es softwaretechnisch lösen.

von Felix Adam (Gast)


Lesenswert?

Ich denke, nach dem Lesen dieser Beiträge werde ich im Mikrocontroller 
eine Routine vorsehen, die nach Abbruch der Kommunikation (mit Timeout) 
den FTDI einmal eigenständig resettet. Der FTDI hat dafür ja einen Pin.

Hat das schonmal jemand gemacht und weiß, ob das geht? Es sollte ja wie 
ein Abziehen vom Bus sein...

Vielleicht hilft das auch dem Gast "ab".

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.