⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdmmc.c

📁 SD卡驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************
 *
 *       Secure Digital and Multimedia Cards Interface
 *
 ******************************************************************************
 * FileName:        sdmmc.c
 * Dependencies:    Compiler.h
 *					spi.h
 *					sdmmc.h
 *					sdmmc_lld.h
 *					string.h
 * Processor:       PIC24FJ128
 * Compiler:        C30
 * Company:         Microchip Technology, Inc.
 *                  zhouyi
 * Software License Agreement
 *
 *
*****************************************************************************/

#include "sdmmc.h"
#include "generic.h"
#include "sdmmc_lld.h"
#include "string.h"
#include "sdhal.h"

/******************************************************************************
 * Global Variables
 *****************************************************************************/

BYTE gblSDMMCBuf[MEDIA_SECTOR_SIZE];

DISK glbDiskData;


#define Yield Nop()


#define SD_CMD_IDLE				0
#define SD_CMD_SEND_OP_COND		1
#define SD_CMD_SET_BLOCK_LEN	16
#define SD_CMD_READ_BLOCK		17
#define SD_CMD_WRITE_BLOCK		24

#define SD_CARD_SYSTEM		// Does this mean we are supporting more than one cards? - NR

typedef enum
{
	GO_IDLE_STATE,
	SEND_OP_COND,
	SEND_CSD,
	SEND_CID,
	STOP_TRANSMISSION,
	SEND_STATUS,
	SET_BLOCKLEN,
	READ_SINGLE_BLOCK,
	READ_MULTI_BLOCK,
	WRITE_SINGLE_BLOCK,
	WRITE_MULTI_BLOCK,
	TAG_SECTOR_START,
	TAG_SECTOR_END,
	UNTAG_SECTOR,
	TAG_ERASE_GRP_START,
	TAG_ERASE_GRP_END,
	UNTAG_ERASE_GRP,
	ERASE,
	LOCK_UNLOCK,
	SD_APP_OP_COND,
	APP_CMD,
	READ_OCR,
	CRC_ON_OFF
}sdmmc_cmd;

/*********************************************************************
 * sdmmc_cmdtable
 * - Provides information for all the sdmmc commands that we support
 * 
 * Notes: We turn off the CRC as soon as possible, so the commands with
 *        0xFF don't need to be calculated in runtime 
 *********************************************************************/
const typMMC_CMD sdmmc_cmdtable[] =
{
	// cmd					crc		response
	{cmdGO_IDLE_STATE,		0x95,	R1, NODATA},
	{cmdSEND_OP_COND,		0xF9,	R1, NODATA},
	{cmdSEND_CSD,			0xAF,	R1, MOREDATA},
	{cmdSEND_CID,			0x1B,	R1, MOREDATA},
	{cmdSTOP_TRANSMISSION,	0xC3,	R1, NODATA},
	{cmdSEND_STATUS,		0xAF,	R2, NODATA},
	{cmdSET_BLOCKLEN,		0xFF,	R1, NODATA},
	{cmdREAD_SINGLE_BLOCK,	0xFF,	R1, MOREDATA},
	{cmdREAD_MULTI_BLOCK,	0xFF,	R1, MOREDATA},
	{cmdWRITE_SINGLE_BLOCK,	0xFF,	R1, MOREDATA},
	{cmdWRITE_MULTI_BLOCK,	0xFF,	R1, MOREDATA}, 
	{cmdTAG_SECTOR_START,	0xFF,	R1, NODATA},
	{cmdTAG_SECTOR_END,		0xFF,	R1, NODATA},
	{cmdUNTAG_SECTOR,		0xFF,	R1, NODATA},
	{cmdTAG_ERASE_GRP_START, 0xFF,	R1, NODATA},
	{cmdTAG_ERASE_GRP_END,	0xFF,	R1, NODATA},
	{cmdUNTAG_ERASE_GRP,	0xFF,	R1, NODATA},
	{cmdERASE,				0xDF,	R1b, NODATA},
	{cmdLOCK_UNLOCK,		0x89,	R1b, NODATA},  
	{cmdSD_APP_OP_COND,		0xE5,	R1, NODATA},
	{cmdAPP_CMD,			0x73,	R1, NODATA},
	{cmdREAD_OCR,			0x25,	R3, NODATA},
	{cmdCRC_ON_OFF,			0x25,	R1, NODATA}
};

