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

📄 sd old.c

📁 常见卡(SD,NAND,XD,MS,ATA,CF)完整DRIVER
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
*******************************************************************************
*                               Magic Pixel
*                  5F, No.3, Creation Road III, Science_Based 
*                   Industrial Park, Hsinchu, Taiwan, R.O.C
*               (c) Copyright 2004, Magic Pixel Inc, Hsinchu, Taiwan
*
* All rights reserved. Magic Pixel's source code is an unpublished work and the 
* use of a copyright notice does not imply otherwise. This source code contains
* confidential, trad secret material. Any attempt or participation in 
* deciphering, decoding, reverse engineering or in ay way altering the source 
* code is strictly prohibited, unless the prior written consent of Magic 
* Pixel is obtained.
*
* Filename      : sd.c
* Programmer(s) : 
* Created       : 
* Descriptions  :
*******************************************************************************
*/
/*
// define this module show debug message or not,  0 : disable, 1 : enable
*/
#define LOCAL_DEBUG_ENABLE 0

/*
// Include section 
*/
#include "global612.h"
#include "mpTrace.h"
#include "uti.h"
#include "Mcard.h"
#include "sd.h"
#include "devio.h"
#include "taskid.h"
#include "ui.h"
#include "flagdefine.h"
#if SD_MMC_ENABLE //byAlexWang 24jun2007 m2project
#if (((CHIP_VER & 0xffff0000) == CHIP_VER_600)&&((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600PQFP_2M_SDRAM)))
#define BYTE_MODE
#endif

/*
// Constant declarations
*/
#define HW_SUPPORT_MMC_4_0
#define SDHC_FLAG	

#define SD_TYPE			1
#define SDHC_TYPE		2
#define MMC_TYPE		3
#define SDIO_TYPE		4

#define OP_RADTC                0x00000400
#define OP_WADTC   			    0x00000200
#define OP_NADTC   			    0x00000100
#define IC_RSPDONE 			    0x00000001
#define IC_TREND   			    0x00000002
#define IC_RSPF    			    0x00000004
#define IC_CRC16F  			    0x00000008
#define IC_CRC7F   			    0x00000010
#define IC_PGMF    			    0x00000020
#define IC_SDTO    			    0x00000040
#define IC_WXF     			    0x00000080
#define IM_RSPDONE 			    0x00000100
#define IM_TREND   			    0x00000200
#define IM_RSPF    			    0x00000400
#define IM_CRC16F  			    0x00000800
#define IM_CRC7F   			    0x00001000
#define IM_PGMF    			    0x00002000
#define IM_SDTO    			    0x00004000
#define IM_WXF     			    0x00008000
#define IM_ALL 0				/*(IM_RSPDONE | IM_TREND | IM_RSPF | IM_CRC16F | IM_CRC7F | IM_PGMF | IM_SDTO | IM_WXF) */

#define BIG_ENDIAN              0x00000080
#define DISABLE_STOP_BY_CMD_HW  0x00000100
#define FSMBUSY                 0x00001000
#define DBUS_1BIT               (0x00000000 | BIG_ENDIAN | DISABLE_STOP_BY_CMD_HW)
#define DBUS_4BIT               (0x00004000 | BIG_ENDIAN | DISABLE_STOP_BY_CMD_HW)
#define DBUS_8BIT               (0x00008000 | BIG_ENDIAN | DISABLE_STOP_BY_CMD_HW)

#define GPIO_DEFINE_0 			0x0000ff00
#define GPIO_DEFINE_1 			0x00000004
#define GPIO_DEFINE_2 			0x00004000
#define GPIO_DEFILE_3 			0x00000180

#define WATCHDOG_TIMER			0x003fffff

