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

any 100% working code for mmc + pic18f series
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Mar 18, 2012 9:30 am     Reply with quote

When you get totally fed up, spend $30, buy a Vinculum based flashdrive module. Withing 2 hours you'll have a complete 'data logger' up and running.
miro



Joined: 15 Jan 2011
Posts: 62

View user's profile Send private message

PostPosted: Sun Mar 18, 2012 9:51 am     Reply with quote

I would recommend you the Chan's FatFS - it is free, maintained, nice examples, ready for pic24 and probably easy to port into ccs and pic18 (ie. asmallri did it Laughing ). There is a lot of docs as well.
http://elm-chan.org/fsw/ff/00index_e.html
adnan jafar



Joined: 26 Sep 2014
Posts: 11

View user's profile Send private message

Interfacing of SD Card with PIC
PostPosted: Fri Dec 12, 2014 4:16 am     Reply with quote

thanks sir, i have correctly implemented this code. I have correctly initialized the SPI, SD card and FAT32.
can any one tell me that how can i make a text file where i will write my sensors data in SD Card. Kindly tell me that how can i edit this code to make a file name and then read or write data in this text file from sensors.
Your Help will be highly Appreciated.

Regards,
Adnan
adnan jafar



Joined: 26 Sep 2014
Posts: 11

View user's profile Send private message

SD Card interfacing with PIC
PostPosted: Fri Dec 12, 2014 5:50 am     Reply with quote

First of all,Thanks for Posting Code here. You have done great job after posting this code. Stay Blessed......................
But brother , i have some issues here.
I am doing job as an electronics Engineer. I have successfully implemented your code that were posted at this link "http://www.ccsinfo.com/forum/viewtopic.php?t=37463". I have to submit my task of data logger to boss till Sunday. i have read your code but i have never found any statement or command to read or write data to and from the SD Card. Actually i am going to write sensors or external environment data to SD Card. Can you tell me that how can i make new file and read/write data to the SD Card. if there is any function available in this code, then kindly write its name. your Help will be highly appreciated


Regards,
Adnan
ckielstra



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

View user's profile Send private message

PostPosted: Fri Dec 12, 2014 1:55 pm     Reply with quote

Sorry, but before using code posted on this forum it makes sense when you read all the reactions. Similar questions like what you ask now have already been asked, and answered, in this thread.

Andre wrote back in 2009 that this program was his first working version with some known problems. He was going to post an updated version but this never happened.

I don't like to repeat myself, so for further advice read my post from Sun 18 Mar 2012.
andreluizeng



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

View user's profile Send private message Send e-mail MSN Messenger

im still alive =)
PostPosted: Fri Jul 15, 2016 12:45 pm     Reply with quote

Sorry for disappearing guys, unfortunately I don't work with PIC anymore (please check the imxcv.blogspot.com), and never get back here either, but as I was helping a friend, I will do something I promised long time ago, which is sharing the working code (I hope it still works), in case of errors or questions, please, note that I don't touch it for years and you will need to figure how to solve it by yourself.

cheers !
Andre
Code:

MMC_SD_Lib.c

#include "MMC_SD_Lib.h"
#include <string.h>
#include <math.h>

struct _cid_str          StructCID;
struct _csd_str          StructCSD;
struct _mmc_sd_str       StructMMC_SD;
char CardType;

//----------------------------------------------------------------------------------------------------
// Function:       MMC_SD_Detect
// Arguments:      None
// Response:       TRUE if there is a card connected, FALSE if there isn´t
//
// Description:   detects when a card is inserted or removed from the system
//----------------------------------------------------------------------------------------------------
char MMC_SD_Detect (void)
{
   char Resp;
   
   TRIS_MMC_SD_DETECT = INPUT;
   

   if (MMC_SD_DETECT_PIN)
   {
      while (MMC_SD_DETECT_PIN);
   }
   
   TRIS_MMC_SD_DETECT    = INPUT;
   
   TRIS_MMC_SD_DETECT    = OUTPUT;
   MMC_SD_DETECT_PIN      = FALSE;
   
   TRIS_MMC_SD_ON_OFF    = OUTPUT;
   
   return Resp;
}   

