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 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
manish12



Joined: 18 Jan 2009
Posts: 15

View user's profile Send private message

any 100% working code for mmc + pic18f series
PostPosted: Thu Jan 22, 2009 1:13 pm     Reply with quote

i thankfull to all who support for mmc and sd card interface [from code lib ]but , i try all[almost all code] with my best level , not suc.

if any one have working code for mmc + pic18f series pl upload it or any project which is check , also helpful to me.

[pic18f4620,452,2550, etc]
asmallri



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

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

Re: any 100% working code for mmc + pic18f series
PostPosted: Fri Jan 23, 2009 12:09 am     Reply with quote

manish12 wrote:
i thankfull to all who support for mmc and sd card interface [from code lib ]but , i try all[almost all code] with my best level , not suc.

if any one have working code for mmc + pic18f series pl upload it or any project which is check , also helpful to me.

[pic18f4620,452,2550, etc]


I sell working SD/SDHC/MMC low level drivers and file system for the PIC18F with the CCS compiler. They work.
_________________
Regards, Andrew

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



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

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

PostPosted: Fri Feb 27, 2009 10:44 am     Reply with quote

Alright,

lets go to the code..

MMCFat32.c

Code:

/**********************************************
 * ANDRE L. V. SILVA
 * [email protected]
 *
 * change the strings to your own language if you want (it is in portuguese br)
 *
 * Example of use:
 *
 *
   int main (void)
   {
      pic initialization....

      InicializaSPI ();
      InicializaMMC ();
      InicializaFAT32 ();

      While (TRUE)
      {
         your code ....
      }

      return 0;
   }

 **********************************************/


#include "MMCFat32.h"
#include "string.h"

//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// Funções do cartão MMC
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------

int32 FATTable[128];
int32 gFirstEmptyCluster;
FAT32Vars gFAT32Vars;
diskinforec DiskInfo;
FILE gFiles[MAXFILES];


#byte MMCAddressL       = gFAT32Vars
#byte MMCAddressH       = gFAT32Vars+1
#byte MMCAddressHL       = gFAT32Vars+2
#byte MMCAddressHH       = gFAT32Vars+3
#byte gStartSectorL    = gFAT32Vars+8
#byte gStartSectorH    = gFAT32Vars+9
#byte gStartSectorHL    = gFAT32Vars+10



//-------------------------------------------------------------------------
// Detecção do MMC 
//-------------------------------------------------------------------------
char DetectaMMC (void)
{
   char Resp;
   
   TRIS_DETECTA_MMC = ENTRADA;
   
   printf ("\r\nDetectando MMC...");
   
   if (MMC_DETECT)
   {
      printf ("Nao Conectado !");
      printf ("\r\nAguardando Conexao... ");
      
      while (MMC_DETECT);
   }
   
   TRIS_DETECTA_MMC = ENTRADA;
   MMC_DETECT = SAIDA;
   MMC_DETECT = FALSE;
   
   
   printf ("OK");   
   
   return Resp;
}   

//-------------------------------------------------------------------------
// Configuração da SPI
//-------------------------------------------------------------------------
void InicializaSPI (char Tipo)
{
   TRIS_SPI_SCK      =   SAIDA;
   TRIS_SPI_SDI      =   ENTRADA;
   TRIS_SPI_SDO      =   SAIDA;
   TRIS_SPI_MMC_CS      =   SAIDA;

   MMC_CS   = TRUE;
   SPI_SCK = TRUE;
   SPI_DI   = TRUE;
   SPI_DO   = FALSE;


   if (Tipo == MAXIMO)
   {
      printf ("\r\nAjustando SPI: ");
      printf ("5 MHz...");

      CKE = FALSE;
      SMP = TRUE;
      CKP = TRUE;
      SSPCON1 = SSPCON1 & SPI_MASTER_SCK_DIV_4;
      SSPEN = TRUE;
   }


   else if (Tipo == MEDIO)
   {
      printf ("\r\nAjustando SPI: ");
      printf ("1.25 MHz...");

      CKE = FALSE;
      SMP = TRUE;
      CKP = TRUE;
      SSPCON1 = SSPCON1 & SPI_MASTER_SCK_DIV_16;
      SSPEN = TRUE;

   }

   else
   {
      printf ("\r\nInicializando SPI: ");
      printf ("312.5 KHz...");

      CKE = FALSE;
      SMP = TRUE;
      CKP = TRUE;
      SSPCON1 = SSPCON1 & SPI_MASTER_SCK_DIV_4;
      SSPEN = TRUE;
   }

   printf ("OK");

   delay_ms (10);

    return;
}



//-------------------------------------------------------------------------
// Função de Seleção do CS do MMC
//-------------------------------------------------------------------------
void SelecionaMMC (boolean Flag)
{
   if (Flag)
   {
      MMC_CS = FALSE;
   }

   else
   {
      MMC_CS = TRUE;
   }
}


//-------------------------------------------------------------------------
// Função para enviar um dado via SPI
//-------------------------------------------------------------------------
void EnviaMMC (char a)
{
   char b;

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

   return;
}

//-------------------------------------------------------------------------
// Função para receber um dado via SPI
//-------------------------------------------------------------------------
char RecebeMMC (void)
{
   char b;

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

   return b;
}

//-------------------------------------------------------------------------
// 8 pulsos de clock dummy
//-------------------------------------------------------------------------
void MMC8Clock (void)
{
   EnviaMMC (0xff);
   return;
}


//-------------------------------------------------------------------------
// Comando de Reset
//-------------------------------------------------------------------------
void ExecutaCMD0 (void)
{
   char Resp;
   long TimeOut;
   char i;

   // comando CMD0 - Reset
//   printf ("\r\n\tResposta ao CMD0...");
   do
   {
      Resp = 0xff;
      TimeOut = 100;

      // envia pelo pulsos de clock para inicialização
      for (i = 0; i < 10; i++)   MMC8Clock ();

      // envia CMD0 -> Idle state
      SelecionaMMC (TRUE);
      EnviaMMC (0x40); // CMD0
      EnviaMMC (0x00);
      EnviaMMC (0x00);
      EnviaMMC (0x00);
      EnviaMMC (0x00);
      EnviaMMC (0x95); // CRC - OK
      MMC8Clock ();

      // espera pela resposta = 0x01 - caso contrário = falha
      while ((Resp != 0x01) && (TimeOut))
      {
         Resp = RecebeMMC ();
         TimeOut--;
      }

      SelecionaMMC (FALSE);

   // roda enquanto der timeout
   } while (! TimeOut);

//   printf ("OK");
   
   return;
}   

