|
|
View previous topic :: View next topic |
Author |
Message |
epideath
Joined: 07 Jun 2006 Posts: 47
|
Help with new style MMC card |
Posted: Wed Aug 16, 2006 5:33 pm |
|
|
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
|
|
Posted: Wed Aug 16, 2006 11:58 pm |
|
|
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
|
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Thu Aug 17, 2006 3:18 am |
|
|
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
|
|
Posted: Thu Aug 17, 2006 5:10 am |
|
|
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
|
|
Posted: Thu Aug 17, 2006 8:50 am |
|
|
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. |
|
|
|
|
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
|