Présentation du travail effectivement réalisé

1) Présentation
2) La modification du firmware
3) La création du Report Descriptor
Les liens utiles

Cette page a été réalisée, en avril 2003, par 3 élèves de 2ème année de SUPÉLEC Campus de Rennes dans le cadre de leur projet :
  • Fabien CHEVALIER
  • Sylvain RICHERIOUX
  • Nicolas SINÈGRE

  • 1) Présentation du problème

    Rappelons que notre projet consiste en la réalisation d'un dispositif de commande de PC à distance, par télécommande standard, le tout en utilisant un microcontrôleur PIC 16C765 de Microchip. Pour les motivés, la datasheet de la bête est téléchargable sur le site du constructeur http://www.microchip.com ou directement ici.
    Comme l'impléméntation complète du protocole USB est très complexe, nous avons utilisé le firmware (zip) fourni par Microchip pour ce PIC. Il s'agit en fait d'un ensemble de programmes déjà écrits et qui permettent de pouvoir utiliser rapidement la puce.

    Néanmoins, il a fallu faire quelques petites adaptations (zip) sur ce firmware, notamment pour que l'on puisse transmettre des données au PIC, et bien entendu, créer un Report Descriptor qui correspondait à nos besoins.
    A ceux pour lesquels l'expression de Report Desriptor donne des frissons, nous ne saurions que conseiller de consulter les documents traitant de la spécification HID.

    Dans la suite de cette page, nous allons exposer les modifications que nous avons entreprises pour que vous puissiez à votre tour réaliser une application USB avec ce joli jouet qu'est le PIC 16C765.


    2) La modification du firmware

    Comme expliqué préalablement, le firmware fourni par Microchip est très complet, mais il nous manquait une petite fonctionnalité que nous avons rajoutée. Cependant, il ne faut pas croire que toutes les fonctions USB sont réalisées par la partie logicielle. Au contraire, une grande partie du travail est opérée directement par l'électronique du PIC, ce qui peut expliquer son prix.

    Nous avons réalisé un organigramme pour expliquer les grandes lignes du fonctionnment de l'USB avec un PIC. Pour plus de précisions, il faudra se reporter à la Documentation du PIC, ou directement au firmware si vous maîtrisez l'assembleur Microchip.

    En effet, le firmware permettait de recevoir des données venant de l'hôte et à destination du périphérique, mais pas de les stocker pour les utiliser dans le cadre d'un programme. C'est là la seule modification du code que nous avons effectuée. Pour les amateurs d'assembleur, il est toujours possible de regarder le code, en téléchargeant le firmware et les modifications (zip).
    Remarque : Dans la mesure où l'implémentation de l'USB chez Microchip est récente, il est souhaitable de regarder de temps en temps si une nouvelle version du firmware est disponible (attention à la version des puces !!).


    3) La création du Report Descriptor

    Cette partie n'étant pas complètement triviale, il est vivement conseillé de maîtriser l'HID avant de se lancer !

    Nous avons créé un nouveau report conforme aux normes HID représentant les données qui vont s'échanger entre le PC et le périphérique USB. En effet, l'utilisation de l'HID facilite beaucoup les choses, puisque nous avons pu établir notre prope formatage des données échangées.

    En effet, il est essentiel pour notre application, que le PIC puisse être configuré par le PC (nombre d'échantillons, délais divers, ...), mais aussi et surtout qu'il renvoie des informations (qui sont les données utiles, traitées par un logiciel en Delphi) vers le PC. Pour ceux qui se souviennent de la spécification HID, cela signifie que il a fallu écrire un Report Descriptor qui autorise les Inputs et les Features (les Inputs pour l'émission du PIC vers le PC, les Features pour l'autre sens).

    La modification du Report Descriptor de la classe HID doit se faire dans le fichier descript.asm du firmware. Si l'un d'entre vous se jette à l'eau, il faut savoir que l'élaboration d'un Report Descriptor qui soit à la fois reconnu par le driver générique HID et qui réalise ce qu'on veut qu'il fasse est une opération longue... Bonne chance !


    Nous sommes donc arrivés au code suivant :
     

    ReportDescriptor

    ........retlw 0x05
    ........retlw 0xFD ; usage page (FD)
    ........retlw 0x09
    ........retlw 0xEF ; usage (EF)

    ........retlw 0xA1
    ........retlw 0x01 ; collection (01)

    ................retlw 0x05
    ................retlw 0xFE ;
    usage page (FE)
    ................retlw 0x09
    ................retlw 0xF0 ;
    usage (F0)

    ................retlw 0xA1
    ................retlw 0x02 ;
    collection (02)

    .......................retlw 0x05
    .......................retlw 0xFE ;
    usage page (FE)
    .......................retlw 0x09
    .......................retlw 0xF2 ;
    usage (F2)
    .......................retlw 0x15
    .......................retlw 0x00 ; logical minimum (0)
    .......................retlw 0x25
    .......................retlw 0x07 ; logical maximum (7)
    .......................retlw 0x95
    .......................retlw 0x01 ; report count (1)
    .......................retlw 0x75
    .......................retlw 0x08 ; report size (8)
    .......................retlw 0x81
    .......................retlw 0x02 ; input (8 bits) Paquet ID

    .......................retlw 0x05
    .......................retlw 0xFE ; usage page (FE)
    .......................retlw 0x19
    .......................retlw 0xF3 ; usage minimum (F3)
    .......................retlw 0x29
    .......................retlw 0xF9 ; usage maximum (F9)
    .......................retlw 0x15
    .......................retlw 0x00 ; logical minimum (0)
    .......................retlw 0x25
    .......................retlw 0xFF ; logical maximum (255)
    .......................retlw 0x95
    .......................retlw 0x07 ; report count (7)
    .......................retlw 0x75
    .......................retlw 0x08 ; report size (8)
    .......................retlw 0x82
    .......................retlw 0x02
    .......................retlw 0x01 ; input (7 buffer byte) Données

    ................retlw 0xC0 ; end collection

    ................retlw 0x05
    ................retlw 0xFF ; usage page (FF)
    ................retlw 0x09
    ................retlw 0xF1 ; usage (F1)

    ................retlw 0xA1
    ................retlw 0x02 ; collection (02)

    .......................retlw 0x05 ; Mode d'échantillonnage
    .......................retlw 0xFF ; usage page (FF)
    .......................retlw 0x09
    .......................retlw 0xFA ; usage (FA)
    .......................retlw 0x15
    .......................retlw 0x00 ; logical minimum (0)
    .......................retlw 0x25
    .......................retlw 0x01 ; logical maximum (1)
    .......................retlw 0x95
    .......................retlw 0x01 ; report count (1)
    .......................retlw 0x75
    .......................retlw 0x01 ; report size (1)
    .......................retlw 0xB1
    .......................retlw 0x02 ; feature (1 bit)

    .......................retlw 0x05 ; Partie constante
    .......................retlw 0xFF ; usage page (FF)
    .......................retlw 0x09
    .......................retlw 0xFB ; usage (FB)
    .......................retlw 0x95
    .......................retlw 0x04 ; report count (4)
    .......................retlw 0x75
    .......................retlw 0x01 ; report size (1)
    .......................retlw 0xB1
    .......................retlw 0x01 ; feature (4 bits)

    .......................retlw 0x05 ; Partie préscal
    .......................retlw 0xFF ; usage page (FF)
    .......................retlw 0x09
    .......................retlw 0xFC ; usage (FC)
    .......................retlw 0x15
    .......................retlw 0x00 ; logical minimum (0)
    .......................retlw 0x25
    .......................retlw 0x07 ; logical maximum (7)
    .......................retlw 0x95
    .......................retlw 0x01 ; report count (1)
    .......................retlw 0x75
    .......................retlw 0x03 ; report size (3)
    .......................retlw 0xB1
    .......................retlw 0x02 ; feature (3 bits)

    .......................retlw 0x05 ; Reset timer0
    .......................retlw 0xFF ; usage page (FF)
    .......................retlw 0x09
    .......................retlw 0xFD ; usage (FD)
    .......................retlw 0x15
    .......................retlw 0x00 ; logical minimum (0)
    .......................retlw 0x25
    .......................retlw 0xFF ; logical maximum (255)
    .......................retlw 0x95
    .......................retlw 0x01 ; report count (1)
    .......................retlw 0x75
    .......................retlw 0x08 ; report size (8)
    .......................retlw 0xB1
    .......................retlw 0x02 ; feature (8 bits)

    .......................retlw 0x05 ; Nb éch wait
    .......................retlw 0xFF ; usage page (FF)
    .......................retlw 0x09
    .......................retlw 0xFE ; usage (FE)
    .......................retlw 0x15
    .......................retlw 0x00 ; logical minimum (0)
    .......................retlw 0x26
    .......................retlw 0xFF
    .......................retlw 0xFF ; logical maximum (65535)
    .......................retlw 0x95
    .......................retlw 0x01 ; report count (1)
    .......................retlw 0x75
    .......................retlw 0x10 ; report size (16)
    .......................retlw 0xB1
    .......................retlw 0x02 ; feature (16 bits)

    .......................retlw 0x05 ; Nb éch sampling
    .......................retlw 0xFF ; usage page (FF)
    .......................retlw 0x09
    .......................retlw 0xFF ; usage (FF)
    .......................retlw 0x15
    .......................retlw 0x00 ; logical minimum (0)
    .......................retlw 0x26
    .......................retlw 0xC0
    .......................retlw 0x01 ; logical maximum (448)
    .......................retlw 0x95
    .......................retlw 0x01 ; report count (1)
    .......................retlw 0x75
    .......................retlw 0x10 ; report size (16)
    .......................retlw 0xB1
    .......................retlw 0x02 ; feature (16 bits)

    ................retlw 0xC0 ; end collection

    ........retlw 0xC0 ; end collection

    end_ReportDescriptor

    Ce Report Descriptor est long, mais finalement assez simple quand on a compris la philosophie de la spécification HID. Il ne faut pas s'inquiéter de l'aspect barbare de l'héxadécimal... c'est simplement pour la programmation du PIC. La traduction est faite en bleu à côté. La correspondance entre les symboles (collection, end collection, usage, ...) et l'héxadécimal est précisée dans la spécification HID.

    On peut détailler un petit peu ce Report Descriptor. En fait, nous définissons des Inputs, formés de 8 octects, dont le premier sert à spécifier l'identifiant de la trame (nous avons pris 8 octets car c'est la longueur maximale d'une trame USB). Ces 8 octets constituent les données transitant du PIC vers le PC. Si certains veulent savoir pourquoi nous avons mis en place ce système de 8 octects, ils peuvent se référer à notre rapport de projet.
    D'autre part, nous avons défini des Features, formés de 6 octects.

    Nous pensons que l'organigramme suivant va mieux vous permettre de mettre en relation le Report Descriptor avec les données échangées. Vous pouvez soit accepter notre format de données tel quel, soit vous reporter au rapport de projet si vous êtes plus courageux(se).


    Voila pour ce qui est du Report Descriptor que nous avons réalisé.

    Nous espérons que vous aurez mieux compris la psychologie de la spécification HID, et que vous pourrez, quand vous aurez besoin de développer un périphérique USB, vous reporter à cette page pour avoir des renseignements précis.


    Les liens utiles

    La spécification HID (pdf)

    Le site de Microchip : http://www.microchip.com

    La Datasheet du PIC 16C765

    Le Firmware original de Microchip

    Les fichiers du Firmware que nous avons modifiés

    Notre rapport intermediaire de projet (pdf)


    Retour vers la page de la documentation USB-HID Retour vers les autres docs