#define MMC_DEFAULT_ADDR              0x00100000
#ifdef  SDHC_FLAG
#define SDHC_CHECK_PATTERN	0xaa
#define NORMAL  1 // 2.7~3.6
#define LOW_VOL	2
#define SDHC_VOLTAGE_SUPPLIED		NORMAL
#define HCS			0x40000000
#endif
#define CMD_GO_IDLE_STATE             (OP_NADTC + 0)
#define CMD_SEND_OP_COND              (OP_NADTC + 1)	// only for MMC
#define CMD_ALL_SEND_CID              (OP_NADTC + 2)
#define CMD_SEND_RELATIVE_ADDR        (OP_NADTC + 3)
#define CMD_SET_DSR                   (OP_NADTC + 4)

#define CMD_SWITCH                    (OP_NADTC + 6)

#define CMD_SELECT_CARD               (OP_NADTC + 7)
#define CMD_SEND_IF_COND		(OP_NADTC + 8)
#define CMD_SEND_EXT_CSD		(OP_RADTC + 8)
#define CMD_SEND_CSD                  (OP_NADTC + 9)
#define CMD_SEND_CID                  (OP_NADTC + 10)
#define CMD_SEND_DAT_UNTIL_STOP       (OP_RADTC + 11)	// only for MMC
#define CMD_STOP_TRANSMISSION         (OP_NADTC + 12)
#define CMD_SEND_STATUS               (OP_NADTC + 13)
#define CMD_GO_INACTIVE_STATE         (OP_NADTC + 15)

#define CMD_SET_BLOCKLEN              (OP_NADTC + 16)
#define CMD_READ_SINGLE_BLOCK         (OP_RADTC + 17)
#define CMD_READ_MULTIPLE_BLOCK       (OP_RADTC + 18)

#define CMD_WRITE_DAT_UNTIL_STOP      (OP_WADTC + 20)

#define CMD_SET_BLOCK_COUNT           (OP_NADTC + 23)	// only for MMC
#define CMD_WRITE_SINGLE_BLOCK        (OP_WADTC + 24)
#define CMD_WRITE_MULTIPLE_BLOCK      (OP_WADTC + 25)
#define CMD_PROGRAM_CID               (OP_WADTC + 26)	// only for MMC
#define CMD_PROGRAM_CSD               (OP_WADTC + 27)

#define CMD_SET_WRITE_PROT            (OP_NADTC + 28)
#define CMD_CLR_WRITE_PROT            (OP_NADTC + 29)
#define CMD_SEND_WRITE_PROT           (OP_RADTC + 30)

#define CMD_ERASE_WR_BLK_START        (OP_NADTC + 32)	// only for SD
#define CMD_ERASE_WR_BLK_END          (OP_NADTC + 33)	// only for SD
#define CMD_ERASE_GROUP_START         (OP_NADTC + 35)	// only for MMC
#define CMD_ERASE_GROUP_END           (OP_NADTC + 36)	// only for MMC
#define CMD_ERASE                     (OP_NADTC + 38)

#define CMD_LOCK_UNLOCK               (OP_WADTC + 42)

#define CMD_APP_COM                   (OP_NADTC + 55)
#define CMD_GEN_COM                   (OP_NADTC + 56)

#define ACMD_SET_BUS_WIDTH            (OP_NADTC + 6)
#define ACMD_SD_STATUS                (OP_RADTC + 13)
#define ACMD_SEND_NUM_WR_BLOCKS       (OP_RADTC + 22)
#define ACMD_SET_WR_BLK_ERASE_COUNT   (OP_NADTC + 23)
#define ACMD_SD_APP_OP_COND           (OP_NADTC + 41)
#define ACMD_SET_CLR_CARD_DETEC       (OP_NADTC + 42)
#define ACMD_SEND_SCR                 (OP_RADTC + 51)

#define NULL_STATE		0
#define STANDBY_STATE       3
#define TRANSFER_STATE      4
#define RECEIVE_STATE       6
#define PROGRAM_STATE       7

#define HOST_OCR_VALUE        0x00ff8000
#define MMC_VER_4_0           0x4