//-------------------------------------------------------------------------
// Modo SPI
//-------------------------------------------------------------------------
void ExecutaCMD1 (void)
{
   char Resp;
   long TimeOut;

   // comando CMD1 - Modo SPI
//   printf ("\r\n\tResposta ao CMD1...");
   do
   {
      Resp = 0xff;
      TimeOut = 100;


      // envia CMD1 -> Modo SPI
      SelecionaMMC (TRUE);
      EnviaMMC (0x41); // CMD1
      EnviaMMC (0x00);
      EnviaMMC (0x00);
      EnviaMMC (0x00);
      EnviaMMC (0x00);
      EnviaMMC (0x01); // CRC - OK
      MMC8Clock ();

      // espera pela resposta = 0x00 - caso contrário = falha
      while (Resp && TimeOut)
      {
         Resp = RecebeMMC ();
         TimeOut--;
      }

      SelecionaMMC (FALSE);


   // roda enquanto der timeout
   } while (! TimeOut);

//   printf ("OK");
   
   return;
}
   
//-------------------------------------------------------------------------
// Ajusta o tamanho do bloco - 512 bytes
//-------------------------------------------------------------------------
void ExecutaCMD16 (void)
{
   char Resp;
   long TimeOut;
   
   // comando CMD16 - Bloco de 512 bytes
//   printf ("\r\n\tResposta ao CMD16...");

   do
   {
      Resp = 0xff;
      TimeOut = 100;

      // envia CMD16 -> block lenght
      SelecionaMMC (TRUE);
      EnviaMMC (0x50); // CMD1
      EnviaMMC (0x00);
      EnviaMMC (0x00);
      EnviaMMC (0x02);
      EnviaMMC (0x00);
      EnviaMMC (0x01); // CRC - OK
      MMC8Clock ();

      // espera pela resposta = 0x00 - caso contrário = falha
      while (Resp && TimeOut)
      {
         Resp = RecebeMMC ();
         TimeOut--;
      }
      SelecionaMMC (FALSE);

   // roda enquanto der timeout
   } while (! TimeOut);

//   printf ("OK");

   return;
}   

//-------------------------------------------------------------------------
// Lê a identificação do cartão - CID
//-------------------------------------------------------------------------
void ExecutaCMD10 (void)
{
   char Resp;
   long TimeOut;
   char i;
   char Ano;
   char Mes;
   char HW;
   char FW;

   // comando CMD10 - Lê a identificação do cartão
   do
   {
      Resp = 0xff;
      TimeOut = 100;

      SelecionaMMC (TRUE);
         EnviaMMC (0x4A);   //CMD10 - Le CID
         EnviaMMC (0x00);
         EnviaMMC (0x00);
         EnviaMMC (0x00);
         EnviaMMC (0x00);
         EnviaMMC (0x01);
      MMC8Clock ();

      // espera pela resposta = 0x00 - caso contrário = falha
      while (Resp && TimeOut)
      {
         Resp = RecebeMMC ();
         TimeOut--;
      }

      // dummy
      MMC8Clock ();

      // respondeu
      if (TimeOut)
      {

//         // recebe a identificação - binário (8bits)
//         printf ("\r\n\r\n\tID do Fabricante: 0x%x", RecebeMMC ());   // identificação para MMCA
//
//         // recebe a id de aplicação - binário (16bits)
//         printf ("\r\n\tID da Aplicação: 0x");
//         for (i = 0; i < 2; i++)
//         {
//            printf ("%x", RecebeMMC ());   // identificação para MMCA
//         }
//         
//         printf ("\r\n\r\n\tProduto: ");
//         for (i = 0; i < 6; i++)
//         {
//            printf ("%c", RecebeMMC ());   // 6 próximos bytes - Nome do Produto
//         }
//
//         // revisão do produto - 8bits - BCD
//         printf ("\r\n\r\n\tRevisão do Produto: %02d", RecebeMMC ());
//
//         printf ("\r\n\tSerial: 0x");
//         
//         for (i = 0; i < 4; i++)
//         {
//            printf ("%x", RecebeMMC ());   // 4 próximos bytes - Serial do Produto
//         }
//
//         
//
//
//         FW = Resp & 0x0f;               // Firmware = 4bits menos significativos
//         HW = (Resp >> 4) & 0x0f;         // Hardware = 4bits mais significativos
//         printf ("\r\n\tFirmware: %2d", FW);
//         printf ("\r\n\tHardware: %02d", HW);
//         printf ("\r\n\tFW+HW: 0x%x", Resp);
//         
//         
//   
//         Resp = RecebeMMC ();       // Mes + Ano;
//         Ano = Resp & 0x0f;         // Ano = 4bits menos significativos
//         Mes = (Resp >> 4) & 0x0f;   // Ano = 4bits mais significativos
//
//         printf ("\r\n\tAno: %02d", Ano);
//         printf ("\r\n\tMes: %02d", Mes);
//         printf ("\r\n\tAno+Mes: 0x%x\r\n", Resp);
      
      }

      SelecionaMMC (FALSE);
      
   // roda enquanto der timeout
   } while (! TimeOut);   
   
   return;
}
   
//-------------------------------------------------------------------------
// Lê o formato do cartão - CSD
//-------------------------------------------------------------------------
void ExecutaCMD9 (void)
{
   char Resp;
   long TimeOut;

   // comando CMD9 - Lê o formato do cartão
//   printf ("\r\n\tResposta ao CMD9...");
   do
   {
      Resp = 0xff;
      TimeOut = 100;

      SelecionaMMC (TRUE);
         EnviaMMC (0x49);   //CMD9 - Le CSD
         EnviaMMC (0x00);
         EnviaMMC (0x00);
         EnviaMMC (0x00);
         EnviaMMC (0x00);
         EnviaMMC (0x01);
      MMC8Clock ();

      // espera pela resposta = 0x00 - caso contrário = falha
      while (Resp && TimeOut)
      {
         Resp = RecebeMMC ();
         TimeOut--;
      }
      
      // Respondeu
      if (TimeOut)
      {
         
      }

      SelecionaMMC (FALSE);

   // roda enquanto der timeout
   } while (! TimeOut);

//   printf ("OK");
   
   return;
}   

//-------------------------------------------------------------------------
// Muda para o modo de high-speed
//-------------------------------------------------------------------------
void ExecutaCMD6 (void)
{
   char Resp;
   long TimeOut;

   // comando CMD6 - high speed (manual mmc plus)
//   printf ("\r\n\tResposta ao CMD6...");
   do
   {
      Resp = 0xff;
      TimeOut = 100;

      SelecionaMMC (TRUE);
      EnviaMMC (0x46); // CMD6
      EnviaMMC (0x03);
      EnviaMMC (0xb9);
      EnviaMMC (0x01);
      EnviaMMC (0x00);
      EnviaMMC (0x01); // CRC - OK
      MMC8Clock ();

      // espera pela resposta = 0x00 - caso contrário = falha
      while (Resp && TimeOut)
      {
         Resp = RecebeMMC ();
         TimeOut--;
      }
      SelecionaMMC (FALSE);

   // roda enquanto der timeout
   } while (! TimeOut);

//   printf ("OK");
   
   return;
}   

