usb_driver.c 6.32 KB
#include <libusb-1.0/libusb.h> //bibliothèque USB
#include <stdio.h>
#include <stdlib.h>

#include <fcntl.h>
#include <strings.h>
#include <unistd.h>


#define LED_ON 0x21
#define LED_OFF 0x22
#define MOVE_RIGHT 0x04
#define MOVE_LEFT 0x08
#define MOVE_STOP 0x10


#define ACM_CTRL_DTR  0x01
#define ACM_CTRL_RTS 0x02

static int ep_in_addr  = 0x83;
static int ep_out_addr = 0x04;

libusb_device **list;
libusb_device_handle *handle = NULL;
libusb_device *device;





void configuration_periph(libusb_device *device) //Configuration de la tourelle
{
  //Ouverture du pepherique
  int status=libusb_open(device,&handle);
  if(status!=0)
    {
      perror("libusb_open"); exit(-1);
    }
    
  
  //Recuperation de la configuration d'indice 0 du périphérique
  struct libusb_config_descriptor *config;
  status=libusb_get_active_config_descriptor(device,&config);
  if(status!=0)
    {
      perror("libusb_get_active_config_descriptor"); exit(-1);
    }

  //Interfaces
  int i;
  int interface;
  
  //On détache le noyau de notre périphérique
  for(i=0;i<(config->bNumInterfaces);i++)
    {
      interface=config->interface[i].altsetting[0].bInterfaceNumber;
      if(libusb_kernel_driver_active(handle,interface))
      {
        status=libusb_detach_kernel_driver(handle,interface);
        if(status!=0)
        {
          perror("libusb_detach_kernel_driver"); exit(-1);
        }
      }
    }


  //Utilisation d'une configuration du périphérique
  int configuration=config->bConfigurationValue;

  status=libusb_set_configuration(handle,configuration);
  if(status!=0)
    {
      perror("libusb_set_configuration"); exit(-1);
    }
    
    
  //Claim interfaces
  for(i=0;i<(config->bNumInterfaces);i++)
    {
      interface=config->interface[i].altsetting[0].bInterfaceNumber;
      printf("Numero d'interface : %d\n", interface);
      status=libusb_claim_interface(handle,interface);
      if(status!=0)
      {
        perror("libusb_claim_interface"); exit(-1);
      }
    }
}


void fermeture(libusb_device_handle *handle) //Fermeture du périphérique
{
  int i, interface, status;
  libusb_device *device = libusb_get_device(handle);
  struct libusb_config_descriptor *config;
  status = libusb_get_active_config_descriptor(device, &config);
  if(status != 0)
    {
      perror("libusb_get_active_config_descriptor");exit(-1);
    }
  
  for(i=0;i<(config->bNumInterfaces);i++)
    {
      interface=config->interface[i].altsetting[0].bInterfaceNumber;
      status=libusb_release_interface(handle,interface); //On libère l'interface
      if(status!=0)
	{
	  perror("libusb_release_interface");
	  exit(-1);
	}
      printf("Interface liberee : %d\n",interface);
    }
   
  libusb_close(handle);
  }


void enumeration(libusb_context *context) //Enumération des périphériques USB
{
  int t=0;
  libusb_device **list;
  ssize_t count=libusb_get_device_list(context,&list);
  if(count<0)
    {
      perror("libusb_get_device_list"); exit(-1);
    }

  ssize_t i=0;
  for(i=0;i<count;i++)
  {
  libusb_device *device=list[i];
  struct libusb_device_descriptor desc;
  int status=libusb_get_device_descriptor(device,&desc);
  if(status!=0) continue;
  uint8_t bus=libusb_get_bus_number(device);
  uint8_t address=libusb_get_device_address(device);
 
 //Lorsque l'on retrouves notre périphérique nous passons à la configuration.
 if ((desc.idVendor==0x0010) && (desc.idProduct==0x1010)) 
    {
      printf("périphérique trouvée !\n");
      t=1;
      configuration_periph(device);
    }
  }
  if(t==0) printf("périphérique non connectée !\n");
}
     



void envoi(unsigned char c)
{
    /* To send a char to the device simply initiate a bulk_transfer to the
     * Endpoint with address ep_out_addr.
     */
    int actual_length;
    if (libusb_bulk_transfer(handle, ep_out_addr, &c, 1,
                             &actual_length, 0) < 0) {
        fprintf(stderr, "Error while sending char\n");
    }
}

int reception(unsigned char * data, int size)
{
    /* To receive characters from the device initiate a bulk_transfer to the
     * Endpoint with address ep_in_addr.
     */
    int actual_length;
    int status = libusb_bulk_transfer(handle, ep_in_addr, data, size, &actual_length,
                                  1000);
    if (status == LIBUSB_ERROR_TIMEOUT) {
        printf("timeout (%d)\n", actual_length);
        return -1;
    } else if (status < 0) {
        fprintf(stderr, "Error while waiting for char\n");
        return -1;
    }

    return actual_length;
}



int main()
{
   //Initialisation de la bibliotheque libusb
  libusb_context *context;
  unsigned char buf[65];
  int len;
  
  int status=libusb_init(&context);
  if(status!=0)
    {
      perror("libusb_init"); exit(-1);
    }

//Enumération des périphériques USB. Si le périphérique est trouvé, cette fonction fait appel à la fonction configuration_perip.
  enumeration(context); 

//configuration du périphérique
 status = libusb_control_transfer(handle, 0x21, 0x22, ACM_CTRL_DTR | ACM_CTRL_RTS,
                                0, NULL, 0, 0);
    if (status < 0) {
        fprintf(stderr, "Error during control transfer: %s\n",
                libusb_error_name(status));
}



     //Configuration du port série.
    unsigned char encoding[] = { 0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08 };
    status = libusb_control_transfer(handle, 0x21, 0x20, 0, 0, encoding,
                                sizeof(encoding), 0);
    if (status < 0) {
        fprintf(stderr, "Error during control transfer: %s\n",
                libusb_error_name(status));
      } 

     

  //Menu de commande
  char action;
  for(;;) 
    { 

      printf("s=fermer / d=allumer led / g=eteindre led / h=moteur gauche / b=moteur droit / t=moteur éteint \n");
      scanf("%c",&action);
	  
    switch (action)
	    {
	    case 's':
	      fermeture(handle);
	      libusb_free_device_list(list,1);
	      libusb_exit(context);
	      return 0;
	      break;
	    case 'd':
	      envoi(LED_ON);
	      sleep(1);
	      
	      break;
	    case 'g':
	      envoi(LED_OFF);
	      sleep(1);
	      break;
	    case 'h':
	      envoi(MOVE_LEFT);
        sleep(1);
	      break;
	    case 'b':
	      envoi(MOVE_RIGHT);
        sleep(1);
	      break;
	    case 't' :
	      envoi(MOVE_STOP);
        sleep(1);
	      break;
	    default :
	      printf("Commande invalide ! Retaper :\n");
	      break;
	    }
        
        sleep(1);
}

  return 0;
}