Sources d'Avr Hid Usb

Il faut la lib UsbKeyboard en plus de celui ci, mais c'est la que tout se passe

#include <avr/pgmspace.h>
#include "usbdrv.h"

/*** Definition de la correspondance touche/code usb (cf usb.org) ***/
#define MOD_CONTROL_LEFT    (1<<0)
#define MOD_SHIFT_LEFT      (1<<1)
#define MOD_ALT_LEFT        (1<<2)
#define MOD_GUI_LEFT        (1<<3)
#define MOD_CONTROL_RIGHT   (1<<4)
#define MOD_SHIFT_RIGHT     (1<<5)
#define MOD_ALT_RIGHT       (1<<6)
#define MOD_GUI_RIGHT       (1<<7)

#define KEY_A       4
#define KEY_B       5
#define KEY_C       6
#define KEY_D       7
#define KEY_E       8
#define KEY_F       9
#define KEY_G       10
#define KEY_H       11
#define KEY_I       12
#define KEY_J       13
#define KEY_K       14
#define KEY_L       15
#define KEY_M       16
#define KEY_N       17
#define KEY_O       18
#define KEY_P       19
#define KEY_Q       20
#define KEY_R       21
#define KEY_S       22
#define KEY_T       23
#define KEY_U       24
#define KEY_V       25
#define KEY_W       26
#define KEY_X       27
#define KEY_Y       28
#define KEY_Z       29
#define KEY_1       30
#define KEY_2       31
#define KEY_3       32
#define KEY_4       33
#define KEY_5       34
#define KEY_6       35
#define KEY_7       36
#define KEY_8       37
#define KEY_9       38
#define KEY_0       39

#define KEY_ENTER   40

#define KEY_SPACE   44

#define KEY_F1      58
#define KEY_F2      59
#define KEY_F3      60
#define KEY_F4      61
#define KEY_F5      62
#define KEY_F6      63
#define KEY_F7      64
#define KEY_F8      65
#define KEY_F9      66
#define KEY_F10     67
#define KEY_F11     68
#define KEY_F12     69

#define KEY_ARROW_LEFT 0x50
#define KEY_ARROW_UP 0x52


/*** Definition des pins de branchement des touches sur l'arduino ***/
#define BTN1 7
#define BTN2 8
#define BTN3 9
#define BTN4 10
#define BTN5 11
#define BTN6 12

/*** Correspondance touche physique / touche envoyé ***/
#define BTN_KEY_1 KEY_ARROW_UP
#define BTN_KEY_2 KEY_E
#define BTN_KEY_3 KEY_D
#define BTN_KEY_4 KEY_C
#define BTN_KEY_5 KEY_B
#define BTN_KEY_6 KEY_Q



#define BUFFER_SIZE 7 // Minimum 2: 1 pour "modifiers" + 1 pour la touche 

/*** Descripteur HID (cf http://www.usb.org/developers/hidpage/) ***/
PROGMEM char usbHidReportDescriptor[35] = { /* USB report descriptor */
  0x05, 0x01,                    // USAGE_PAGE (Generic Desktop) 
  0x09, 0x06,                    // USAGE (Keyboard) 
  0xa1, 0x01,                    // COLLECTION (Application) 
  0x05, 0x07,                    //   USAGE_PAGE (Keyboard) 
  0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl) 
  0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI) 
  0x15, 0x00,                    //   LOGICAL_MINIMUM (0) 
  0x25, 0x01,                    //   LOGICAL_MAXIMUM (1) 
  0x75, 0x01,                    //   REPORT_SIZE (1) 
  0x95, 0x08,                    //   REPORT_COUNT (8) 
  0x81, 0x02,                    //   INPUT (Data,Var,Abs) 
  0x95, BUFFER_SIZE-1,           //   REPORT_COUNT (simultaneous keystrokess) 
  0x75, 0x08,                    //   REPORT_SIZE (8) 
  0x25, 0x65,                    //   LOGICAL_MAXIMUM (101) 
  0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated)) 
  0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application) 
  0x81, 0x00,                    //   INPUT (Data,Ary,Abs) 
  0xc0                           // END_COLLECTION 
};


// Tableau qui contient les touches enfoncées
byte keystrokes[(BUFFER_SIZE-1)];
// Tableau qui contient les touches enfoncées précédemment
byte previouskeystrokes[(BUFFER_SIZE-1)];

uchar   key, lastKey = 0, keyDidChange = 0;
uchar   idleCounter = 0;
boolean key_pressed=false;
static uchar    idleRate;           // in 4 ms units 

