CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Help with new style MMC card

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
epideath



Joined: 07 Jun 2006
Posts: 47

View user's profile Send private message

Help with new style MMC card
PostPosted: Wed Aug 16, 2006 5:33 pm     Reply with quote

Hi All,

I have had this code working flawlessly with the original MMC card that I had purchased. it has a single row of 7 contacts just like you would see on any of the web sites talking about interfacing to an MMC card.

Well my problem lies in the fact that I can't seem to find one like that anywhere. All I can find is the cards that have a second row of contacts. This is a SD card. it is supposedly backwards compatible with older MMC cards.

I can't seem to find any datasheets on this style. So I still use the Sandisk version.

My problem is that the cards passes the initialization commands. But when I try to do a read or write command I'm not getting a zero response for success. I am getting 0xFF always.

Is there anyone out there that can elighten me on what might be the differences in thes cards?

I'll post some of my code. just for reference. But it does work without problem with the older MMC card if I plug it in to my hardware.

Just as a side note I do share the SPI line with a seral EEPROM and a DAC.

The PIC chip I use is an 18F4520 using internal oscillator set at 8MHz.

Thanks for any help.

Code:

   setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_64);   //|SPI_SAMPLE_AT_END);


Code:

/******************************************************************/
/* Sends the MMC command through SPI port to MMC                  */
/* Format 0xFF, command, address MSB-LSB, checksum, 0xFF.         */
/* Returns the status of the command action                       */
/******************************************************************/   
int8 MMC_Command(int8 cmd, int32 addr)
{
   int8 out[8];
   int8 i;

   //Prepare the command data to send to MMC
   out[0] = 0xFF;
   out[1] = cmd | 0x40;
   out[5] = make8(addr,0);
   out[4] = make8(addr,1);
   out[3] = make8(addr,2);
   out[2] = make8(addr,3);
   if(cmd == 0)
      out[6] = 0x95;
   else
      out[6] = 0xFF;
   out[7] = 0xFF;

   //Send the commad to MMC
   for(i=0; i<8; i++)
      spi_write(out[i]);
   //Return the status of the MMC command
   return spi_read(0);
}

/******************************************************************/
/* Reads the selected MMC block. Blocks are in 512 byte chunks    */
/* This funxtion will read the raw recipe data from the MMC card  */
/* This will then be transferred to the EEPROM.                   */
/******************************************************************/ 
int8 MMC_Read(int16 block)
{
   int32 addr;
   int8 r1, i,j,k;
   int16 to;

   addr = (int32)block*512;
   output_low(PIN_C7);
   r1 = MMC_Command(17, addr);
   for(to=0;to<1024;to++){
       r1=SPI_READ(0xFF);
        if (r1==0x00) goto ReadToken; // read token $00
   }
   lcd_setCursor(0,11,NORMAL);
   printf(LCD_putc,"CMD RESP. ERROR  ");
   goto ReadError;
ReadToken:
   for(to=0;to<1024;to++){
         r1=SPI_READ(0xFF);
        if (r1==0xFE) goto ReadData; // read token $FE
   }
   lcd_setCursor(0,11,NORMAL);
   printf(LCD_putc,"DATA START ERROR ");
   goto ReadError;

ReadData:
   lcd_setCursor(0,11,NORMAL);
   printf(LCD_putc,"Read Data");
   _blockValid = spi_read(0);
   for(i=0; i<8; i++) {
      for(j=0; j<24; j++)
         rawProgramA[i][j] = spi_read(0);   //Read first half of program
      for(k=0; k<8; k++)      //read in the 8 bytes to make 32 bytes total
         r1 = spi_read(0);
   }
   for(i=0; i<7; i++) {
      for(j=0; j<24; j++)
         rawProgramB[i][j] = spi_read(0);   //Read second half of program
      for(k=0; k<8; k++)      //read in the 8 bytes to make 32 bytes total
         r1 = spi_read(0);
   }
   for(k=0; k<31; k++)
      r1 = spi_read(0);   //read in 32 more bytes to make a total of 512 bytes
   spi_write(0xFF);
   output_high(PIN_C7);
   spi_write(0xFF);
   return TRUE;
ReadError:
   spi_write(0xFF);
   output_high(PIN_C7);
   spi_write(0xFF);
   return FALSE;
}

