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

📄 cf.c

📁 常见卡(SD,NAND,XD,MS,ATA,CF)完整DRIVER
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*******************************************************************************
*                               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      : cf.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 "cf.h"
#include "devio.h"
#include "taskid.h"
#include "ui.h"
#if CF_ENABLE //byAlexWang 24jun2007 m2project

/*
// Constant declarations
*/
#define MEMORY_MODE                 0x00000000
#define IO_MODE                     0x00000004
#define TRUE_IDE_MODE               0x00000008
#define ADR_NORMAL                  0x00000000
#define ADR_PRIMARY                 0x00000010
#define ADR_SECONDARY               0x00000020
#define WIDTH_8BIT                  0x00000040
#define WIDTH_16BIT                 0x00000000
#define SINGLE_SECTOR               0x00000000
#define MULTI_SECTOR                0x00000100
#define MULTI_SECTOR_WAIT_EDGE      0x00000000
#define MULTI_SECTOR_WAIT_TIME      0x00000200
#define RESET_ENABLE                0x00010000

 #if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
#define MEMORY_SETTING (MEMORY_MODE | ADR_NORMAL | WIDTH_8BIT | SINGLE_SECTOR & (~RESET_ENABLE))
#else
#define MEMORY_SETTING (MEMORY_MODE | ADR_NORMAL | WIDTH_16BIT | SINGLE_SECTOR & (~RESET_ENABLE))
#endif
#define TRUE_IDE_SETTING (TRUE_IDE_MODE | ADR_NORMAL | WIDTH_16BIT | SINGLE_SECTOR | RESET_ENABLE)
#define IO_SETTING (IO_MODE | ADR_NORMAL | WIDTH_16BIT | SINGLE_SECTOR & (~RESET_ENABLE))
#define IC_CD1                      0x00000001
#define IC_CD2                      0x00000002
#define IC_FRDY                     0x00000004
#define IC_FVS1                     0x00000008
#define IC_FVS2                     0x00000010
#define IC_ACSER                    0x00000020
#define IC_CFTCE                    0x00000040
#define IC_CFTO                     0x00000080
#define IC_CD_ALL (IC_CD1 | IC_CD2)
#define IM_CD1                      0x00000100
#define IM_CD2                      0x00000200
#define IM_FRDY                     0x00000400
#define IM_FVS1                     0x00000800
#define IM_FVS2                     0x00001000
#define IM_ACSER                    0x00002000
#define IM_CFTCE                    0x00004000
#define IM_CFTO                     0x00008000
#define IM_ALL                      0	/*(IM_FRDY | IM_ACSER | IM_CFTCE | IM_CFTO) */
#define PL_HIGH_CD1                 0x00010000
#define PL_HIGH_CD2                 0x00020000
#define PL_HIGH_FRDY                0x00040000
#define PL_HIGH_FVS1                0x00080000
#define PL_HIGH_FVS2                0x00100000
#define PL_HIGH_ACSER               0x00200000
#define PL_HIGH_CFTCE               0x00400000
#define PL_HIGH_CFTO                0x00800000
#define MD_EDGE_CD1                 0x01000000
#define MD_EDGE_CD2                 0x02000000
#define MD_EDGE_FRDY                0x04000000
#define MD_EDGE_FVS1                0x08000000
#define MD_EDGE_FVS2                0x10000000
#define MD_EDGE_ACSER               0x20000000
#define MD_EDGE_CFTCE               0x40000000
#define MD_EDGE_CFTO                0x80000000

 #if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
 	#if((CHIP_VER & 0x0000ffff) == CHIP_VER_A)
#define GPIO_DEFINE_0               0x00003bff
#define GPIO_DEFINE_1               0x00001ff1
#define GPIO_DEFINE_2               0x00000000
#define H_GPIO_DEFINE_0               0x3bff0000
#define H_GPIO_DEFINE_1               0x1ff10000
#define H_GPIO_DEFINE_2               0x00000000
	#elif(((CHIP_VER & 0x0000ffff) == CHIP_VER_B)||((CHIP_VER & 0x0000ffff) == CHIP_VER_C))
		#define GPIO_DEFINE_0               0x00003bff
		#define GPIO_DEFINE_1               0x00000fd0 // rick for backlight(FGPIO 28 FREG) not be affect by CF
		#define GPIO_DEFINE_2               0x00000000
		#define H_GPIO_DEFINE_0               0x3bff0000
		#define H_GPIO_DEFINE_1               0x0fd00000 // rick for backlight(FGPIO 28 FREG) not be affect by CF
		#define H_GPIO_DEFINE_2               0x00000000

	#endif
 #else
#define GPIO_DEFINE_0               0x0000ffff
#define GPIO_DEFINE_1               0x0000ffff
#define GPIO_DEFINE_2               0x0000007f
#define H_GPIO_DEFINE_0               0xffff0000
#define H_GPIO_DEFINE_1               0xffff0000
#define H_GPIO_DEFINE_2               0x007f0000
#endif

#define MEMORY_READ_TIMMING1		0x02020701 // for video play lag but command may fail when mmc plug out
#define MEMORY_READ_TIMMING         0x04020702
#define MEMORY_WRITE_TIMMING        0x04030d02

