## 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.
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 :
- 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 :
- 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
Aucun commentaire pour le moment.