// BPB FAT12
typedef struct __BPB_FAT12 {
        SWORD BS_jmpBoot;        // Jump Command
        BYTE  BS_OEMName[8];     // OEM name
        WORD BPB_BytsPerSec;     // BYTEs per sector
        BYTE  BPB_SecPerClus;     // sectors per allocation unit
        WORD BPB_RsvdSecCnt;     // number of reserved sectors after start
        BYTE  BPB_NumFATs;        // number of FATs
        WORD BPB_RootEntCnt;     // number of root directory entries
        WORD BPB_TotSec16;       // total number of sectors
        BYTE  BPB_Media;          // media descriptor
        WORD BPB_FATSz16;         // number of sectors per FAT
        WORD BPB_SecPerTrk;      // sectors per track
        WORD BPB_NumHeads;       // number of heads
        DWORD BPB_HiddSec;        // number of hidden sectors
        BYTE  BS_Reserved0;       // Nothing
        BYTE  BS_DrvNum;          // Int 13 drive number
        BYTE  BS_Reserved1;       // Nothing
        BYTE  BS_BootSig;         // 0x29
        BYTE  BS_VolID[4];        // Volume Id
        BYTE  BS_VolLab[11];       // Volume Label
        BYTE  BS_FilSysType[8];   // File system type, not used for determination   
}_BPB_FAT12;

typedef _BPB_FAT12 * BPB_FAT12;

// BPB FAT32
typedef struct __BPB_FAT32 {
        SWORD BPB_jmpBoot;        // Jump Command
        BYTE  BPB_OEMName[8];     // OEM name
        WORD BPB_BytsPerSec;     // BYTEs per sector
        BYTE  BPB_SecPerClus;     // sectors per allocation unit
        WORD BPB_RsvdSecCnt;     // number of reserved sectors after start
        BYTE  BPB_NumFATs;        // number of FATs
        WORD BPB_RootEntCnt;     // number of root directory entries
        WORD BPB_TotSec16;       // total number of sectors
        BYTE  BPB_Media;          // media descriptor
        WORD BPB_FATSz16;         // number of sectors per FAT
        WORD BPB_SecPerTrk;      // sectors per track
        WORD BPB_NumHeads;       // number of heads
        DWORD BPB_HiddSec;        // number of hidden sectors
        DWORD BPB_TotSec32;       // New 32bit total sec count
        DWORD BPB_FATSz32;        // Sectors occupied by one FAT
        WORD BPB_ExtFlags;       // Presently active FAT as defined by bits 0-3 if bit 7 is 1
        WORD BPB_FSVers;         // FAT32 filesystem version, should be 0:0
        DWORD BPB_RootClus;       // start cluster of the root directory (should be 2)
        WORD BPB_FSInfo;         // filesystem info structure sector
        WORD BPB_BkBootSec;      // backup boot sector normally 6
        BYTE  BPB_Reserved[12];   // Reserved memory
        BYTE  BS_DrvNum;          // Int 13 drive number
        BYTE  BS_Reserved1;       // Nothing
        BYTE  BS_BootSig;         // 0x29
        BYTE  BS_VolID[4];        // Volume Id
        BYTE  BS_VolLab[11];       // Volume Label
        BYTE  BS_FilSysType[8];   // File system type, not used for determination  
}_BPB_FAT32;

typedef _BPB_FAT32 * BPB_FAT32;

// BPB FAT16
typedef struct __BPB_FAT16 {
        SWORD BS_jmpBoot;        // Jump Command
        BYTE  BS_OEMName[8];     // OEM name
        WORD BPB_BytsPerSec;     // BYTEs per sector
        BYTE  BPB_SecPerClus;     // sectors per allocation unit
        WORD BPB_RsvdSecCnt;     // number of reserved sectors after start
        BYTE  BPB_NumFATs;        // number of FATs
        WORD BPB_RootEntCnt;     // number of root directory entries
        WORD BPB_TotSec16;       // total number of sectors
        BYTE  BPB_Media;          // media descriptor
        WORD BPB_FATSz16;         // number of sectors per FAT
        WORD BPB_SecPerTrk;      // sectors per track
        WORD BPB_NumHeads;       // number of heads
        DWORD BPB_HiddSec;        // number of hidden sectors
        DWORD BPB_TotSec32;       // New 32bit total sec count
        BYTE  BS_DrvNum;          // Int 13 drive number
        BYTE  BS_Reserved1;       // Nothing
        BYTE  BS_BootSig;         // 0x29
        BYTE  BS_VolID[4];        // Volume Id
        BYTE  BS_VolLab[11];       // Volume Label
        BYTE  BS_FilSysType[8];   // File system type, not used for determination     
}_BPB_FAT16;