//-------------------------------------------------------------------------
// Inicialização do MMC
//-------------------------------------------------------------------------
void InicializaMMC (void)
{

   printf ("\r\nInicializando MMC...");
   
   ExecutaCMD0 ();
   ExecutaCMD1 ();
   ExecutaCMD16 ();
   ExecutaCMD10 ();
   ExecutaCMD9 ();
   
   printf ("\r\nInicializando MMC...OK");

   return;
}

//-------------------------------------------------------------------------
// Le um setor da memória - FAT32
//-------------------------------------------------------------------------
void ReadSector(int32 sector, char *buffer)
{
      char errs,response;
      char cnt2,cnt3;

      #byte sectorL = sector
      #byte sectorH = sector+1
      #byte sectorHL = sector+2

      // if (input(CardInserted)) return;
      
   // Disable_interrupts(GLOBAL);
      Restart_wdt();
      
      MMCAddressL = 0;
      MMCAddressH = sectorL;
      MMCAddressHL = sectorH;
      MMCAddressHH = sectorHL;
      gFAT32Vars.MMCAddress <<= 1;

   SelecionaMMC (TRUE);
      EnviaMMC (0x51);
      EnviaMMC (MMCAddressHH);
      EnviaMMC (MMCAddressHL);
      EnviaMMC (MMCAddressH & 0xFE);

      EnviaMMC (0);
      EnviaMMC (0x01);
      errs = 8;
      
   do
   {
       response = RecebeMMC ();
      
     } while ((--errs) && (response == 0xFF));
      
      
      errs = 50;
   
      do
   {
      
         response = RecebeMMC ();
       
      if (response == 0xFE) break;
      
         delay_ms(1);
         
      } while (--errs);
      
      *0xFE9 = (int16) buffer;
   
      cnt3 = 2;
      cnt2 = 0;
   
   do
   {
         do
         {
            SSPBUF = 0xFF;
            while (!BF);
            
            *0xFEE = SSPBUF;
           
      } while (--cnt2);
      } while (--cnt3);
      
      
      response = RecebeMMC ();
      response = RecebeMMC ();
      
   SelecionaMMC (FALSE);
      
//      enable_interrupts(GLOBAL);
}


//-------------------------------------------------------------------------
// Escreve em um setor da memória - FAT32
//-------------------------------------------------------------------------
void WriteSector (int32 sector, char *buffer)
{
   char errs;
      char response;
      char cnt2;
      char cnt3;
      #byte sectorL = sector
      #byte sectorH = sector+1
      #byte sectorHL = sector+2

//      if (input (CardInserted)) return;
   
//      disable_interrupts(GLOBAL);
//      restart_wdt();
   
      MMCAddressL    = 0;
      MMCAddressH    = sectorL;
      MMCAddressHL = sectorH;
      MMCAddressHH = sectorHL;
      gFAT32Vars.MMCAddress <<= 1;
   
      response = 0;

   SelecionaMMC (TRUE);
   
      EnviaMMC (0x58);
      
    EnviaMMC (MMCAddressHH);
    EnviaMMC (MMCAddressHL);
    EnviaMMC (MMCAddressH & 0xFE);
 
      EnviaMMC (0);
      EnviaMMC (0x01);
      MMC8Clock ();
      errs = 8;
      
      do
   {
       response = RecebeMMC ();
       
      } while (--errs && response==0xFF);
      
      if (response)
   {
      SelecionaMMC (FALSE);
       
         MMC8Clock();
//         enable_interrupts(GLOBAL);
         
        return;
      }
      
      MMC8Clock ();
      EnviaMMC (0xFE);
      *0xFE9 = (int16)buffer;
      
      cnt3 = 2;
      cnt2 = 0;
      
   do
   {
       do
       {
            SSPBUF = *0xFEE;
            while (!BF);
            response = SSPBUF;
            
         } while (--cnt2);
         
      } while (--cnt3);
   
      EnviaMMC (0x00);
      EnviaMMC (0x01);
      
      response = RecebeMMC ();
      response ^= 0xE5;
      
      if (response)
   {
       goto endwr3;
      }
      
      do
   {
       response = RecebeMMC ();
       
      } while (response == 0);
      
      response = 0;
      
endwr3:
   SelecionaMMC (FALSE);
    MMC8Clock();
    
//      enable_interrupts (GLOBAL);
}



//-------------------------------------------------------------------------
// mostra um determinado setor - FAT32
//-------------------------------------------------------------------------
void MostraSetor (int32 setor, char *dados, long tamanho)
{
   long i;
   long j;
   long k;

   printf ("\r\n\r\nLendo setor: %lx\r\n\r\n", setor);
   ReadSector (setor, dados);

   j = 0;
   for (i = 0; i < tamanho; i++)
   {
      printf ("%02X ", dados[i]);
      if (j >= 15)
      {
         printf ("          ");

         for (k = (i - 15); k < i; k++)
         {
            if (! isalnum (dados[k])) printf (".");
            else printf ("%c", dados[k]);
         }

         printf ("\r\n");
         j = 0;
      }

      else
      {
         j++;
      }

      delay_ms (1);

   }
}

//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// Funções da FAT32
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------


char IsSelfDir (char *be)
{
   if (be[0] == '.' && be[1] == '.') return 0xFF;
   else return 0;
}


int16 GetCurrentDOSDate ()
{
   int16 retval;

   retval = myrec.tm_year - 1980;
   retval <<= 9;
   retval |= ((int16)myrec.tm_mon << 5);
   retval |= (int16)myrec.tm_mday;

   return retval;
}

int16 GetCurrentDOSTime ()
{
   int16 retval;

   retval = myrec.tm_hour;
   retval <<= 11;
   retval |= ((int16)myrec.tm_min << 5);
   retval |= (int16)myrec.tm_sec >> 1;
   
   return retval;
}