// Buffer des touches à envoyer
static uchar    reportBuffer[BUFFER_SIZE];

// fonction utile pour avr-usb
#ifdef __cplusplus
extern "C"{
#endif 
  // USB_PUBLIC uchar usbFunctionSetup
uchar usbFunctionSetup(uchar data[8]) {
    usbRequest_t    *rq = (usbRequest_t *)((void *)data);
    
    usbMsgPtr = reportBuffer;
    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){
    /* class request type */
    
    if(rq->bRequest == USBRQ_HID_GET_REPORT){
    /* wValue: ReportType (highbyte), ReportID (lowbyte) */
    
    /* we only have one report type, so don't look at wValue */
        // TODO: Ensure it's okay not to return anything here?    
    return 0;
    
      }else if(rq->bRequest == USBRQ_HID_GET_IDLE){
    //            usbMsgPtr = &idleRate;
    //            return 1;
    return 0;
      }else if(rq->bRequest == USBRQ_HID_SET_IDLE){
    idleRate = rq->wValue.bytes[1];
      }
    }else{
      /* no vendor specific requests implemented */
    }
    return 0;
  }
#ifdef __cplusplus
} // extern "C"
#endif



void setup() {
  // Reset des ports usb
  PORTD = 0;
  DDRD |= ~USBMASK;
  usbInit();
  sei(); // activation des interruptions
    
  memset(reportBuffer, 0, sizeof(reportBuffer));      
  usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
  
  // input des boutons, les boutons sont a l'etat haut par defaut, il faut les mettres a la masse pour les actives
  pinMode(BTN1, INPUT);
  digitalWrite(BTN1, HIGH);
  pinMode(BTN2, INPUT);
  digitalWrite(BTN2, HIGH);
  pinMode(BTN3, INPUT);
  digitalWrite(BTN3, HIGH);
  pinMode(BTN4, INPUT);
  digitalWrite(BTN4, HIGH);
  pinMode(BTN5, INPUT);
  digitalWrite(BTN5, HIGH);
  pinMode(BTN6, INPUT);
  digitalWrite(BTN6, HIGH);
  
}

// lit les touches et met les key dans le tableau keystrokes
static void lectureTouche() {
    // reset du tableau des touches
    memset(keystrokes, 0, sizeof(keystrokes));
    int pos=0;
    if (digitalRead(BTN1) == 0) {
     keystrokes[pos]=BTN_KEY_1;
     pos++;
  }
  if (digitalRead(BTN2) == 0) {
     keystrokes[pos]=BTN_KEY_2;
     pos++;
  }
  if (digitalRead(BTN3) == 0) {
     keystrokes[pos]=BTN_KEY_3;
     pos++;
  }
  if (digitalRead(BTN4) == 0) {
     keystrokes[pos]=BTN_KEY_4;
     pos++;
  }
  if (digitalRead(BTN5) == 0) {
     keystrokes[pos]=BTN_KEY_5;
     pos++;
  }
  if (digitalRead(BTN6) == 0) {
     keystrokes[pos]=BTN_KEY_6;
     pos++;
  }
}

// Envoyer le tableau des touches si il a ete modifie
static void envoyerTouche() {
    // verifier la taille du nouveau tableau et de l'ancien
    if (sizeof(keystrokes)==sizeof(previouskeystrokes)) {
         boolean identique=true;
         for (int i=0;i<sizeof(keystrokes);i++) {
             if (previouskeystrokes[i]!=keystrokes[i]) {
                  identique=false;
             }
         }
         if (identique) {
            // le tableau est inchange, ne rien envoyer
            return; 
         }
    }
    
    // reocpier le tableau actuel dans la mémoire pour la comparaison boucle suivante
    memset(previouskeystrokes, 0, sizeof(previouskeystrokes));
    for (int i=0;i<sizeof(keystrokes);i++) {
        previouskeystrokes[i]=keystrokes[i];
    }
    
    // Construction du tableau à envoyer
    memset(reportBuffer, 0, sizeof(reportBuffer));
    reportBuffer[0] = 0;
    int pos=1;
    for (int i=0;i<(BUFFER_SIZE-1);i++) {
        if (keystrokes[i]!=NULL) {
             reportBuffer[pos]=keystrokes[i];
         pos++;
        }
    }
    
    // Attente de 22ms (voir pourquoi)
    delay(22);
    
    // Envoi du tableau des touches
    usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
}

void loop() {

  // Synchro avec l'usb ?
  usbPoll();
  
  // Construction du tableau des touches utilisées
  lectureTouche();

  // Envoi du résultat
  envoyerTouche();
}