VLSI Solution Oy VLSI Solution Oy Evaluation MP3 Player Source Code Documentation

Main Page | Class List | File List | Class Members | File Members | Related Pages

mmc.h File Reference

MMC interface routines for storage.c. More...

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Functions

unsigned char InitMMC ()
 Start-up the MMC card.

unsigned char SeekSector (unsigned long sectorN)
 Perform MMC Seek Command for offset sectorN*512.

unsigned char ReadPhysicalSector ()
 Perform block read of previously sought sector to diskSect.

unsigned char WritePhysicalSector ()
 Perform MMC block write from *dataBufPtr to sector sectorAddress.l.


Variables

xdata unsigned char storageFlags
 Storage status flags.


Detailed Description

MMC interface routines for storage.c.

Definition in file mmc.h.


Function Documentation

unsigned char InitMMC  ) 
 

Start-up the MMC card.

  • Returns 0 when successful and supports seek-before-read
  • Returns 0x0e when successful but no support for seek-before-read
  • Returns 1 when MMC card is not found
  • Returns 2 when MMC card seems to be present but can't be read from.

Definition at line 246 of file mmc.c.

References DiskBlock::Raw::buf, Delay(), diskSect, GetStorageInformation(), Temp::i, MMC_OFF, MmcCommand(), MMCDeselect, MMCSelect, NO, Public, DiskBlock::raw, ReadPhysicalSector(), RebootMMC(), SeekSector(), SPIPutChar, SPIPutCharWithoutWaiting, SPIWait, temp, and YES.

Referenced by InitStorage(), and OpenFile().

00246 { 00247 unsigned char c; 00248 00249 //Switch off the MMC power supply 00250 MMC_OFF = YES; 00251 00252 ConsoleWrite ("Init: MMC\r"); 00253 Delay(100); 00254 00255 //Switch on the MMC power supply 00256 MMC_OFF = NO; 00257 Delay(100); 00258 00259 MMCSelect(); 00260 /* Allow MMC some time and clock cycles to reset */ 00261 for (c=0; c<200; c++){ 00262 SPIPutCharWithoutWaiting(0xff); 00263 SPIWait(); 00264 } 00265 Delay(20); 00266 00267 if (RebootMMC()) return 1; //not able to powerup; 00268 //An existing MMC card should be able to respond now. 00269 00270 GetStorageInformation(); 00271 00272 /* Set Block Size of 512 bytes (2 == 512 << 8) */ 00273 if ((c=MmcCommand(0x50,0,0,2,0))) return c|0x80; /* blocksize error */ 00274 00275 /* Check if MMC supports interrupted data transfer */ 00276 /* This does a simple checksum check to see if interrupted and 00277 * non-interrupted read blocks are the same. */ 00278 /* This could be a function, so it is in braces for clarity purposes */ 00279 { 00280 if (SeekSector(0)) return 2; //Storage powerup failure 00281 if (ReadPhysicalSector()) return 2; //Storage powerup failure 00282 00283 temp.i = diskSect.raw.buf[511]; 00284 for (c=0; c<250; c++){ 00285 temp.i += diskSect.raw.buf[c]; 00286 } 00287 00288 if (SeekSector(0)) return 2;//Storage powerup failure 00289 00290 /* Send some extra SPI clocks */ 00291 MMCDeselect(); 00292 SPIPutCharWithoutWaiting(0xff); 00293 for (c=0; c<100; c++){ 00294 SPIPutChar(0xff); 00295 } 00296 SPIWait(); 00297 00298 if (ReadPhysicalSector()){ 00299 ConsoleWrite("Interrupted read failed.\r"); 00300 ConsoleWrite("Using compatibility mode.\r"); 00301 return 0x0e; //ok but no support for seek-before-read 00302 00303 }else{ 00304 //Check if received data was same 00305 temp.i -= diskSect.raw.buf[511]; 00306 for (c=0; c<250; c++){ 00307 temp.i -= diskSect.raw.buf[c]; 00308 } 00309 } 00310 00311 if (temp.i) { /* Checksum does not match */ 00312 ConsoleWrite("This MMC has no support for interrupted read. "); 00313 ConsoleWrite("Using compatibility mode.\r"); 00314 return 0x0e; //ok but no support for seek-before-read 00315 } 00316 00317 ConsoleWrite("\rInitMMC ok.\r"); 00318 } 00319 00320 /* All OK return */ 00321 return 0; //ok and MMC supports seek-before-read 00322 00323 }

Here is the call graph for this function:

unsigned char ReadPhysicalSector  ) 
 

Perform block read of previously sought sector to diskSect.

Definition at line 463 of file mmc.c.

References MMCDeselect, MMCSelect, MmcWaitForData(), PerformBlockRead(), Public, and SPI8Clocks().

Referenced by InitMMC(), and ReadDiskSector().

00463 { 00464 00465 // RED_LED = LED_ON; /* Disk Read LED on */ 00466 00467 MMCSelect(); 00468 MmcWaitForData(); 00469 PerformBlockRead(); 00470 00471 /* generate SPI clock edges to finish up the command */ 00472 00473 SPI8Clocks(4); //Send 8*4=32 clocks (4 ff's) to MMC to be nice. 00474 MMCDeselect(); 00475 SPI8Clocks(4); //Again, give the poor MMC some clocks, it likes them. 00476 00477 //RED_LED = LED_OFF; /* Disk Read LED off */ 00478 00479 return 0; //ok return 00480 }

Here is the call graph for this function:

unsigned char SeekSector unsigned long  sectorN  ) 
 

