Détérioration de contrôleur de carte µSD
Modérateurs : Papy.G, fneck, Carl
- Papy.G
- Modérateur
- Messages : 3054
- Inscription : 10 juin 2014 13:40
- Localisation : Haute-Garonne/Gers
Détérioration de contrôleur de carte µSD
Bonjour à tous, voilà, je viens de cramer une carte µSD malgré qu'elle soit récente et n'ait pas été utilisée intensivement, et comme c'est la deuxième en six mois, j'avais plusieurs questions à vous poser:
Pensez-vous qu'il soit possible par des erreurs de communications (envoi de mauvaises commandes, utilisation de programmes "expérimentaux", retrait de carte à la sauvage…) de rendre hors-service une carte SD? (Je sais qu'on peut foutre en l'air ainsi un système de fichiers, mais carrément de ne plus pouvoir formater.)
Avez-vous des utilitaires qui pourraient intervenir sur le fonctionnement bas-niveau d'une carte SD? Tout ce que je trouve en cherchant son des utilitaires de restauration de fichiers après formatage rapide.
Pensez-vous qu'il soit possible par des erreurs de communications (envoi de mauvaises commandes, utilisation de programmes "expérimentaux", retrait de carte à la sauvage…) de rendre hors-service une carte SD? (Je sais qu'on peut foutre en l'air ainsi un système de fichiers, mais carrément de ne plus pouvoir formater.)
Avez-vous des utilitaires qui pourraient intervenir sur le fonctionnement bas-niveau d'une carte SD? Tout ce que je trouve en cherchant son des utilitaires de restauration de fichiers après formatage rapide.
Soyez exigeants, ne vous contentez pas de ce que l'on vous vend.
Demandez-en plus, ou faites-le vous-même.
Demandez-en plus, ou faites-le vous-même.
-
- Messages : 7983
- Inscription : 18 sept. 2010 12:08
- Localisation : Brest et parfois les Flandres
Re: Détérioration de contrôleur de carte µSD
Je pige pas le titre : tu parles du contrôleur ou de la µSD elle-même ?
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
- jojo
- Messages : 668
- Inscription : 13 mai 2007 13:27
- Localisation : Entre la France, la Suisse et l'Italie ... dans la vallée du bien décolleté.
Re: Détérioration de contrôleur de carte µSD
Je ne sais pas si ça peux t'aider mais Sandisk renvoie systématiquement une carte sd en cas de défaillance dans les 10 ans après l'achat et ce même sans la preuve d'achat (une photo recto-verso avec le n° de série suffit en expliquant que le ticket a été perdu par exemple). Certes, ça ne permet pas de récupérer le contenu de la carte défectueuse mais ça évite surtout d'avoir à en racheter une ! J'ai déjà eu recours 2 fois à ce service suite à une mauvaise manipulation de la carte sd dans un téléphone.
Le lien pour le retour si tu es concerné: Demande d’Autorisation de Retour de Matériel
Le lien pour le retour si tu es concerné: Demande d’Autorisation de Retour de Matériel
- Papy.G
- Modérateur
- Messages : 3054
- Inscription : 10 juin 2014 13:40
- Localisation : Haute-Garonne/Gers
Re: Détérioration de contrôleur de carte µSD
Sam> Le contrôleur de/dans la carte, si je ne m'abuse, en gros, une carte SD, c'est un bloc mémoire, et un bloc contôleur/interface, non?
L'idée, c'est qu'un hdd par exemple, tu peux foirer son système de fichiers, mais tu peux toujours re-formater et après, ça roule. La question est: le micro-programme de contrôle interne d'une carte SD est-il inscriptible, ou est-ce le système de protection (Secure Digital) pourrait être activé par erreur?
Dans ma GC, où elle est adressée en SPI, je vois les bonnes valeurs de mémoire totale et occupée, sur le Mac ou machine virtuelle Windows, le disque est inexploitable, et apparaît verrouillé en écriture.
Jojo> Oui, j'avais fait une procédure pour un proche avec une carte SanDisk ou Kingston, je ne sais plus, et ils ne sont pas trop regardants.
Il y a des marques qui tiennent à leur image, j'ai obtenu un échange sur une manette de Game Cube BigBen longtemps après l'achat, j'avais l'emballage d'origine, le ticket, mais surtout, j'ai relevé une arnaque manifeste sur l'emballage (double moteur de vibration annoncé, et à l'intérieur de ladite manette, ô surprise, un seul vibreur! )
Mais c'est une marque de redistribution polonaise (Platinet), je vais essayer de les contacter, ou voir aussi avec l'organisme de cashback par lequel je l'avais obtenu (Maximiles).
Pour les données, c'étaient des dumps/backups de mes disques GameCube, rien d'unique ou rare n'a été perdu. Mais bon, c'était une carte de 64Go, quand-même…
Je me demande s'il n'y a pas un soucis avec mon lecteur de cartes ou l'utilisation de la capture de port USB de VirtualBox, car c'est lors d'une telle utilisation que les deux défaillances sont apparues.
L'idée, c'est qu'un hdd par exemple, tu peux foirer son système de fichiers, mais tu peux toujours re-formater et après, ça roule. La question est: le micro-programme de contrôle interne d'une carte SD est-il inscriptible, ou est-ce le système de protection (Secure Digital) pourrait être activé par erreur?
Dans ma GC, où elle est adressée en SPI, je vois les bonnes valeurs de mémoire totale et occupée, sur le Mac ou machine virtuelle Windows, le disque est inexploitable, et apparaît verrouillé en écriture.
Jojo> Oui, j'avais fait une procédure pour un proche avec une carte SanDisk ou Kingston, je ne sais plus, et ils ne sont pas trop regardants.
Il y a des marques qui tiennent à leur image, j'ai obtenu un échange sur une manette de Game Cube BigBen longtemps après l'achat, j'avais l'emballage d'origine, le ticket, mais surtout, j'ai relevé une arnaque manifeste sur l'emballage (double moteur de vibration annoncé, et à l'intérieur de ladite manette, ô surprise, un seul vibreur! )
Mais c'est une marque de redistribution polonaise (Platinet), je vais essayer de les contacter, ou voir aussi avec l'organisme de cashback par lequel je l'avais obtenu (Maximiles).
Pour les données, c'étaient des dumps/backups de mes disques GameCube, rien d'unique ou rare n'a été perdu. Mais bon, c'était une carte de 64Go, quand-même…
Je me demande s'il n'y a pas un soucis avec mon lecteur de cartes ou l'utilisation de la capture de port USB de VirtualBox, car c'est lors d'une telle utilisation que les deux défaillances sont apparues.
Soyez exigeants, ne vous contentez pas de ce que l'on vous vend.
Demandez-en plus, ou faites-le vous-même.
Demandez-en plus, ou faites-le vous-même.
-
- Messages : 7983
- Inscription : 18 sept. 2010 12:08
- Localisation : Brest et parfois les Flandres
Re: Détérioration de contrôleur de carte µSD
Est-ce que tu as essayé cet oui de l'association SD ?
https://www.sdcard.org/downloads/formatter/
https://www.sdcard.org/downloads/formatter/
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Re: Détérioration de contrôleur de carte µSD
Première question à se poser : Quel fabricant et quel modèle ? Carte authentique ou contrefaçon ?
Si c'est une carte sans marque ou une contrefaçon de Sandisk, c'est normal que le contrôleur tombe en panne.
Deuxième question : Sur quoi a-t-elle été connectée ? Si elle a été exposée à des tensions trop élevées, ou inverses, les diodes de protection ne suffisent pas toujours à la protéger efficacement.
J'ai déjà utilisé plus d'une centaine de cartes microSD. Aucune carte de marque (Sandisk, Kingston, Toshiba, etc.) n'est tombée en panne. Les cartes chinoises ont presque toutes eu un problème : lenteurs inexplicables, initialisation impossible, erreurs d'écriture ou de lecture.
Pour vérifier l'authenticité des cartes microSD j'ai écrit un programme Arduino qui liste sur un petit écran TFT toutes les informations des principaux registres : OCR, CID et CSD. Le voici :
Ou celui-ci, qui fonctionne sur tous les ordinateurs Thomson :
Si c'est une carte sans marque ou une contrefaçon de Sandisk, c'est normal que le contrôleur tombe en panne.
Deuxième question : Sur quoi a-t-elle été connectée ? Si elle a été exposée à des tensions trop élevées, ou inverses, les diodes de protection ne suffisent pas toujours à la protéger efficacement.
J'ai déjà utilisé plus d'une centaine de cartes microSD. Aucune carte de marque (Sandisk, Kingston, Toshiba, etc.) n'est tombée en panne. Les cartes chinoises ont presque toutes eu un problème : lenteurs inexplicables, initialisation impossible, erreurs d'écriture ou de lecture.
Pour vérifier l'authenticité des cartes microSD j'ai écrit un programme Arduino qui liste sur un petit écran TFT toutes les informations des principaux registres : OCR, CID et CSD. Le voici :
Code : Tout sélectionner
/**************************************************\
* S D C A R D I N F O _ T F T *
* (c) 2020 - Daniel Coulom *
* http://dcmoto.free.fr/ *
* http://forum.system-cfg.com/ *
*--------------------------------------------------*
* Ce code est distribue gratuitement dans l'espoir *
* qu'il sera utile, mais sans aucune garantie et *
* sans engager la responsabilité de l'auteur. *
* Vous pouvez l' utiliser, le modifier et le *
* diffuser librement, en conservant cette licence *
* et les références de l'auteur dans toutes les *
* copies. L'exploitation commerciale est interdite.*
\**************************************************/
/*
Affichage de contenu des registres de la carte SD,
en particulier le CID et le CSD
*/
/***************************************************
* Version 2020.02.03 *
****************************************************
Historique
2020.02.03 affichage sur ecran TFT
2020.02.02 premiere version operationnelle
Connexion module Catalex pour carte micro SD
GND --> Arduino GND
SCK --> Arduino D13
MISO --> Arduino D12
MOSI --> Arduino D11
VCC --> Arduino VCC (5V)
CS --> Arduino D10
*****************************************************************
SD card management is adapted from SimpleSDAudio library.
Visit SimpleSDAudio website for more information:
http://www.hackerspace-ffm.de/wiki/index.php?title=SimpleSDAudio
*****************************************************************
*/
//#define DEBUG
#define SDCARDINFO_VERSION " v1.0"
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
// Assign human-readable names to some common 16-bit color values:
#define BLACK 0x0000
#define WHITE 0xFFFF
#define GRAY 0x8410
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define PINK 0xF8FF
#define ORANGE 0xFA60
#define CYAN 0x07FF
#define AQUA 0x04FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
// SD card constants
#define SD_CARD_TYPE_SD1 1 /** Standard capacity V1 SD card */
#define SD_CARD_TYPE_SD2 2 /** Standard capacity V2 SD card */
#define SD_CARD_TYPE_SDHC 3 /** High Capacity SD card */
#define SD_PARTTYPE_UNKNOWN 0
#define SD_PARTTYPE_SUPERFLOPPY 1
#define SD_PARTTYPE_FAT16 2
#define SD_PARTTYPE_FAT32 3
#define SD_INIT_TIMEOUT 2000 /** temps maxi pour l'initialisation */
#define SD_READ_TIMEOUT 300 /** temps maxi pour le debut de la lecture d'un bloc */
#define SD_COMMAND_TIMEOUT 300 /** temps maxi pour repondre a une commande */
#define SD_READY_STATE 0x00 /** status for card in the ready state */
#define SD_IDLE_STATE 0x01 /** status for card in the idle state */
#define SD_ILLEGAL_COMMAND 0x04 /** status bit for illegal command */
#define SD_DATA_START_BLOCK 0xFE /** start data token for read or write single block*/
// SD card commands
#define SD_CMD0 0x00 /** GO_IDLE_STATE - init card in spi mode if CS low */
#define SD_CMD8 0x08 /** SEND_IF_COND - verify SD Memory Card interface operating condition.*/
#define SD_CMD9 0x09 /** SEND_CSD - read the Card Specific Data (CSD register), response R1 */
#define SD_CMD10 0x0A /** SEND_CID - read the card identification information (CID register), response R1 */
#define SD_CMD12 0x0C /** STOP_TRANSMISSION - end multiple block read sequence, response R1b */
#define SD_CMD13 0x0D /** SEND_STATUS - read the card status register, response R2 */
#define SD_CMD16 0x10 /** SET_BLOCKLEN arg0[31:0]: block length, response R1 */
#define SD_CMD17 0x11 /** READ_SINGLE_BLOCK - read a single data block from the card, response R1 */
#define SD_CMD18 0x12 /** READ_MULTIPLE_BLOCK - read a multiple data blocks from the card, response R1 */
#define SD_CMD55 0x37 /** APP_CMD - escape for application specific command */
#define SD_CMD58 0x3A /** READ_OCR - read the OCR register of a card */
#define SD_CMD59 0x3B /** CRC_ON_OFF - Turns CRC option on or off, response R1 */
#define SD_ACMD41 0x29 /** SD_SEND_OP_COMD - Sends host capacity support information and activates the card's initialization process */
// SD card error codes
#define SD_ERROR_CMD0 0x01 /** timeout error for command CMD0 (initialize card in SPI mode), signal problem */
#define SD_ERROR_CMD8 0x02 /** CMD8 was not accepted - not a valid SD card */
#define SD_ERROR_ACMD41 0x03 /** ACMD41 initialization process timeout */
#define SD_ERROR_CMD58 0x04 /** card returned an error response for CMD58 (read OCR) */
#define SD_ERROR_CMD16 0x05 /** card returned an error response for CMD16 (set block len) */
#define SD_ERROR_VOLTMATCH 0x06 /** card operation voltage range doesn't match (2.7V - 3.6V) */
#define SD_ERROR_READ_TIMEOUT 0x07 /** timeout while waiting for start of read data */
#define SD_ERROR_READ 0x08 /** card returned error token when tried to read data */
#define SD_ERROR_CMD17 0x09 /** card returned an error response for CMD17 (read single block) */
#define SD_ERROR_CMD9 0x0e /** card returned an error response for CMD9 (read CSD) */
#define SD_ERROR_CMD10 0x0f /** card returned an error response for CMD10 (read CID) */
#define SD_ERROR_CMD18 0x10 /** card returned an error response for CMD18 (read multi block) */
#define SD_ERROR_INVAL_SECT0 0x30 /** No valid MBR/FAT-BS signature found in sector 0 */
#define SD_ERROR_INVAL_BS 0x31 /** Malformed FAT boot sector */
#define SD_ERROR_FAT12 0x32 /** FAT12 is not supported */
#define SD_ERROR_FAT_NOT_INIT 0x33 /** FAT not initialized properly */
#define SD_ERROR_DIR_EOC 0x34 /** End of cluster reached (not a real error, just information) */
#define SD_ERROR_FILE_NOT_FOUND 0x35 /** File not found after reaching end of directory */
#define SD_ERROR_EOF 0x38 /** End of file reached */
// SD card structures
typedef struct {
uint8_t Attributes;
uint32_t Size; // in bytes
uint32_t FirstCluster; // First cluster
uint32_t ActSector; // 0 to (SD_FAT.SecPerClus - 1)
uint32_t ActBytePos; // 0 to Size
} SD_File_t;
typedef struct {
uint8_t PartType; // Use this to test whether it is FAT16 or FAT32 or not initialized
// Stuff from FAT boot sector
uint8_t SecPerClus;
uint16_t RsvdSecCnt;
uint8_t NumFATs;
uint16_t RootEntryCount;
uint32_t TotalSec;
uint32_t SecPerFAT;
uint32_t RootClus;
// For cluster calculations
uint8_t ClusterSizeShift;
uint32_t ClusterCount;
// Start addresses (all in blocks / sector addresses)
uint32_t BootSectorStart; // Address of boot sector from FAT
uint32_t FatStart; // First file allocation table starts here
uint32_t RootDirStart; // Root directory starts here
uint32_t DataStart; // Cluster 0 starts here
uint32_t ClusterEndMarker; // if Cluster >= this then end of file reached.
} SD_FAT_t;
// SD card variables
SD_File_t FileInfo; // information fichier
SD_FAT_t SD_FAT; // FAT
uint8_t SD_type; // type de la carte SD
uint8_t SD_CSPin; // numero de la broche CS de la carte SD
uint8_t SD_buffer[513]; // SD buffer must hold 512 bytes + 1
// chaine de caracteres pour affichage
char name[20];
/////////////////////////////////////////////////////////////////////////////
// Programme principal
/////////////////////////////////////////////////////////////////////////////
void setup()
{
uint32_t i;
uint32_t an, mois;
uint32_t blocklength;
uint32_t cardsize;
uint64_t mult;
uint8_t SDHC;
uint8_t reg[18];
char string[256];
uint16_t identifier; // TFT identifier
#ifdef DEBUG
char barre[256];
strcpy(barre, "================================================================");
Serial.begin(9600); //open the serial port at 9600 bps:
#endif
//Initialisations
SD_CSPin = 10; //numero de la broche CS de la carte SD
SD_Init(); //initialiser la carte SD
//========================================================================
// Affichage de l'ecran de presentation
//========================================================================
tft.reset();
identifier = tft.readID(); // lecture de l'identifiant
tft.begin(identifier); // initialisation de l'ecran
tft.setRotation(1); // mode paysage
tft.fillScreen(BLACK);
tft.fillRect(0,0,320,16,YELLOW);
tft.setCursor(24,1);
tft.setTextSize(2);
tft.setTextColor(BLACK); tft.print(F("SDCARD INFO "));
tft.setTextColor(RED); tft.print(F("T"));
tft.setTextColor(GREEN);tft.print(F("F"));
tft.setTextColor(BLUE);tft.print(F("T"));
tft.setTextColor(BLACK); tft.println(F(SDCARDINFO_VERSION));
tft.setTextColor(GREEN);
tft.setTextSize(1);
tft.println();
//========================================================================
// OCR
//========================================================================
//CMD58 command (read 0CR)
SD_CardCommand(58, 0); //envoi CMD58
for(i = 0; i < 4; i++) //boucle sur 4 octets
{
reg[i] = SD_SpiReadByte();
sprintf(string + 3 * i, "%02x ", reg[i]);
}
//OCR en hexadecimal
#ifdef DEBUG
Serial.println(barre);
Serial.print("OCR = ");
Serial.println(string);
Serial.println(barre);
#else
tft.println("OCR =================================================");
tft.println(string);
#endif
//Voltage
#ifdef DEBUG
Serial.print("Voltage................: ");
if(reg[2] & 128) Serial.print("2.7 ");
if(reg[1] & 1) Serial.print("2.8 ");
if(reg[1] & 2) Serial.print("2.9 ");
if(reg[1] & 4) Serial.print("3.0 ");
if(reg[1] & 8) Serial.print("3.1 ");
if(reg[1] & 16) Serial.print("3.2 ");
if(reg[1] & 32) Serial.print("3.3 ");
if(reg[1] & 64) Serial.print("3.4 ");
if(reg[1] & 128) Serial.print("3.5 3.6");
Serial.println();
#else
tft.print("Voltage: ");
if(reg[2] & 128) tft.print("2.7 ");
if(reg[1] & 1) tft.print("2.8 ");
if(reg[1] & 2) tft.print("2.9 ");
if(reg[1] & 4) tft.print("3.0 ");
if(reg[1] & 8) tft.print("3.1 ");
if(reg[1] & 16) tft.print("3.2 ");
if(reg[1] & 32) tft.print("3.3 ");
if(reg[1] & 64) tft.print("3.4 ");
if(reg[1] & 128) tft.print("3.5 3.6");
tft.println();
#endif
//Switching to 1.8V
#ifdef DEBUG
Serial.print("Switching to 1.8V......: ");
if(reg[0] & 1) Serial.println("YES");
else Serial.println("NO");
#else
tft.print("Switching to 1.8V.....: ");
if(reg[0] & 1) tft.println("YES");
else tft.println("NO");
#endif
//Card capacity status
#ifdef DEBUG
Serial.print("Card capacity status...: ");
Serial.println((reg[0] >> 6) & 1);
#else
tft.print("Card capacity status..: ");
tft.println((reg[0] >> 6) & 1);
#endif
//Card power up status
#ifdef DEBUG
Serial.print("Card power up status...: ");
Serial.println((reg[0] >> 7) & 1);
Serial.println();
#else
tft.print("Card power up status..: ");
tft.println((reg[0] >> 7) & 1);
tft.println();
#endif
//========================================================================
// CID
//========================================================================
//CMD10 command (read CID)
SD_CardCommand(10, 0); //envoi CMD10
while(SD_SpiReadByte() != 0xfe); //attente octet $FE de debut de bloc
for(i = 0; i < 18; i++) //boucle sur 18 octets (CID=16 + CRC=2)
{
reg[i] = SD_SpiReadByte();
sprintf(string + 3 * i, "%02x ", reg[i]);
}
string[3 * i - 1] = 0;
//CID en hexadecimal
#ifdef DEBUG
Serial.println(barre);
Serial.print("CID = ");
Serial.println(string);
Serial.println(barre);
#else
tft.println("CID =================================================");
tft.print(string);
#endif
//Manufacturer
string[2] = 0;
#ifdef DEBUG
Serial.print("Manufacturer ID........: ");
Serial.print(string);
#else
tft.print("Manufacturer.ID.......: ");
tft.print(string);
#endif
Manufacturer(reg[0]);
#ifdef DEBUG
Serial.print(" (");
Serial.print(name);
Serial.println(")");
#else
tft.print(" (");
tft.print(name);
tft.println(")");
#endif
//Application ID
string[8] = 0;
for(i = 0; i < 2; i++) name[i] = reg[i + 1];
name[2] = 0;
#ifdef DEBUG
Serial.print("Application ID.........: ");
Serial.print(string + 3);
Serial.print(" (");
Serial.print(name);
Serial.println(")");
#else
tft.print("Application.ID........: ");
tft.print(string + 3);
tft.print(" (");
tft.print(name);
tft.println(")");
#endif
//Product name
string[23] = 0;
for(i = 0; i < 5; i++) name[i] = reg[i + 3];
name[5] = 0;
#ifdef DEBUG
Serial.print("Product name...........: ");
Serial.print(string + 9);
Serial.print(" (");
Serial.print(name);
Serial.println(")");
#else
tft.print("Product name..........: ");
tft.print(string + 9);
tft.print(" (");
tft.print(name);
tft.println(")");
#endif
//Product revision
string[26] = 0;
#ifdef DEBUG
Serial.print("Product revision.......: ");
Serial.println(string + 24);
#else
tft.print("Product revision......: ");
tft.println(string + 24);
#endif
//Product serial number
string[38] = 0;
#ifdef DEBUG
Serial.print("Product serial number..: ");
Serial.println(string + 27);
#else
tft.print("Product serial number.: ");
tft.println(string + 27);
#endif
//Manufacturing date
string[44] = 0;
i = 256 * reg[13] + reg[14]; mois = i & 15; an = 2000 + (i >> 4);
#ifdef DEBUG
Serial.print("Manufacturing date.....: ");
Serial.print(string + 39);
Serial.print(" (");
Serial.print(an);
Serial.print("/");
Serial.print(mois);
Serial.println(")");
#else
tft.print("Manufacturing date....: ");
tft.print(string + 39);
tft.print(" (");
tft.print(an);
tft.print("/");
tft.print(mois);
tft.println(")");
#endif
//checksum
string[47] = 0;
#ifdef DEBUG
Serial.print("Checksum...............: ");
Serial.println(string + 45);
#else
tft.print("Checksum..............: ");
tft.println(string + 45);
#endif
//CRC
string[53] = 0;
#ifdef DEBUG
Serial.print("CRC for R2 response....: ");
Serial.println(string + 48);
Serial.println();
#else
tft.print("CRC for R2 response...: ");
tft.println(string + 48);
tft.println();
#endif
//========================================================================
// CSD
//========================================================================
//CMD9 command (read CSD)
SD_CardCommand(9, 0); //envoi CMD9
while(SD_SpiReadByte() != 0xfe); //attente octet $FE de debut de bloc
for(i = 0; i < 18; i++) //boucle sur 18 octets (CSD=16 + CRC=2)
{
reg[i] = SD_SpiReadByte();
sprintf(string + 3 * i, "%02x ", reg[i]);
}
string[3 * i - 1] = 0;
//CSD en hexadecimal
#ifdef DEBUG
Serial.println(barre);
Serial.print("CSD = ");
Serial.println(string);
Serial.println(barre);
#else
tft.println("CSD =================================================");
tft.print(string);
#endif
//CSD Structure version
SDHC = reg[0] & 64;
#ifdef DEBUG
Serial.print("CSD structure version..: ");
if(SDHC) Serial.println("2.0 - High Capacity (SDHC) & Extended Capacity (SDXC)");
else Serial.println("1.0 - Standard Capacity (SDSC)");
#else
tft.print("CSD structure version.: ");
if(SDHC) tft.println("2.0 - SDHC & SDXC");
else tft.println("1.0 - SD ou SDSC");
#endif
//READ_BL_LEN
i = (reg[5] & 15) - 1;
blocklength = 2 << i;
#ifdef DEBUG
Serial.print("Read data block length.: ");
Serial.println(blocklength);
#else
tft.print("Read data block length: ");
tft.println(blocklength);
#endif
//C_SIZE
if(SDHC)
{
cardsize = reg[7] << 16;
cardsize += reg[8] << 8;
cardsize += reg[9];
}
else
{
cardsize = (reg[6] & 3) << 10;
cardsize += reg[7] << 2;
cardsize += reg[8] >> 6;
}
#ifdef DEBUG
Serial.print("Device size.................: ");
Serial.println(cardsize);
#else
tft.print("Device size...........: ");
tft.println(cardsize);
#endif
//C_SIZE_MULT
if(SDHC == 0)
{
i = (reg[9] & 3) << 1;
i += reg[10] >> 7;
#ifdef DEBUG
Serial.print("Device size multiplier.: ");
Serial.println(i);
#else
tft.print("Device size multiplier: ");
tft.println(i);
#endif
}
//Card size
if(SDHC) mult = 1024; else mult = 2 << (i + 1);
mult *= cardsize + 1; //resultat sur 64 bits
mult *= blocklength; //resultat sur 64 bits
cardsize = mult / 10000; //partie gauche
#ifdef DEBUG
Serial.print("Card memory capacity...: ");
Serial.print(cardsize);
#else
tft.print("Card memory capacity..: ");
tft.print(cardsize);
#endif
cardsize = mult % 10000; //partie droite
#ifdef DEBUG
sprintf(string, "%04u", cardsize);
Serial.println(string);
#else
sprintf(string, "%04u", cardsize);
tft.println(string);
#endif
//checksum
string[47] = 0;
#ifdef DEBUG
Serial.print("Checksum...............: ");
Serial.println(string + 45);
#else
tft.print("Checksum..............: ");
tft.println(string + 45);
#endif
//CRC
string[53] = 0;
#ifdef DEBUG
Serial.print("CRC for R2 response....: ");
Serial.println(string + 48);
Serial.println();
#else
tft.print("CRC for R2 response...: ");
tft.println(string + 48);
tft.println();
#endif
}
/////////////////////////////////////////////////////////////////////////////
// Decodage du code fabricant
/////////////////////////////////////////////////////////////////////////////
void Manufacturer(uint8_t code)
{
switch(code)
{
case 0x00: strcpy(name, "Unbranded"); break;
case 0x01: strcpy(name, "Panasonic"); break;
case 0x02: strcpy(name, "Toshiba"); break;
case 0x03: strcpy(name, "Sandisk"); break;
case 0x1b: strcpy(name, "Samsung"); break;
case 0x1d: strcpy(name, "AData"); break;
case 0x27: strcpy(name, "Phison"); break;
case 0x28: strcpy(name, "Lexar"); break;
case 0x31: strcpy(name, "Silicon Power"); break;
case 0x41: strcpy(name, "Kingston"); break;
case 0x74: strcpy(name, "Transcend"); break;
case 0x76: strcpy(name, "Patriot?"); break;
case 0x82: strcpy(name, "Sony?"); break;
default: strcpy(name, "Unknown"); break;
}
return;
}
/////////////////////////////////////////////////////////////////////////////
// Fonction d'acces a la carte SD
/////////////////////////////////////////////////////////////////////////////
/**************************************************************************\
* Set CS High
* Sends also one dummy byte to ensure MISO goes high impedance
\**************************************************************************/
void SD_SetCSHigh()
{
digitalWrite(SD_CSPin, HIGH);
SD_SpiSendByte(0xff);
}
/**************************************************************************\
* Sends a raw byte to the SPI - \param[in] b The byte to sent.
\**************************************************************************/
void SD_SpiSendByte(uint8_t b)
{
SPDR = b;
while(!(SPSR & (1 << SPIF))); /* wait for byte to be shifted out */
SPSR &= ~(1 << SPIF);
}
/**************************************************************************\
* Send a command to the memory card which responses with a R1 response
* (and possibly others).
* \param[in] command The command to send.
* \param[in] arg The argument for command.
* \returns The command answer.
\**************************************************************************/
uint8_t SD_CardCommand(uint8_t cmd, uint32_t arg)
{
uint8_t response;
uint8_t crc;
uint16_t t0;
// select card
digitalWrite(SD_CSPin, LOW);
// wait up to timeout if busy
t0 = ((uint16_t)millis());
while (SD_SpiReadByte() != 0xFF)
if ((((uint16_t)millis()) - t0) >= SD_COMMAND_TIMEOUT) break;
// send command
SD_SpiSendByte(cmd | 0x40);
// send argument
SD_SpiSendByte((arg >> 24) & 0xff);
SD_SpiSendByte((arg >> 16) & 0xff);
SD_SpiSendByte((arg >> 8) & 0xff);
SD_SpiSendByte((arg >> 0) & 0xff);
// send CRC, only required for commands 0 and 8
crc = 0xFF;
if (cmd == SD_CMD0) crc = 0x95; // correct crc for CMD0 with arg 0
if (cmd == SD_CMD8) crc = 0x87; // correct crc for CMD8 with arg 0X1AA
SD_SpiSendByte(crc);
// skip stuff byte for stop read
if (cmd == SD_CMD12) SD_SpiReadByte();
// wait for response
for(uint8_t i = 0; i < 100; ++i)
{
response = SD_SpiReadByte();
if(response != 0xff) break;
}
return response;
}
/**************************************************************************\
* Send an application specific command which responses with a R1 response
* (and possibly others).
* \param[in] command The command to send.
* \param[in] arg The argument for command.
* \returns The command answer.
\**************************************************************************/
uint8_t SD_CardACommand(uint8_t cmd, uint32_t arg)
{
SD_CardCommand(SD_CMD55, 0);
return SD_CardCommand(cmd, arg);
}
/**************************************************************************\
* Initialize the SD memory card.
* Power up the card, set SPI mode.
* Detects the card version (V1, V2, SDHC), sets sector length to 512.
* \return Zero if successfull, errorcode otherwise
\**************************************************************************/
uint8_t SD_Init()
{
uint8_t status;
uint16_t t0 = ((uint16_t)millis());
uint32_t arg;
/* Setup ports */
pinMode(SD_CSPin, OUTPUT);
digitalWrite(SD_CSPin, HIGH);
pinMode(MISO, INPUT);
pinMode(SCK, OUTPUT);
pinMode(MOSI, OUTPUT);
pinMode(SS, OUTPUT);
digitalWrite(SCK, LOW);
digitalWrite(MOSI, LOW);
digitalWrite(SS, HIGH);
/*
* SPI configuration:
* - enable uC for SPI master
* - typical no interrupts are used for SPI
* - data order: MSB is transmitted first
* - clock polarity: CLK is low when idle
* - clock phase: 1-0 > Sample, 0-1 > Setup
* - clock frequency: less than 400kHz
* (will be switched to higher value after initialization)
*/
/* initialize SPI with lowest frequency; max. 400kHz during identification mode of card */
SPCR = (0 << SPIE) | /* SPI Interrupt Enable */
(1 << SPE) | /* SPI Enable */
(0 << DORD) | /* Data Order: MSB first */
(1 << MSTR) | /* Master mode */
(0 << CPOL) | /* Clock Polarity: SCK low when idle */
(0 << CPHA) | /* Clock Phase: sample on rising SCK edge */
(1 << SPR1) | /* Clock Frequency: f_OSC / 128 */
(1 << SPR0);
SPSR &= ~(1 << SPI2X); /* No doubled clock frequency */
// must supply min of 74 clock cycles with CS high.
SD_SetCSHigh();
for (uint8_t i = 0; i < 10; i++) SD_SpiSendByte(0xFF);
// command to go idle in SPI mode
while ((SD_CardCommand(SD_CMD0, 0)) != SD_IDLE_STATE)
if ((((uint16_t)millis()) - t0) > SD_INIT_TIMEOUT) {SD_SetCSHigh(); return(SD_ERROR_CMD0);}
// check SD version ( 2.7V - 3.6V + test pattern )
SD_type = 0;
if ((SD_CardCommand(SD_CMD8, 0x1AA) & SD_ILLEGAL_COMMAND)) SD_type = SD_CARD_TYPE_SD1;
// Not done here: Test if SD or MMC card here using CMD55 + CMD1
else
{
// only need last byte of r7 response
SD_SpiReadByte();
SD_SpiReadByte();
status = SD_SpiReadByte();
if ((status & 0x01) == 0) // card operation voltage range doesn't match
{SD_SetCSHigh(); return(SD_ERROR_VOLTMATCH);}
if (SD_SpiReadByte() != 0xAA) {SD_SetCSHigh(); return(SD_ERROR_CMD8);}
SD_type = SD_CARD_TYPE_SD2;
}
// Turn CRC option off
SD_CardCommand(SD_CMD59, 0);
// initialize card and send host supports SDHC if SD2
arg = (SD_type == SD_CARD_TYPE_SD2) ? 0X40000000 : 0;
while ((SD_CardACommand(SD_ACMD41, arg)) != SD_READY_STATE) // check for timeout
if ((((uint16_t)millis()) - t0) > SD_INIT_TIMEOUT) {SD_SetCSHigh(); return(SD_ERROR_ACMD41);}
// if SD2 read OCR register to check for SDHC card
if (SD_type == SD_CARD_TYPE_SD2)
{
if (SD_CardCommand(SD_CMD58, 0)) {SD_SetCSHigh(); return(SD_ERROR_CMD58);}
// other implementation test only against 0x40 for SDHC detection...
if ((SD_SpiReadByte() & 0xC0) == 0xC0) SD_type = SD_CARD_TYPE_SDHC;
// discard rest of ocr - contains allowed voltage range
SD_SpiReadByte();
SD_SpiReadByte();
SD_SpiReadByte();
}
// set block size to 512 bytes
if(SD_CardCommand(SD_CMD16, 512)) {SD_SetCSHigh(); return(SD_ERROR_CMD16);}
SD_SetCSHigh();
SD_SpiSetHighSpeed();
return 0;
}
/**************************************************************************\
* Set SPI for full operation speed (up to 25 MHz).
* Will be called after first part of card
* initialization was successful.
\**************************************************************************/
void SD_SpiSetHighSpeed(void)
{
SPCR &= ~((1 << SPR1) | (1 << SPR0)); /* Clock Frequency: f_OSC / 4 */
SPSR |= (1 << SPI2X); /* Doubled Clock Frequency: f_OSC / 2 */
}
/**************************************************************************\
* Receives a raw byte from the SPI.
* \returns The byte which should be read.
\**************************************************************************/
uint8_t SD_SpiReadByte()
{
SPDR = 0xff; /* send dummy data for receiving some */
while(!(SPSR & (1 << SPIF)));
SPSR &= ~(1 << SPIF);
return SPDR;
}
/**************************************************************************\
* Read a 512 byte block from an SD card.
* \param[in] blockNumber Logical block to be read.
* \param[out] dst Pointer to the location that will receive the data.
* \return 0 is returned for success, error code otherwise
\**************************************************************************/
uint8_t SD_ReadBlock(uint32_t blockNumber)
{
uint8_t status;
uint16_t t0;
// use address if not SDHC card
if (SD_type != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
if (SD_CardCommand(SD_CMD17, blockNumber)) {SD_SetCSHigh(); return(SD_ERROR_CMD17);}
// wait for start block token
t0 = ((uint16_t)millis());
while ((status = SD_SpiReadByte()) == 0xFF)
if ((((uint16_t)millis()) - t0) > SD_READ_TIMEOUT) {SD_SetCSHigh(); return(SD_ERROR_READ_TIMEOUT);}
if (status != SD_DATA_START_BLOCK) {SD_SetCSHigh(); return(SD_ERROR_READ);}
// transfer data
SPDR = 0xFF;
for (uint16_t i = 0; i < 512; i++)
{
while (!(SPSR & (1 << SPIF)));
SD_buffer[i] = SPDR;
SPDR = 0xFF;
}
while (!(SPSR & (1 << SPIF)));
SD_buffer[512] = SPDR;
// discard CRC
SD_SpiReadByte();
SD_SpiReadByte();
SD_SetCSHigh();
return 0;
}
void loop(void){}
Ou celui-ci, qui fonctionne sur tous les ordinateurs Thomson :
Code : Tout sélectionner
/**************************************************\
* S D D R I V E _ I N I T *
* (c) 2018 - Daniel Coulom *
* http://dcmoto.free.fr/ *
* http://forum.system-cfg.com/ *
*--------------------------------------------------*
* Ce code est distribue gratuitement dans l'espoir *
* qu'il sera utile, mais sans aucune garantie et *
* sans engager la responsabilité de l'auteur. *
* Vous pouvez l' utiliser, le modifier et le *
* diffuser librement, en conservant cette licence *
* et les références de l'auteur dans toutes les *
* copies. L'exploitation commerciale est interdite.*
\**************************************************/
* Ce programme initialise une carte SD.
* En cas d'echec il affiche un message
* permettant d'identifier l'erreur.
* Sinon il affiche le contenu des registres
* CID et CSD de la carte.
* Cette version est compatible avec les cartes SD
* et SDHC sur MO et sur TO
/**************************************************\
* Version 2018.07.16 *
\**************************************************/
* Historique
* 2018.07.16 premiere version issue de cs91280_init
*------------------------------------------------------
* DETECTION DU TYPE D'ORDINATEUR TO OU MO
*------------------------------------------------------
ORG $9000
INIT
PSHS U,Y,X,DP,B,A,CC
ORCC #$50 desactive les interruptions
LDA #$E7 valeur initialisation DP pour TO
LDB >$FFF2 $FFF2: $F0(MO) et $70(TO)
BPL INIT1 TO detecte
*-------------------------------------------------------
* MODIFICATIONS POUR LES ORDINATEURS MO
*-------------------------------------------------------
LDD #$3F82 affichage caractere MO = SWI #$82
STD WCHAR modification routine affichage
LDA #$A7 valeur initialisation DP pour MO
*-------------------------------------------------------
* Initialisation DP pour SDDRIVE
*-------------------------------------------------------
INIT1
TFR A,DP DP = $A7(MO) ou $E7(TO)
*------------------------------------------------------
* CMD0 = SOFTWARE RESET
* Commande precedee de tops d'horloge (minimum 74)
* Test successivement retour 1 et retour 3
*------------------------------------------------------
RESET0
LDY #$0008 compteur pour 8 boucles
RESET1
LDA #$0A pour 10 fois 8 tops
LBSR CLOCK envoi de A*8 tops horloge
LDU #CMD0 commande CMD0
LBSR EXCMD0 execution commande
BCC RESET2 code retour = 1 (OK)
LEAY -1,Y decrementation compteur
BNE RESET1 nouvel essai
BRA ERROR1 erreur apres 8 essais
*------------------------------------------------------
* CMD8 = SEND INTERFACE CONDITION
* Non reconnue par les cartes SD de version < 2.00
* c'est pourquoi le code retour n'est pas teste.
* Lire les 4 derniers octets de la reponse R7
*------------------------------------------------------
RESET2
CLR SD_TYP,PCR carte SD par defaut
LBSR EXCMD execution commande
LDA #$04 nbre d'octets
LBSR CLOCK envoi 4 fois 8 tops horloge
*------------------------------------------------------
* CMD55 + ACMD41 = INITIALISATION
* Si la commande ne renvoie pas le code retour
* attendu elle boucle eternellement
*------------------------------------------------------
RESET3
LDY #$0100 compteur pour 255 essais
RESET4
LEAY -1,Y decrementation compteur
BEQ ERROR2 erreur apres 255 essais
LEAU CMD55,PCR adresse commande CMD55
LBSR EXCMD execution commande CMD55
LBSR EXCMD execution commande ACMD41
BCS RESET4 carte non prete, nouvel essai
*------------------------------------------------------
* CMD58 = LECTURE OCR
* Permet de determiner le type de carte SD ou SDHC
* Premier octet bit 6 : SD=0 SDHC=1
*------------------------------------------------------
RESET5
LBSR EXCMD execution commande
BCS ERROR3 erreur commande
LBSR RBYTE lecture OCR poids fort
ASLA isole le type de carte
BPL RESET6 carte SD : SD_TYP=0
INC SD_TYP,PCR carte SDHC : SD_TYP=1
RESET6
LDA #$03 pour 3 octets
LBSR CLOCK lecture OCR (octets 2, 3, 4)
*------------------------------------------------------
* PAS D'ERREUR DETECTEE
*------------------------------------------------------
ERROR0
LDY #MESS0 message "initialisation OK"
LBSR DISPL affichage message
BRA GETOCR lecture OCR
*------------------------------------------------------
* ERREUR CMD0
*------------------------------------------------------
ERROR1
LDY #MESS1 message "erreur CMD0"
LBSR DISPL affichage message
BRA RETOUR retour au Basic
*------------------------------------------------------
* ERREUR ACMD41
*------------------------------------------------------
ERROR2
LDY #MESS2 message "erreur ACMD41"
LBSR DISPL affichage message
BRA RETOUR retour au Basic
*------------------------------------------------------
* ERREUR CMD58
*------------------------------------------------------
ERROR3
LDY #MESS3 message "erreur CMD58"
LBSR DISPL affichage message
BRA RETOUR retour au Basic
*------------------------------------------------------
* CMD58 LECTURE OCR
*------------------------------------------------------
GETOCR
LDU #CMD58 commande CMD58
LBSR EXCMD EXCMD = execution commande
LDY #MESS6 adresse du message a afficher
LBSR DISPL affichage message
BSR DUMP affichage registre
LDB #$0A line feed
LBSR WCHAR envoi
*-------------------------------------------------------
* CMD10 LECTURE CID
*-------------------------------------------------------
GETCID
LBSR EXCMD EXCMD = execution commande
WAIT1
LBSR RBYTE lecture d'un octet
CMPA #$FE test debut de bloc $FE
BNE WAIT1 attente debut de bloc
LDY #MESS4 adresse du message a afficher
LBSR DISPL affichage message
BSR DUMP affichage registre
LDB #$0A line feed
LBSR WCHAR envoi
*-------------------------------------------------------
* CMD9 LECTURE CSD
*-------------------------------------------------------
GETCSD
LBSR EXCMD EXCMD = execution commande
WAIT2
LBSR RBYTE lecture d'un octet
CMPA #$FE test debut de bloc $FE
BNE WAIT2 attente debut de bloc
LDY #MESS5 adresse du message a afficher
LBSR DISPL affichage message
BSR DUMP affichage registre
*------------------------------------------------------
* RETOUR AU BASIC
*------------------------------------------------------
RETOUR
PULS CC,A,B,DP,X,Y,U,PC
*-------------------------------------------------------
* Dump d'un registre
*-------------------------------------------------------
DUMP
LDB #$03 nombre de lignes
PSHS B empilage compteur lignes
DUMP1
LDY #$9F00 adresse buffer ligne
LDB #$08 nombre d'octets par ligne
PSHS B empilage compteur octets
HEX
LBSR RBYTE lecture d'un octet
STA ,Y stockage dans le buffer
LBSR HEXA affichage en hexadecimal
DEC ,S decrementation compteur
BNE HEX octet suivant
PULS B depilage compteur octet
LDY #$9F00 adresse buffer ligne
LDB #$08 nombre d'octets par ligne
PSHS B empilage compteur octet
ASCII
LBSR CHAR affichage du caractere
DEC ,S decrementation compteur
BNE ASCII caractere suivant
PULS B depilage compteur octet
LDB #$0D carriage return
LBSR WCHAR envoi
LDB #$0A line feed
LBSR WCHAR envoi
DEC ,S decrementation compteur ligne
BNE DUMP1 nouvelle ligne
PULS B depilage compteur ligne
RTS retour
*------------------------------------------------------
* AFFICHAGE D'UN CARACTERE POINTE PAR Y
* Y EST INCREMENTE POUR LA LECTURE DU CARACTERE SUIVANT
*------------------------------------------------------
CHAR
LDB ,Y+ lecture du caractere du buffer
CMPB #$20 test par rapport a $20
BLO CHAR1 plus petit = non affichable
CMPB #$80 test par rapport a $80
LBLO WCHAR plus petit = affichable
CHAR1
LDB #$2E caractere remplace par un point
LBRA WCHAR affichage
*------------------------------------------------------
* AFFICHAGE CARACTERE POINTE PAR Y EN HEXADECIMAL
* Y EST INCREMENTE POUR LA LECTURE DU CARACTERE SUIVANT
*------------------------------------------------------
HEXA
LDA ,Y+ lecture du caractere
TFR A,B transfert du caractere dans B
LSRB decalage
LSRB a droite
LSRB de quatre
LSRB bits
BSR HEXB affichage chiffre hexadecimal
TFR A,B transfert du caractere dans B
ANDB #$0F garde les 4 bits de droite
BSR HEXB affichage chiffre hexadecimal
LDB #$20 espace
LBSR WCHAR affichage espace
RTS retour
*------------------------------------------------------
* AFFICHAGE CHIFFRE B EN HEXADECIMAL
*------------------------------------------------------
HEXB
CMPB #$0A comparaison avec $0A
BLO HEXB1 branchement si plus petit
ADDB #$07 sinon ajout de 7
HEXB1
ADDB #$30 conversion binaire vers ASCII
LBSR WCHAR affichage du caractere
RTS retour
*------------------------------------------------------
* AFFICHAGE MESSAGE TERMINE PAR ZERO BINAIRE
* ADRESSE DANS LE REGISTRE Y
*------------------------------------------------------
DISPL
LDB ,Y+
BEQ DISPL9 fin de la chaine
LBSR WCHAR envoi caractere
BRA DISPL caractere suivant
DISPL9
RTS retour
*------------------------------------------------------
* LECTURE DE 4 OCTETS NON SIGNIFICATIFS (32 BITS)
*------------------------------------------------------
RBIT32
BSR RBYTE lecture d'un octet
BSR RBYTE lecture d'un octet
BSR RBYTE lecture d'un octet
BRA RBYTE lecture d'un octet
*------------------------------------------------------
* ATTENTE CARTE PRETE PUIS EXECUTION D'UNE COMMANDE
* Le registre U pointe sur les 6 octets de la commande
* Le registre B n'est pas preserve.
* le code retour est dans le registre A
*------------------------------------------------------
EXCMD
BSR RBYTE lecture d'un octet dans A
INCA ajout de 1 ($FF --> $00)
BNE EXCMD attente carte prete
EXCMD0
LDB #$06 nombre d'octets de la commande
EXCMD2
LDA ,U+ chargement octet de commande
BSR WBYTE ecriture de l'octet
DECB decrementation compteur
BNE EXCMD2 il reste des octets a envoyer
LDX #$0100 compteur pour 255 essais
LDB #$7F valeur A et B pour signal SCK
EXCMD3
LEAX -1,X decrementation compteur
BEQ EXCMD4 pas de reponse
LBSR RB0 lecture d'un bit dans A
ANDA #$01 isole le bit lu
BNE EXCMD3 attendre bit a zero
BSR RB6 lecture des 7 autres bits
CMPA ,U+ test code de retour
BEQ EXCMD5 code bon, carry clear
COMB carry set en erreur
EXCMD4
COMB carry set en erreur
EXCMD5
RTS retour
*------------------------------------------------------
* LECTURE D'UN OCTET
* Valeur de l'octet dans le registre A en sortie
*------------------------------------------------------
RBYTE
LDB #$7F initialisation de B (2)
CMPB <$BF lecture bit 7 (4)
ROLA pousser dans A (2)
RB6
CMPB <$BF lecture bit 6 (4)
ROLA pousser dans A (2)
RB5
CMPB <$BF lecture bit 5 (4)
ROLA pousser dans A (2)
RB4
CMPB <$BF lecture bit 4 (4)
ROLA pousser dans A (2)
RB3
CMPB <$BF lecture bit 3 (4)
ROLA pousser dans A (2)
RB2
CMPB <$BF lecture bit 2 (4)
ROLA pousser dans A (2)
RB1
CMPB <$BF lecture bit 1 (4)
ROLA pousser dans A (2)
RB0
CMPB <$BF lecture bit 0 (4)
ROLA pousser dans A (2)
RTS retour octet dans A (5)
*------------------------------------------------------
* ECRITURE D'UN OCTET
* Valeur de l'octet dans le registre A en entree
*------------------------------------------------------
WBYTE
ROLA b7 dans carry (2)
ROLA b7 dans b0 (2)
STA <$BF ecriture bit 7 (4)
ROLA b6 dans b0 (2)
STA <$BF ecriture bit 6 (4)
ROLA b5 dans b0 (2)
STA <$BF ecriture bit 5 (4)
ROLA b4 dans b0 (2)
STA <$BF ecriture bit 4 (4)
ROLA b3 dans b0 (2)
STA <$BF ecriture bit 3 (4)
ROLA b2 dans b0 (2)
STA <$BF ecriture bit 2 (4)
ROLA b1 dans b0 (2)
STA <$BF ecriture bit 1 (4)
ROLA b0 dans b0 (2)
STA <$BF ecriture bit 0 (4)
RTS retour (5)
*------------------------------------------------------
* ENVOI DE 8*A TOPS D'HORLOGE
* Le registre B est preserve. Au retour A=0
*------------------------------------------------------
CLOCK
CMPB <$BF envoi d'un top d'horloge
CMPB <$BF envoi d'un top d'horloge
CMPB <$BF envoi d'un top d'horloge
CMPB <$BF envoi d'un top d'horloge
CMPB <$BF envoi d'un top d'horloge
CMPB <$BF envoi d'un top d'horloge
CMPB <$BF envoi d'un top d'horloge
CMPB <$BF envoi d'un top d'horloge
DECA
BNE CLOCK
RTS
*------------------------------------------------------
* AFFICHAGE CARACTERE (CARACTERE DANS REGISTRE B)
* Version TO remplacee par SWI #$82 pour MO
*------------------------------------------------------
WCHAR
JMP $E803 envoi caractere
*------------------------------------------------------
* Zones de travail
*------------------------------------------------------
SD_TYP
FCB 0
*------------------------------------------------------
* Messages a afficher
*------------------------------------------------------
MESS0
FCB $0D,$0A
FCC "Initialisation OK"
FCB $0D,$0A,$0D,$0A,$00
MESS1
FCC "Erreur CMD0"
FCB $0D,$0A,$0D,$0A,$00
MESS2
FCC "Erreur ACMD41"
FCB $0D,$0A,$0D,$0A,$00
MESS3
FCC "Erreur CMD58"
FCB $0D,$0A,$0D,$0A,$00
MESS4
FCC "CID Card IDentification"
FCB $0D,$0A,$00
MESS5
FCC "CSD Card Specific Data"
FCB $0D,$0A,$00
MESS6
FCC "OCR Operation Conditions"
FCB $0D,$0A,$00
*------------------------------------------------------
* COMMANDES
*------------------------------------------------------
CMD0
FCB $40 go iddle state
FDB $0000
FDB $0000
FCB $95 checksum obligatoire
FCB $01 code retour attendu 1
*------------------------------------------------------
CMD8
FCB $48 send interface condition
FDB $0000
FDB $01AA
FCB $87 checksum obligatoire
FCB $00 code retour attendu
*------------------------------------------------------
CMD55
FCB $77 application command
FDB $0000
FDB $0000
FCB $FF checksum non testee
FCB $00 code retour attendu
*------------------------------------------------------
AC41
FCB $69 activate card initialization
FDB $4000
FDB $0000
FCB $FF checksum non testee
FCB $00 code retour attendu
*------------------------------------------------------
CMD58
FCB $7A read OCR
FDB $0000
FDB $0000
FCB $FF checksum non testee
FCB $00 code retour attendu
*------------------------------------------------------
CMD10
FCB $4A send CID
FDB $0000 dummy
FDB $0000 dummy
FCB $FF checksum non testee
FCB $00 code retour attendu
*------------------------------------------------------
CMD9
FCB $49 send CSD
FDB $0000 dummy
FDB $0000 dummy
FCB $FF checksum non testee
FCB $00 code retour attendu
*------------------------------------------------------
END
Daniel
L'obstacle augmente mon ardeur.
L'obstacle augmente mon ardeur.
- Papy.G
- Modérateur
- Messages : 3054
- Inscription : 10 juin 2014 13:40
- Localisation : Haute-Garonne/Gers
Re: Détérioration de contrôleur de carte µSD
Merci Sam, bon, ça marche pas, mais je le garde de côté.
Daniel>Mauvaise pioche, Corée et Taiwan, l'une accompagnait un téléphone Nokia, et l'autre, c'est celle que je viens de cramer, je ne l'ai pas importée moi-même (genre achetée sur Alix, BG, MiniITB ou autre…).
L'appareil en commun est un hub avec lecteur multi-cartes de qualité médiocre (XOOPAR Podium), mais je n'ai pas cramé de cartes avec celui-ci jusque récemment, car j'utilise plus souvent Virtual Box quand j'ai besoin de Windows (avant j'avais une config PC headless et mon bootcamp).
Ton utilitaire m'intéresse, Daniel, mais je n'ai ni Thomson, ni Arduino.
Personne n'a fait cet outil pour Windows, ou sur GameCube, à la rigueur…
Falkor> C'est pas que je sois un sauvage, mais quand un appareil plante en lecture ou écriture, c'est un peu comme si la carte était retirée sans déconnection…
Daniel>Mauvaise pioche, Corée et Taiwan, l'une accompagnait un téléphone Nokia, et l'autre, c'est celle que je viens de cramer, je ne l'ai pas importée moi-même (genre achetée sur Alix, BG, MiniITB ou autre…).
L'appareil en commun est un hub avec lecteur multi-cartes de qualité médiocre (XOOPAR Podium), mais je n'ai pas cramé de cartes avec celui-ci jusque récemment, car j'utilise plus souvent Virtual Box quand j'ai besoin de Windows (avant j'avais une config PC headless et mon bootcamp).
Ton utilitaire m'intéresse, Daniel, mais je n'ai ni Thomson, ni Arduino.
Personne n'a fait cet outil pour Windows, ou sur GameCube, à la rigueur…
Falkor> C'est pas que je sois un sauvage, mais quand un appareil plante en lecture ou écriture, c'est un peu comme si la carte était retirée sans déconnection…
Soyez exigeants, ne vous contentez pas de ce que l'on vous vend.
Demandez-en plus, ou faites-le vous-même.
Demandez-en plus, ou faites-le vous-même.