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 239 of file mmc.c.

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

Referenced by InitStorage(), and OpenFile().

00239 { 00240 unsigned char c; 00241 00242 //Switch off the MMC power supply 00243 MMC_OFF = YES; 00244 ConsoleWrite ("Init: MMC\r"); 00245 Delay(100); 00246 00247 //Switch on the MMC power supply 00248 MMC_OFF = NO; 00249 Delay(100); 00250 00251 /* Allow MMC some time and clock cycles to reset */ 00252 for (c=0; c<200; c++){ 00253 SPIPutCharWithoutWaiting(0xff); 00254 SPIWait(); 00255 } 00256 Delay(20); 00257 00258 if (RebootMMC()) return 1; //not able to powerup; 00259 //An existing MMC card should be able to respond now. 00260 00261 GetStorageInformation(); 00262 00263 /* Set Block Size of 512 bytes (2 == 512 << 8) */ 00264 if ((c=MmcCommand(0x50,0,0,2,0))) return c|0x80; /* blocksize error */ 00265 00266 /* Check if MMC supports interrupted data transfer */ 00267 /* This does a simple checksum check to see if interrupted and 00268 * non-interrupted read blocks are the same. */ 00269 /* This could be a function, so it is in braces for clarity purposes */ 00270 { 00271 if (SeekSector(0)) return 2; //Storage powerup failure 00272 if (ReadPhysicalSector()) return 2; //Storage powerup failure 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;//Storage powerup failure 00280 00281 /* Send some extra SPI clocks */ 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; //ok but no support for seek-before-read 00293 00294 }else{ 00295 //Check if received data was same 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) { /* Checksum does not match */ 00303 ConsoleWrite("This MMC has no support for interrupted read. "); 00304 ConsoleWrite("Using compatibility mode.\r"); 00305 return 0x0e; //ok but no support for seek-before-read 00306 } 00307 00308 ConsoleWrite("\rInitMMC ok.\r"); 00309 } 00310 00311 /* All OK return */ 00312 return 0; //ok and MMC supports seek-before-read 00313 00314 }

Here is the call graph for this function:

unsigned char ReadPhysicalSector  ) 
 

Perform block read of previously sought sector to diskSect.

Definition at line 464 of file mmc.c.

References LED_OFF, LED_ON, MMC_NOT_SELECTED, MMC_SELECTED, MMC_XCS, MmcWaitForData(), PerformBlockRead(), Public, RED_LED, and SPI8Clocks().

Referenced by InitMMC(), and ReadDiskSector().

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

Here is the call graph for this function:

unsigned char SeekSector unsigned long  sectorN  ) 
 

Perform MMC Seek Command for offset sectorN*512.

Definition at line 418 of file mmc.c.

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

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

00418 { 00419 00420 unsigned char c; 00421 00422 #ifdef MMCDEBUG 00423 ConsoleWrite("{s"); //Seek called 00424 #endif 00425 00426 do{ 00427 sectorAddress.l = sectorN * 2; //convert to bytes (combined with 8bit shift) 00428 c=MmcCommand(0x51,sectorAddress.b.b2,sectorAddress.b.b1, 00429 sectorAddress.b.b0, 0); 00430 sectorAddress.l = sectorAddress.l >> 1; //convert back to blocks 00431 00432 //if MMC returs "nothing" (0xff) or 0x81(busy), 00433 //toggle chip select and retry 00434 if ((c==0xff)||(c==0x81)){ 00435 c=0xff; 00436 RebootMMC(); 00437 } 00438 if (c==0x01){ //MMC says "busy" 00439 c=0xff; //try again 00440 } 00441 00442 }while(c==0xff); //repeat until we get signal from MMC. 00443 00444 if ((c & 0xfe)){ //MMC returns something else than idle or busy signal 00445 ConsoleDecipherMMCResponse(c); 00446 MMC_XCS = MMC_NOT_SELECTED; 00447 00448 #ifdef MMCDEBUG 00449 ConsoleWrite("!s}"); 00450 #endif 00451 return 7; /* failed to execute mmc command */ 00452 } 00453 00454 MMC_XCS = MMC_NOT_SELECTED; 00455 00456 #ifdef MMCDEBUG 00457 ConsoleWrite("s}"); 00458 #endif 00459 return 0; //ok return 00460 }

Here is the call graph for this function:

unsigned char WritePhysicalSector  ) 
 

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

Definition at line 485 of file mmc.c.

References Address::b, Address::B::b0, Address::B::b1, Address::B::b2, DiskBlock::Raw::buf, dataBufPtr, diskSect, Address::l, LED_OFF, LED_ON, MMC_NOT_SELECTED, MMC_SELECTED, MMC_XCS, MmcCommand(), MmcWaitForData(), DiskBlock::raw, RED_LED, sectorAddress, SPI8Clocks(), SPIGetChar(), SPIPutCharWithoutWaiting, and SPIWait.

Referenced by WriteDiskSector().

00485 { 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; //convert to bytes (combined with 8bit shift) 00494 c=MmcCommand(24 | 0x40 ,sectorAddress.b.b2,sectorAddress.b.b1, 00495 sectorAddress.b.b0, 0); 00496 sectorAddress.l = sectorAddress.l >> 1; //convert back to blocks 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(); //Wait for 0xFE token 00516 while (SPIGetChar()==0) 00517 ; // Wait until MMC not busy. 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 }

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