void InicializaFAT32 ()
{
   int32 actsector;
   char i;
   
   gFirstEmptyCluster       = 0;
      gFAT32Vars.gStartSector = 0;
      
   // limpa o CREN (comunicação contínua)
   printf ("\r\nInicializando FAT32...");
      
      ReadSector (gFAT32Vars.gStartSector, gFiles[MAXFILES-1].IOpuffer);
      
   if (gFiles[MAXFILES-1].IOpuffer[0] != 0xEB)
   {
      gStartSectorL    = gFiles[MAXFILES-1].IOpuffer[0x1C6];
         gStartSectorH    = gFiles[MAXFILES-1].IOpuffer[0x1C7];
         gStartSectorHL    = gFiles[MAXFILES-1].IOpuffer[0x1C8];
         
         ReadSector (gFAT32Vars.gStartSector, gFiles[MAXFILES-1].IOpuffer);
     }
      
      memcpy (&DiskInfo, gFiles[MAXFILES-1].IOpuffer, sizeof(DiskInfo));
      
     actsector = gFAT32Vars.gStartSector + DiskInfo.Reserved1;
     
      ReadSector (actsector, FATTable);
      gFAT32Vars.FATstartidx = 0;
      
      gFAT32Vars.gFirstDataSector = gFAT32Vars.gStartSector + DiskInfo.FATCopies * DiskInfo.hSectorsPerFat + DiskInfo.Reserved1 - 2;
   
      for (i = 0; i < MAXFILES; i++)
      gFiles[i].Free = TRUE;
      
   printf ("OK");
   
   return;
}


int32 GetNextCluster (int32 curcluster)
{
      int32 actsector;
      int32 clpage;
      char clpos;

      clpage = curcluster >> 7;
      clpos = curcluster & 0x7F;
      
      if (clpage != gFAT32Vars.FATstartidx)
     {
        // read in the requested page
      actsector = gFAT32Vars.gStartSector+DiskInfo.Reserved1 + clpage;
         ReadSector (actsector, FATTable);
         
         gFAT32Vars.FATstartidx = clpage;
   }
   
   return (FATTable[clpos]);
}

void SetClusterEntry (int32 curcluster, int32 value)
{
      int32 actsector;
      int32 clpage;
      char clpos;

      clpage = curcluster >> 7;
      clpos = curcluster & 0x7F;
      actsector = gFAT32Vars.gStartSector + DiskInfo.Reserved1 + clpage;
      
      if (clpage != gFAT32Vars.FATstartidx)
   {
       ReadSector (actsector, FATTable);
         gFAT32Vars.FATstartidx = clpage;
      }
   
      FATTable[clpos] = value;
      WriteSector (actsector, FATTable);
      actsector += DiskInfo.hSectorsPerFat;
      WriteSector (actsector,FATTable);
}

void ClearClusterEntry (int32 curcluster)
{
   int32 actsector;
      int32 clpage;
      char clpos;

      clpage = curcluster >> 7;
      clpos = curcluster & 0x7F;
      
      if (clpage != gFAT32Vars.FATstartidx)
   {
       actsector = gFAT32Vars.gStartSector + DiskInfo.Reserved1 + gFAT32Vars.FATstartidx;
         WriteSector (actsector, FATTable);
         
         actsector += DiskInfo.hSectorsPerFat;
         WriteSector (actsector,FATTable);
         
         actsector = gFAT32Vars.gStartSector + DiskInfo.Reserved1 + clpage;
         ReadSector (actsector,FATTable);
     
         gFAT32Vars.FATstartidx = clpage;
      }
      
   FATTable[clpos] = 0;
}


int32 FindFirstFreeCluster ()
{
   int32 i;
   int32 st;
   int32 actsector;
   int32 retval;
   char j;

      st = gFirstEmptyCluster;
      
      for (i = st; i < DiskInfo.hSectorsPerFat; i++)
   {
       if (i != gFAT32Vars.FATstartidx)
       {
           actsector = gFAT32Vars.gStartSector + DiskInfo.Reserved1 + i;
           ReadSector (actsector, FATTable);
            gFAT32Vars.FATstartidx = gFirstEmptyCluster = i;
         }
         
         for (j=0;j<128;j++)
         {
            if (FATTable[j] == 0)
           {
               retval = i;
               retval <<= 7;
               retval |= j;
               return retval;
            }
         }
      }
      
      return 0x0FFFFFFF;
}

void ConvertFilename (DIR *beDir, char *name)
{
   char i;
   char j;
   char c;

      j = 0;

      name[0] = 0;

      for (i = 0; i < 8; i++)
   {
       c = beDir->sName[i];
       
         if (c == ' ') break;
         
         name[j++] = c;
      }
     
      for (i = 0; i < 3; i++)
   {
         c = beDir->spam[i];
         
         if ((c == ' ') || (c == 0)) break;
         
         if (!i) name[j++] = '.';
         
       name[j++] = c;
      }
      
      name[j++] = 0;
}

void GetDOSName (DIR *pDir, char *fname)
{
   char i;
   char j;
   char leng;
   char c;
   char toext;

      toext = FALSE;
      j = 0;
      
      leng = strlen(fname);
      
      for (i = 0; i < 8; i++)
       pDir->sName[i] = ' ';
       
      for (i = 0; i < 3; i++)
         pDir->spam[i] = ' ';
         
      for (i = 0; i < leng; i++)
      {
       c = fname[i];
         c = toupper(c);
         
         if (c == '.')
       {
            toext = TRUE;
            continue;
         }
         
         if (toext) pDir->spam[j++] = c;
         else pDir->sName[i] = c;
      }
}


void ReadRootDirectory (char fil)
{
   int32 actsector;

      if (fil > (MAXFILES-1)) return;
      
     actsector = gFAT32Vars.gStartSector + (DiskInfo.FATCopies * DiskInfo.hSectorsPerFat) + DiskInfo.Reserved1;

      ReadSector (actsector, gFiles[fil].IOpuffer);
      
   gFAT32Vars.gDirEntrySector = actsector;
      gFiles[fil].dirSector = actsector;
      gFiles[fil].dirIdx = 0;
      memcpy (&(gFiles[fil].DirEntry), gFiles[fil].IOpuffer,32);
      gFiles[fil].CurrentCluster = DiskInfo.hRootStartCluster;
}