#define BSI_BOOTJMP			0
#define BSI_OEM_NAME		3
#define BSI_BytesPerSec		11
#define BSI_SecPerClus		13
#define BSI_RsvdSecCount 	14
#define BSI_NumFATs			16
#define BSI_RootEntCnt		17
#define BSI_TotSec16 		19
#define BSI_Media 			21
#define BSI_FATSz16 		22
#define BSI_SecPerTrk 		24
#define BSI_NumHeads 		26
#define BSI_HiddSec 		28
#define BSI_TotSec32 		32
#define BSI_DrvNum 			36
#define BSI_Reserved1 		37
#define BSI_BootSig 		38
#define BSI_VolID 			39
#define BSI_VolLab 			43
#define BSI_FilSysType 		54

typedef _BPB_FAT16 * BPB_FAT16;

// PTE_FAT - Partition Table Entry

typedef struct _PTE_FAT
{
    BYTE      PTE_BootDes;            // Boot Descriptor, 0x80
    SWORD     PTE_FrstPartSect;       // First Partion Sector
    BYTE      PTE_FSDesc;             // File System Descriptor 
    SWORD     PTE_LstPartSect;        // Last Partion Sector
    DWORD     PTE_FrstSect;           // First Sector Position
    DWORD     PTE_NumSect;            // Number of Sectors in partion
}PTE_FAT;

// PT_FAT - Partition Table 
typedef struct __PT_FAT
{
    BYTE      ConsChkRtn[446];
    PTE_FAT Partition0;
    PTE_FAT Partition1;
    PTE_FAT Partition2;
    PTE_FAT Partition3;
    BYTE      Signature0;     // 0x55
    BYTE      Signature1;     // 0xAA
}_PT_FAT;

typedef _PT_FAT *  PT_FAT;

typedef union _MMCstate
{
    struct
	{
        BYTE isSDMMC : 1;     // set if it is a SDMMC 
        BYTE isWP    : 1;     // set if it is write protected 
    };
    BYTE  _byte;
}MMCSTATE;

typedef struct __BS
{
    union
    {
        _BPB_FAT32  FAT_32;	
        _BPB_FAT16  FAT_16;	
        _BPB_FAT12  FAT_12;	
    }FAT;    
    BYTE  	Reserved[MEDIA_SECTOR_SIZE-sizeof(_BPB_FAT32)-2];
    BYTE      Signature0;     // 0x55
    BYTE      Signature1;     // 0xAA
}_BS;

typedef _BS * BS;

typedef union _CARDSTATUS
{
    struct
    {
        BYTE  CS_Inserted:1;  // Card is inserted and initialized
        BYTE  CS_Reset:1;     // Card has just been reset
        BYTE  CS_SDMMC:1;     // Card is of the SDMMC type
        BYTE  CS_WP:1;        // Card is write Protected
        BYTE  CS_Failure:1;   // There was a failure initializing the card
    };
    WORD _word;   
}CARDSTATUS;

// Master Boot Record offsets
#define FO_MBR          0L  // master boot record sector LBA

#ifndef EOF
#define EOF         (-1)
#endif

#define FAT_GOOD_SIGN_0     0x55
#define FAT_GOOD_SIGN_1     0xAA
#define BOOTABLE            0x80
#define NON_BOOTABLE        0x00

/******************************************************************************
 * Prototypes
 *****************************************************************************/

BYTE DISKmount( DISK *dsk, BYTE* b, MMCSTATE *Flag);
BYTE LoadMBR(DISK *dsk);
BYTE LoadBootSector(DISK *dsk);
extern void Delayms(BYTE milliseconds);
void StopCard(DISK *dsk, CARDSTATUS *cs);
BYTE StartupCard(DISK *dsk, CARDSTATUS *CardStatus);
BYTE ReadMedia(void);
BYTE MediaInitialize(void);
MMC_RESPONSE SendMMCCmd(BYTE cmd, DWORD address);
BYTE ReadByte( BYTE* pBuffer, WORD index );
WORD ReadWord( BYTE* pBuffer, WORD index );
DWORD ReadDWord( BYTE* pBuffer, WORD index );