//----------------------------------------------------------------------------------------------------
// Function:       InitSpi
// Arguments:      SLOW_SPEED, MEDIUM_SPEED, HIGH_SPEED
// Response:       None
//
// Description:   Initializates SPI hardware peripheral
//----------------------------------------------------------------------------------------------------
void InitSPI (char Mode)
{
   TRIS_SPI_SCK         =   OUTPUT;
   TRIS_SPI_SDI         =   INPUT;
   TRIS_SPI_SDO         =   OUTPUT;
   TRIS_SPI_MMC_SD_CS   =   OUTPUT;

   MMC_SD_CS               = TRUE;
   SPI_SCK              = TRUE;
   SPI_DI               = TRUE;
   SPI_DO               = FALSE;
   
   switch (Mode)
   {
      case HIGH_SPEED:     SSPEN = FALSE;
                           SSPCON1 = SPI_MASTER_SCK_DIV_4;
                           SMP = TRUE;
                           CKE = FALSE;
                           CKP = TRUE;
                           SSPEN = TRUE;
                           break;

      case MEDIUM_SPEED:   SSPEN = FALSE;
                           SSPCON1 = SPI_MASTER_SCK_DIV_16;
                           SMP = TRUE;
                           CKE = FALSE;
                           CKP = TRUE;
                           SSPEN = TRUE;
                           break;

      case LOW_SPEED:      SSPEN = FALSE;
                           SSPCON1 = SPI_MASTER_SCK_DIV_64;
                           SMP = TRUE;
                           CKE = FALSE;
                           CKP = TRUE;
                           SSPEN = TRUE;
                           break;
                           
      default:               SSPEN = FALSE;   
                           SSPCON1 = SPI_MASTER_SCK_DIV_64;      // low speed
                           CKE = FALSE;
                           SMP = TRUE;
                           CKP = TRUE;
                           SSPEN = TRUE;
                           break;                              
   }

   delay_ms (10);

    return;
}



//----------------------------------------------------------------------------------------------------
// Function:       MMC_SD_Select
// Arguments:      TRUE to select or FALSE to deselect
// Response:       None
//
// Description:   Set/Clear peripheral Slave Select
//----------------------------------------------------------------------------------------------------
void MMC_SD_Select (boolean Flag)
{
   if (Flag)
   {
      MMC_SD_CS = FALSE;
   }

   else
   {
      MMC_SD_CS = TRUE;
   }
}


//----------------------------------------------------------------------------------------------------
// Function:       WriteSPI
// Arguments:      8bit value
// Response:       None
//
// Description:   write a 8bit value on SPI bus
//----------------------------------------------------------------------------------------------------
void WriteSPI (char a)
{
   char b;

   BF = FALSE;
   SSPBUF = a;
   while (! BF);
   b = SSPBUF;

   return;
}

//----------------------------------------------------------------------------------------------------
// Function:       ReadSPI
// Arguments:      None
// Response:       8bit value
//
// Description:   read a 8bit value from SPI bus
//----------------------------------------------------------------------------------------------------
char ReadSPI (void)
{
   char b;

   BF = FALSE;
   SSPBUF = 0xff;
   while (! BF);
   b = SSPBUF;

   return b;
}

//----------------------------------------------------------------------------------------------------
// Function:       MMC_SD_8Clock
// Arguments:      None
// Response:       None
//
// Description:   Clocks out a dummy value on SPI bus
//----------------------------------------------------------------------------------------------------
void MMC_SD_8Clock (void)
{
   WriteSPI (0xff);
   return;
}


//----------------------------------------------------------------------------------------------------
// Function:       GoIdleState
// Arguments:      None
// Response:       TRUE for success and FALSE for failure
//
// Description:   Resets all cards to idle state
//----------------------------------------------------------------------------------------------------
char GoIdleState (void)
{
   char Resp;
   char i;
   char Flag;
   
   MMC_SD_Select (FALSE);
   
   // some dummy clocks for initialization
   for (i = 0; i < 10; i++)   MMC_SD_8Clock ();   

   Flag = FALSE;

   for (i = 0; i < 20; i++)
   {
      WAIT_FF;
      MMC_SD_Select (TRUE);
      Resp = MMC_SD_SendCmd (CMD0, 0, 0x95);
      MMC_SD_Select (FALSE);
      
      if (Resp == IN_IDLE_STATE)
      {      
            Flag = TRUE;
            break;
      }   
      
      delay_ms (20);      
   }   

   
   return Flag;
}   


