|
|
View previous topic :: View next topic |
Author |
Message |
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sun Mar 18, 2012 9:30 am |
|
|
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
|
|
Posted: Sun Mar 18, 2012 9:51 am |
|
|
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 ). 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
|
Interfacing of SD Card with PIC |
Posted: Fri Dec 12, 2014 4:16 am |
|
|
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
|
SD Card interfacing with PIC |
Posted: Fri Dec 12, 2014 5:50 am |
|
|
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
|
|
Posted: Fri Dec 12, 2014 1:55 pm |
|
|
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
|
im still alive =) |
Posted: Fri Jul 15, 2016 12:45 pm |
|
|
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 |
|
|
|
|
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
|