Retour à l'accueil

Contrôleur USB 1.0 sur SpinalHDL : Implémentation

L'article décrit l'implémentation d'un contrôleur hôte USB 1.0 sur SpinalHDL pour SoC RISC-V. Couvre la couche physique, le protocole, les descripteurs HID, la FSM matérielle et le pilote. Exemples de tests avec clavier, souris, manette.

SpinalHDL USB 1.0 : du protocole au FPGA
Advertisement 728x90

## Implémentation d'un contrôleur hôte USB 1.0 en SpinalHDL pour SoC RISC-V

Le développement d'un système sur puce synthétisable basé sur RISC-V nécessite l'intégration d'interfaces périphériques modernes. Un contrôleur hôte USB 1.0 permet de connecter des dispositifs d'entrée HID : claviers, souris, manettes de jeu. Son implémentation en SpinalHDL fournit une gestion matérielle du protocole sans les compromis logiciels du PS/2 ou des joysticks analogiques.

La couche physique USB utilise une paire différentielle D+ et D-, ainsi que les lignes VBUS et GND. Le mode de transmission half-duplex distingue l'USB de l'UART : les données sont envoyées bit par bit dans une seule direction à la fois, avec une séparation stricte des rôles hôte et périphérique.

Couche physique USB 1.0

Les caractéristiques électriques définissent les niveaux de signal : l'état au repos sur D+ et D- détermine la vitesse. Low-speed (1,5 Mbit/s) — D- haut, full-speed (12 Mbit/s) — D+ haut. Codage NRZI : une transition de signal code « 1 », l'absence code « 0 ». Synchronisation via bit stuffing : un bit inversé est inséré après six bits identiques.

Google AdInline article slot

Signaux de contrôle :

  • SE0 (Single Ended Zero) : D+/D- bas — pour le reset du bus.
  • États J/K : niveaux différentiels pour l'état au repos et la vitesse.
  • Chirp : échange K/J pour détecter la vitesse du hub.

La transmission commence par SYNC (8 bits « 0 »), suivi du PID (Packet ID).

Protocole USB : Paquets et Transactions

Le PID définit le type de paquet :

Google AdInline article slot
  • Tokens : SETUP (requêtes de contrôle), IN (lecture), OUT (écriture), SOF (début de trame).
  • Data : DATA0/1 (bits de basculement pour l'intégrité).
  • Handshake : ACK (accusé de réception), NAK (rejet), STALL (erreur).

Transactions :

  • Transfert de contrôle : SETUP + DATA (optionnel) + IN/OUT + ACK.
  • Transfert interrupt : IN/OUT + DATA + ACK — pour les rapports HID.
  • Transfert bloc : gros blocs, avec retry.
  • Isochrone : sans handshake, pour les flux.

Sommes de contrôle : CRC5 pour les tokens, CRC16 pour les données. Formules :

// CRC5 for address/kontsa
crc5_next = crc5_reg ^ data_in;
// Polinom: x^5 + x^2 + 1 (0b001101)

Descripteurs et Initialisation du Périphérique

Les descripteurs décrivent le périphérique :

Google AdInline article slot
  • Device Descriptor : bLength=18, bDescriptorType=1, idVendor, idProduct.
  • Configuration Descriptor : bConfigurationValue, maxPower.
  • Interface/Endpoint : bInterfaceClass (HID=3), bEndpointAddress, bmAttributes (interrupt).
  • HID Descriptor : bcdHID, bCountryCode, Report Descriptor.

Initialisation :

  • Reset du bus (SE0 >10 µs).
  • GET_DESCRIPTOR (Device).
  • SET_ADDRESS.
  • GET_DESCRIPTOR (Configuration).
  • SET_CONFIGURATION.

Pour HID, ajouter GET_DESCRIPTOR (Report). Exemple de rapport clavier : octet modificateur + réservé + 6 codes de touches.

Implémentation matérielle en SpinalHDL

Le contrôleur est construit comme une hiérarchie de machines à états finis :

  • USBMain : FSM principale, gère la séquence.
  • USBSendSE0 : génération de SE0 pour le reset.
  • USBSendShortToken : tokens courts (SOF).
  • USBSendLongToken : tokens complets (addr+endp).
  • USBSendData : codage NRZI + bit stuffing.
  • USBReceiver : décodage NRZI, vérification CRC.

Interfaces :

import spinal.core._
case class USB_IO() extends Bundle {
  val dpp = in Bool()
  val dpn = in Bool()
  val txen = out Bool()
  val txdp = out Bool()
  val txdn = out Bool()
}

Apb3USB10Ctrl s'intègre dans le SoC via APB3. Horloges : 48 MHz pour full-speed.

Intégration dans KarnixSoC et Pilote

Connexion : USB Type A sur la carte Karna, signaux routés depuis le FPGA. La configuration SpinalHDL ajoute le module au niveau supérieur.

Pilote C pour RISC-V :

  • usb10_bus_reset() : SE0 pendant 20 µs.
  • usb10_in_request() : token IN + DATA1 + ACK.
  • usb10_setup_request() : SETUP + DATA + IN.

Initialisation : usb10_init() détecte le périphérique, lit les descripteurs, définit l'adresse.

Tests avec des périphériques HID

Application karnix_usb10_test :

  • Manette de jeu : axes analogiques, boutons dans l'endpoint interrupt 1.
  • Souris : delta X/Y, boutons dans des rapports de 4 octets.
  • Clavier : protocole boot, rapports de 8 octets (modificateurs + touches).

Intégration dans TetRISC-V : remplacement du PS/2 par entrée USB.

Points clés :

  • USB 1.0 full-speed (12 Mbit/s) implémenté avec FSM sans MACRO-IP.
  • SpinalHDL génère du RTL pour la synthèse FPGA.
  • Protocole boot HID simplifie les pilotes pour clavier/souris.
  • NRZI + bit stuffing nécessitent un timing précis (clk 48 MHz).
  • Vérification CRC5/16 prévient les erreurs de paquets.

— Editorial Team

Advertisement 728x90

Lire ensuite