/*
#ifdef CPU_120M
#define CPU_CLOCK           120000              //120MHz = 120000kHz
#define OPEN_DRAIN_DELAY_1  0x200
#define OPEN_DRAIN_DELAY_2  0x400
#define INITIAL_CLOCK       0x7                       
#elif defined CPU_108M
#define CPU_CLOCK           108000              //108MHz = 108000kHz
#define OPEN_DRAIN_DELAY_1  0x200
#define OPEN_DRAIN_DELAY_2  0x400
#define INITIAL_CLOCK       0x7                       
#elif defined CPU_96M
#define CPU_CLOCK           96000               //96MHz = 96000kHz
#define OPEN_DRAIN_DELAY_1  0x200
#define OPEN_DRAIN_DELAY_2  0x400
#define INITIAL_CLOCK       0x7                       
#elif defined CPU_72M
#define CPU_CLOCK           72000               //72MHz = 72000kHz
#define OPEN_DRAIN_DELAY_1  0x3000
#define OPEN_DRAIN_DELAY_2  0x3000
#define INITIAL_CLOCK       0x7                       
#elif defined CPU_48M
#define CPU_CLOCK           48000               //48MHz = 48000kHz
#define OPEN_DRAIN_DELAY_1  0x3000
#define OPEN_DRAIN_DELAY_2  0x3000
#define INITIAL_CLOCK       0x6   
#elif defined CPU_36M
#define CPU_CLOCK           36000               //36MHz = 36000kHz
#define OPEN_DRAIN_DELAY_1  0x3000
#define OPEN_DRAIN_DELAY_2  0x3000
#define INITIAL_CLOCK       0x6   
#endif

#define MCARD_CLOCK_1       CPU_CLOCK
#define MCARD_CLOCK_1_2     (CPU_CLOCK / 2)
#define MCARD_CLOCK_1_3     (CPU_CLOCK / 3)
#define MCARD_CLOCK_1_4     (CPU_CLOCK / 4)
#define MCARD_CLOCK_1_5     (CPU_CLOCK / 5)
#define MCARD_CLOCK_1_6     (CPU_CLOCK / 6)
#define MCARD_CLOCK_1_128   (CPU_CLOCK / 128)
#define MCARD_CLOCK_1_256   (CPU_CLOCK / 256)

enum
{
    SD_MMC_MIN_CLOCK = 0,

    CPU_CLOCK_1_256 = SD_MMC_MIN_CLOCK,
    CPU_CLOCK_1_128,
    CPU_CLOCK_1_6,
    CPU_CLOCK_1_5,
    CPU_CLOCK_1_4,
    CPU_CLOCK_1_3,
    CPU_CLOCK_1_2,
    CPU_CLOCK_1,

    SD_MMC_MAX_CLOCK = CPU_CLOCK_1_2
};
*/

///
///@defgroup SD_MMC SD and MMC
///@ingroup CONSTANT
///@{

/// The device's function executes commands without any problem.
#define SD_PASS               0
#define BAD_CRC7           -1
/// Wait for response's signal fail.
#define RES_TIMEOUT        -2
/// When reading data, card had no response with previous command.
#define READ_TIMEOUT       -3
/// When writing data, card had no response with previous command.
#define WRITE_TIMEOUT      -4
#define TRANSFER_FAIL      -5
#define PROGRAM_FAIL       -6
/// When reading data, the data had failed the CRC examination
#define BAD_CRC16          -7
#define CARD_NOT_SUPPORT   -8
/// Unknown or general error encounter.
#define GENERAL_FAIL       -9
///@}


//#define ENABLE_CHACK_TACC_MECHANISM
//#define HW_SUPPORT_MMC_4_0 
#define MMC_BUS_WIDTH       0x1	// 0: 1 bit, 1: 4bit, 2: 8bit

#define RETRY_TIME      3

#define MULTI_W_SECTOR_NUM   1