/******************************************************************/
/* Writes the selected MMC block. Blocks are in 512 byte chunks   */
/* This funxtion will write the raw recipe data to the MMC        */
/* The raw data written will be previously loaded from the EEPROM.*/
/******************************************************************/   
int1 MMC_Write(int16 block, int1 erase)
{
   int8 r1, i,j,k;
   int16 to;
   int32 addr;


   addr = (int32)block*512;
   output_low(PIN_C7);
   to = 20;

   r1 = MMC_Command(24, addr);
WriteRetry1:
   if(r1 != 0) {
      delay_ms(10);
      r1 = spi_read(0);
      if(--to)
         goto WriteRetry1;
      else {
         lcd_setCursor(0,11,NORMAL);
         printf(LCD_putc,"CMD RESP. ERROR ");
         goto WriteError;
      }
   }
   spi_write(0xFF);
   spi_write(0xFF);
   spi_write(0xFE);

   if(erase) {
      spi_write(0);   //Flag the block is empty or invalid
      for(to=0; to<511; to++)
         spi_write('0');
   }
   else {
      spi_write(1);   //Flag that this block is a valid program
      for(i=0; i<8; i++) {      //write first 256 bytes
         for(j=0; j<24; j++)
            spi_write(rawProgramA[i][j]);
      for(k=0; k<8; k++)
         spi_write(0);      //fill data for 32 bytes per write
   }
   for(i=0; i<7; i++) {      //write second 256 bytes
      for(j=0; j<24; j++)
         spi_write(rawProgramB[i][j]);   
      for(k=0; k<8; k++)
         spi_write(0);      //fill data for 32 bytes per write
   }
   for(k=0; k<31; k++)
      spi_write(0);      //fill up the rest of the block for a total of 512 bytes.
   }

   spi_write(0xFF);
   spi_write(0xFF);

WriteRetry2:
   for(to=0;to<1024;to++){
         r1=SPI_READ(0xFF);
      r1 &= 0x0F;
        if (r1==0x05) goto WriteValid; // read token $FE
   }
   goto WriteError;
WriteValid:
   for(to=0;to<1024;to++){
         r1=SPI_READ(0xFF);
        if (r1==0xFF) goto WriteDone; // read token $FE
   }
   goto WriteError;
WriteDone:
   spi_write(0xFF);
   output_high(PIN_C7);
   spi_write(0xFF);
   return TRUE;

WriteError:
   spi_write(0xFF);
   output_high(PIN_C7);
   spi_write(0xFF);
   return FALSE;
}
/******************************************************************/
/* Initializes the MMC. If the MMC is not present or there is a   */
/* problem with it an error is returned                           */
/******************************************************************/   
int1 MMC_Initialize(void)
{
   int8 i; //, r1;
   int8 to = 20;

   output_high(PIN_C7);   //MMC select off
   for(i=0; i < 20; i++)
      spi_write(0xFF);
   output_low(PIN_C7);
   if(MMC_Command(0x00, 0) != 1)
      goto ErrorMMC;
MMCLoop:
   if(MMC_Command(0x01, 0) != 0)
   {
      delay_ms(10);
      if(--to)
         goto MMCLoop;
      else
         goto ErrorMMC;
   }
   spi_write(0xFF);
   output_high(PIN_C7);
   spi_write(0xFF);
   return TRUE;

ErrorMMC:
   spi_write(0xFF);
   output_high(PIN_C7);
   spi_write(0xFF);
   return FALSE;
}


Thanks for any help. Much appreciated.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 16, 2006 11:58 pm     Reply with quote

Quote:
All I can find is the cards that have a second row of contacts.
This is a SD card.

How do you know it's an SD card ? If I do a Google search for:
"sd card" pinout
I get hits like this, that show 9 pins:
http://www.interfacebus.com/Secure_Digital_Card_Pinout.html

Post the manufacturer and part number of the card.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Aug 17, 2006 1:56 am     Reply with quote

Most likely you have an MMC Plus card, this is the only card I know with two rows of contacts and is backwards compatible to the standard MMC cards. Check http://www.mobilehandsetdesignline.com/howto/showArticle.jhtml?articleID=189601225 for a description and pinout example.
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Thu Aug 17, 2006 3:18 am     Reply with quote

If you're making the correct electrical connection to the 7 backwards compatible (with MMC) pins then possibly the SPI mode may not be the same.
Try a different combination for SPI_H_TO_L |SPI_XMIT_L_TO_H
in your setup_spi statement
Permutations of SPI_H_TO_L |SPI_XMIT_L_TO_H yield 4 modes 0 1 2 3
MMC may not exactly comply with SPI specs but it most often works in mode 0 or even in mode3
I believe most SD cards only work in Mode 0

CMD1 (aka init) on MMC may need to be changed to ACMD41 for SD.
If CMD1 doen't work for your card then try ACMD41
So much for consistency but if you pay thousands of dollars and join the exclusive documentation club the standard committee might let you know about the next quirky variation on the standard they came up with after lunch.
Also often the bigger the capacity of the cards the longer it takes to get them iniatlized over to SPI.. you may need to extend the initial polling time.
Kenny



Joined: 07 Sep 2003
Posts: 173
Location: Australia

View user's profile Send private message

PostPosted: Thu Aug 17, 2006 5:10 am     Reply with quote

I have a similar problem with the Pretec 512MB MMC Plus cards, although the Kingston 512MB MMC Plus ones work fine.
Both are a fraction of the cost of equivalent size MMC here, so it would be nice to sort this out.
The differences between MMC and MMC plus are described here

http://www.mmca.org/compliance/buy_spec/AN_MMCA050419.pdf

When I get back from a break I'll try Douglas Kennedy's suggestion with different spi modes and initialisation, thanks for the tip.
epideath



Joined: 07 Jun 2006
Posts: 47

View user's profile Send private message

PostPosted: Thu Aug 17, 2006 8:50 am     Reply with quote

Thanks much for the quick responses. It is good to see a data sheet on these MMC Plus cards. hehe I didn't even know what they where called. again thanks alot. I will look over all of the information. I will elt you know what I find out if I get it working.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group