char FindDirEntry (char *fname, char f)
{
   DIR *pDir;
      int16 i;
      char filename[16];
      int32 nextcluster;
      int32 actsector;

      if (f > (MAXFILES-1)) return FALSE;
   
      gFAT32Vars.gFirstEmptyDirEntry = 0xFFFF;
      gFAT32Vars.gFirstDirEntryCluster = 0x0FFFFFFF;
      
   do
   {
       pDir = (DIR*)(gFiles[f].IOpuffer);
       
         for (i = 0; i < 16; i++)
       {
            if (((pDir->sName[0] == 0xE5) || (pDir->sName[0] == 0)) && (gFAT32Vars.gFirstEmptyDirEntry == 0xFFFF))
           {
              // store first free
                 gFAT32Vars.gFirstEmptyDirEntry = i;
               gFAT32Vars.gFirstDirEntryCluster = gFiles[f].CurrentCluster;
            }

               if (pDir->sName[0] == 0) return FALSE;
                 
         ConvertFilename (pDir,filename);
             if (!strcmp (filename, fname))
           {
               memcpy(&(gFiles[f].DirEntry), pDir, 32);
               gFiles[f].dirIdx = i;
               gFAT32Vars.gDirEntryIdx = i;
               return TRUE;
            }
            
            pDir++;
         }
         
         nextcluster = GetNextCluster (gFiles[f].CurrentCluster);
         
        
            if ((nextcluster != 0x0FFFFFFF) && (nextcluster != 0))
       {
            actsector = nextcluster + gFAT32Vars.gFirstDataSector;
            ReadSector (actsector, gFiles[f].IOpuffer);
            
            gFAT32Vars.gDirEntrySector = actsector;
            gFiles[f].dirSector = actsector;
            gFiles[f].CurrentCluster = nextcluster;
         }
       
         
      } while ((nextcluster != 0x0FFFFFFF) && (nextcluster != 0));
      
      return FALSE;
}

// file I/O routines
char *TryFile(char *fname, char *f)
{
   char i;
      char leng;
      char *filename;

      (*f) = 0xFF;
   
      for (i = 0; i < MAXFILES; i++)
   {
         if (gFiles[i].Free)
        {
           (*f) = i;
            break;
         }
      }
      
      if ((*f) == 0xFF) return 0;
      
      ReadRootDirectory (*f);
      
      filename = fname;
      leng = strlen (fname);
      
      for (i = 0; i < leng; i++)
   {
       if (fname[i] == '/')
       {
           fname[i] = 0;
            
            if (! cwd (filename,(*f)))
           {
                 gFiles[(*f)].Free = TRUE;
               return 0;
            }
         
            filename = fname + i + 1;
            
        }
      }
   
      return filename;
}

char fcreate (char f, char *fname)
{
   DIR *pDir;
      int32 actsector;
      char actcl;
      int16 i;

      if (f > (MAXFILES-1)) return FALSE;
      
      if (gFAT32Vars.gFirstDirEntryCluster == 0x0FFFFFFF)
   {
       // extend the directory file !!!
         gFAT32Vars.gFirstDirEntryCluster = FindFirstFreeCluster ();
         gFAT32Vars.gFirstEmptyDirEntry = 0;
         SetClusterEntry(gFiles[f].CurrentCluster, gFAT32Vars.gFirstDirEntryCluster);
      SetClusterEntry(gFAT32Vars.gFirstDirEntryCluster, 0x0FFFFFFF);
         actsector = gFAT32Vars.gFirstDirEntryCluster + gFAT32Vars.gFirstDataSector;
         
         for (i = 0; i < 512; i++)
         {
            gFiles[f].IOpuffer[i] = 0;
        }
       
         WriteSector(actsector, gFiles[f].IOpuffer);
      }
      
      actsector = gFAT32Vars.gFirstDirEntryCluster + gFAT32Vars.gFirstDataSector;
      ReadSector (actsector, gFiles[f].IOpuffer);
   
   
      pDir = (DIR*)(&(gFiles[f].IOpuffer[32 * gFAT32Vars.gFirstEmptyDirEntry]));
      gFiles[f].dirSector = actsector;
      gFiles[f].dirIdx = gFAT32Vars.gFirstEmptyDirEntry;
      
      GetDOSName (pDir, fname);
      
      pDir->bAttr = 0;
      actcl = FindFirstFreeCluster ();
      pDir->hCluster = actcl & 0xFFFF;
      pDir->hClusterH = actcl >> 16;
      
      SetClusterEntry (actcl, 0x0FFFFFFF);
      pDir->wSize = 0;
      gFiles[f].position = 0;
      pDir->hDate = GetCurrentDOSDate ();
      pDir->hTime = GetCurrentDOSTime ();
      
      WriteSector (actsector, gFiles[f].IOpuffer);
      memcpy (&(gFiles[f].DirEntry), pDir,32);
      
   return TRUE;
}

int32 ComposeCluster (char f)
{
   int32 retval;

   retval = gFiles[f].DirEntry.hClusterH;
   retval <<= 16;
   retval |= gFiles[f].DirEntry.hCluster;

   return retval;
}

char fopen (char *fname, char mode)
{
   char found;
      char f;
      int32 actsector;
      int32 actcluster;
      int32 nextcluster;
      char *filename;

      //if (input(CardInserted)) return 0xFF;
   
            
      filename = TryFile (fname, &f);

      if (filename == 0) return 0xFF;

      found = FALSE;
      found = FindDirEntry (filename,f);

      
      if (!found)
   {
         if (mode == 'r')
         {
            gFiles[f].Free = TRUE;
            return 0xFF;
         }
       else
      {
           if (! fcreate(f, filename)) return 0xFF;
            found = TRUE;
         }
      }
   
   if (found)
   {
         gFiles[f].Free = FALSE;
         gFiles[f].mode = mode;
         
         if  (mode == 'a') // com problemas
       {
           gFiles[f].position = gFiles[f].DirEntry.wSize;
           
            actcluster = ComposeCluster(f);
            
            while ((actcluster != 0x0FFFFFFF) && (nextcluster != 0))
           {
               nextcluster = GetNextCluster(actcluster);
                  
                  if ((nextcluster == 0x0FFFFFFF) || (nextcluster == 0)) break;
                  
                  actcluster = nextcluster;
            }
           
            actsector = actcluster + gFAT32Vars.gFirstDataSector;
            ReadSector (actsector, gFiles[f].IOpuffer);
            
            gFiles[f].CurrentCluster = actcluster;
            gFiles[f].posinsector = gFiles[f].position & 0x01FF;
            
            if ((gFiles[f].posinsector == 0) && (gFiles[f].position != 0))
            {
               gFiles[f].posinsector = 512;
         }   
         }
      
      else
      {
           gFiles[f].position = 0;
           
            actsector = ComposeCluster (f);
            actsector += gFAT32Vars.gFirstDataSector;
         ReadSector(actsector,gFiles[f].IOpuffer);
         
            gFiles[f].CurrentCluster = ComposeCluster (f);
            gFiles[f].posinsector = 0;
         }
      }
   
      return f;
}

void fclose (char f)
{
      if (f > (MAXFILES-1)) return;
      if ((gFiles[f].mode == 'a') || (gFiles[f].mode == 'w')) fflush(f);
      
      gFiles[f].Free = TRUE;
}