//----------------------------------------------------------------------------------------------------
// Function:       SendIfCond
// Arguments:      None
// Response:       FALSE for mmc/sdsc cards, TRUE for sdv2/sdhc cards and ERROR1 for unsupported cards
//
// Description:   Sends SD Memory Card interface condition, which includes host supply
//                  voltage information and asks the card whether card supports voltage
//----------------------------------------------------------------------------------------------------
char SendIfCond (void)
{
   char Resp;
   char i;
   char Ocr[4];

   WAIT_FF;
   MMC_SD_Select (TRUE);

   for (i = 0; i < 20; i++)
   {   
      Resp = MMC_SD_SendCmd (CMD8, 0x01AA, 0x87);

      // MMC or SDSC detected
      if (Resp == (ILLEGAL_COMMAND | IN_IDLE_STATE))
      {
         return FALSE;
      }
      
      if (Resp == IN_IDLE_STATE)
      {
         break;
      }   
   }      
   
   // read Ocr register
   for (i = 0; i < 4; i++)
   {
      Ocr[i] = ReadSPI ();
   }   

   MMC_SD_Select (FALSE);

   if ((Ocr[2] == 0x01) && (Ocr[3] == 0xaa))
   {
      // The card can work at vdd range of 2.7-3.6V
      return TRUE;
   }   
      
   // wrong vdd range
   printf ("FAILURE");                  
   printf ("\r\nFATAL ERROR: Unsupported card type");      
   MMC_SD_Debug (Resp);
   printf ("\r\nMMC/SD Card initialization sequence FAILED !\r\n");

   return ERROR1;

}   

//----------------------------------------------------------------------------------------------------
// Function:       SendOpCond
// Arguments:      Card type, received from SendIfCond
// Response:       MMC, SDSC, SDV2, SDHC, ERROR1
//
// Description:   Sends host capacity support information (HCS) and asks the accessed card to
//                  send its operating condition register (OCR) content in the response on the
//                  CMD line. HCS is effective when card receives SEND_IF_COND command.
//                  Reserved bit shall be set to ‘0’. CCS bit is assigned to OCR[30].
//----------------------------------------------------------------------------------------------------
char SendOpCond (char Type)
{
   char Resp;
   char Flag = FALSE;
   char i;
   int32 FlagSDHC = 1;
   char Ocr[4];

   /// SDV2 or SDHC
   if (Type)
   {
      Flag = FALSE;
      
      for (i = 0; i < 20; i++)
      {
      
         // APPLICATION CMD
         WAIT_FF;
         MMC_SD_Select (TRUE);
         Resp = MMC_SD_SendCmd (CMD55, 0, 0xff);
         MMC_SD_Select (FALSE);

         // ACMD41 + HCS bit
         WAIT_FF;
         MMC_SD_Select (TRUE);
         Resp = MMC_SD_SendCmd (ACMD41, FlagSDHC << 30, 0xff);
         MMC_SD_Select (FALSE);
         
         
         if (! Resp)
         {
            Flag = TRUE;
            break;
         }   
         
         delay_ms (20);
         
      }   
      
      if (Flag)
      {
         WAIT_FF;
         MMC_SD_Select (TRUE);

         for (i = 0; i < 20; i++)
         {
            // Ocr read command
            Resp = MMC_SD_SendCmd (CMD58, 0, 0xff);
      
            if (! Resp)
            {
               Flag = TRUE;
               break;
            }   
         }   
         
         if (Flag)
         {
            // read Ocr
            for (i = 0; i < 4; i++)
            {
               Ocr[i] = ReadSPI ();
            }   
                  
            // Check CCS bit, if 1 = SDHC, else = SD v2
            if (Ocr[0] & 0x40)
            {
               Resp = SDHC;
            }   

            else
            {
               Resp = SDV2;
            }            
         }            
         
         MMC_SD_Select (FALSE);      
      }   
      
      
      else
      {
         Resp = ERROR1;
      }   
   }
   
   // SDSC or MMC
   else
   {
      Flag = FALSE;
      for (i = 0; i < 20; i++)
      {
         
         // APPLICATION CMD
         WAIT_FF;
         MMC_SD_Select (TRUE);
         Resp = MMC_SD_SendCmd (CMD55, 0, 0xff);
         MMC_SD_Select (FALSE);
         
         // ACMD41 without HCS bit
         WAIT_FF;
         MMC_SD_Select (TRUE);
         Resp = MMC_SD_SendCmd (ACMD41, 0, 0xff);
         MMC_SD_Select (FALSE);
         
      
         if (! Resp)
         {
            Flag = TRUE;   
            break;
         }   
         
         delay_ms (20);
      }   
      
      // SDSC V1
      if (Flag)
      {
         Resp = SDSC;
      }   
   
      else // MMC
      {
         Flag = FALSE;
         
         for (i = 0; i < 20; i++)
         {   
            WAIT_FF;
            MMC_SD_Select (TRUE);
            Resp = MMC_SD_SendCmd (CMD1, 0, 0xff);
            MMC_SD_Select (FALSE);               
            
            if (! Resp)
            {
               Flag = TRUE;   
               break;
            }   
            delay_ms (20);
         }   

         if (Flag)
         {
            Resp = MMC;
         }   
         
         else
         {
            Resp = ERROR1;
         }   
      }      
   }

   if (Resp == ERROR1)
   {
      printf ("FAILURE");                  
      printf ("\r\nFATAL ERROR: Unsupported card type");      
      MMC_SD_Debug (Resp);
      printf ("\r\nMMC/SD Card initialization sequence FAILED !\r\n");
   }   
   
   return Resp;
}

