Blame view

USB/usb_driver.c 10.4 KB
bcd81fea   dmohamed   UPDATE-AJout des ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
  #include <libusb-1.0/libusb.h> //bibliothèque USB
  #include <stdio.h>
  #include <stdlib.h>
  #include <termios.h>
  #include <fcntl.h>
  #include <strings.h>
  #include <unistd.h>
  
  
  libusb_device **list;
  libusb_device_handle *handle = NULL;
  libusb_device *device;
  struct termios termios_p;
  
  
  int init_serial(char *device,int speed) //Initialisation du port série
  {
  int fd=open(device,O_RDWR);
  if(fd<0){perror(device); exit(-1);}
  //Lecture des parametres courants
  tcgetattr(fd,&termios_p);
  //On ignore les BREAK et les caracteres avec erreurs de parite
  termios_p.c_iflag = IGNBRK | IGNPAR;
  //Pas de mode de sortie particulier
  termios_p.c_oflag = 0;
  //Liaison a 9600 bps avec 7 bits de donnees et une parite paire
  termios_p.c_cflag = B9600 | CS7 | PARENB;
  //Mode non-canonique avec echo
  termios_p.c_lflag = ECHO;
  //Caracteres immediatement disponibles
  termios_p.c_cc[VMIN] = 1;
  termios_p.c_cc[VTIME] = 0;
  //Sauvegarde des nouveaux parametres
  tcsetattr(fd,TCSANOW,&termios_p);
  return fd;
  }
  
  
  void close_serial(int fd) //Fermeture du port série
  {
  tcsetattr(fd,TCSANOW,&termios_p);
  close(fd);
  }
  
  
  void callback(struct libusb_transfer *transf) //Fonction pour le transfert des instructions à la tourelle
  {
    libusb_fill_control_setup(transf->buffer, 0xa1, 0x01, 0x300, 0x00, 0);
    libusb_fill_control_transfer(transf, transf->dev_handle, transf->buffer, NULL, NULL, 1000);
    fflush(stdout);
    libusb_free_transfer(transf); //on libere la structure de transfert 
  }  
  
  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;
    
    //Probleme noyau
    for(i=0;i<(config->bNumInterfaces);i++)
      {
        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;
    printf("%d\n", configuration);
  /*
    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);
    printf("Device Found @ (Bus:Address) %d:%d\n",bus,address);
    printf("Vendor ID 0x0%x\n",desc.idVendor);
    printf("Product ID 0x0%x\n",desc.idProduct);
  
    if ((desc.idVendor==0x0010) && (desc.idProduct==0x1010)) //si la tourelle est trouvee parmis les peripheriques USB, on lance sa configuration
      {
        printf("Tourelle trouvée !\n");
        t=1;
        configuration_periph(device);
      }
    }
    if(t==0) printf("Tourelle non connectée !\n");
  }
  
  
  void tir(libusb_device_handle *handle) //On fait appel à cette fonction quand on désire tirer dans la fonction commande
  {
    unsigned char tab[13];
    struct libusb_transfer *transf;
    
    //1ère requête
    transf = libusb_alloc_transfer(0);
    libusb_fill_control_setup(tab, 0x21, 0x09, 0x300, 0x00, 13);
    tab[12] = 0x5e;
    tab[11] = 0x00;
    tab[10] = 0x00;
    tab[8] = 0x00;
    tab[9] = 0x00;
  
    //Structure de transfert
    libusb_fill_control_transfer(transf, handle, tab, callback, NULL, 0);
    //Envoi sur le port serie
    libusb_submit_transfer(transf);
    
    //2ème requête
    transf = libusb_alloc_transfer(0);
    libusb_fill_control_setup(tab, 0x21, 0x09, 0x300, 0x00, 13);
    tab[12] = 0x5c;
    tab[11] = 0x00;
    tab[10] = 0x00;
    tab[8] = 0x00;
    tab[9] = 0x00;
    
    //Structure de transfert
    libusb_fill_control_transfer(transf, handle, tab, callback, NULL, 0);
    //Envoi sur le port serie
    libusb_submit_transfer(transf);
  
    //Tir
    transf = libusb_alloc_transfer(0);
    libusb_fill_control_setup(tab, 0x21, 0x09, 0x300, 0x00, 13);
    tab[12] = 0xfe;
    tab[11] = 0xff;
    tab[10] = 0xe0;
    tab[8] = 0x5f;
    tab[9] = 0x10;
  
    //Structure de transfert
    libusb_fill_control_transfer(transf, handle, tab, callback, NULL, 0);
    //Envoi sur le port serie
    libusb_submit_transfer(transf);
  }
  
  
  void commande(char action, libusb_device_handle *handle) //Cette fonction permet de commander les déplacements et tirs de la tourelle
  {
    char cmd;
    
    //Declaration de la structure d'envoi pour les données de la requette
    struct libusb_transfer *transf;
    unsigned char tab[13];
    transf = libusb_alloc_transfer(0);
  
    //Paramètres des requêtes
    libusb_fill_control_setup(tab, 0x21, 0x09, 0x300, 0x00, 13);
    
    switch(action)
      {
      case 'g': //déplacement à gauche
        cmd=0x04;
        break;
      case 'd': //déplacement à droite
        cmd=0x08;
        break;
      case 'h': //déplacement en haut
        cmd=0x02;
        break;
      case 'b': //déplacement en bas
        cmd=0x01;
        break;
      case 'a': //arrêt
        cmd=0x00;
        break;
      case 't': //tir
        cmd=0x10;
        break;
      default :
        printf("Commande invalide\n");
        break;
      }
  
    if(cmd==0x10)//Si l'on veut tirer
      {
        tir(handle); //Les requêtes sont différentes pour la commande de tir (voir la fonction dédiée)
      }
    else
      {
        //Données de la requette à envoyer à la tourelle pour les mouvements. tab[9] correspond à l'action à effectuer (gauche, droite, haut, bas ou arrêt)
        tab[12] = 0xfe;
        tab[11] = 0xff;
        tab[10] = 0xe0;
        tab[8] = 0x5f;
        tab[9] = cmd;
     
        //Structure de transfert
        libusb_fill_control_transfer(transf, handle, tab, callback, NULL, 0);
        //Envoi sur le port serie
        libusb_submit_transfer(transf);
      }     
  }
   
       
  int main()
  {
     //Initialisation de la bibliotheque libusb
    libusb_context *context;
    
    int status=libusb_init(&context);
    if(status!=0)
      {
        perror("libusb_init"); exit(-1);
      }
  
    enumeration(context); //Enumération des périphériques USB. Si la tourelle est trouvée, cette fonction fait appel à la fonction configuration_periph qui va configurer la tourelle.
  
    //Initialisation du port serie
    char *device="/dev/ttyACM0";
    int fd=init_serial(device,B9600); //Vitesse 9600 bauds
    printf("port init\n");
  
  
  //close_serial(fd);
    //Menu de commande
    char action, choix;
    printf("\nPilotage de la tourelle\n");
    printf("------------------------\n");
    printf("Taper 0 pour piloter la tourelle au clavier ou 1 pour la piloter avec l'arduino : ");
    scanf("%c",&choix);
  
    if(choix=='0')
      {
        printf("\nPilotage au clavier\n");
        printf("Taper d pour droite, g pour gauche, h pour haut, b pour bas, t pour tirer, s pour sortir du programme :\n");
      }
    if(choix=='1')
      {
        printf("\nPilotage avec l'arduino\n");
        printf("Pour diriger la tourelle, utiliser le joystick, pour tirer appuyer dessus et pour sortir du programme appuyer sur D3.\n");
      }
  
    for(;;) //Boucle dxécution
      { 
        if(choix=='0') //Pilotage au clavier
  	{
  	  while(getchar() != '\n');
  	  scanf("%c",&action);
  	  switch (action)
  	    {
  	    case 's':
  	      fermeture(handle);
  	      close_serial(fd);
  	      libusb_free_device_list(list,1);
  	      libusb_exit(context);
  	      return 0;
  	      break;
  	    case 'd':
  	      commande(action, handle);
  	      sleep(1);
  	      commande('a',handle);
  	      break;
  	    case 'g':
  	      commande(action, handle);
  	      sleep(1);
  	      commande('a',handle);
  	      break;
  	    case 'h':
  	      commande(action, handle);
  	      sleep(1);
  	      commande('a',handle);
  	      break;
  	    case 'b':
  	      commande(action, handle);
  	      sleep(1);
  	      commande('a',handle);
  	      break;
  	    case 't' :
  	      commande(action, handle);
  	      sleep(1);
  	      commande('a',handle);
  	      commande(action, handle);
  	      sleep(1);
  	      commande('a',handle);
  	      commande(action, handle);
  	      sleep(1);
  	      commande('a',handle); 
  	      break;
  	    default :
  	      printf("Commande invalide ! Retaper :\n");
  	      break;
  	    }
  	}
  
        if(choix=='1') //Pilotage avec l'arduino
  	{
  	  read(fd,&action,1); //On lit sur le port série
  	  printf("%c\n",action);
  	  write(fd,"o",1); //On envoie le caractère 'o' sur le port série en réponse
  	  commande(action,handle); //Permet de déplacer la tourelle ou d'arreter ses mouvements selon le caractère reçu (d,g,b,h ou a)
  	  if(action=='t') //Si l'on reçoit l'ordre de tirer
  	    {
  	      commande(action, handle);
  	      sleep(1);
  	      commande('a',handle);
  	      commande(action, handle);
  	      sleep(1);
  	      commande('a',handle);
  	      commande(action, handle);
  	      sleep(1);
  	      commande('a',handle);
  	    }
  	  if(action=='s') //Si l'on reçoit le caractère 's' on ferme le programme
  	    {
  	      fermeture(handle);
  	      close_serial(fd);
  	      libusb_free_device_list(list,1);
  	      libusb_exit(context);
  	      return 0;
  	    }
  	      
      	}
      
      } 
  
    return 0;
  }