#define IDE_READ_TIMMING            0x02010804
#define IDE_WRITE_TIMMING           0x02010804

#define I_O_READ_TIMMING            0x00010201
#define I_O_WRITE_TIMMING           0x00010201

#define INITIAL_MEMORY          0x0
#define INITIAL_TRUE_IDE        0x1
#define INITIAL_IO              0x2

#define COMMAND_IDENTIFY_DRIVE  0xec
#define COMMAND_READ_SECTOR     0x20
#define COMMAND_WRITE_SECTOR    0x30
#define COMMAND_TOTAL           0x03
#define DRIVE_PROPERTY          0xe0

#define IDENTIFY_ID     0x848a
#define ERR         0x01
#define CORR        0x04
#define DRQ         0x08
#define DSC         0x10
#define DWF         0x20
#define RDY         0x40
#define BUSY        0x80

#define TIMEOUT_COUNT       1200000

#define CF_CLOCK    0x1

///
///@defgroup CF CompactFlash
///@ingroup CONSTANT
///@{


/// Wait for CompactFlash's ready signal fail.
#define TIMEOUT                     -2
/// Wait for FIFO transaction end Fail.
#define IC_SFTCE_TIMEOUT            -3
/// Wait for DMA end Fail.
#define DMA_TIMEOUT                 -4
///@}

/*
// Variable declarations
*/
static BYTE bDescriptor[2] = "CF";
static volatile BOOL blTimeOutFlag;
#pragma alignvar(4)
/*
// Macro declarations
*/
//#define CF_TIMEOUT_HANDLE

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