//----------------------------------------------------------------------------------------------------
// Function:       AllSendCid
// Arguments:      None
// Response:       TRUE for success or FALSE for failure
//
// Description:   Addressed card sends its card identification (CID) on CMD the line.
//----------------------------------------------------------------------------------------------------
char AllSendCid (void)
{
   int i;
   char Buffer[17];
   char Resp;
   char Flag;


   
   WAIT_FF;
   MMC_SD_Select (TRUE);
   
   Resp = MMC_SD_SendCmd (CMD10, 0, 0xff);

   // wait for R1
   for (i = 0; i < 30; i++)
   {
      if (! Resp) break;
      Resp = ReadSPI ();
   }

   // error
   if (Resp)
   {
      MMC_SD_Debug (Resp);
      MMC_SD_Select (FALSE);
      return FALSE;
   }   

   Flag = FALSE;
   for (i = 0; i < 20; i++)
   {      
      if (Resp == START_BYTE)
      {
         Flag = TRUE;
         break;
      }   
      
      else
      {
         Resp = ReadSPI ();
      }   
   }
   
   if (! Flag)
   {
      MMC_SD_Debug (Resp);
      MMC_SD_Select (FALSE);
      return FALSE;
   }      

   // read CID      
   Buffer[0] = resp;
      
   for (i = 0; i < 16; i++)
   {
      Buffer[i] = ReadSPI ();
   }   
   MMC_SD_Select (FALSE);
   

//   StructCID.manfid          = Buffer[0];
//   StructCID.oemid[0]       = Buffer[1];
//   StructCID.oemid[1]       = Buffer[2];   
   StructCID.prod_name[0]    = Buffer[3];
   StructCID.prod_name[1]    = Buffer[4];
   StructCID.prod_name[2]    = Buffer[5];
   StructCID.prod_name[3]    = Buffer[6];
   StructCID.prod_name[4]    = Buffer[7];
   StructCID.prod_name[5]    =  '\0';
//   StructCID.prod_rev       = Buffer[8];
//   StructCID.serial          = make32 (Buffer[9], Buffer[10], Buffer[11], Buffer[12]);
   
//   MDTAux = make16 (Buffer[13], Buffer[14]);
   
//   StructCID.Year =  (MDTAux >> 4) & 0xff;
//   StructCID.Month = MDTAux & 0x0f;
   
   
   printf("\r\nProduct Name: %s", StructCID.prod_name);   
   
   return TRUE;
}   

