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 support@ccsinfo.com

SD card weirdness

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



Joined: 21 Sep 2006
Posts: 6

View user's profile Send private message

SD card weirdness
PostPosted: Thu Sep 28, 2006 7:52 am     Reply with quote

I've been trying the same setup everyone else has been using (http://www.cc5x.de/MMC/ for example), where I have a 3.3V power source to the SD, and then I use voltage dividers to get the PIC outputs down to 3.3V signals.

I can successfully read and write to the card, but only after I do a certain proceedure. The attached code (modified from http://www.ccsinfo.com/forum/viewtopic.php?t=27823&highlight=card) is what I use to just initialize and read from the card. When I first apply power to the SD card, I have to switch the MMC_DI and MMC_DO pins in software, try to intitialize, then switch the pins back and then everything works fine. Then I can sit and program just fine until I remove power to the MMC card, in which case I have to switch the pins again.

Code:

#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7)

//Define New Pin Out
#define MMC_CS      PIN_E0
#define MMC_CLK      PIN_C3
#define MMC_DI      PIN_C5
#define MMC_DO      PIN_C4
#include<mmc_spi.c>

int8  buffer[512];
int16 size=512;

void main(void)
{
   int32 address=0;
   int8  *ptra;
   int16 f;
   int16 i;

   //initialize buffer
   for (i=0; i<512; i++)
      buffer[i] = 0;

   //set pointer
   ptra = &(buffer[0]);

   //initialization sequence
   printf("\n\rInitializing SD drivers...\n\r");
   if(mmc_init()==0)
      printf("PASSED\n\r");
   else
      printf("FAILED\n\r");

   address = 0;
   while(TRUE)
   {
   while(input(PIN_A4));
   while(!input(PIN_A4));

   //read block
   if(mmc_read_block(address, 512,ptra)==0)
      printf("\n\rread ok\n\r");
   else
      printf("\n\rread fault");

   //print the buffer
   printf("\n\n\r 512 bytes starting at ADDRESS = %lu:\n\r", address);
   for(f=0;f<=511;f++)
      printf("%u ",buffer[f]);

   address += 512;

   }

   while(TRUE)
   {
      output_low(PIN_B4);
      delay_ms(500);
      output_high(PIN_B4);
      delay_ms(500);
   }
}




Does anyone have any suggestions? Some mentioned something about the PIC powering down and not knowing where the SD card went. I'm using the CCS PIC18F452 protoboard right now.[/code]
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Sep 28, 2006 8:52 am     Reply with quote

SD initialization code...

Code:
DSTATUS SD_init(void)
///////////////////////////////////////////////////////////////////////////
//   SD_init()
//
//   Initialize the SPI bus and Memory card
//
///////////////////////////////////////////////////////////////////////////
   {
   int16 i;
   BYTE Response;
   DSTATUS SDCardStatus;

   Card = none;

   DeselectSD;
   delay_ms(10);
   SD_Flush_SPI();

   if (SD_CD)
      {
      printf("ERROR - No Media Detected in the Socket\r\n");
      return(STA_NODISK);
      }

   if (!SD_WP)
      SDCardStatus = STA_PROTECT;
   else
      SDCardStatus = 0;

   SelectSD;
   Response = SD_cmd(SD_CMD_GO_IDLE_STATE,0);
   if ((Response != 0x01) && (Response != 0))
      {
      printf("ERROR - Card not going into Idle state - Response = %x\r\n", Response);
      DeselectSD;
      return(STA_NOINIT | SDCardStatus);
      }

   // Maximum 500ms CMD1 (SD_CMD_SEND_OP_COND) to Ready
   i = 0;
   do
      {
      Response = SD_cmd(SD_CMD_SEND_OP_COND,0);   
      if (Response != 0x00 )
         delay_us(100);
      i++;
      }
   while ((!(Response==0x00)) && (i < 5000));

   if(Response)
      {
      printf("Error - SD card failed to respond to CMD_SEND_OP_COND - Response = %x\r\n", Response);
      DeselectSD;
      return(STA_NOINIT | SDCardStatus);
      }

   // send an SD specific application command
   // and see how the card responds
   //   printf("Attempting card type discovery by sending SD specific application command\r\n");
   Response = SD_cmd(SD_CMD_APPL_CMD,0);
   if (Response)
      {
      // if any response then the card cannot support application commands
      // and therefore cannot be an SD card
      printf("Non Zero response to SD Application command - must be an MMC Card\r\n");
      Card = MMC;
      }
   else
      {
      // send SD_SEND_OP_COND
      Response = SD_cmd(SD_CMD_SD_SEND_OP_COND,0);
      if (!Response)
         {
         printf("OK response from SD specific command - indicates SD card\r\n");
         Card = SD;
         }
      else
         {
         printf("Invalid response to SD Application command - trying MMC init sequence\r\n");
         Card = MMC;

         // reinitialise as MMC card
         Response = SD_cmd(SD_CMD_GO_IDLE_STATE,0);
         if ((Response !=0x01) && (Response != 0))
            {
            printf("Card reset failure - aborting SD card initialization\r\n");
            DeselectSD;
            return(STA_NOINIT | SDCardStatus);
            }
         }
      }

   // Completed card identification
   switch (card)
      {
      case MMC :
         printf("MMC Card found\r\n");
         break;

      case SD :
         printf("SD Card found\r\n");
         break;

      default :
         printf("Card Type Discovery Error - should never get here\r\n");
         DeselectSD;
         return(STA_NOINIT | SDCardStatus);
      }

   printf("Card reset success - Cmd to Ready count = %lu\r\n", i);

   // set the SPI bus speed to high
   setup_spi(spi_master | spi_l_to_h | spi_clk_div_4 | spi_xmit_l_to_h);
   clear_interrupt(INT_SSP);

   i = 0;
   do
      {
      Response = SD_cmd(SD_CMD_SEND_OP_COND,0);   
      if (Response != 0x00 )
         delay_us(100);
      i++;
      }
   while ((!(Response==0x00)) && (i < 100));
   
   if (Response != 0x00)
      {
      DUMMY++;
      printf(" Card activate failure. Card Response = %X\r\n", Status);
      DeselectSD;
      return(STA_NOINIT | SDCardStatus);
      }

   DUMMY++;
   printf(" Card activate success on attempt %lu\r\n",i);
   DeSelectSD;
   return(SDCardStatus);
   }

_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
jgrauer



Joined: 21 Sep 2006
Posts: 6

View user's profile Send private message

PostPosted: Thu Sep 28, 2006 9:03 am     Reply with quote

Thanks for the code, but I'm not sure how to use it. Where do functions(?) like Card, DeselectSD, SD_Flush_SPI, ..., come from?

Is it just a fluke that the MMC initialization file from CCS works with SD cards too? I was reading through the SD manual and it looked like the commands were the same.

Thanks!
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Sep 28, 2006 1:02 pm     Reply with quote

jgrauer wrote:
Thanks for the code, but I'm not sure how to use it. Where do functions(?) like Card, DeselectSD, SD_Flush_SPI, ..., come from?


Card is a variable which holds the type of card information discovered by the SD_init() such as MMC, SD, Unknown

SelectSD and DeSelectSD are defined to assert and deassert the SD Cards CS input.

SD_Flush_SPI is a function to flush the SPI bus.

Quote:

Is it just a fluke that the MMC initialization file from CCS works with SD cards too? I was reading through the SD manual and it looked like the commands were the same.!


The MMC commands are a subset of the SD command set however most embedded applications would simply use the common MMC command set, with one important difference being the initialization sequence. the SD_Init function determines the type of card are initializes it accordingly. If you are initializing an SD card using the MMC initialization sequence then you should not expect the card to function correctly.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
jgrauer



Joined: 21 Sep 2006
Posts: 6

View user's profile Send private message

PostPosted: Thu Sep 28, 2006 1:54 pm     Reply with quote

Thanks a lot for your help. I think I'll just buy an MMC card instead. I was hoping to have something more or less work out of the box, and it looks like CCS's mmc_spi.c file will do that if I just use an MMC card... like the file says.
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