void fflush (char f)
{
   int32 actsector;
   DIR *pDir;

      if (f > (MAXFILES-1)) return;
   
      actsector = gFiles[f].CurrentCluster + gFAT32Vars.gFirstDataSector;
      WriteSector (actsector, gFiles[f].IOpuffer);
      ReadSector(gFiles[f].dirSector, gFiles[f].IOpuffer);
   
      pDir = (DIR*)(&(gFiles[f].IOpuffer[32 * gFiles[f].dirIdx]));
   
      if (gFiles[f].DirEntry.bAttr & 0x10) pDir->wSize = 0; // if it is a directory
      else pDir->wSize = gFiles[f].position;
   
      pDir->hDate = GetCurrentDOSDate ();
      pDir->hTime = GetCurrentDOSTime ();
      WriteSector(gFiles[f].dirSector,gFiles[f].IOpuffer);
      ReadSector(actsector, gFiles[f].IOpuffer);
}

char cwd (char *fname, char f)
{
   int32 actsector;

     if (f > (MAXFILES-1))
      {
      return FALSE; // just in case of overaddressing
      }
   
   if (IsSelfDir(fname))
      {
         return TRUE; // already in Root dir
      }   
      
      if (!FindDirEntry(fname,f))
      {
         return FALSE; // not found
      }

 
      actsector = ComposeCluster (f);
      actsector += gFAT32Vars.gFirstDataSector; // read current dir
      ReadSector (actsector, gFiles[f].IOpuffer);
      
      gFAT32Vars.gDirEntrySector = actsector;
      gFiles[f].dirSector = actsector;
      gFiles[f].CurrentCluster = ComposeCluster (f);
            
      return TRUE;
}

void fputch (char be, char f)
{
      int32 nextcluster;
      int32 actsector;

      if (f > (MAXFILES-1)) return;
      
      if (gFiles[f].posinsector == 512)
   {
       actsector = gFiles[f].CurrentCluster + gFAT32Vars.gFirstDataSector;
         WriteSector (actsector,gFiles[f].IOpuffer);
         
         nextcluster = FindFirstFreeCluster ();
     
       if ((nextcluster != 0x0FFFFFFF) && (nextcluster != 0))
      {
           SetClusterEntry (gFiles[f].CurrentCluster, nextcluster);
            SetClusterEntry (nextcluster, 0x0FFFFFFF);
            actsector = nextcluster + gFAT32Vars.gFirstDataSector;
            //ReadSector (actsector,gFiles[f].IOpuffer);  //-- nao tem a necessidade de ler o setor toda vez que for gravar um bloco
            gFiles[f].CurrentCluster = nextcluster;
            gFiles[f].posinsector = 0;
         }
      }
      
      gFiles[f].IOpuffer[gFiles[f].posinsector] = be;
      gFiles[f].posinsector++;
      gFiles[f].position++;

   return;      
}

void fputstring (char *be, char f)
{
   int16 leng;
   int16 i;

      if (f > (MAXFILES-1)) return;
   
      leng = strlen (be);
   
      for (i = 0; i < leng; i++)
       fputch (be[i], f);
   
}

int16 fread (char *buffer, int16 leng, char f)
{
   int16 i;
   int16 retv;
   char c;
   char v;

      if (f > (MAXFILES-1)) return 0;
      
      retv = 0;
      
      for (i = 0; i < leng; i++)
   {
       v = fgetch (&c, f);
       
         if (v)
        {
           buffer[i] = c;
            retv++;
         }
         
         else break;
      }
   
      return retv;
}

void fwrite (char *buffer, int16 leng, char f)
{
   int16 i;

      if (f > (MAXFILES-1)) return;
      
      for (i = 0; i < leng; i++)
       fputch (buffer[i],f);

}


char fgetch (char *ki, char f)
{
      int32 nextcluster;
      int32 actsector;

      if (f > (MAXFILES-1)) return FALSE;
      
      if (gFiles[f].position >= gFiles[f].DirEntry.wSize) return FALSE;
      
      *ki = gFiles[f].IOpuffer[gFiles[f].posinsector];
      
      gFiles[f].posinsector++;
      gFiles[f].position++;
   
   if (gFiles[f].posinsector == 512)
   {
       nextcluster = GetNextCluster (gFiles[f].CurrentCluster);
       
         if ((nextcluster != 0x0FFFFFFF) && (nextcluster != 0))
         {
            actsector = nextcluster + gFAT32Vars.gFirstDataSector;
            ReadSector (actsector,gFiles[f].IOpuffer);
            
            gFiles[f].CurrentCluster = nextcluster;
            gFiles[f].posinsector = 0;
         }
      }
   
      return TRUE;
}

char remove (char *fname)
{
      char i;
      char found;
      char f;
      DIR *pDir;
      int32 nextcluster;
      int32 currentcluster;
      char *filename;

      filename = TryFile (fname, &f);
      
      if (filename == 0) return FALSE;
      
      found = FindDirEntry (filename,f);
      
   if (!found)
   {
       gFiles[f].Free = TRUE;
       
       printf ("Arquivo não encontrado...\r\n");
         return FALSE;
      }
      
   
   
      pDir = (DIR*)(&(gFiles[f].IOpuffer[32 * gFAT32Vars.gDirEntryIdx]));
      pDir->sName[0] = 0xE5;
      
      for (i = 1; i < 8; i++)
      pDir->sName[i] = ' ';
      
      for (i = 0; i < 3; i++)
         pDir->spam[i] = ' ';
         
      WriteSector (gFAT32Vars.gDirEntrySector, gFiles[f].IOpuffer);
      currentcluster = ComposeCluster (f);
      
      while ((currentcluster != 0x0FFFFFFF) && (nextcluster != 0))
   {
       nextcluster = GetNextCluster (currentcluster);
         ClearClusterEntry (currentcluster);
          currentcluster = nextcluster;
      }
      
      ClearClusterEntry (currentcluster);
      SetClusterEntry (currentcluster, 0);
      currentcluster = gFAT32Vars.gStartSector + DiskInfo.Reserved1 + gFAT32Vars.FATstartidx;
      WriteSector (currentcluster, FATTable);
      currentcluster += DiskInfo.hSectorsPerFat;
      WriteSector (currentcluster, FATTable);
      gFiles[f].Free = TRUE;
   
      return TRUE;
}

char getfsize (char *fname, int32 *fsiz)
{
      char found;
      char f;
      DIR *pDir;
      char *filename;

      filename = TryFile (fname, &f);
      
      if (filename == 0) return FALSE;
      
      found = FindDirEntry (filename, f);
   
   if (!found)
   {
       gFiles[f].Free = TRUE;
       
         return FALSE;
      }
   
      pDir = (DIR*)(&(gFiles[f].IOpuffer[32 * gFAT32Vars.gDirEntryIdx]));
   
      gFiles[f].Free = TRUE;
      *fsiz = pDir->wSize;
   
      return TRUE;
}


MMCFAT32.h

Code:

