pic with mmc circuit

pankajkumar

Joined Apr 15, 2009
9
sorry, by mistake i have posted same in other thread also....

I am using pic18lf452 to write image data(HEX) on MMC and then read back.
MCC 18 platform is used while ICD 2 is used for programming.
I have simulated code on PROTEUS and its working. But on hardware I am facing the problem.

pic and mmc communicating in SPI mode.
MMC is accepting cmd0(reset) and cmd1(initialization), but not other cmds. I am sending cmd16 after cmd0&1 to set block length but every time i get a timeout.
I have used voltage divider to bring 5v of pic to 3.3v for mmc.
If anybody has any idea regarding this please post.

steinar96

Joined Apr 18, 2009
239
Voltage dividers are quite bad for this usage. It's very poorly regulated and ineffecient. Varying loads means changing voltages. The mmc might easily lock up if it can't handle voltage swings around the 3.3V point very well.

mik3

Joined Feb 4, 2008
4,846
Use voltage regulator IC top regulate the voltage down to 3.3V. The voltage of a voltage divider varies with current.

davebee

Joined Oct 22, 2008
539
According to a Sandisk SD document:

"The default block length is as specified in the CSD (512 bytes). A set block length of less than 512 bytes will cause a write error. The only valid write set block length is 512 bytes. CMD16 is not mandatory if the default is accepted."

I don't know if MMC cards are just like SD cards for this command, but they are identical in many ways, so maybe your MMC card has a restriction on what a valid block length may be.

Maybe it would make sense for you to first go with the default blocklength of 512 bytes, get basic data reads and writes working, then try changing the blocklength if you really need to.

pankajkumar

Joined Apr 15, 2009
9
Thanks 4 ur ideas
@davebee
I made some changes in my code. Now I am sending mmc block write cmd instead of cmd for setting blocklength after cmd 0&1. But still I am getting a timeout, that is cmd is not accepted. so ultimately the situation is same.

davebee

Joined Oct 22, 2008
539
Another thing you could do is format the card for a PC FAT filesystem then verify that the DOS FAT signature $55AA is correctly read from the last two bytes of sector zero. I would say forget about trying to write to the card until you can show a working read. Thread Starter pankajkumar Joined Apr 15, 2009 9 Hello all @davebee thanks 4 ur idea i ll try read in place of write. But I want to share something about latest status as I have 18LF452, I can operate it at 3.3V also. In that case there is no need of voltage divider before mmc and I have connected spi pins of pic and mmc directly but still write cmd wasn't accepted after cmd0 &1. Now I ll try read also. Thread Starter pankajkumar Joined Apr 15, 2009 9 Hello all I tried sending read command , CSD command after cmd 0 & 1 but all in vain. neither read nor CSD command's response is 0x00 ie cmd itself is not accepted. i cant understand its a problem of code or hardware. Here is some part of code i am using int mmc_read_block(unsigned long block_number) { unsigned long i; //unsigned long varh,varl; //varl=((block_number&0x003F)<<9); //varh=((block_number&0xFFC0)>>7); SPI_CS = 0; // set SS = 0 (on) SPI_WRITE(0x51); // send mmc read single block command SPI_WRITE(0x00)); // arguments are address SPI_WRITE(0x00)); SPI_WRITE(0x00)); SPI_WRITE(0x00); SPI_WRITE(0xFF); // checksum is no longer required but we always send 0xFF SPI_WRITE(0xFF); //dummy if((mmc_response(0x00))==1) return 1; // if mmc_response returns 1 then we failed to get a 0x00 response (affirmative) puts("Got response to read block command\n\r"); if((mmc_response(0xFE))==1) return 1; // wait for data token puts("Got data token\n\r"); for(i=0;i<512;i++) { SPI_READ(); // we should now receive 512 bytes } SPI_READ(); // CRC bytes that are not needed SPI_READ(); SPI_CS=1; // set SS = 1 (off) SPI_WRITE(0xFF); // give mmc the clocks it needs to finish off puts("\n\rEnd of read block\n\r"); return 0; } I am getting return 1 ie command response is not correct Thanks Papabravo Joined Feb 24, 2006 12,388 In the specification JEDS84-B41, section 9.5.7, p.90, it says: The host must poll the card (by repeatedly sending CMD1) until the in-idle-state bit in the card response indicates (by being set to 0) that the card has completed its initialization processes and is ready for the next command. In my implementation, which responds only to manual input from the keyboard, it takes two CMD1 commands before the "In-Idle-State" bit goes to '0'. You did not say what value was returned in the R1 status byte, but I'm guessing it was a value like 0x05, which means that the card was still "In-Idle-State" and there was an illegal command/switch. After the second CMD1 the "In-Idle-State" bit was 0 and I have successfully issued commands CMD10 to read the CID register, CMD13 to read the status, and CMD58 to read the OCR. Thread Starter pankajkumar Joined Apr 15, 2009 9 @ papabravo In my code i am sending cmd0 once after that cmd1 with polling ie i ll be sending cmd1 again n again (255 times before timeout) until it gets 0x00. I am comparing return of SPI_Read with 0x00 only. right now i am not with hardware but at best of my knowledge i was also getting cmd1 acceptance response after sending it twice. Thanks Papabravo Joined Feb 24, 2006 12,388 The other point is that you really should get copies of the JEDEC specs for the MMC cards. The SD card specs from San-Disk will lead you astray. davebee Joined Oct 22, 2008 539 What does your mmc_response($FE) call do?
Looking over code that's worked for me, I've found that after enabling the CS, sending $51, sending the 4 byte address, then$FF, I had to loop repeatedly, several hundred times sometimes, sending $FF and looking for$FE in the response, in order to allow the card time to perform the read.