//----------------------------------------------------------------------------------------------------
// Function:       AllSendCsd
// Arguments:      None
// Response:       TRUE for success or FALSE for failure
//
// Description:   Addressed card sends its card-specific data (CSD) on the CMD line.
//----------------------------------------------------------------------------------------------------
char AllSendCsd (void)
{
   int i;
   char Buffer[17];
   char Resp;
   char Flag;
   int32 Cap;
   
   WAIT_FF;
   MMC_SD_Select (TRUE);
   Resp = MMC_SD_SendCmd (CMD9, 0, 0xff);

   // wait for R1
   for (i = 0; i < 30; i++)
   {
      if (! Resp) break;
      Resp = ReadSPI ();
   }

   // error
   if (Resp)
   {
      MMC_SD_Select (FALSE);
      return FALSE;
   }   
   
   Flag = FALSE;
   for (i = 0; i < 20; i++)
   {      
      if (Resp == START_BYTE)
      {
         Flag = TRUE;
         break;
      }   
      
      else
      {
         Resp = ReadSPI ();
      }   
   }
   
   if (! Flag)
   {
      MMC_SD_Select (FALSE);
      return FALSE;
   }      

   // read CID         
   for (i = 0; i < 16; i++)
   {
      Buffer[i] = ReadSPI ();
   }   
   MMC_SD_Select (FALSE);
   
   
   StructCSD.mmca_vsn = (Buffer[0] >> 6) & 0x03;

   printf ("\r\nCSD struct: v%.1f", (float) StructCSD.mmca_vsn + 1);   
   
   
   // v2.0
   if (StructCSD.mmca_vsn)
   {
      // memory capacity = (C_SIZE+1) * 512K byte
      StructCSD.max_dtr = Buffer[3];
      StructCSD.c_size = make32 (Buffer[6], Buffer[7], Buffer[8], Buffer[9]) & 0x003fffff;
      StructCSD.capacity = (StructCSD.c_size + 1) * 512; // in KB
            
      printf ("\r\nMax transfer speed: %d MHz", (StructCSD.max_dtr == 0x32) ? 25 : 50);
      printf ("\r\nDevice Size: %lu KB (%lu MB)", StructCSD.capacity, (StructCSD.capacity / 1024 ) + 1);
   }
   
   // v1.0
   else
   {
      // memory capacity = (2 ^ blk_len) * ((2 ^ (c_size_mult + 2)) * (c_size + 1))
      
      StructCSD.max_dtr = Buffer[3];
      StructCSD.read_blkbits = Buffer[5] & 0x0f;
      StructCSD.c_size = ((((int16)Buffer[6]) & 0x03) << 10) | (((int16)Buffer[7]) << 2) | (((int16)Buffer[8]) & 0xc0) >> 6;
      StructCSD.c_size_mult = (int) (0x00000007 & (make32 (0, Buffer[9], Buffer[10], Buffer[11]) >> 15)) + 2;
      StructCSD.capacity = pow (2, StructCSD.read_blkbits) * pow (2, StructCSD.c_size_mult) * StructCSD.c_size;
      
      Cap = StructCSD.capacity / 1048576;

      printf ("\r\nMax transfer speed: %d MHz", (StructCSD.max_dtr == 0x32) ? 25 : 50);
      printf ("\r\nDevice Size: %lu Bytes (%lu MB)", StructCSD.capacity,  Cap + 1);      
      
         
   }      
   
   
   return TRUE;
}   

//----------------------------------------------------------------------------------------------------
// Function:       SetBlckLen
// Arguments:      16bit integer
// Response:       TRUE for success, FALSE for failure
//
// Description:   set card´s block size
//----------------------------------------------------------------------------------------------------
char SetBlckLen (long length)
{
   char i;
   char Flag;
   char Resp;

   printf ("\r\nSetting block size (%lu bytes): ", length);
   Flag = FALSE;

   WAIT_FF;
   MMC_SD_Select (TRUE);
   for (i = 0; i < 20; i++)
   {
      Resp = MMC_SD_SendCmd (CMD16, 512, 0x01);
      
      
      if (! Resp)
      {      
            Flag = TRUE;
            break;
      }   
      
      delay_ms (20);      
   }   
   
   MMC_SD_Select (FALSE);
   
   if (Flag)
   {
      printf ("OK");                  
   }   
   else
   {      
      printf ("FAILED");      
      MMC_SD_Debug (Resp);
      printf ("\r\nMMC/SD Card initialization sequence FAILED !\r\n");
   }   
   
   return Flag;
}