/*******************************************************
 * ANDRE L. V. SILVA
 * [email protected]
 *******************************************************/

#ifndef __MMCFat32_h__
#define __MMCFat32_h__



// user config. - change it for your desired pic
#byte PORTA_A          =    0xf80          // (PIC16F - 0x05) (PIC18F - 0xf80)
#byte PORTA_B          =   0xf81          // (PIC16F - 0x06) (PIC18F - 0xf81)
#byte PORTA_C          =   0xf82          // (PIC16F - 0x07) (PIC18F - 0xf82)

#byte TRIS_PORTA_A       =    0xf92    // (PIC16F - 0x85) (PIC18F - 0xf92)
#byte TRIS_PORTA_B       =   0xf93    // (PIC16F - 0x86) (PIC18F - 0xf93)
#byte TRIS_PORTA_C       =   0xf94    // (PIC16F - 0x87) (PIC18F - 0xf94)

#bit TRIS_SPI_SCK      =   TRIS_PORTA_C.3
#bit TRIS_SPI_SDI      =   TRIS_PORTA_C.4
#bit TRIS_SPI_SDO      =   TRIS_PORTA_C.5
#bit TRIS_SPI_MMC_CS   =   TRIS_PORTA_B.0
#bit TRIS_DETECTA_MMC   =   TRIS_PORTA_B.4

#bit MMC_CS          =    PORTA_B.0
#bit SPI_SCK          =    PORTA_C.3
#bit SPI_DI            =    PORTA_C.4
#bit SPI_DO            =    PORTA_C.5
#bit MMC_DETECT         =    PORTA_B.4


#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   // flag that indicates traffic on SPI bus
#bit CKE        = SSPSTAT.6   // 1 = data exchange on HIGH to Idle, 0 on Idle to HIGH
#bit SMP        = SSPSTAT.7   // in Master mode let this bit set (sample at end), in slave mode this bit must be cleared 0   
#bit CKP      = SSPCON1.4   // clock polarity (1 = low, 0 = high)
#bit SSPEN       = SSPCON1.5   // 1 = spi mode, 0 = io mode

#define SPI_SLAVE_SS_DESABILITADO    0xf5
#define SPI_SLAVE_SS_HABILITADO    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

// timer 0 = 1 / 4000000 / 4 / 256 = 64us   (with pll, timer 0 uses 4MHZ clock ???)


#ifndef MAXFILES
#define MAXFILES 1
#endif

#ifndef SAIDA
#define SAIDA 0
#endif

#ifndef ENTRADA
#define ENTRADA 1
#endif

#define MINIMO 0
#define MEDIO  1
#define MAXIMO 2

#define SINAL 0

#define SALVAR 1
#define PARAR  0

#define TAMANHO_BLOCO    512
#define START_BYTE      0xfe


typedef struct 
{
   unsigned long     tm_year;
   char            tm_mon;
   char            tm_day;
   char            tm_mday;
   char            tm_hour;
   char            tm_min;
   char            tm_sec;
   
} TimeRecord;


TimeRecord myrec; // this variable is updated in regular intervals in DoIdle()

typedef struct _diskinforec
{
   char  hJumpCode[3];
   char  OEMName[8];
   int16 hBytesPerSector;
   char  bSectorsPerCluster;
   int16 Reserved1;
   char  FATCopies;
   int16 hMaxRootEntries;
   int16 hSectors;
   char  Descriptor;
   int16 holdSectorsPerFat;
   int16 hSectorsPerTrack;
   int16 hNumberofHeads;
   int32 hNumberofHidden;
   int32 hNumberofSectors;

   int32 hSectorsPerFat;
   int16 hFlags;
   int16 hFAT32Version;
   int32 hRootStartCluster;
   
} diskinforec;

typedef struct _direntry
{
   char  sName[8];
   char  spam[3];
   char  bAttr;
   char  bReserved[8];
   int16 hClusterH;
   int16 hTime;
   int16 hDate;
   int16 hCluster;
   int32 wSize;
   
} DIR;

typedef struct _fileentry
{
   char    IOpuffer[512];
   DIR   DirEntry;
   int32 CurrentCluster;
   int16 posinsector;
   int32 position;
   int32 dirSector;
   int16 dirIdx;
   char  mode;
   char  Free;
   
} FILE;

typedef struct
{
   int32 MMCAddress;
   int32 FATstartidx;
   int32 gStartSector;
   int32 gFirstDataSector;
   int16 gDirEntryIdx;
   int32 gDirEntrySector;
   int16 gFirstEmptyDirEntry;
   int32 gFirstDirEntryCluster;
   
} FAT32Vars;


void InicializaSPI       (char Tipo);
void InicializaMMC       (void);
void SelecionaMMC        (boolean Flag);
void EnviaMMC         (char a);
char RecebeMMC         (void);
void MMC8Clock         (void);
void ReadSector         (int32 sector, char *buffer);
void WriteSector       (int32 sector, char *buffer);


char DetectaMMC (void);

void ExecutaCMD0    (void);
void ExecutaCMD1    (void);
void ExecutaCMD16    (void);
void ExecutaCMD10    (void);
void ExecutaCMD9    (void);
void ExecutaCMD6    (void);

void InicializaFAT32   ();
char FindDirEntry   (char *fname, char f);
char fopen         (char *fname, char mode);
void fclose         (char f);
void fflush         (char f);
char cwd         (char *fname, char f);
void fputch         (char be, char f);
char fgetch         (char *ki, char f);
void fputstring      (char *be, char f); // fputs is reserved in CCS C
int16 fread         (char *buffer, int16 leng, char f);
void fwrite         (char *buffer, int16 leng, char f);
char remove         (char *fname);
char getfsize      (char *fname, int32 *fsiz);

#endif


enjoy it.

I got it working on my 18f4620, 18f4525, 18f2620

regards.
_________________
Andre
ckielstra



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

View user's profile Send private message

PostPosted: Mon Mar 02, 2009 6:18 pm     Reply with quote

Andre, thanks for posting the code.

A few comments though:
Code:
   else
   {
      printf ("\r\nInicializando SPI: ");
      printf ("312.5 KHz...");

      CKE = FALSE;
      SMP = TRUE;
      CKP = TRUE;
      SSPCON1 = SSPCON1 & SPI_MASTER_SCK_DIV_4;
      SSPEN = TRUE;
   }
The setup for SSPCON1 has two problems:
1) you should have used DIV_64 instead of DIV_4
2) The '&' construction only resets bits, but a few bits need to be set as well.
For example change to:
Code:
SPI_MASTER_SCK_DIV_64  0x02
SPI_MASTER_SCK_DIV_16  0x01
SPI_MASTER_SCK_DIV_4   0x00

