QuickAudine

Une interface USB pour la caméra CCD Audine
Mise à jour : 26/01/2003


Choose your language


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);
}

Retour