
Firmware RP2040 faisant le pont entre un microdrive SDIO Toshiba MK4001MTD 0,85" et un périphérique de stockage de masse USB, implémentant la pile de protocole SDIO-ATA complète à partir de zéro avec des lectures/écritures accélérées par PIO et la récupération des secteurs défectueux.
Micrologiciel pour RP2040 Pico qui fait le pont entre un microdrive Toshiba MK4001MTD 0,85" SDIO et un périphérique de stockage de masse USB.

Le MK4001MTD est un microdrive de 4 Go initialement utilisé dans le Nokia N91 (téléphone musical) et certains autres appareils, comme des lecteurs MP3 ou des clés USB, à une époque où le stockage flash était encore assez cher.
Vous avez peut-être vu des présentations affirmant que ce disque utilise le protocole MMC, mais c'est en fait incorrect. J'ai enquêté là-dessus un moment : j'ai essayé de construire un lecteur de carte MMCplus 8 bits et testé différents lecteurs SD/MMC sans succès. En dernier recours, j'ai acheté un Nokia N91 pour capturer des traces logiques et confirmer quel protocole il utilise réellement.
Voici la photo de ma tentative d'utilisation avec ma carte lecteur 8-bit-MMCPlus, et il s'avère que ce n'est pas du MMC :(

J'ai donc fini par obtenir un N91 pour collecter des traces :

Contrairement aux microdrives ATA/CF standard, il utilise une interface SDIO avec des commandes ATA tunnelisées via CMD52/CMD53. Aucun pilote existant ne prend en charge ce protocole, donc ce micrologiciel implémente la pile complète à partir de zéro.
Cela m'a surpris, car il existe une norme SDIO vers ATA appelée CE-ATA. Mais si l'on regarde attentivement la chronologie des versions, CE-ATA est arrivée après ce disque. Par conséquent, ce disque repose entièrement sur les commandes SDIO, et CE-ATA n'est pas disponible. CE-ATA a deux nouvelles commandes CMD60/CMD61 et utilise CMD12/39, mais on voit d'après les traces qu'il n'en utilise aucune.
Le second point matériel à mentionner est qu'une autre désinformation qui circule — affirmant qu'il s'agit d'une carte MMCPlus 8 bits — est non seulement fausse, mais en plus le brochage ne correspond pas non plus à la norme MMC. Vous pouvez trouver le manuel de service du Nokia N91 avec une documentation sur le brochage : bien que la numérotation des broches suive la norme MMCPlus, le mappage des broches ne la suit pas. C'est un détail important si vous câblez vous-même : il utilise le même connecteur MMC, mais le mappage des broches est différent, plus d'informations dans la section Matériel.
Enfin, notez que ce projet est co-développé avec Claude/OpenClaw. J'ai collecté les traces logiques manuellement et mis en place une station de test en boucle fermée pour qu'OpenClaw puisse itérer sur le développement — analyser les traces et implémenter les fonctionnalités. La documentation sera principalement rédigée par Claude ; j'ajouterai mes notes en ligne également. J'ai moi-même lu et vérifié la documentation, elle devrait être fiable et facile à suivre.
Pour des informations sur l'analyse de la trace N91, consultez /docs/N91_TRACE_ANALYSIS.md. J'ai également mis le manuel de service N91 ainsi que les traces logiques brutes.
Voir plus dans l'article de blog ici : https://www.willwhang.dev/Reading-MK4001MTD/
Voir en action ici : https://youtu.be/GC4xil3_Bbc
Stockage de masse USB entièrement fonctionnel avec lectures/écritures accélérées par PIO et gestion de l'alimentation en veille.
| Métrique | Valeur |
|---|---|
| Vitesse de lecture | ~985 ko/s (limité par la pleine vitesse USB) |
| Vitesse d'écriture | ~920 ko/s (limité par la pleine vitesse USB, cache d'écriture annoncé) |
| Vitesse côté SDIO brute | ~2,35 Mo/s en lecture / ~2,15 Mo/s en écriture (limité par le disque) |
| Capacité | 3,75 Go (7 862 400 secteurs) |
| Système de fichiers | FAT32 vérifié (montage/démontage/fsck propre) |
| Intégrité des données | Écriture+relecture vérifiée ; CRC16 par bloc sur les 4 lignes DAT |
| Veille inactif | 5 s d'inactivité ou suspension USB → STANDBY IMMEDIATE + coupure d'alimentation |
Hôte USB ←→ USB MSC (TinyUSB) ←→ Couche ATA ←→ Couche SDIO (PIO) ←→ MK4001MTD
Le micrologiciel comporte quatre couches :
USB MSC (msc_device.c) — Classe de stockage de masse TinyUSB. Traduit SCSI READ(10)/WRITE(10) en opérations de secteurs ATA. Tampon EP de 32 Ko, regroupement jusqu'à 64 secteurs par transfert USB. Les E/S du disque sont chevauchées avec l'USB dans les deux sens, comme un véritable pont ATA-USB avec un disque à cache : un préfetcheur de lecture séquentielle récupère le bloc suivant pendant que le précédent est envoyé à l'hôte, et les écritures sont mises en scène et vidées pendant que l'USB reçoit le morceau suivant. Le périphérique annonce son cache d'écriture (page de mode Caching, WCE=1 — les hôtes rapportent « Write cache: enabled » et émettent SYNCHRONIZE CACHE à fsync/démontage/suspension, ce que le micrologiciel respecte). Un vidage en arrière-plan qui échoue se manifeste par une MEDIUM ERROR sur le prochain WRITE ou SYNCHRONIZE CACHE ; les écritures sur des secteurs connus comme défectueux empruntent un chemin synchrone strict.
ATA sur SDIO (ata_sdio.c) — Implémente les commandes ATA (IDENTIFY, READ SECTORS, WRITE SECTORS) en écrivant dans les registres ATA mappés dans l'espace d'adressage de la fonction SDIO 1 via CMD52, et en transférant les données de secteur via CMD53. Logique de nouvelle tentative à 3 niveaux (CMD, données et ATA).
PIO SDIO (sdio_pio.c, sdio.pio) — SDIO accéléré par matériel utilisant le périphérique PIO du RP2040 (bus 4 bits à 10 MHz, 4 cycles PIO par bit avec synchroniseurs d'entrée contournés). Trois programmes PIO partagent une seule machine d'état via un échange dynamique de programmes :
Broches/Alimentation (sdio_hw.c) — Initialisation des GPIO et commande d'alimentation du disque dur. Toute la communication SDIO utilise le PIO.
Notes humaines : Fait intéressant, Claude était vraiment réticent à implémenter le SDIO en PIO, et de nombreux cycles de développement ont été perdus à faire des allers-retours entre PIO et bit-bang.
Le MK4001MTD se présente comme une carte SDIO avec une fonction d'E/S. L'initialisation standard de carte SDIO (CMD5/CMD3/CMD7) configure le bus, puis les registres ATA sont accédés via des commandes SDIO :
Accès aux registres (CMD52) : Chaque registre ATA est mappé à une adresse de la fonction 1 :