Le clavier et l'USB
Le clavier de la Neo6502kbd est un clavier USB, derrière un hub. Pour le lire, et pour lire la clé, Eliott65 a son propre pilote USB, écrit directement sur les registres du RP2040.
Dans cette page
Un pilote écrit pour le projet
Le pilote parle directement au contrôleur USB du RP2040, avec les seules définitions de registres du pico-sdk. Il sait :
- faire les transactions de base (SETUP, IN, OUT) et les transferts de contrôle ;
- énumérer les appareils, c’est-à-dire les découvrir et leur donner une adresse ;
- gérer le hub : alimenter les ports, les réinitialiser, les surveiller ;
- lire un clavier en mode « boot », le mode simple que tout clavier USB comprend ;
- parler à une clé USB (stockage de masse).
Il tient compte d’un défaut connu du RP2040 (l’errata RP2040-E4) et du paquet PRE qu’exigent les appareils lents placés derrière un hub rapide.
Le clavier « zéro appel »
Le clavier est interrogé par le contrôleur USB lui-même, toutes les 10 ms : le cœur 0 n’a qu’à relever le résultat.
Côté 6502, Eliott65 va plus loin : le programme déclare une file de 18 octets dans sa propre mémoire. Le noyau y dépose les caractères tapés, la donnée d’abord, l’index ensuite. Pour savoir si une touche attend, le programme compare deux octets, sans aucun appel système.
La conversion des touches gère les dispositions US (QWERTY) et FR (AZERTY), les combinaisons Ctrl+A à Ctrl+Z, les flèches, et ignore les répétitions parasites. Le clavier de la carte est en QWERTY : c’est la disposition par défaut.
Premier branchement
| Où | Appareil | Résultat |
|---|---|---|
| carte | hub FE1.1s, 4 ports | énuméré |
| port 1 | clavier, Low Speed | actif : dix touches tapées, dix reçues |
| port 4 | souris, Low Speed | énumérée (pas encore exploitée) |
| port 3 | clé USB, Full Speed | échec |
L’appareil qui ne répondait pas
La clé acceptait la première étape de la requête, puis la suivante expirait au bout de 50 ms, même après trois essais. Les appareils lents passaient ; seuls les appareils rapides derrière le hub échouaient. On pense à un défaut matériel.
Le diagnostic a montré autre chose : aucune erreur de ligne, seulement des réponses « pas encore prête ». La cause était le délai de 50 ms, choisi parce qu’il semblait raisonnable. Or la norme USB accorde jusqu’à 500 ms à un appareil pour répondre à certaines requêtes, et une clé en a besoin juste après sa réinitialisation. Avec le délai de la norme, la clé s’énumère.
La clé USB
Une clé parle le protocole Bulk-Only et des commandes SCSI : un bloc de commande de 31 octets, les données par paquets de 64 octets, un bloc de statut de 13 octets. Le pilote gère les blocages (STALL) et les incohérences en réinitialisant le transport.
La clé de test répond « General USB Flash Disk », 15 669 248 blocs de 512 octets (7,5 Gio).
Le service STOCKAGE lit et écrit un bloc directement à l’adresse choisie dans la mémoire de la 6502, sans copie intermédiaire. Premier essai : le bloc 0 est lu, sa signature est juste et la première partition est bien en FAT32.
Écrire sur la clé de quelqu’un
L’écriture a d’abord été testée sur un faux disque en mémoire, pas sur la clé : elle pouvait contenir des données. Avec l’accord de son propriétaire, l’essai réel a visé le dernier bloc de la clé : lecture et sauvegarde, écriture d’un motif, relecture, restauration, relecture.
Surprise : ce bloc « en fin de clé » n’était pas vide (489 octets non nuls). La sauvegarde n’était pas une précaution de trop.
Plus vite : plusieurs blocs par commande, FAT différée
Mesure de départ : écrire 64 Kio prenait 1,6 s. Deux changements :
- des commandes de plusieurs blocs (jusqu’à 128 par commande) ;
- une FAT en écriture différée : la table d’allocation n’est plus réécrite à chaque cluster, mais une fois par secteur modifié, en fin d’opération.
Le vrai coupable était le second : une centaine de petites écritures de 512 octets, à environ 14 ms chacune sur cette clé.
| 64 Kio | Avant | Après |
|---|---|---|
| écriture | 1,6 s | 0,238 s (275 Kio/s, × 6,7) |
| lecture après réécriture | 1,9 s | 0,357 s (184 Kio/s, × 5,3) |
Résister aux erreurs passagères
Le banc USB de l’émulateur a révélé un défaut : un seul blocage pendant la lecture du shell suffisait à l’empêcher de démarrer, sans message. Désormais chaque lecture ou écriture est réessayée trois fois ; une vraie panne est rendue au noyau sans blocage.
Brancher et débrancher
Le pilote scrute les ports du hub chaque seconde. Une clé ou un clavier retiré puis rebranché est oublié, réénuméré, et le système de fichiers est remonté. Dans l’émulateur, on a même arraché la clé pendant une écriture, à de nombreux instants différents (balayés par pas de 2 500 cycles) : le programme reçoit une erreur, et la FAT reste saine ou n’a que des dégâts bénins. Voir Les fichiers.