/*
// Static function prototype
*/
static void CommandProcess(void *McardDev);
static SWORD WaitReady(void);
static SWORD CommandReady(void);
static void TimeoutHandle(void);
static SWORD LogicalRead(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD LogicalWrite(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD Identify(DWORD * pdwTotalSector);
static SWORD WriteSector(DWORD dwBufferAdress, WORD wSize);
static SWORD ReadSector(DWORD dwBufferAdress, WORD wSize);
static void SetCommand(BYTE bCommand);
static void SetParameter(DWORD dwSectorCount, DWORD dwLogAddr);
static void Select(BYTE bMode);
static void DeSelect(void);
static SWORD FlatRead(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD FlatWrite(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD Format(void);

/*
// Definition of internal functions
*/
void CfInit(ST_MCARD_DEV * sDev)
{
	sDev->pbDescriptor = bDescriptor;
	sDev->dwLunNum = CF_LUN_NUM;
	sDev->wMcardType = CF;
	sDev->Flag.Installed = 1;
	sDev->CommandProcess = CommandProcess;
}

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

	McardSetClock(CF_CLOCK);
	sMcardRMail = pDev->sMcardRMail;
	Select(INITIAL_MEMORY);
	switch (sMcardRMail->wCmd)
	{
	case INIT_CARD_CMD:
		pDev->Flag.Detected = Ui_CheckCfPlugIn();
		if (pDev->Flag.Detected)
		{
			//card in
			McardIODelay(0x500);
			pDev->Flag.Detected = 1;
			if ((pDev->swStatus = Identify(&(pDev->dwCapacity))))
			{
				pDev->Flag.Detected = 0;
				pDev->Flag.Present = 0;
				pDev->wSectorSize = 0;
				pDev->dwCapacity = 0;
				McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
			}
			else
			{
				pDev->wRenewCounter++;
				pDev->Flag.ReadOnly = 0;
				pDev->Flag.Present = 1;
				pDev->wSectorSize = MCARD_SECTOR_SIZE;
				McardSetCurLun(pDev->dwLunNum, pDev->wMcardType);
				//EventSet(UI_EVENT, EVENT_CARD_INIT);                      
			}
		}
		else
		{
			//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);  
		}
		break;
	case REMOVE_CARD_CMD:		//Athena 03.11.2006 seperate card in & out
		//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);
		break;
	case READ_PAGE_CMD:
		pDev->swStatus =
			FlatRead(sMcardRMail->dwBuffer, sMcardRMail->dwBlockCount, sMcardRMail->dwBlockAddr);
		break;

	case WRITE_PAGE_CMD:
		pDev->swStatus =
			FlatWrite(sMcardRMail->dwBuffer, sMcardRMail->dwBlockCount, sMcardRMail->dwBlockAddr);
		break;

	case FORMAT_CMD:
		pDev->swStatus = Format();
		break;

	default:
		MP_DEBUG1("-E- INVALID CMD %d", sMcardRMail->wCmd);
		break;
	}
	DeSelect();
}

//==========================================================================
static inline BOOL Polling_CF_Status(void)
{
	extern BYTE g_bCfCardFlag;
	register MCARD *sMcard;

	sMcard = (MCARD *) MCARD_BASE;
#if((CHIP_VER  == (CHIP_VER_600 |CHIP_VER_B))||(CHIP_VER == (CHIP_VER_600 | CHIP_VER_C)))
	if ((sMcard->McCfIc & 0x1) != 0x1)
#else
	if ((sMcard->McCfIc & 0x3) != 0x3)
#endif		
	{
		McardIODelay(10);

#if((CHIP_VER  == (CHIP_VER_600 |CHIP_VER_B))||(CHIP_VER == (CHIP_VER_600 | CHIP_VER_C)))
	return ((sMcard->McCfIc & 0x1) != 0x1);
#else
	return ((sMcard->McCfIc & 0x3) != 0x3);
#endif		
		
	}

	return 0;
}

static SWORD WaitReady(void)
{
	register CFATA *sCfata;
	DWORD dwTimeCount;

	sCfata = (CFATA *) (MC_CFCOM_BASE);
	dwTimeCount = (g_bAniFlag & ANI_VIDEO)? (TIMEOUT_COUNT>>4):TIMEOUT_COUNT;
	while (dwTimeCount)
	{
		if (Polling_CF_Status())
			return FAIL;

		if (sCfata->StatusCommand == (DSC | RDY))
		{
			return PASS;
		}
		dwTimeCount--;
		TASK_YIELD();
	}
	return TIMEOUT;
}

static SWORD CommandReady(void)
{
	register CFATA *sCfata;
	DWORD dwTimeCount;

	sCfata = (CFATA *) (MC_CFCOM_BASE);
	dwTimeCount = (g_bAniFlag & ANI_VIDEO)? (TIMEOUT_COUNT>>4):TIMEOUT_COUNT;
	while ((sCfata->StatusCommand & (BUSY | DRQ)) != DRQ)
	{
		if (Polling_CF_Status())
			return FAIL;

		if (dwTimeCount == 0)
		{
			MP_DEBUG1("-E- command FAIL (status: %x)", sCfata->StatusCommand);
			return TIMEOUT;
		}
		dwTimeCount--;
		TASK_YIELD();
		McardIODelay(5);
	}
	return PASS;
}

static void TimeoutHandle(void)
{
	register CHANNEL *sChannel;

	sChannel = (CHANNEL *) (DMA_MC_BASE);
	sChannel->Control = 0;
	DmaIntDis(IM_MCRDDM);
	blTimeOutFlag = 1;
	TaskWakeup(MCARD_TASK);
}

static SWORD LogicalRead(register DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr)
{
	register DWORD dwCount, dwTempSectorCount;
	register SWORD swRetValue;
	register BYTE *pbBuffer;

	pbBuffer = (BYTE *) dwBufferAddress;
	while (dwSectorCount)
	{
		if (dwSectorCount >= 256)
		{
			dwTempSectorCount = 256;
			dwCount = 0;
		}
		else
		{
			dwTempSectorCount = dwSectorCount;
			dwCount = dwSectorCount;
		}
		//if (Polling_CF_Status())
		//	return FAIL;

		SetParameter(dwCount, dwLogAddr);
		SetCommand(COMMAND_READ_SECTOR);

		dwCount = dwTempSectorCount;
		while (dwCount)
		{
			//if (Polling_CF_Status())
			//	return FAIL;
			if ((swRetValue = CommandReady()))
			{
				MP_DEBUG1("-E- Read command FAIL (swRetValue: %d)", swRetValue);
				return swRetValue;
			}

			if ((swRetValue = ReadSector((DWORD) pbBuffer, MCARD_SECTOR_SIZE)))
			{
				MP_DEBUG1("-E- DMA Read FAIL (swRetValue: %d)", swRetValue);
				return swRetValue;
			}

			pbBuffer += MCARD_SECTOR_SIZE;
			dwCount--;
		}

		dwSectorCount = dwSectorCount - dwTempSectorCount;
		dwLogAddr = dwLogAddr + dwTempSectorCount;

		if ((swRetValue = WaitReady()))
		{
			MP_DEBUG1("-E- Ready FAIL(swRetValue: %d)", swRetValue);
			return swRetValue;
		}
	}

	return PASS;
}

static SWORD LogicalWrite(DWORD dwBufferAddress, volatile DWORD dwSectorCount,
						  volatile DWORD dwLogAddr)
{
	DWORD dwCount, dwTempSectorCount;
	SWORD swRetValue;
	BYTE *pbBuffer;

	pbBuffer = (BYTE *) dwBufferAddress;
	while (dwSectorCount)
	{
		if (Polling_CF_Status())
			return FAIL;
		if (dwSectorCount >= 256)
		{
			dwTempSectorCount = 256;
			dwCount = 0;
		}
		else
		{
			dwTempSectorCount = dwSectorCount;
			dwCount = dwSectorCount;
		}

		SetParameter(dwCount, dwLogAddr);
		SetCommand(COMMAND_WRITE_SECTOR);

		dwCount = dwTempSectorCount;
		while (dwCount)
		{
			if ((swRetValue = CommandReady()))
			{
				MP_DEBUG1("-E- Write command FAIL (swRetValue: %d)", swRetValue);
				return swRetValue;
			}
			if ((swRetValue = WriteSector((DWORD) pbBuffer, MCARD_SECTOR_SIZE)))
			{
				MP_DEBUG1("-E- DMA Write FAIL (swRetValue: %d)", swRetValue);
				return swRetValue;
			}

⌨️ 快捷键说明

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