//----------------------------------------------------------------------------------------------------
// Function:       MMC_SD_Init
// Arguments:      None
// Response:       TRUE for success, FALSE for failure
//
// Description:   MMC/SDSC/SDv2/SDHC initialization sequence
//----------------------------------------------------------------------------------------------------
char MMC_SD_Init (void)
{
   char Resp;

   char Ret = TRUE;
   
   
   printf ("\r\nMMC/SD Card initialization sequence started");

   //----------------------------------------------------------------------   
   // Idle State
   //----------------------------------------------------------------------
   printf ("\r\nGoing to Idle state: ");
   Resp = GoIdleState ();
   
   if (Resp)
   {
      printf ("OK");                  
   }   
   else
   {      
      printf ("FAILURE");                  
      return FALSE;
   }   


   //----------------------------------------------------------------------   
   // Checking CMD8 (CMD8 - SEND_IF_COND)
   //----------------------------------------------------------------------   
   printf ("\r\nChecking card type: ");
   Resp = SendIfCond ();

   if (Resp == ERROR1)
   {
      return FALSE;
   }   

   //----------------------------------------------------------------------   
   // ACMD41 - SD_SEND_OP_COND with/without HC bit or CMD1 if card is MMC
   //----------------------------------------------------------------------   
   Resp = SendOpCond (Resp);
   
   CardType = Resp;

   switch (CardType)
   {
      case SDHC:   printf ("SDHC high speed card detected");                  
                  break;

      case SDV2:   printf ("SD high speed card detected");                  
                  break;
                  
      case SDSC:   printf ("SDSC card detected");                  
                  break;
                  
      case MMC:   printf ("MMC card detected");                  
                  break;
                  
      default:      printf ("FAILURE");                  
                  printf ("\r\nFATAL ERROR: Unsupported card type");      
                  MMC_SD_Debug (Resp);
                  printf ("\r\nMMC/SD Card initialization sequence FAILED !\r\n");
                  return FALSE;
      

   }   
   
   //----------------------------------------------------------------------   
   // CMD16 - SET BLOCK LENGTH
   //----------------------------------------------------------------------   
   Resp = SetBlckLen (512);
   
   if (Resp == FALSE)
   {
      return FALSE;
   }   
            

   //----------------------------------------------------------------------   
   // CMD10 - ALL_SEND_CID
   //----------------------------------------------------------------------   
   Resp = AllSendCid ();

   if (Resp == FALSE)
   {
      printf ("\r\nWARNING: Cant read CID");      
   }   

   //----------------------------------------------------------------------   
   // CMD9 - ALL_SEND_CSD
   //----------------------------------------------------------------------   
   Resp = AllSendCsd ();

   if (Resp == FALSE)
   {
      printf ("\r\nWARNING: Cant read CSD");      
   }   
   

   printf ("\r\nMMC/SD Card initialization sequence completed\r\n");


   return Ret;
}   


//----------------------------------------------------------------------------------------------------
// Function:       MMC_SD_SendCmd
// Arguments:      CMDx, cmd arg., CRC
// Response:       R1 (SD Specifications)
//
// Description:   send a command to the card
//----------------------------------------------------------------------------------------------------
char MMC_SD_SendCmd (char Command, int32 Value, char CRC)
{
   char Resp;
   char Cmd[4];

   Cmd[0] = Value & 0x000000ff;
   Cmd[1] = (Value >> 8) & 0x000000ff;
   Cmd[2] = (Value >> 16) & 0x000000ff;
   Cmd[3] = (Value >> 24) & 0x000000ff;
   
   WriteSPI (Command);
     WriteSPI (Cmd[3]);
     WriteSPI (Cmd[2]);
     WriteSPI (Cmd[1]);
     WriteSPI (Cmd[0]);
     WriteSPI (CRC);
     MMC_SD_8Clock ();
     

   Resp = ReadSPI ();      

   return Resp;   
}   



//----------------------------------------------------------------------------------------------------
// Function:       MMC_SD_Debug
// Arguments:      Resp, value for debug
// Response:       None
//
// Description:   prints R1 response
//----------------------------------------------------------------------------------------------------
void MMC_SD_Debug (char Resp)
{
   printf ("\r\nResponse: 0x%x\r\n", Resp);
   
   if (Resp & IN_IDLE_STATE)
   {
      printf ("IN IDLE STATE\r\n");
   }   
   
   if (Resp & ERASE_RESET)
   {
      printf ("ERASE RESET\r\n");
   }   
   
   if (Resp & ILLEGAL_COMMAND)
   {
      printf ("ILLEGAL COMMAND\r\n");
   }   

   if (Resp & COMMAND_CRC_ERROR)
   {
      printf ("COMMAND CRC ERROR\r\n");
   }   

   if (Resp & ERASE_SEQUENCE_ERROR)
   {
      printf ("ERASE SEQUENCE ERROR\r\n");
   }   

   if (Resp & ADDRESS_ERROR)
   {
      printf ("ADDRESS ERROR\r\n");
   }   
   
   if (Resp & PARAMETER_ERROR)
   {
      printf ("PARAMETER ERROR\r\n");
   }
   
   if (! Resp)   
   {
      printf ("COMMAND OK\r\n");
   }
   
   return;
}   


Code:

MMC_SD_Lib.h

#ifndef __MMC_SD_Lib_h__
#define __MMC_SD_Lib_h__

