QuickAudine
Une
interface USB pour la caméra CCD Audine
Mise
à jour :
26/01/2003
QuickAudine est un petit boîtier permettant de
connecter la caméra Audine aux ordinateurs possédant une interface USB (Universal
Serial Bus). Aucune modification de la caméra n'est nécessaire. L'installation
est immédiate, même pour les non-experts, grâce au caractère Plug&Play
de l'interface USB.
Par rapport à l'interface imprimante, QuickAudine offre les avantages suivants :
L'interface "QuickA" en action. Elle est contenue dans un petit boîtier qui est ici relié à la caméra par un court câble parallèle. Le câble parallèle d'origine de la caméra Audine convient parfaitement. De l'autre côté du boîtier part le cable série USB vers l'ordinateur.
QuickAudine existe sous deux formes :
QuickAudine a été concue par Thierry
Maciaszek, avec la collaboration des membres du groupe Pixels
& Cassoulet.
Description sommaire
Le cœur de l'interface est un circuit FT245 (FTDI Chip) qui a la charge de la communication USB proprement dite. Un microcontroleur PIC 16F876 fonctionnant à 20 Mhz, aisément reprogrammable, complète le système. Ce microcontroleur émule le fonctionnement du port imprimante et implémente le code de pilotage de la caméra Audine. Le code du 16F876 a été écrit en FlashBasic.
Des exemples de programmation de la puce FT245 sont accessibles sur le site FTDI. Un des grands intérêt de cette puce est que son fabriquant met à disposition gratuitement et libre de droits les pilotes de ces puces USB. C'est une grosse tache de travail qui est déjà faite. La fiabilité de ce code semble excellente.
Un protocole de communication simple entre QuickAudine et le PC a été écrit au travers duquel sont passé les paramètres de l'acquisition. Une fois ces paramètres chargés dans la mémoire du Pic (format d'image, binning, etc), la main est rendu au PC pour comptabiliser le temps d'intégration. C'est ensuite le code du Pic qui prend le relais pour lire le CCD pixels après pixels et transmettre l'information numérique vers le PC. Le brochage coté caméra respecte l'agencement des broches du port imprimante. L'interface est compatible non seulement avec la série Audine, mais aussi avec ces nombreux clones et notamment la caméra Genesis réalisée aux USA.
On donne à la fin de cette page un exemple de programmation de la carte d'interface via une DLL spécialement écrite pour cela (cette DLL est utilisée par le programme Pisco pour gérer l'Audine via l'interface "QuickA").
On reconnaît sur le circuit imprimé la puce FT245 (petit carré en haut) et le contrôleur 16F876, monté sur un support tulipe. Deux LED permettent de vérifier le fonctionnement du système.
Installation de QuickAudine
Lors du premier branchement de l'interface à l'ordinateur, le système d'exploitation reconnaît immédiatement la présence d'un nouveau périphérique. A ce stade, vous devez fournir le pilote de l'interface. Celui-ci peut être télécharger gratuitement depuis le site FTDI. Vous pouvez aussi en obtenir une version en cliquant ici (décompressez le fichier Zip "DRIVERS.ZIP" de 250K et copier les fichiers extraits sur une disquette ou dans un CDROM par exemple).
Au premier branchement, voici la boite de dialogue qui apparaît à l'écran (système Windows XP) :
Choisissez l'option "Installer à partir d'un emplacement spécifié", puis cliquer sur le bouton "Suivant". Une nouvelle boite apparaît :
Cliquez sur "Suivant". Au bout de quelques instant, il vous est demandé de désigner l'endroit où ce trouve le pilote de l'interface :
Indiquer le chemin de la disquette, du CDROM, ou du répertoire de disque dur où vous avez copier les fichiers d'installation du pilote.
Un message d'avertissement s'affiche à l'écran. Pas de panique, passer outre en cliquant sur "Continuer".
Après quelques secondes, Windows vous signifie que l'installation est achevée. Le voyant vert de l'interface est allumée. Vous pouvez immédiatement utiliser QuickAudine, ce n'est pas plus compliqué !
Utilisation de Pisco avec l'interface QuickAudine
Vous devez avoir installer la version 2.0 de Pisco, ou une version supérieure
Pour télécharger Pisco V2.0 cliquer ici. Avant de procéder à l'installation de la version 2.0, il est recommandé de désinstaller au besoin la version précédente.
Lancer Pisco V2.0 et aller dans l'onglet "Réglages", puis cliquer le bouton "Réglages avancés". La boite de dialogue suivante apparaît :
Choisissez l'option "Interface USB". Profitez-en pour sélectionner la coupure de l'amplificateur durant la pose, ce qui est toujours recommandé. Vérifier que le CCD sélectionné est bien le votre (KAF-0400 ou KAF-1600).
Cliquez sur "OK".
Dans l'onglet "Réglages", si votre caméra Audine est équipée d'un obturateur, il faudra peut être définir combien de temps est laissé à la mécanique de cet obturateur pour ce fermer avant la lecture de l'image. QuickAudine autorise un délai jusqu'à 2,4 secondes.
Vous pouvez acquérir dès maintenant votre première image.
Lors de la phase de lecture de l'image, après le temps de pose, le voyant rouge de l'interface s'allume faiblement. Si votre ordinateur est lent, ou si le bus USB est chargé, il se peut que la fluidité de transfert des données de la caméra vers l'ordinateur soit altérée. La LED rouge devient alors plus brillant par intermitance. Le résultat se matérialise par de faibles lignes horizontales dans l'image, comme montré ci-après :
Cette image provient d'une Audine KAF-1600 et est acquise en binning 2x2. Le temps de pose est de 5 secondes sans refroidissement, ce qui explique les nombreux points chauds dans l'image. Plusieurs pixels défectueux perturbent aussi la lecture des colonnes (traits verticaux). Le problème de ralentissement momentané de la lecture de la caméra se manifeste par les traits horizontaux. Au moment de l'acquisition de cette image, le PC était connecté au réseau via un moden ADSL branché sur le port USB, ce qui n'est pas du tout recommandé pour une lecture propre de l'image ! Vous pouvez bien sur déconnecter cette charge USB, mais en refroidissant la caméra, plus rien n'y parait, comme le montre l'image suivante :
Il a été constaté que ce problème de lignage ce manifeste de manière assez variable suivant les configurations de PC. Un ordinateur relativement lent à 500 Mhz n'en présente pas du tout, un autre tournant à une fréquence d'horloge de 1,7 Ghz en montre de temps à autres. Sur les PC portable, le fait d'enlever le système de contrôle d'énergie en tache de fond a été un moyen d'éliminer les artéfacts. La difficulté vient de ce que la carte QuickA utilise une mémoire tampon très limitée (celle de la puce FTD245) lors de la communication avec le PC et elle est donc sensible à des ralentissements du canal USB. Par exemple si vous avez une souris USB branché au PC, il n'est pas judicieux de la déplacer lors de la phase de lecture de la caméra (en revanche, pas de problème avec les souris branchées sur l'interface série). C'est le revers de la simplicité extrême du schéma électronique adopté, une volonté délibéré de faire le plus dépouillé possible et au plus bas coût. En pratique, lors d'une utilisation normale en refroidissant le CCD, le phénomène de lignage horizontal n'est jamais un problème car imperceptible dans les images.
Une Webcam, elle même branchée sur le port USB, peut être utilisée simultanément avec QuickAudine. Simplement, lors de la phase de lecture de la caméra Audine, le fonctionnement de la Webcam est bloqué. Ceci permet d'exploiter une Webcam pour par exemple réaliser un autoguidage en parallèle au pilotage de l'Audine avec "QuickA".
QuickAudine autorise l'overscan, à la fois sur l'axe X et sur l'axe Y du CCD. On rappelle que l'overscan est une technique dans laquelle on lit plus de pixels que n'en contient le CCD, ce qui permet d'obtenir un signal de précharge (offset) de référence pour certaines applications. Pour cela, dans la boite de dialogue "Réglages avancés", entrer la valeur de l'overscan en pixel comme le montre la figure suivante (overscan de 60 pixels suivant l'axe X du CCD dans cet exemple) :
Voici le résultat dans la figure suivante, qui montre un extrait de l'image résultante (CCD non refroidi). La zone d'overscan est la bande sombre à gauche.
Exemple
de programmation avec QUICKA.DLL
En installant Pisco, une DLL ayant pour nom QUICKA.DLL, est copiée automatiquement dans le répertoire windows/system (sous Windows 98) ou le répertoire windows/system32 (sous Windows 2000, XP).
Vous pouvez télécharger cette DLL indépendemment de Pisco et l'utiliser pour vos propres applications.
Cliquez ici pour télécharger QUICKA.DLL (fichier de 30 Ko - V1.1).
Les sources en C de QUICKA.DLL peuvent être téléchargés en cliquant ici (fichier sources.zip de 16 Ko). Vous trouverez le nécessaire pour effectuer une compilation sous Visual C++ 6.0. Ces sources sont libres de droit d'utilisation et peuvent être modifiés comme bon vous semble. Cependant, en retour, il est demandé que vous partagiez avec la communauté des utilisateurs des caméras Audines et caméras dérivées vos avancés et astuces au travers de publications (Web, articles ou autres).
Le code suivant montre comment appeler les fonctions de QUICKA.DLL depuis une application programmée en VisualBasic 6.0.
------------------------
(1)
Declare QUICKA functions
------------------------
Public
Declare Function usb_loadlib Lib "QUICKA.DLL" () As Integer
Public
Declare Function usb_closelib Lib "QUICKA.DLL" () As Integer
Public
Declare Function usb_init Lib "QUICKA.DLL" () As Integer
Public
Declare Function usb_end Lib "QUICKA.DLL" () As Integer
Public
Declare Function usb_write Lib "QUICKA.DLL" (ByVal v As Integer) As
Integer
Public Declare Function usb_start Lib "QUICKA.DLL" (ByVal
KAF As Integer, _
ByVal x1 As Integer, ByVal y1 As Integer, ByVal x2 As Integer,
ByVal y2 As Integer, _
ByVal bin_x As Integer, ByVal bin_y As Integer, ByVal
shutter As Integer, _
ByVal shutter_mode As Integer, ByVal ampli_mode As
Integer, ByVal acq_mode As Integer, _
ByVal d1 As Integer, ByVal d2 As Integer,
ByVal speed As Integer, ByRef imax As Integer, _
ByRef jmax As Integer) As Integer
Public Declare
Function usb_readaudine Lib "QUICKA.DLL" (ByVal imax As Integer, _
ByVal
jmax As Integer, ByRef buf As Integer) As Integer
-----------------------------
(2)
Some variable declarations...
-----------------------------
Dim shutter As Integer, shutter_mode As
Integer
Dim ampli_mode As Integer, d1 As Integer, d2 As Integer
Dim x1
As Integer, x2 As Integer, y1 As Integer, y2 As Integer
Dim bin_x As Integer,
bin_y As Integer
Dim KAF As Integer, program as Integer, r As Integer
Dim
speed As Integer
Dim
imax As Integer, jmax As Integer
Dim delay As Double
------------------------------
(3)
Load the USB library functions
------------------------------
r = usb_loadlib() ' Register the FTDI USB
functions
If r <> 0 Then
MsgBox ("ERROR:
QuickAudine USB interface driver not found")
Exit
Sub
End If
r = usb_init() ' Check physical presence
of QuickAudine interface
If r <> 0 Then
MsgBox
("ERROR: QuickAudine USB interface not connected")
Exit
Sub
End If
r = usb_end() ' End of the check
------------------------------------------------------------------
(4)
Configuration of the acquisition, clear the CCD and start exposure
------------------------------------------------------------------
shutter = 1 ' Synchro shutter (0 value
= close shutter)
shutter_mode = 0 ' Inversion of the shutter command (1 value
= inverted mode)
ampli_mode = 1 ' shutdown the CCD amplifier during exposure
(0 value = always on)
delay = 1.2 ' delay in seconds between shutter close
and effective reading of the images
If delay > 2.4 Then ' 2.4 seconds
is the max. value
d1 = 0
d2 = 15
Else
d1 = 0
d2 = CInt(6.25 * delay)
End
If
x1 = 1 : y1 = 1 : x2 = 768 : y2 = 512 ' digitized image zone (KAF-0400
full frame example)
bin_x = 1 : bin_y = 1 ' binning factor (valid value:
1, 2, 3 and 4)
KAF = 1 ' CCD model (1 = KAF0400 , 2 = KAF1600)
program
= 1 ' version of the QuickA internal program version
speed = 6 ' speed of
the interface (valid value: 1...15 - standard value=6)
' Setup of the acquisition
' Note:
the usb_start function return the effective size of the image (imax, jmax)
r
= usb_start(KAF, x1, y1, x2, y2, bin_x, bin_y, shutter, shutter_mode, _
ampli_mode,
program, d1, d2, speed, imax, jmax)
If r = 12 Then
MsgBox
("Error: QuickAudine USB interface USB not ready")
Exit
Sub
ElseIf r = 16 Then
MsgBox ("Error: Dialog
problem with the QuickAudine USB interface")
Exit
Sub
ElseIf r = 17 Then
MsgBox ("Error: USB data
transmission error")
Exit Sub
End If
-------------------------------
(5) Gestion of the integration time
-------------------------------
...
... Your code
...
-------------------
(6)
End of the exposure
-------------------
r = usb_write(255) ' CCD amplifier on
Sleep
(100) ' small delay
r = usb_write(255) ' Close the shutter
--------------
(7)
Read the image
--------------
' allocate memory (note: option base 0
for the arrays)
ReDim buffer(imax - 1,jmax - 1) As Integer
r = usb_readaudine(imax, jmax, buffer(0, 0))
' Note: The reading start after the delay (d1, d2) relative to the shutter shutdown
-------------------------------------------
(8)
Erase USB FTDI library functions (optional)
-------------------------------------------
r = usb_closelib()
' The image is now in the 768x512 - 16-bits array BUFFER(i,j)
' It's all !
Exemple d'appel direct des routines FTDI
Extrait de programme en C (Visual C++) montrant comment lire la caméra Audine en appelant directement les routines de la DLL FTDI.
//////////// C DRIVER
ROUTINES FOR QuickAudine USB interface ////////////
//
// Some declaration
in the header of your program
typedef DWORD FT_HANDLE;
typedef DWORD FT_STATUS;
EXTERN
FT_HANDLE UsbHandle;
EXTERN HMODULE g_usb_module;
typedef FT_STATUS
(WINAPI *PtrToOpen)(PVOID, FT_HANDLE *);
EXTERN PtrToOpen g_usb_Open;
EXTERN
int UsbOpen(PVOID);
typedef FT_STATUS (WINAPI *PtrToClose)(FT_HANDLE);
EXTERN
PtrToClose g_usb_Close;
EXTERN int UsbClose();
typedef FT_STATUS (WINAPI
*PtrToRead)(FT_HANDLE, LPVOID, DWORD, LPDWORD);
EXTERN PtrToRead g_usb_Read;
EXTERN
int UsbRead(LPVOID, DWORD, LPDWORD);
typedef FT_STATUS (WINAPI *PtrToWrite)(FT_HANDLE,
LPVOID, DWORD, LPDWORD);
EXTERN PtrToWrite g_usb_Write;
EXTERN int UsbWrite(LPVOID,
DWORD, LPDWORD);
typedef FT_STATUS (WINAPI *PtrToResetDevice)(FT_HANDLE);
EXTERN
PtrToResetDevice g_usb_ResetDevice;
EXTERN int UsbResetDevice();
typedef
FT_STATUS (WINAPI *PtrToGetQueueStatus)(FT_HANDLE, LPDWORD);
EXTERN PtrToGetQueueStatus
g_usb_GetQueueStatus;
EXTERN int UsbGetQueueStatus(LPDWORD);
///////////////////////////////////////////////////////
//
First, load FTDI library at the start of the program
///////////////////////////////////////////////////////
open_ftdi();
// At the end of the program call to the routine close_libftdi()
/////////////////////////////////
//
Main routine for read an image
/////////////////////////////////
unsigned
long longueur_buffer=1024;
char ReadBuffer[1024];
DWORD Nb_RxOctets;
unsigned
long int i,j,k;
unsigned char tx[2], rx[2];
double integration;
int
flag_ampli;
int ampli;
int obturateur;
int inv_obturateur;
int
nb_fastvidage;
int kaf,i_prog,speed;
int x1,y1,x2,y2,bin_x,bin_y;
int imax,jmax;
///////////////////////////
//// Acquisition
parameters
///////////////////////////
i_prog = 1; // prog. version
kaf=1;
// 1 = KAF-0400 - 2 = KAF-1600
x1=1; y1=1; x2=kaf*768; y2=kaf*512;
bin_x=1;
// valuable value : 1, 2, 3, 4
bin_y=1;
obturateur=1; // 1 = synchro
- 0 = closed
inv_obturateur=0; // 0 : no inverted - 1 : inverted
nb_fastvidage=2;
// number of fast clear of the CCD - max. 15
ampli=1; // 1=shutdown
during integration time
speed=6: // speed of the interface
x1=x1/bin_x;
x2=x2/bin_x;
y1=y1/bin_y;
y2=y2/bin_y;
if
(x1<=0) x1=1;
if (y1<=0) y1=1;
if (x2<=0) x2=10;
if (y2<=0)
y2=10;
imax=x2-x1+1;
jmax=y2-y1+1;
if (InitUsb()==PB) exit(-1); // check USB interface
unsigned long nb_pixel = imax*jmax; //
size of the image
int X1_H_1 = x1/256;
int X1_L_2 = (x1-X1_H_1*256)/16;
int
X1_L_1 = x1-X1_H_1*256 - X1_L_2*16;
int X2_H_1 = x2 / 256;
int X2_L_2
= (x2 - X2_H_1 * 256) / 16;
int X2_L_1 = x2 - X2_H_1 * 256 - X2_L_2 * 16;
int
Y1_H_1 = y1/256;
int Y1_L_2 = (y1-Y1_H_1*256)/16;
int Y1_L_1 = y1-Y1_H_1*256
- Y1_L_2*16;
int Y2_H_1 = y2 / 256;
int Y2_L_2 = (y2 - Y2_H_1 * 256) /
16;
int Y2_L_1 = y2 - Y2_H_1 * 256 - Y2_L_2 * 16;
tx[0]=0;
tx[1]=i_prog
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=kaf * 16;
usbWrite(tx,2,&Nb_RxOctets);
tx[1]=bin_x
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=bin_y
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=X1_L_1
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=X1_L_2
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=X1_H_1
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=X2_L_1
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=X2_L_2
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=X2_H_1
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=Y1_L_1
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=Y1_L_2
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=Y1_H_1
* 16;
usbWrite(tx,2,&Nb_RxOctets);
tx[1]=Y2_L_1
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=Y2_L_2
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=Y2_H_1
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=nb_fastvidage
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=obturateur
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[1]=inv_obturateur
* 16;
UsbWrite(tx,2,&Nb_RxOctets);
tx[0]=0;
tx[1]=16*0;
// q1
UsbWrite(tx,2,&Nb_RxOctets);
tx[0]=0;
tx[1]=16*15;
// q2 delay before shutter closing = (q1+16.q2)*10 ms
UsbWrite(tx,2,&Nb_RxOctets);
tx[0]=0;
tx[1]=ampli
* 16;
UsbWrite(tx,2,&Nb_RxOctets);tx[0]=0;
tx[0]=0;
tx[1]=speed
* 16; // speed of the interface (value
between 1 and 15 - normal value = 6)
UsbWrite(tx,2,&Nb_RxOctets);
tx[0]=0;
tx[1]=0;
// reserved
UsbWrite(tx,2,&Nb_RxOctets);
tx[0]=0;
tx[1]=0;
// reserved
UsbWrite(tx,2,&Nb_RxOctets);
tx[0]=0;
tx[1]=0;
// reserved
UsbWrite(tx,2,&Nb_RxOctets);
////////////////
// Clear the CCD
////////////////
k=0;
UsbGetQueueStatus(&Nb_RxOctets);
while
(Nb_RxOctets==0)
{
UsbGetQueueStatus(&Nb_RxOctets);
sleep(100); // TimeOut
k++;
if (k==200)
{
msg("USB
interface not ready");
CloseUsb();
exit(-1);
}
}
UsbRead(rx,1,&Nb_RxOctets);
if ((rx[0]
& 240) / 16 != 11)
{
msg("Data transmission
error");
CloseUsb();
exit(-1);
}
///////////
// Exposure
///////////
// Your code...
//////////////////
// End of exposure
//////////////////
tx[0]=0;
tx[1]=255;
UsbWrite(tx,2,&Nb_RxOctets);
// ampli on
sleep(100); // delay
tx[0]=0;
tx[1]=255;
UsbWrite(tx,2,&Nb_RxOctets);
// close shutter
//////////////////////
// Image
read
//////////////////////
// p is a pointer to a short type buffer
of size (imax,jmax)
j=0;
k=0;
int v1,v2,v3,v4,v;
while (j<=4*nb_pixel-longueur_buffer)
{
UsbGetQueueStatus(&Nb_RxOctets);
while
(Nb_RxOctets<longueur_buffer) UsbGetQueueStatus(&Nb_RxOctets);
UsbRead(ReadBuffer,longueur_buffer,&Nb_RxOctets);
for (i=0;i<Nb_RxOctets;i+=4)
{
v1=(int)ReadBuffer[i] & 15;
v2=(int)ReadBuffer[i+1]
& 15;
v3=(int)ReadBuffer[i+2] & 15;
v4=(int)ReadBuffer[i+3] & 15;
v=v1+16*v2+256*v3+4096*v4;
if (v>32767)
p[k]=32767;
else
p[k]=(short)v;
k++;
}
j=j+longueur_buffer;
}
if (j!=4*nb_pixel)
{
UsbGetQueueStatus(&Nb_RxOctets);
while (Nb_RxOctets<4*nb_pixel-j) UsbGetQueueStatus(&Nb_RxOctets);
UsbRead(ReadBuffer,4*nb_pixel-j,&Nb_RxOctets);
for
(i=0;i<Nb_RxOctets;i+=4)
{
v1=(int)ReadBuffer[i]
& 15;
v2=(int)ReadBuffer[i+1] &
15;
v3=(int)ReadBuffer[i+2] & 15;
v4=(int)ReadBuffer[i+3] & 15;
v=v1+16*v2+256*v3+4096*v4;
if (v>32767)
p[k]=32767;
else
p[k]=(short)v;
k++;
}
}
CloseUsb();
/********* InitUsb ***********/
int
InitUsb()
{
if (UsbOpen(0)!=0)
{
msg("USB
not Ok");
return(PB);
}
UsbResetDevice();
return(OK);
}
/*********** CloseUsb **********/
int
CloseUsb()
{
UsbClose();
return(OK);
}
//********************************************************************
int
UsbRead(LPVOID lpvBuffer, DWORD dwBuffSize, LPDWORD lpdwBytesRead)
{
return
(*g_usb_Read)(UsbHandle,lpvBuffer,dwBuffSize,lpdwBytesRead);
}
//********************************************************************
int
UsbWrite(LPVOID lpvBuffer,DWORD dwBuffSize,LPDWORD lpdwBytes)
{
return
(*g_usb_Write)(UsbHandle,lpvBuffer,dwBuffSize,lpdwBytes);
}
//********************************************************************
int
UsbOpen(PVOID pvDevice)
{
return (*g_usb_Open)(pvDevice,&UsbHandle);
}
//********************************************************************
int
UsbClose()
{
return (*g_usb_Close)(UsbHandle);
}
//********************************************************************
int
UsbResetDevice()
{
return (*g_usb_ResetDevice)(UsbHandle);
}
//*********************************************************************
int
UsbGetQueueStatus(LPDWORD lpdwAmountInRxQueue)
{
return (*g_usb_GetQueueStatus)(UsbHandle,lpdwAmountInRxQueue);
}
/****************** OPEN_LIBFTDI ******************/
/*
Load FTDI library */
/**************************************************/
int
open_libftdi(void)
{
g_usb_module=LoadLibrary("Ftd2xx.dll");
if
(g_usb_module == NULL)
{
AfxMessageBox("Error:
Can't Load ft8u245.dll");
return 1;
}
g_usb_Write=(PtrToWrite)GetProcAddress(g_usb_module,
"FT_Write");
if (g_usb_Write == NULL)
{
AfxMessageBox("Error:
Can't Find FT_Write");
return 1;
}
g_usb_Read
= (PtrToRead)GetProcAddress(g_usb_module, "FT_Read");
if (g_usb_Read
== NULL)
{
AfxMessageBox("Error: Can't
Find FT_Read");
return 1;
}
g_usb_Open = (PtrToOpen)GetProcAddress(g_usb_module,
"FT_Open");
if (g_usb_Open == NULL)
{
AfxMessageBox("Error:
Can't Find FT_Open");
return 1;
}
g_usb_Close = (PtrToClose)GetProcAddress(g_usb_module,
"FT_Close");
if (g_usb_Close == NULL)
{
AfxMessageBox("Error:
Can't Find FT_Close");
return 1;
}
g_usb_ResetDevice = (PtrToResetDevice)GetProcAddress(g_usb_module,
"FT_ResetDevice");
if (g_usb_ResetDevice == NULL)
{
AfxMessageBox("Error: Can't Find FT_ResetDevice");
return 1;
}
g_usb_GetQueueStatus = (PtrToGetQueueStatus)GetProcAddress(g_usb_module,
"FT_GetQueueStatus");
if (g_usb_GetQueueStatus == NULL)
{
AfxMessageBox("Error: Can't Find FT_GetQueueStatus");
return 1;
}
return 0;
}
/************** CLOSE_LIBFTDI *************/
/*
Libère la librairie FTDI de la mémoire */
/******************************************/
int
close_libftdi(void)
{
FreeLibrary(g_usb_module);
return(0);
}