SSPCON1 = (SSPCON1 & 0xF0) | SPI_MASTER_SCK_DIV_64;


According to the MMC / SD card specifications you have to send a minimum of 74 clock pulses to the card after power-on. This is used by the card for internal initialisation. The chip select line should not be active during these pulses and the clock speed should be lower than 400kHz.
You have mixed this functionality with sending the CMD0 command. Not very nice as it now only works for the slowest clock speed setting.

The above mentioned problems with clock speed setting could cause some cards to fail starting up correctly.
andreluizeng



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

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

PostPosted: Mon Mar 02, 2009 10:20 pm     Reply with quote

ckielstra

thanks for looking the code, it was the first that I got running, there are wrong comments, but a new one is almost finished.

but just to fix it, replace that code for this new one

Code:

   if (Tipo == MAXIMO)
   {
      SSPEN = FALSE;
      SSPCON1 = SPI_MASTER_SCK_DIV_4;
      SMP = TRUE;
      CKE = FALSE;
      CKP = TRUE;
      SSPEN = TRUE;
   }


   else if (Tipo == MEDIO)
   {
      SSPEN = FALSE;
      SSPCON1 = SPI_MASTER_SCK_DIV_16;
      SMP = TRUE;
      CKE = FALSE;
      CKP = TRUE;
      SSPEN = TRUE;

   }

   else if (Tipo == MINIMO)
   {
      SSPEN = FALSE;
      SSPCON1 = SPI_MASTER_SCK_DIV_64;
      SMP = TRUE;
      CKE = FALSE;
      CKP = TRUE;
      SSPEN = TRUE;


I think that Im not far to got my SDHC running... hope to post it working soon..

thanks again..

regards
_________________
Andre
manish12



Joined: 18 Jan 2009
Posts: 15

View user's profile Send private message

PostPosted: Wed Mar 04, 2009 6:33 am     Reply with quote

ckt diagram for this code pic18f4620 / else, xtal value, setting programming bits ??
andreluizeng



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

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

PostPosted: Wed Mar 04, 2009 7:24 am     Reply with quote

Manish,

this is only the library functions, but I used with 10, 20 and 40Mhz, (HS and H4 fuses) this was my first "functional" code.
And if you have some problems with card initialization, tell me then I post a new one. Sorry for didn't post the later version, but everything that comes for free has no funny to work with =)

ps 1: in "initicializaMMC" function on CMD the issue regarding CS Active as ckielstra said, I believe that is correct, because I'm just sending dummy clocks for "clean" and make sure that SD Card has nothing else to respond.

ps2: Some cards cannot initializes correctly with this function, so you should try removing 2 commands from the code:


Code:

   ExecutaCMD10 ();
   ExecutaCMD9 ();


I know.. this makes a very basic initialization sequence but will work fine with SDSC and MMC cards. How I said, I'm still working on a better lib, and a few moments before post this message I got my SDHC (4GB kingston) working =), hope to post it soon.

regards.
_________________
Andre
vascotech88



Joined: 10 Mar 2009
Posts: 33
Location: Aveiro, Portugal / Lodz, Polska

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

PostPosted: Mon Jul 05, 2010 11:06 am     Reply with quote

Hi andre!

Before all thanks for sharing your code with the community!
Luckily i understand your code because i am Portuguese :P

I want to ask one think that i never found concrete answer. Your code works with MMC only or with SD cards too?

What have to be changed if its different working?


I am trying to put your code working with Proteus, but its not easy :S

See ya!
andreluizeng



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

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

PostPosted: Mon Jul 05, 2010 11:57 am     Reply with quote

Hi Mate =), nice to now that you are from Portugal, I prefer to speak in portuguese, but as we are here to help, let keep it using the English Language.

My code works with both mmc and sd card, I believe that it will be hard to get it working on proteus, I made myself crazy just trying to work with cards over there. In my first attempt it was working fine, but then I lost control and I move to the real circuitry and there I got better results.

I have my library working with mmc, sd, minisd, sdsc, sdhc (>= 4GB). But unfortunately I still can't share for free.

regards,

Andre
_________________
Andre
vascotech88



Joined: 10 Mar 2009
Posts: 33
Location: Aveiro, Portugal / Lodz, Polska

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

PostPosted: Mon Jul 05, 2010 1:29 pm     Reply with quote

Yes, its true, we have to keep language!

Well actually I have half of your code working in Proteus. I haven't start making it on real because I am waiting for components.
Until now I can read and write RAW data to sectors to a zero filled card image. It works great. The next step will be try to add the FAT support.
I will spend next thousand hours in front of CCS :P

Yes! Of course I understand that you don't share it for free! Most part of this takes lots of time and to "work just to heat up" like we say in PT is not good idea! hahaha. Anyway I think is better for other people to understand the code than just copy it from somebody.

I will try to put this working! If I have some problem I will ask!

Best regards mate! =) Thanks!
KONAMI



Joined: 29 Aug 2010
Posts: 11

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

How to Handle fopen
PostPosted: Wed Mar 14, 2012 6:32 am     Reply with quote

Hi Andrew.
How do you handle fopen?
I am asking how do you know if filename exist or name on mms/sd
and what error did you return in in case of exist or not ?
ckielstra



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

View user's profile Send private message

PostPosted: Wed Mar 14, 2012 12:57 pm     Reply with quote

Konami,
Please don't bump all the old SD Card related threads.

The questions you post here make no sense to me because we have no clue as to which SD-library you are using.
If you have a problem then start a new thread where you explain your problem and ask clear questions, if possible with a small demo program.
temtronic



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

View user's profile Send private message

PostPosted: Wed Mar 14, 2012 3:53 pm     Reply with quote

Also show us a schematic of the hardware you're using !!
prometyus2010



Joined: 12 Feb 2012
Posts: 7

View user's profile Send private message

PostPosted: Fri Mar 16, 2012 2:09 pm     Reply with quote

hi..
Thanks for code.
How can I use this code for example how can open a file (xxx.txt) ?
What code I must write main func. ?
ckielstra



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

View user's profile Send private message

PostPosted: Sun Mar 18, 2012 7:21 am     Reply with quote

prometyus2010 wrote:
What code I must write main func. ?
Have a look at the first 10 lines of the posted code.
Then for opening a file it makes sense to add a call to fopen().

But, why use this library? Andre did a great job by posting this code, but as he writes himself it is only a first running version. A new version was promised back in 2009 but never posted.
As alternatives with more users using the same code you can choose from:
- CCS supplied library (has few known problems but workarounds are posted in the forums).
- Tomi's FAT32 code in the Code Library
- Douglas' FAT16 code, also in the Code Library
- A commercial FAT32 implementation from Brush Electronics
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 1, 2  Next
Page 1 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