//----------------------------------------------------------------
// User Configuration - change this values regarding your hardware
//----------------------------------------------------------------
#byte PORT_A          =       0xf80          // (PIC16F - 0x05) (PIC18F - 0xf80)
#byte PORT_B             =   0xf81          // (PIC16F - 0x06) (PIC18F - 0xf81)
#byte PORT_C             =   0xf82          // (PIC16F - 0x07) (PIC18F - 0xf82)
#byte PORT_D             =   0xf83          // (PIC16F - 0x07) (PIC18F - 0xf82)
#byte PORT_E             =   0xf84          // (PIC16F - 0x07) (PIC18F - 0xf82)

#byte TRIS_PORT_A       =    0xf92    // (PIC16F - 00x85) (PIC18F - 0xf92)
#byte TRIS_PORT_B       =   0xf93    // (PIC16F - 0x86) (PIC18F - 0xf93)
#byte TRIS_PORT_C       =   0xf94    // (PIC16F - 0x87) (PIC18F - 0xf94)
#byte TRIS_PORT_D       =   0xf95    // (PIC16F - 0x87) (PIC18F - 0xf94)
#byte TRIS_PORT_E       =   0xf96    // (PIC16F - 0x87) (PIC18F - 0xf94)

#bit TRIS_SPI_SCK         = TRIS_PORT_C.3
#bit TRIS_SPI_SDI         = TRIS_PORT_C.4
#bit TRIS_SPI_SDO         = TRIS_PORT_C.5
#bit TRIS_SPI_MMC_SD_CS   = TRIS_PORT_B.5
#bit TRIS_MMC_SD_DETECT   = TRIS_PORT_B.2
#bit TRIS_MMC_SD_ON_OFF = TRIS_PORT_B.3

#bit SPI_SCK             =    PORT_C.3
#bit SPI_DI               =    PORT_C.4
#bit SPI_DO               =    PORT_C.5

#bit MMC_SD_CS          =    PORT_B.5 //PORT_B.0                                                                                                                                                                           
#bit MMC_SD_DETECT_PIN   =    PORT_B.2
#bit MMC_SD_ON_OFF        =  PORT_B.3


//----------------------------------------------------------------
// SPI peripheral definitions
//----------------------------------------------------------------
#byte SSPBUF     = 0xfc9     // (PIC16F - 0x13) (PIC18F - 0xfc9)
#byte SSPSTAT    = 0xfc7     // (PIC16F - 0x94) (PIC18F - 0xfc7)
#byte SSPCON1    = 0xfc6     // (PIC16F - 0x14) (PIC18F - 0xfc6)
#byte SSPCON2    = 0xfc5     // (PIC16F - 0x91) (PIC18F - 0xfc5)

#bit  BF        = SSPSTAT.0   
#bit CKE        = SSPSTAT.6   
#bit SMP        = SSPSTAT.7   
#bit CKP         = SSPCON1.4   
#bit SSPEN       = SSPCON1.5   // 1 = spi mode, 0 = io mode

#define SPI_SLAVE_SS_DISABLED       0xf5
#define SPI_SLAVE_SS_ENABLED          0xf4
#define SPI_MASTER_SCK_TMR2         0xf3
#define SPI_MASTER_SCK_DIV_64         0xf2
#define SPI_MASTER_SCK_DIV_16         0xf1
#define SPI_MASTER_SCK_DIV_4         0xf0


//----------------------------------------------------------------
// MMC/SD Commands definitions available for SPI mode
//----------------------------------------------------------------
#define CMD0    0x40   // GO_IDLE_STATE         - R1 
#define CMD1   0x41    // SEND_OP_COND (MMC)   - R1   
#define CMD6   0x46    // SWITCH_FUNC            - R1
#define CMD8    0x48   // SEND_IF_COND         - R7
#define CMD9   0x49   // SEND_CSD               - R1
#define CMD10   0x4A   // SEND_CID               - R1
#define CMD16   0x50   //   SET_BLOCKLEN         - R1
#define CMD17   0x51   // READ_SINGLE_BLOCK      - R1
#define CMD18   0x52   // READ_MULTIPLE_BLOCK   - R1
#define CMD24  0x58   // WRITE_SINGLE_BLOCK   - R1
#define CMD25  0x59   // WRITE_MULTIPLE         - R1
#define CMD27   0x5B   // PROGRAM_CSD            - R1
#define ACMD41 0x69   // SEND_OP_COND (SD)      - R1   
#define CMD55  0x77   // APP_CMD               - R1
#define CMD58  0x7A   // READ_OCR               - R3