/*
// Structure declarations
*/
struct ST_INFO_TAG
{
	BYTE bInitFlag;
	BYTE bMultiReadFlag;
	BYTE bType;
	BYTE bSDInit;
	DWORD dwBusWidth;
	DWORD dwCardTag;
	DWORD dwClock;
	DWORD dwSpeed;
	DWORD dwRelativeCardAddr;
	DWORD dwCapacity;
};

struct ST_CLOCK_SPEED_TYPE_TAG
{
	BYTE bSettingValue;
	DWORD dwClockValue;
};

/*
// Type declarations
*/
typedef struct ST_INFO_TAG ST_INFO;
typedef struct ST_CLOCK_SPEED_TYPE_TAG ST_CLOCK_SPEED_TYPE;

/*
// Variable declarations
*/
static DWORD dwCPU_CLOCK;
static DWORD dwOPEN_DRAIN_DELAY_1;
static DWORD dwOPEN_DRAIN_DELAY_2;
static DWORD dwINITIAL_CLOCK;
static DWORD dwMCARD_CLOCK_1;
static DWORD dwMCARD_CLOCK_1_2;
static DWORD dwMCARD_CLOCK_1_3;
static DWORD dwMCARD_CLOCK_1_4;
static DWORD dwMCARD_CLOCK_1_5;
static DWORD dwMCARD_CLOCK_1_6;
static DWORD dwMCARD_CLOCK_1_128;
static DWORD dwMCARD_CLOCK_1_256;

static DWORD dwSD_MMC_MIN_CLOCK;
static DWORD dwCPU_CLOCK_1_256;
static DWORD dwCPU_CLOCK_1_128;
static DWORD dwCPU_CLOCK_1_6;
static DWORD dwCPU_CLOCK_1_5;
static DWORD dwCPU_CLOCK_1_4;
static DWORD dwCPU_CLOCK_1_3;
static DWORD dwCPU_CLOCK_1_2;
static DWORD dwCPU_CLOCK_1;
static DWORD dwSD_MMC_MAX_CLOCK;

static ST_INFO sInfo;
static volatile BOOL blTimeOutFlag;
static BYTE bDescriptor[6] = "SD_MMC";
static ST_CLOCK_SPEED_TYPE sClockSpeedTable[8];

static BYTE bSlow_Card = 0;
/*
static const ST_CLOCK_SPEED_TYPE sClockSpeedTable[] = 
{
    {0x7,   MCARD_CLOCK_1_256},
    {0x6,   MCARD_CLOCK_1_128},
    {0x5,   MCARD_CLOCK_1_6},
    {0x4,   MCARD_CLOCK_1_5},
    {0x3,   MCARD_CLOCK_1_4},
    {0x2,   MCARD_CLOCK_1_3},
    {0x1,   MCARD_CLOCK_1_2},
    {0x0,   MCARD_CLOCK_1},
};
*/
static const BYTE bSpeedFactor[] = {
	// all parameter X 10
	0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
};

static const DWORD dwSpeedUnit[] = {
	100, 1000, 10000, 100000, 0, 0, 0, 0
};
#pragma alignvar(4)
/*
// Macro declarations
*/
//#define SD_TIMEOUT_HANDLE

//#define SD_TASK_YIELD
#ifdef SD_TASK_YIELD
#define TASK_YIELD() TaskYield()
#else
#define TASK_YIELD()
#endif

/*
// Static function prototype
*/
static void CommandProcess(void *pMcardDev);
static void DeSelect(void);
static void DeSelectData(void);
static void Select(void);
static BYTE GetWPFlag(void);
static void SetClockSpeed(DWORD dwSpeed);
static SWORD GoTransferMode(void);
static void SetCommand(WORD wCommand, DWORD dwArgument);
static SWORD WaitHostReady(void);
static void OpenDrainDelay(void);
static SWORD WaitResponse(void);
static SWORD SetBlockLen(DWORD dwBlockLen);
static SWORD SelCard(void);
static void TimeoutHandle(void);
static void SetDataDma(DWORD dwBufferAddress, DWORD dwSize, DWORD dwDirection);
static SWORD WaitChannelStop(void);
static void DmaReset(void);
static void DmaReset(void);
static SWORD WaitTranState(void);
static SWORD WaitDataRead(void);
static SWORD WaitDataWrite(void);
static SWORD WaitBusy(void);
static SWORD FlatRead(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD LogicalRead(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD FlatWrite(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD LogicalWrite(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD Format(void);

/*
// Definition of internal functions
*/
void SdInitForClk(void)
{
	switch (g_dwCpuClk)
	{
	case CLOCK_96M_PLL1CFG:
		{
			dwCPU_CLOCK = 96000;	//96MHz = 96000kHz
			dwOPEN_DRAIN_DELAY_1 = 0x200;
			dwOPEN_DRAIN_DELAY_2 = 0x400;
			dwINITIAL_CLOCK = 0x7;
		}
		break;
	case CLOCK_108M_PLL1CFG:
	case CLOCK_108M_PLL2CFG:
		{
			dwCPU_CLOCK = 108000;	//96MHz = 96000kHz
			dwOPEN_DRAIN_DELAY_1 = 0x200;
			dwOPEN_DRAIN_DELAY_2 = 0x400;
			dwINITIAL_CLOCK = 0x7;
		}
		break;
	default:					// 72MHz
		{
			dwCPU_CLOCK = 72000;	//96MHz = 96000kHz
			dwOPEN_DRAIN_DELAY_1 = 0x3000;
			dwOPEN_DRAIN_DELAY_2 = 0x3000;
			dwINITIAL_CLOCK = 0x7;
		}
		break;
	}

	dwMCARD_CLOCK_1 = dwCPU_CLOCK;
	dwMCARD_CLOCK_1_2 = (dwCPU_CLOCK / 2);
	dwMCARD_CLOCK_1_3 = (dwCPU_CLOCK / 3);
	dwMCARD_CLOCK_1_4 = (dwCPU_CLOCK / 4);
	dwMCARD_CLOCK_1_5 = (dwCPU_CLOCK / 5);
	dwMCARD_CLOCK_1_6 = (dwCPU_CLOCK / 6);
	dwMCARD_CLOCK_1_128 = (dwCPU_CLOCK / 128);
	dwMCARD_CLOCK_1_256 = (dwCPU_CLOCK / 256);

	sClockSpeedTable[0].bSettingValue = 0x7;
	sClockSpeedTable[0].dwClockValue = dwMCARD_CLOCK_1_256;
	sClockSpeedTable[1].bSettingValue = 0x6;
	sClockSpeedTable[1].dwClockValue = dwMCARD_CLOCK_1_128;
	sClockSpeedTable[2].bSettingValue = 0x5;
	sClockSpeedTable[2].dwClockValue = dwMCARD_CLOCK_1_6;
	sClockSpeedTable[3].bSettingValue = 0x4;
	sClockSpeedTable[3].dwClockValue = dwMCARD_CLOCK_1_5;
	sClockSpeedTable[4].bSettingValue = 0x3;
	sClockSpeedTable[4].dwClockValue = dwMCARD_CLOCK_1_4;
	sClockSpeedTable[5].bSettingValue = 0x2;
	sClockSpeedTable[5].dwClockValue = dwMCARD_CLOCK_1_3;
	sClockSpeedTable[6].bSettingValue = 0x1;
	sClockSpeedTable[6].dwClockValue = dwMCARD_CLOCK_1_2;
	sClockSpeedTable[7].bSettingValue = 0x0;
	sClockSpeedTable[7].dwClockValue = dwMCARD_CLOCK_1;

	dwSD_MMC_MIN_CLOCK = 0;
	dwCPU_CLOCK_1_256 = dwSD_MMC_MIN_CLOCK;
	dwCPU_CLOCK_1_128 = dwSD_MMC_MIN_CLOCK + 1;
	dwCPU_CLOCK_1_6 = dwSD_MMC_MIN_CLOCK + 2;
	dwCPU_CLOCK_1_5 = dwSD_MMC_MIN_CLOCK + 3;
	dwCPU_CLOCK_1_4 = dwSD_MMC_MIN_CLOCK + 4;
	dwCPU_CLOCK_1_3 = dwSD_MMC_MIN_CLOCK + 5;
	dwCPU_CLOCK_1_2 = dwSD_MMC_MIN_CLOCK + 6;
	dwCPU_CLOCK_1 = dwSD_MMC_MIN_CLOCK + 7;
	dwSD_MMC_MAX_CLOCK = dwCPU_CLOCK_1_2;
}

void SdInit(ST_MCARD_DEV * sDev)
{
	MP_ASSERT(sDev != NULL);
	
	sDev->pbDescriptor = bDescriptor;
	sDev->dwLunNum = SD_MMC_LUN_NUM;
	sDev->wMcardType = SD_MMC;
	sDev->Flag.Installed = 1;
	sDev->CommandProcess = CommandProcess;
	sInfo.dwClock = dwINITIAL_CLOCK;
	sInfo.bSDInit = 0;
}

static inline BOOL Polling_SD_Status(void)
{
	if (!Ui_CheckSdPlugIn())
	{
		McardIODelay(10);
		if (!Ui_CheckSdPlugIn())
			return 1;
	}
	return 0;
}

DWORD SdGetSpeed(void)
{
	return sInfo.dwSpeed;
}

/*
// Definition of local functions 
*/
static void CommandProcess(void *pMcardDev)
{
	ST_MCARD_MAIL *sMcardRMail;
	register ST_MCARD_DEV *pDev = ((ST_MCARD_DEV *) pMcardDev);

	sMcardRMail = pDev->sMcardRMail;
	Select();
	switch (sMcardRMail->wCmd)
	{
	case INIT_CARD_CMD:
		pDev->Flag.Detected = Ui_CheckSdPlugIn();
		if (pDev->Flag.Detected)
//		MP_DEBUG1("COmmandProcess sInfo.bSDInit = %d",sInfo.bSDInit);
//		if ((pDev->Flag.Detected) &&(sInfo.bSDInit == 0))
		{
			MP_DEBUG("-I- SD Cardin & Detected");
			//card in
			sInfo.bInitFlag = FALSE;
			sInfo.dwCardTag = MCARD_DMA_SD;
			sInfo.dwBusWidth = DBUS_1BIT;
			sInfo.dwClock = dwINITIAL_CLOCK;
			McardSetClock(sInfo.dwClock);
			pDev->Flag.Detected = 1;
            		MP_DEBUG("-I- SD GoTransferMode");
			if ((pDev->swStatus = GoTransferMode()))
			{
				//pDev->Flag.Detected = 0;
				pDev->Flag.Present = 0;
				pDev->dwCapacity = 0;
				pDev->wSectorSize = 0;
				McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
			}
			else
			{
			    MP_DEBUG("-I- SD GoTransferMode out");
				sInfo.bSDInit = 1;					
				pDev->wRenewCounter++;
				pDev->Flag.ReadOnly = GetWPFlag();
				pDev->Flag.Present = 1;
				pDev->dwCapacity = sInfo.dwCapacity;
				pDev->wSectorSize = MCARD_SECTOR_SIZE;
				McardSetCurLun(pDev->dwLunNum, pDev->wMcardType);
				//EventSet(UI_EVENT, EVENT_CARD_INIT);                                
			}
            MP_DEBUG("-I- SD init cmd pass");
		}
		else if (!(pDev->Flag.Detected))
		{
			//card out
			pDev->Flag.Detected = 0;
			pDev->Flag.Present = 0;
			pDev->Flag.ReadOnly = 0;
			pDev->Flag.PipeEnable = 0;
			pDev->swStatus = 0;
			pDev->dwCapacity = 0;
			pDev->wSectorSize = 0;
			McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
			//EventSet(UI_EVENT, EVENT_CARD_INIT);            

⌨️ 快捷键说明

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