Perform MMC Seek Command for offset sectorN*512.

In English: Send the Read Sector command to MMC

Definition at line 431 of file mmc.c.

References Address::b, Address::B::b0, Address::B::b1, Address::B::b2, ConsoleDecipherMMCResponse(), Address::l, MmcCommand(), MMCDeselect, Public, RebootMMC(), and sectorAddress.

Referenced by InitMMC(), PrepareToReadDiskSector(), and ReadDiskSector().

00431 { 00432 unsigned char c, retries; 00433 00434 retries = 0; 00435 do{ 00436 retries++; 00437 sectorAddress.l = sectorN * 2; //convert to bytes (combined with 8bit shift) 00438 c=MmcCommand(0x51,sectorAddress.b.b2,sectorAddress.b.b1, 00439 sectorAddress.b.b0, 0); 00440 sectorAddress.l = sectorAddress.l >> 1; //convert back to blocks 00441 00442 // If MMC works properly, it returns Busy (== Not idle) at this stage. 00443 if (c!=0x00){ 00444 if (c != 0xff){ 00445 //MMC returns something else than Busy or "Idle Bus", print what it is 00446 ConsoleDecipherMMCResponse(c); 00447 } 00448 // Something is wrong, take the standard action... 00449 RebootMMC(); 00450 if (retries > 10){ 00451 return 7; /* failed to execute mmc command */ 00452 } 00453 } 00454 }while(c!=0x00); //repeat until we get busy signal from MMC. 00455 00456 MMCDeselect(); 00457 00458 return 0; //ok return 00459 }

Here is the call graph for this function:

unsigned char WritePhysicalSector  ) 
 

Perform MMC block write from *dataBufPtr to sector sectorAddress.l.

Definition at line 484 of file mmc.c.

References Address::b, Address::B::b0, Address::B::b1, Address::B::b2, DiskBlock::Raw::buf, dataBufPtr, diskSect, Address::l, MmcCommand(), MMCDeselect, DiskBlock::raw, sectorAddress, SPI8Clocks(), SPIGetChar(), SPIPutCharWithoutWaiting, and SPIWait.

Referenced by WriteDiskSector().

00484 { 00485 unsigned char c; 00486 00487 #ifdef MMCDEBUG 00488 ConsoleWrite("<W"); 00489 #endif 00490 00491 00492 //RED_LED = LED_ON; 00493 sectorAddress.l = sectorAddress.l * 2; //convert to bytes (combined with 8bit shift) 00494 c=MmcCommand(0x40 | 24, sectorAddress.b.b2, sectorAddress.b.b1, 00495 sectorAddress.b.b0, 0); 00496 sectorAddress.l = sectorAddress.l >> 1; //convert back to blocks 00497 00498 //ConsolePutChar('w'); 00499 //ConsolePutHex8(c); 00500 00501 if (c!=0x00) return (c); //Error - MMC did not go to write mode 00502 00503 /* 00504 while (c!=0x00) { //wait for BUSY token, if you get 0x01(idle), it's an ERROR! 00505 c = SPIGetChar(); 00506 ConsolePutHex8(c); 00507 } 00508 */ 00509 dataBufPtr = diskSect.raw.buf; 00510 SPIPutCharWithoutWaiting(0xFE); 00511 SPIWait(); 00512 00513 for (c=0;c<128;c++){ 00514 SPIPutCharWithoutWaiting(*dataBufPtr++); 00515 SPIWait(); 00516 SPIPutCharWithoutWaiting(*dataBufPtr++); 00517 SPIWait(); 00518 SPIPutCharWithoutWaiting(*dataBufPtr++); 00519 SPIWait(); 00520 SPIPutCharWithoutWaiting(*dataBufPtr++); 00521 SPIWait(); 00522 } 00523 //ConsolePutChar('-'); 00524 00525 c = SPIGetChar(); //crc 1st byte (sends 0xff) 00526 c = SPIGetChar(); //crc 2nd byte (sends 0xff) 00527 c = SPIGetChar(); 00528 //ConsolePutHex8(c); //This prints xxx00101, (usually e5) when data ok 00529 00530 // while (SPIGetChar()!=0xff) //busy wait moved to mmcCommand 00531 // ; // Wait until MMC not busy. 00532 00533 #ifdef MMCDEBUG 00534 ConsoleWrite("W>"); 00535 #endif 00536 00537 00538 SPI8Clocks(16); 00539 MMCDeselect(); 00540 SPI8Clocks(16); 00541 00542 //RED_LED = LED_OFF; 00543 00544 return 0; 00545 }

Here is the call graph for this function:


Variable Documentation

xdata unsigned char storageFlags
 

Storage status flags.

  • Bit 1 (LSB): 1=Device does not support interrupted read
  • Bit 2: 1=A sector is seeked and ready for reading
  • Bit 3: 1=No storage

Definition at line 8 of file mmc.h.

Referenced by InitStorage(), PrepareToReadDiskSector(), and ReadDiskSector().


All software copyright 2000-2004 VLSI Solution OY. Redistribution of these software modules are limited to promotional use only and only with the VS1011 / VS1002 / VS1003 MP3-Evakit evaluation boards. Free or commercial use of these software modules in MP3 players is ok if the product includes MP3 decoder chip(s) from VLSI. You can request the complete (compilable) package from mp3@vlsi.fi