void OpenSPI( unsigned char sync_mode, unsigned char bus_mode, unsigned char smp_phase);
void CloseSPI( void );
unsigned char WriteSPI( unsigned char data_out );

BYTE SD_ReadRegister(WORD len, BYTE *recbuf);
BYTE SD_GetCardInfo();
void SD_SPIDelay(char value)
{
    char i;

    for(i = 0; i < value; i++)
        WriteSPI(0xFF);
		//Nop();	
	return;					
}		
/******************************************************************************
 * Function:        BYTE MediaDetect(void)
 *
 * PreCondition:    MediaInit function has been executed.
 *
 * Input:           void
 *
 * Output:          TRUE   - Card detected
 *                  FALSE   - No card detected
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 *****************************************************************************/
BYTE MediaDetect()
{
	// give it a debounce here
	Delayms(10);

//	return(!SD_CD);
	return 1;
}//end MediaDetect


/******************************************************************************
 * Function			BYTE MediaInit (void)
 * KETTER
******************************************************************************/

BYTE MediaInit ()
{
	BYTE result;
	CARDSTATUS	cs;
			//Write Protect - input
	init_spi1();
//    StartupCard (&glbDiskData, &cs) == CE_GOOD
	result = StartupCard(&glbDiskData, &cs);
	return  ( result );
}
		

/******************************************************************************
 * Function:        BYTE MediaInitialize(MMCSTATE *Flag)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          mmcValid                    - Everything is fine
 *                  mmcCardInitCommFailure      - Communication has never been established with card
 *                  mmcCardNotInitFailure       - Card did not go into an initialization phase
 *                  mmcCardInitTimeout          - Card initialization has timedout
 *                  mmcCardTypeInvalid          - Card type was not able to be defined
 *                  mmcCardBadCmd               - Card did not reconized the command
 *                  mmcCardTimeout              - Card timedout during a read, write or erase sequence
 *                  mmcCardCRCError             - A CRC error has occurred during a read, data should be invalidated
 *                  mmcCardDataRejected         - Card and data sent's CRC did not match
 *
 * Side Effects:    Variable 'gblMMC_media' is updated
 *
 * Overview:        MediaInitialize initializes the media card and supporting variables.
 *
 * Note:            goto's were used for errro conditions
 *****************************************************************************/
BYTE MediaInitialize(void)
{
	    MMC_RESPONSE    response;
 		BYTE status = TRUE;
		int timeout = 0xfff,i=0;

		CS_LOW;
		
		SD_SPIDelay(100);      //delay more than 74 clock
		CS_HIGH;
		WriteSPI(0xff); 
		WriteSPI(0xff); 
		i = 0xfff;
		do	
		{
			response = SendMMCCmd(GO_IDLE_STATE,0x0);//GO_IDLE_STATE
			i--;
		}while((response.r1._byte != 0x01)&&( i  > 0));
		if((response.r1._byte != 0x01)||(i <= 0))                  //0x01=No Err&Busy Initializing
		{
			status = FALSE;      // we have not got anything back from the card
			goto InitError;
		}
		do
		{	
			response = SendMMCCmd(APP_CMD ,0x0);
			response = SendMMCCmd(SD_APP_OP_COND ,0x0);//SEND_OP_COND SD_APP_OP_COND
			timeout--;
		}while((response.r1._byte != 0x00)&&(timeout > 0));
		if(response.r1._byte != 0x00)
		{	
			timeout = 0xfff;
			do
			{
				response = SendMMCCmd(SEND_OP_COND ,0x0);
			}while((response.r1._byte != 0x00)&&(timeout > 0));
			if(timeout <= 0x00)
			{
				status = FALSE;
				goto InitError;
			}
		}
		//SD_GetCardInfo();
		for(timeout = 0xFF; timeout > 0 && SECTORread(0,gblSDMMCBuf) != TRUE; timeout--)
		{;}
		//SECTORwrite(10,(void *)"zhouyi");
		//SECTORread(10,gblSDMMCBuf);
		if(timeout == 0)
		{
			status = FALSE;
			goto InitError;
		}
		return(status);
InitError:
		CS_HIGH;                             // deselect the devices
		return(status);
}//end MediaInitialize

//----------------------------------------------------------------------
// ShutdownMedia

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -