00001
00006
#include "mmc.h"
00007
#include "board.h"
00008
#include "console.h"
00009
#include "buffer.h"
00010
00011
00012
00013
00014
00019 unsigned char MmcCommand(
unsigned char c1,
00020
unsigned char c2,
00021
unsigned char c3,
00022
unsigned char c4,
00023
unsigned char c5){
00024
00025
00026 xdata
char c;
00027
00028
00029
00030
MMC_OFF =
NO;
00031
MMC_XCS =
MMC_NOT_SELECTED;
00032
00033
00034
SPI8Clocks(8);
00035
MMC_XCS =
MMC_SELECTED;
00036
SPI8Clocks(8);
00037
00038 c=0;
00039
00040
while ((
SPIGetChar()!=0xff) && (c<100)){
00041 ConsolePutChar(
'.');
00042 c++;
00043 }
00044
00045
00046
00047
if (
SPI_RESULT_BYTE != 0xff){
00048 ConsoleWrite(
"\rUnexpected busy signal from MMC. ");
00049
MMC_XCS =
MMC_NOT_SELECTED;
00050
return 0x81;
00051 }
00052
00053
#ifdef MMCDEBUG
00054
DebugMessage(
" \x1b[7m");
00055 ConsolePutChar(
'C'); ConsolePutHex8(c1); ConsolePutHex8(c2); ConsolePutHex8(c3);
00056 ConsolePutHex8(c4); ConsolePutHex8(c5); ConsolePutChar(
'|');
00057
#endif
00058
00059
00060
SPIPutCharWithoutWaiting(c1);
00061
SPIPutChar(c2);
00062
SPIPutChar(c3);
00063
SPIPutChar(c4);
00064
SPIPutChar(c5);
00065
SPIPutChar(0x95);
00066
SPIWait();
00067
00068
00069
00070
#ifdef MMCDEBUG
00071
{
00072 c1=100;
00073
while((c1--)&&((c2=
SPIGetChar())&0x80)){
00074
00075
if (c2!=0xff){ConsolePutHex8(c2);ConsolePutChar(
'|');}
00076 }
00077 ConsolePutHex8(c2);
00078 DebugMessage(
"\x1b[0m ");
00079 }
00080
#else
00081
{
00082 c1=100;
00083
while((c1--)&&((c2=
SPIGetChar())&0x80))
00084 ;
00085 }
00086
#endif
00087
00088
return c2;
00089 }
00090
00091
00102 unsigned char MmcWaitForData(){
00103
00104
unsigned char c;
00105
00106 DebugMessage(
"<t:");
00107
00108
00109
00110
do {
00111 c=
SPIGetChar();
00112
#ifdef MMCDEBUG
00113
if (c!=0xFF) ConsolePutHex8(c);
00114
#endif
00115
}
while ((c == 0xff));
00116
00117
00118
00119
if (c != 0xfe){
00120
00121
00122
00123
00124
00125
00126
#ifdef MMCLONGDEBUG
00127
{
00128
unsigned int i;
00129 ConsoleWrite(
"\rMMCWaitForData failed. ");
00130 ConsoleWrite(
"Expected 0xFE token, received: ");
00131
for (i=0;i<550;i++){
00132 ConsolePutHex8(c);
00133 c=
SPIGetChar();
00134 }
00135 }
00136
#else
00137
SPI8Clocks(200);
00138
SPI8Clocks(200);
00139
SPI8Clocks(200);
00140
#endif
00141
00142
MMC_XCS =
MMC_NOT_SELECTED;
00143 DebugMessage(
"!t>");
00144
return 5;
00145
00146 }
00147
00148 DebugMessage(
"t>");
00149
return 0;
00150
00151 }
00152
00153
00159 void MmcGetData(
unsigned int amountOctets){
00160 DebugMessage(
"<G");
00161
00162
dataBufPtr =
diskSect.
raw.
buf;
00163
while (amountOctets--){
00164 *
dataBufPtr++=
SPIGetChar();
00165 }
00166 DebugMessage(
"G>");
00167 }
00168
00169
00171 unsigned char GetStorageInformation(){
00172
if (
MmcCommand(0x4a,0,0,0,0)&0xfe)
00173
return 4;
00174
MmcWaitForData();
00175
MmcGetData(30);
00176
00177 ConsoleWrite(
"\rMMC Manufacturer#: ");
00178 ConsolePutUInt(
diskSect.
raw.
buf[0]);
00179 ConsoleWrite(
"Product Name: ");
00180 ConsolePutChar(
diskSect.
raw.
buf[3]);
00181 ConsolePutChar(
diskSect.
raw.
buf[4]);
00182 ConsolePutChar(
diskSect.
raw.
buf[5]);
00183 ConsolePutChar(
diskSect.
raw.
buf[6]);
00184 ConsolePutChar(
diskSect.
raw.
buf[7]);
00185 ConsolePutChar(
diskSect.
raw.
buf[8]);
00186 ConsoleWrite(
" Production date: ");
00187 ConsolePutUInt(
diskSect.
raw.
buf[14]>>4);
00188 ConsoleWrite(
"/ ");
00189 ConsolePutUInt((
diskSect.
raw.
buf[14]&0x0f)+1997);
00190 ConsolePutChar(
'\r');
00191 ConsoleWrite(
"Media serial number: ");
00192 ConsolePutHex8(
diskSect.
raw.
buf[10]);
00193 ConsolePutHex8(
diskSect.
raw.
buf[11]);
00194 ConsolePutHex8(
diskSect.
raw.
buf[12]);
00195 ConsolePutHex8(
diskSect.
raw.
buf[13]);
00196 ConsolePutChar(
'\r');
00197
00198
00199
00200
00201
00202
00203
00204
00205
return 0;
00206 }
00207
00208
00209
00211 unsigned char RebootMMC(){
00212
unsigned char c;
00213
00214
00215
do{
00216
00217
MmcCommand(0x7B,0,0,0,0);
00218
00219 }
while (
MmcCommand(0x40,0,0,0,0)!=0x01);
00220
00221
00222 ConsoleWrite(
"Card found, starting... ");
00223
00224 c=255;
00225
while ((c--)&&(
MmcCommand(0x41,0,0,0,16))){
00226
Delay(10);
00227
if (c==1){
00228
00229 ConsoleWrite(
"Failed.\r");
00230
return 2;
00231 }
00232 }
00233
00234 ConsoleWrite(
"Ok.\r");
00235
return 0;
00236 }
00237
00238
00239 Public unsigned char InitMMC(){
00240
unsigned char c;
00241
00242
00243
MMC_OFF =
YES;
00244 ConsoleWrite (
"Init: MMC\r");
00245
Delay(100);
00246
00247
00248
MMC_OFF =
NO;
00249
Delay(100);
00250
00251
00252
for (c=0; c<200; c++){
00253
SPIPutCharWithoutWaiting(0xff);
00254
SPIWait();
00255 }
00256
Delay(20);
00257
00258
if (
RebootMMC())
return 1;
00259
00260
00261
GetStorageInformation();
00262
00263
00264
if ((c=
MmcCommand(0x50,0,0,2,0)))
return c|0x80;
00265
00266
00267
00268
00269
00270 {
00271
if (
SeekSector(0))
return 2;
00272
if (
ReadPhysicalSector())
return 2;
00273
00274
temp.
i =
diskSect.
raw.
buf[511];
00275
for (c=0; c<250; c++){
00276
temp.
i +=
diskSect.
raw.
buf[c];
00277 }
00278
00279
if (
SeekSector(0))
return 2;
00280
00281
00282
MMC_XCS =
MMC_NOT_SELECTED;
00283
SPIPutCharWithoutWaiting(0xff);
00284
for (c=0; c<100; c++){
00285
SPIPutChar(0xff);
00286 }
00287
SPIWait();
00288
00289
if (
ReadPhysicalSector()){
00290 ConsoleWrite(
"Interrupted read failed.\r");
00291 ConsoleWrite(
"Using compatibility mode.\r");
00292
return 0x0e;
00293
00294 }
else{
00295
00296
temp.
i -=
diskSect.
raw.
buf[511];
00297
for (c=0; c<250; c++){
00298
temp.
i -=
diskSect.
raw.
buf[c];
00299 }
00300 }
00301
00302
if (
temp.
i) {
00303 ConsoleWrite(
"This MMC has no support for interrupted read. ");
00304 ConsoleWrite(
"Using compatibility mode.\r");
00305
return 0x0e;
00306 }
00307
00308 ConsoleWrite(
"\rInitMMC ok.\r");
00309 }
00310
00311
00312
return 0;
00313
00314 }
00315
00316
00319 void PerformBlockRead(){
00320
00321
#ifdef MMCDEBUG
00322
ConsoleWrite(
"<R");
00323
#endif
00324
00325
00326
00327
dataBufPtr =
diskSect.
raw.
buf;
00328
while (
dataBufPtr <
diskSect.
raw.
buf+512){
00329
SPIPutCharWithoutWaiting(0xff);
00330
SPIWait();
00331 *
dataBufPtr++=
SPI_RESULT_BYTE;
00332
SPIPutCharWithoutWaiting(0xff);
00333
SPIWait();
00334 *
dataBufPtr++=
SPI_RESULT_BYTE;
00335
SPIPutCharWithoutWaiting(0xff);
00336
SPIWait();
00337 *
dataBufPtr++=
SPI_RESULT_BYTE;
00338
SPIPutCharWithoutWaiting(0xff);
00339
SPIWait();
00340 *
dataBufPtr++=
SPI_RESULT_BYTE;
00341
SPIPutCharWithoutWaiting(0xff);
00342
SPIWait();
00343 *
dataBufPtr++=
SPI_RESULT_BYTE;
00344
SPIPutCharWithoutWaiting(0xff);
00345
SPIWait();
00346 *
dataBufPtr++=
SPI_RESULT_BYTE;
00347
SPIPutCharWithoutWaiting(0xff);
00348
SPIWait();
00349 *
dataBufPtr++=
SPI_RESULT_BYTE;
00350
SPIPutCharWithoutWaiting(0xff);
00351
SPIWait();
00352 *
dataBufPtr++=
SPI_RESULT_BYTE;
00353
SPIPutCharWithoutWaiting(0xff);
00354
SPIWait();
00355 *
dataBufPtr++=
SPI_RESULT_BYTE;
00356
SPIPutCharWithoutWaiting(0xff);
00357
SPIWait();
00358 *
dataBufPtr++=
SPI_RESULT_BYTE;
00359
SPIPutCharWithoutWaiting(0xff);
00360
SPIWait();
00361 *
dataBufPtr++=
SPI_RESULT_BYTE;
00362
SPIPutCharWithoutWaiting(0xff);
00363
SPIWait();
00364 *
dataBufPtr++=
SPI_RESULT_BYTE;
00365
SPIPutCharWithoutWaiting(0xff);
00366
SPIWait();
00367 *
dataBufPtr++=
SPI_RESULT_BYTE;
00368
SPIPutCharWithoutWaiting(0xff);
00369
SPIWait();
00370 *
dataBufPtr++=
SPI_RESULT_BYTE;
00371
SPIPutCharWithoutWaiting(0xff);
00372
SPIWait();
00373 *
dataBufPtr++=
SPI_RESULT_BYTE;
00374
SPIPutCharWithoutWaiting(0xff);
00375
SPIWait();
00376 *
dataBufPtr++=
SPI_RESULT_BYTE;
00377 }
00378
00379
#ifdef MMCDEBUG
00380
ConsoleWrite(
"R>");
00381
#endif
00382
00383 }
00384
00386 void ConsoleDecipherMMCResponse(
unsigned char c){
00387
00388 ConsoleWrite (
"\rSeek failed, MMC returns ");
00389 ConsolePutHex8 (c);
00390 ConsoleWrite (
"h (");
00391
00392
if (c&128) ConsoleWrite(
"which is NOT an R1 response!!");
00393
else{
00394
if (c&64) ConsoleWrite(
"ParameterError ");
00395
if (c&32) ConsoleWrite(
"AddressError ");
00396
if (c&16) ConsoleWrite(
"EraseSequenceError ");
00397
if (c&8) ConsoleWrite(
"CommandCrcError ");
00398
if (c&4) ConsoleWrite(
"IllegalCommandCode ");
00399
if (c&2) ConsoleWrite(
"EraseCancelled ");
00400
if (c&1) ConsoleWrite(
"Idle ");
00401 }
00402
00403 ConsoleWrite (
") for sector ");
00404 ConsolePutUInt (
sectorAddress.
l);
00405 ConsoleWrite(
".\rFurther reading data returns: \r");
00406
for (c=0; c<255; c++){
00407 ConsolePutHex8(
SPIGetChar());
00408 }
00409 ConsolePutChar(13);
00410
while (!
KEY_BUTTON);
00411
00412
00413 }
00414
00415
00416
00417
00418 Public unsigned char SeekSector(
unsigned long sectorN){
00419
00420
unsigned char c;
00421
00422
#ifdef MMCDEBUG
00423
ConsoleWrite(
"{s");
00424
#endif
00425
00426
do{
00427
sectorAddress.
l = sectorN * 2;
00428 c=
MmcCommand(0x51,
sectorAddress.
b.
b2,
sectorAddress.
b.
b1,
00429
sectorAddress.
b.
b0, 0);
00430
sectorAddress.
l =
sectorAddress.
l >> 1;
00431
00432
00433
00434
if ((c==0xff)||(c==0x81)){
00435 c=0xff;
00436
RebootMMC();
00437 }
00438
if (c==0x01){
00439 c=0xff;
00440 }
00441
00442 }
while(c==0xff);
00443
00444
if ((c & 0xfe)){
00445
ConsoleDecipherMMCResponse(c);
00446
MMC_XCS =
MMC_NOT_SELECTED;
00447
00448
#ifdef MMCDEBUG
00449
ConsoleWrite(
"!s}");
00450
#endif
00451
return 7;
00452 }
00453
00454
MMC_XCS =
MMC_NOT_SELECTED;
00455
00456
#ifdef MMCDEBUG
00457
ConsoleWrite(
"s}");
00458
#endif
00459
return 0;
00460 }
00461
00462
00463
00464 Public unsigned char ReadPhysicalSector(){
00465
00466
RED_LED =
LED_ON;
00467
00468
MMC_XCS =
MMC_SELECTED;
00469
MmcWaitForData();
00470
PerformBlockRead();
00471
00472
00473
00474
SPI8Clocks(4);
00475
MMC_XCS =
MMC_NOT_SELECTED;
00476
SPI8Clocks(4);
00477
00478
RED_LED =
LED_OFF;
00479
00480
return 0;
00481 }
00482
00483
00485 unsigned char WritePhysicalSector(){
00486
unsigned char c;
00487
00488
#ifdef MMCDEBUG
00489
ConsoleWrite(
"<W");
00490
#endif
00491
00492
RED_LED =
LED_ON;
00493
sectorAddress.
l =
sectorAddress.
l * 2;
00494 c=
MmcCommand(24 | 0x40 ,
sectorAddress.
b.
b2,
sectorAddress.
b.
b1,
00495
sectorAddress.
b.
b0, 0);
00496
sectorAddress.
l =
sectorAddress.
l >> 1;
00497
MMC_XCS =
MMC_SELECTED;
00498
00499
00500
dataBufPtr =
diskSect.
raw.
buf;
00501
SPIPutCharWithoutWaiting(0xFE);
00502
SPIWait();
00503
00504
for (c=0;c<128;c++){
00505
SPIPutCharWithoutWaiting(*
dataBufPtr++);
00506
SPIWait();
00507
SPIPutCharWithoutWaiting(*
dataBufPtr++);
00508
SPIWait();
00509
SPIPutCharWithoutWaiting(*
dataBufPtr++);
00510
SPIWait();
00511
SPIPutCharWithoutWaiting(*
dataBufPtr++);
00512
SPIWait();
00513 }
00514
00515
MmcWaitForData();
00516
while (
SPIGetChar()==0)
00517 ;
00518
00519
#ifdef MMCDEBUG
00520
ConsoleWrite(
"W>");
00521
#endif
00522
00523
00524
SPI8Clocks(16);
00525
MMC_XCS =
MMC_NOT_SELECTED;
00526
SPI8Clocks(16);
00527
00528
RED_LED =
LED_OFF;
00529
00530 }
00531
00532