// Card type
#define MMC    1
#define SDSC    2
#define SDV2   3
#define SDHC    4

extern char CardType;

#ifndef FALSE
#define FALSE    0
#endif

#ifndef TRUE
#define TRUE    1
#endif


#define ERROR1 0xff      



#define BLOCK_SIZE  2048
#define START_BYTE   0xfe



//----------------------------------------------------------------
// MMC/SD Commands definitions
//----------------------------------------------------------------
#define IN_IDLE_STATE         0x01
#define ERASE_RESET            0x02
#define ILLEGAL_COMMAND         0x04
#define COMMAND_CRC_ERROR      0x08
#define ERASE_SEQUENCE_ERROR   0x10
#define ADDRESS_ERROR         0x20
#define PARAMETER_ERROR         0x40



//----------------------------------------------------------------
// General definitions
//----------------------------------------------------------------
#ifndef OUTPUT
#define OUTPUT 0
#endif

#ifndef INPUT
#define INPUT 1
#endif

#define LOW_SPEED       0
#define MEDIUM_SPEED     1
#define HIGH_SPEED       2

#define SINAL 0
#define SALVAR 1
#define PARAR  0



//----------------------------------------------------------------
// SPI Functions prototypes
//----------------------------------------------------------------
void InitSPI          (char Mode);
void WriteSPI         (char a);
char ReadSPI         (void);


//----------------------------------------------------------------
// MMC/SD Functions prototypes
//----------------------------------------------------------------
char MMC_SD_Init      (void);
char MMC_SD_SendCmd   (char Command, int32 Value, char CRC);
void MMC_SD_Debug    (char Resp);
void MMC_SD_Select   (boolean Flag);
void MMC_SD_8Clock   (void);
char MMC_SD_Detect    (void);

char GoIdleState    (void);
char SendIfCond     (void);
char SendOpCond   (char Type);
char SetBlckLen   (long length);
char AllSendCid   (void);
char AllSendCsd   (void);


//----------------------------------------------------------------
// General Functions prototypes
//----------------------------------------------------------------
int32 UnStuffBits (char *Buffer, int Start, int Size);


//----------------------------------------------------------------
// Some usefull macros
//----------------------------------------------------------------
#define WAIT_FF  while(ReadSPI()!=0xff)


//----------------------------------------------------------------
// structs
//----------------------------------------------------------------

// minimal local versions of CSD/CID structures,
// somewhat ripped from linux MMC layer, the entire
//   CSD struct is larger and is not completley parsed

struct _cid_str
{
   char      manfid;            // An 8-bit binary number that identifies the card manufacturer.    [127:120]
   char      oemid[3];         // A 2-character ASCII string that identifies the card OEM and/or the card contents [119:104]
   char      prod_name[6];     // The product name is a string, 5-character ASCII string. [103:64]
   char      prod_rev;          // The product revision is composed of two Binary Coded Decimal (BCD) digits, four bits each [63:56]
   int32      serial;            // The Serial Number is 32 bits of binary number. [55:24]
   
                              // The manufacturing date is composed of two hexadecimal digits, one is 8 bits representing the year(y)
                              // and the other is 4 bits representing the month (m).
   char      month;            // The “m” field [11:8] is the month code. 1 = January.
   char      year;               // The “y” field [19:12] is the year code. 0 = 2000.
                              // As an example, the binary value of the Date field for production date “April 2001” will be:00000001 0100.
                              // [19:8]
};
extern struct _cid_str StructCID;



struct _csd_str
{            
   unsigned char      mmca_vsn;      // CSD_STRUCTURE
   unsigned char      tacc_clks;     // TAAC    
   unsigned char      tacc_ns;         // NSAC
   unsigned char      max_dtr;         // TRAN_SPEED
   unsigned int16      cmdclass;      // CCC
   unsigned char      read_blkbits;   // READ_BL_LEN
   unsigned int32      c_size;         // DEVICE SIZE
   unsigned char      c_size_mult;   // DEVICE SIZE MULTIPLIER
   unsigned char      write_blkbits;   // WRITE_BL_LEN
   unsigned int32      capacity;
};
extern struct _csd_str StructCSD;


struct _mmc_sd_str
{
   char    card_type;
   char    mmca_vsn;
   char    max_speed;
   int32 capacity;
};
extern struct _mmc_sd_str StructMMC_SD;

   
#endif

_________________
Andre
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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