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

📄 ms.c

📁 常见卡(SD,NAND,XD,MS,ATA,CF)完整DRIVER
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
*******************************************************************************
*                               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      : ata.c
* Programmer(s) : 
* Created       : 
* Descriptions  :
*******************************************************************************
*/
/*
// define this module show debug message or not,  0 : disable, 1 : enable
*/
#define LOCAL_DEBUG_ENABLE 0

//#define MS_IRQ
/*
// Include section 
*/
#include "global612.h"
#include "mpTrace.h"
#include "uti.h"
#include "Mcard.h"
#include "ms.h"
#include "devio.h"
#include "taskid.h"
#include "ui.h"
#if MS_ENABLE //byAlexWang 24jun2007 m2project

#define MsProFaster	0
#define MsProNormal	1
#define MsSpeedStatus MsProFaster

#define ABEL_MS_TEST			//need check

/*
// Constant declarations
*/
#define TPC_READ_LONG_DATA      0x00000002
#define TPC_READ_SHORT_DATA     0x00000003
#define TPC_WRITE_LONG_DATA     0x0000000d
#define TPC_WRITE_SHORT_DATA    0x0000000c
#define TPC_GET_INT             0x00000007
#define TPC_SET_CMD             0x0000000e
#define TPC_EX_SET_CMD          0x00000009
#define TPC_WRITE_REG           0x0000000b
#define TPC_READ_REG            0x00000004
#define TPC_SET_RW_REG_ADR      0x00000008

#define DATA_PATH_BY_DMA        0x00000040
#define DATA_PATH_BY_CPU        0x00000000
#define PAGE_MOD_512_BYTE       0x00000080
#define PAGE_MOD_BY_DATA_LEN    0x00000000

#define STATUS_HWRREQ           0x00000001
#define STATUS_HRDREQ           0x00000002
#define STATUS_FIFOIDLE         0x00000004
#define STATUS_FIFOFULL         0x00000008
#define STATUS_FIFOEMPTY        0x00000010
#define STATUS_INVALIDACC       0x00000020
#define STATUS_CMDINT           0x00000040
#define STATUS_CMDEND           0x00000080
#define STATUS_CRCERROR         0x00000100
#define STATUS_TIMEOUT0         0x00000200
#define STATUS_TIMEOUT1         0x00000400
#define STATUS_INVALIDCMD       0x00020000
#define STATUS_CED              0x00040000
#define STATUS_ERR              0x00080000
#define STATUS_BREQ             0x00100000
#define STATUS_CMDNK            0x00200000


#define IC_HWRREQ               0x00000001
#define IC_HRDREQ               0x00000002
#define IC_CMDINT               0x00000004
#define IC_CMDEND               0x00000008
#define IC_TIMEOUT1             0x00000010
#define IC_INVALIDCMD           0x00000020
#define IM_HWRREQ               0x00000100
#define IM_HRDREQ               0x00000200
#define IM_CMDINT               0x00000400
#define IM_CMDEND               0x00000800
#define IM_TIMEOUT1             0x00001000
#define IM_INVALIDCMD           0x00002000
#define PL_HWRREQ               0x00010000
#define PL_HRDREQ               0x00020000
#define PL_CMDINT               0x00040000
#define PL_CMDEND               0x00080000
#define PL_TIMEOUT1             0x00100000
#define PL_INVALIDCMD           0x00200000
#define PL_ALL_HIGH (PL_HWRREQ | PL_HRDREQ | PL_CMDINT | PL_CMDEND | PL_TIMEOUT1 | PL_INVALIDCMD)
#define MD_HWRREQ               0x01000000
#define MD_HRDREQ               0x02000000
#define MD_CMDINT               0x04000000
#define MD_CMDEND               0x08000000
#define MD_TIMEOUT1             0x10000000
#define MD_INVALIDCMD           0x20000000
#define GPIO_DEFINE_0           0x00000010
#define GPIO_DEFINE_1           0x00008000
#define GPIO_DEFINE_2           0x0f000f00

#define WATCHDOG_TIMER          0x003fffff
#define BUS_WIDTH_4             0x20
#define BUS_WIDTH_1             0x60

///
///@defgroup MS Memory Stick
///@ingroup CONSTANT
///@{


/// Unsupport memory stick type.
#define TYPE_NOT_SUPPORT            -2
#define CMD_FAIL                    -3
/// Transfer protocol command's ready signal fail.
#define TPC_RB_TIMEOUT              -4
/// Transfer protocol command's interrupt signal fail.
#define TPC_INT_TIMEOUT             -5
/// When reading data, the data had failed the CRC examination.
#define READ_DATA_CRC_ERROR         -6
/// Wait for DMA end Fail.
#define DMA_TIMEOUT                 -7
/// Memory Stick has been switched to write protect ON.
#define WRITE_PROTECT               -8
#define WRITE_PS_NG                 -9
///@}

#define READ_TIMEOUT1   0x83d6	// 5ms = x * 1/6.75MHz
#define WRITE_TIMEOUT1  0x107ac	// 10ms = x * 1/6.75MHz
#define ERASE_TIMEOUT1  0xa4cb8	// 100ms = x * 1/6.75MHz
#define PRO_TIMEOUT1    0x134fd90	// 1000ms

// define command code for MS
#define BLOCK_READ					0x00
#define BLOCK_WRITE					0x01
#define BLOCK_END					0x02
#define BLOCK_ERASE					0x03
#define SLEEP						0x00
#define CLEAR_BUF					0x01
#define RESET						0x02

// define command code for MS PRO
#define PRO_READ_DATA               0x00
#define PRO_WRITE_DATA              0x01
#define PRO_READ_ATRB               0x02
#define PRO_STOP                    0x03
#define PRO_ERASE                   0x04
#define PRO_FORMAT                  0x00
#define PRO_SLEEP                   0x01

#define CED         0x80
#define ERR         0x40
#define BREQ        0x20
#define CMDNK       0x01

#define UCFG        0x01
#define FGER        0x02
#define UCEX        0x04
#define EXER        0x08
#define UCDT        0x10
#define DTER        0x20
#define FB1         0x40
#define MB          0x80

#define MAXSEGMENT              32
#define MAXLOGBLOCK             496
#define MAXPHYBLOCK             512

#define FORMAT_PARAM_MAX_SIZE   6
/*
#ifdef CPU_120M
#define MS_CLOCK    0x5     //120MHz / 6
#elif defined CPU_108M
#define MS_CLOCK    0x5     //108MHz / 6
#elif defined CPU_96M
#define MS_CLOCK    0x4     // 96MHz / 5
#elif defined CPU_72M
#define MS_CLOCK    0x3     // 72MHz / 4
#elif defined CPU_48M
#define MS_CLOCK    0x2     // 48MHz / 3
#elif defined CPU_36M
#define MS_CLOCK    0x1     // 36MHz / 2
#endif
*/
/*
// Structure declarations
*/
struct ST_PRO_PARAM_REG_TAG
{
	BYTE bCmdCode;
	BYTE bDataCount1;
	BYTE bDataCount0;
	BYTE bDataAddr3;
	BYTE bDataAddr2;
	BYTE bDataAddr1;
	BYTE bDataAddr0;
	BYTE bTpcParameter;
	BYTE bCmdParameter;
	BYTE bReserve[3];
};
struct ST_INFO_TAG
{
	BYTE bBootBlock;
	BYTE bWriteProtected;
	BYTE bMsPro;
	BYTE bBusWidth;
	BYTE bBootProtectFlag;
	BYTE bProtectBlockCount;
	BYTE bReserve0[2];
	BYTE bExtraData[32][4];
	WORD wProtectBlockTable[11];
	BYTE bReserve1[2];
	WORD wLog2PhyTable[MAXSEGMENT * MAXPHYBLOCK];
	WORD wReAssignTable[MAXSEGMENT];
	DWORD dwSegment;
	DWORD dwBlockSize;
	DWORD dwBlock;
	DWORD dwEffBlock;
	DWORD dwPagePerBlock;
	DWORD dwCapacity;
};
struct ST_RW_REG_TPC_ADDR_TAG
{
	BYTE bReadRegAddr;
	BYTE bReadRegSize;
	BYTE bWriteRegAddr;
	BYTE bWriteRegSize;
};
struct ST_EXTRA_DATA_TAG
{
	BYTE bOverWriteFlag;
	BYTE bManagementFlag;
	BYTE bLogicalAddr1;
	BYTE bLogicalAddr0;
	BYTE bReserveArea4;
	BYTE bReserveArea3;
	BYTE bReserveArea2;
	BYTE bReserveArea1;
	BYTE bReserveArea0;
	BYTE bReserve[3];
};
struct ST_PARAM_REG_TAG
{
	BYTE bSysParameter;
	BYTE bBlockAddrReg2;
	BYTE bBlockAddrReg1;
	BYTE bBlockAddrReg0;
	BYTE bCmdParameter;
	BYTE bPageAddr;
//	BYTE bReserve[2];
	struct ST_EXTRA_DATA_TAG sExtra;
};
struct ST_FORMAT_PARAM_TAG
{
	BYTE bBlockSize;
	WORD wCapacityID;	
	BYTE bMbrParam[16];
	BYTE bPbrParam[62];
};

/*
// Type declarations
*/
typedef struct ST_INFO_TAG ST_INFO;
typedef struct ST_RW_REG_TPC_ADDR_TAG ST_RW_REG_TPC_ADDR;
typedef struct ST_EXTRA_DATA_TAG ST_EXTRA_DATA;
typedef struct ST_PARAM_REG_TAG ST_PARAM_REG;
typedef struct ST_PRO_PARAM_REG_TAG ST_PRO_PARAM_REG;
typedef struct ST_FORMAT_PARAM_TAG ST_FORMAT_PARAM;

/*
// Variable declarations
*/
static BYTE bMS_CLOCK;
static ST_INFO sInfo;
static ST_RW_REG_TPC_ADDR sRWRegTpcAddr;
static ST_PARAM_REG sParamReg;
static ST_PRO_PARAM_REG sProParamReg;
static BYTE bTempBuffer[MCARD_SECTOR_SIZE * 32];
static const BYTE bFlashCMD[5] = { 0xAA, 0x55, 0x33, 0x99, 0xCC };
static const BYTE bFuncCMD[3] = { 0x5A, 0xC3, 0x3C };

static const BYTE bProFlashCMD[5] = { 0x20, 0x21, 0x24, 0x25, 0x26 };
static const BYTE bProFuncCMD[2] = { 0x10, 0x11 };

static BYTE bDescriptor[2] = "MS";
static const BYTE bSpecialFile[12] =
	{ 'M', 'E', 'M', 'S', 'T', 'I', 'C', 'K', 'I', 'N', 'D', 0X03 };
static const ST_FORMAT_PARAM sFormatParamTable[FORMAT_PARAM_MAX_SIZE] = {
	/*
	   {
	   wCapacityID,
	   bMbrParam,
	   bPbrParam,
	   }
	 */
	//Block size 8K
	//4MB
	{
	 0x08,
	 0x0200,
	 {0x80, 0x01, 0x0c, 0x00, 0x01, 0x01, 0x10, 0xf5, 0x1b, 0x00, 0x00, 0x00, 0xa5, 0x1e, 0x00,
	  0x00},
	 {0xe9, 0x00, 0x00, 'M', 'A', 'G', 'I', 'C', ' ', ' ', ' ', 0x00, 0x02, 0x10, 0x01, 0x00,
	  0x02, 0x00, 0x02, 0xa5, 0x1e, 0xf8, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x1b, 0x00, 0x00,
	  0x00,
	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 'N', 'O', ' ', 'T', 'Y',
	  'P', 'E', ' ', ' ', ' ', ' ', 'F', 'A', 'T', '1', '2', ' ', ' ', ' '}
	 },
	//8MB
	{
	 0x08,
	 0x0400,
	 {0x80, 0x01, 0x0a, 0x00, 0x01, 0x01, 0x50, 0xed, 0x19, 0x00, 0x00, 0x00, 0xa7, 0x3d, 0x00,
	  0x00},
	 {0xe9, 0x00, 0x00, 'M', 'A', 'G', 'I', 'C', ' ', ' ', ' ', 0x00, 0x02, 0x10, 0x01, 0x00,
	  0x02, 0x00, 0x02, 0xa7, 0x3d, 0xf8, 0x03, 0x00, 0x10, 0x00, 0x02, 0x00, 0x19, 0x00, 0x00,
	  0x00,
	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 'N', 'O', ' ', 'T', 'Y',
	  'P', 'E', ' ', ' ', ' ', ' ', 'F', 'A', 'T', '1', '2', ' ', ' ', ' '}
	 },
	//Block size 16K
	//16MB
	{
	 0x10,
	 0x0400,
	 {0x80, 0x01, 0x0a, 0x00, 0x01, 0x03, 0x50, 0xed, 0x19, 0x00, 0x00, 0x00, 0x67, 0x7b, 0x00,
	  0x00},
	 {0xe9, 0x00, 0x00, 'M', 'A', 'G', 'I', 'C', ' ', ' ', ' ', 0x00, 0x02, 0x20, 0x01, 0x00,
	  0x02, 0x00, 0x02, 0x67, 0x7b, 0xf8, 0x03, 0x00, 0x10, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00,
	  0x00,
	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 'N', 'O', ' ', 'T', 'Y',
	  'P', 'E', ' ', ' ', ' ', ' ', 'F', 'A', 'T', '1', '2', ' ', ' ', ' '}
	 },
	//32MB
	{
	 0x10,
	 0x0800,
	 {0x80, 0x01, 0x04, 0x00, 0x01, 0x03, 0xd0, 0xdd, 0x13, 0x00, 0x00, 0x00, 0x6d, 0xf7, 0x00,
	  0x00},
	 {0xe9, 0x00, 0x00, 'M', 'A', 'G', 'I', 'C', ' ', ' ', ' ', 0x00, 0x02, 0x20, 0x01, 0x00,
	  0x02, 0x00, 0x02, 0x6d, 0xf7, 0xf8, 0x06, 0x00, 0x10, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00,
	  0x00,
	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 'N', 'O', ' ', 'T', 'Y',
	  'P', 'E', ' ', ' ', ' ', ' ', 'F', 'A', 'T', '1', '2', ' ', ' ', ' '}
	 },
	//64MB
	{
	 0x10,
	 0x1000,
	 {0x80, 0x02, 0x08, 0x00, 0x01, 0x07, 0xd0, 0xdd, 0x27, 0x00, 0x00, 0x00, 0xd9, 0xee, 0x01,
	  0x00},
	 {0xe9, 0x00, 0x00, 'M', 'A', 'G', 'I', 'C', ' ', ' ', ' ', 0x00, 0x02, 0x20, 0x01, 0x00,
	  0x02, 0x00, 0x02, 0x00, 0x00, 0xf8, 0x0c, 0x00, 0x10, 0x00, 0x08, 0x00, 0x27, 0x00, 0x00,
	  0x00,
	  0xd9, 0xee, 0x01, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 'N', 'O', ' ', 'T', 'Y',
	  'P', 'E', ' ', ' ', ' ', ' ', 'F', 'A', 'T', '1', '2', ' ', ' ', ' '}
	 },
	//128MB
	{
	 0x10,
	 0x2000,
	 {0x80, 0x02, 0x02, 0x00, 0x06, 0x0f, 0xd0, 0xdd, 0x21, 0x00, 0x00, 0x00, 0xdf, 0xdd, 0x03,
	  0x00},
	 {0xe9, 0x00, 0x00, 'M', 'A', 'G', 'I', 'C', ' ', ' ', ' ', 0x00, 0x02, 0x20, 0x01, 0x00,
	  0x02, 0x00, 0x02, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x10, 0x00, 0x10, 0x00, 0x21, 0x00, 0x00,
	  0x00,
	  0xdf, 0xdd, 0x03, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 'N', 'O', ' ', 'T', 'Y',
	  'P', 'E', ' ', ' ', ' ', ' ', 'F', 'A', 'T', '1', '6', ' ', ' ', ' '}
	 }
};

/*
// Macro declarations
*/
/*
// Macro declarations
*/
#pragma alignvar(4)
//#define MS_TASK_YIELD
#ifdef MS_TASK_YIELD
#define TASK_YIELD() TaskYield()
#else
#define TASK_YIELD()
#endif

#define SetRWRegTpcAddr(bReadAddr, bReadSize, bWriteAddr, bWriteSize)   \
{                                                                       \
	register ST_RW_REG_TPC_ADDR *psRWRegTpcAddr = &sRWRegTpcAddr;		\
    psRWRegTpcAddr->bReadRegAddr = bReadAddr;                             \
    psRWRegTpcAddr->bReadRegSize = bReadSize;                             \
    psRWRegTpcAddr->bWriteRegAddr = bWriteAddr;                           \
    psRWRegTpcAddr->bWriteRegSize = bWriteSize;                           \
}

#define SetParaReg(bSysParam, dwBlockAddrReg, bCmdParam, bPageAdr)      \
{                                                                       \
	register ST_PARAM_REG *psParamReg = &sParamReg;						\
    psParamReg->bSysParameter = bSysParam;                                \
    psParamReg->bBlockAddrReg2 = (BYTE)(dwBlockAddrReg >> 16);            \
    psParamReg->bBlockAddrReg1 = (BYTE)(dwBlockAddrReg >> 8);             \
    psParamReg->bBlockAddrReg0 = (BYTE)(dwBlockAddrReg);                  \
    psParamReg->bCmdParameter = bCmdParam;                                \
    psParamReg->bPageAddr = bPageAdr;                                     \
}

#define SetWriteParaReg(bSysParam, dwPhyAdr, bCmdParam, bPageAdr)           \
{                                                                           \
	register ST_PARAM_REG *psParamReg = &sParamReg;							\
    psParamReg->bSysParameter = bSysParam;                                    \
    psParamReg->bBlockAddrReg2 = (BYTE)(dwPhyAdr >> 16);                      \
    psParamReg->bBlockAddrReg1 = (BYTE)(dwPhyAdr >> 8);                       \
    psParamReg->bBlockAddrReg0 = (BYTE)(dwPhyAdr);                            \
    psParamReg->bCmdParameter = bCmdParam;                                    \
    psParamReg->bPageAddr = bPageAdr;                                         \
}

#define SetExtraParaReg(bOverWrite, bManagement, bLogAddr1, bLogAddr0)      \
{                                                                           \
	register ST_PARAM_REG *psParamReg = &sParamReg;							\
    psParamReg->sExtra.bOverWriteFlag = bOverWrite;                           \
    psParamReg->sExtra.bManagementFlag  = bManagement;                        \
    psParamReg->sExtra.bLogicalAddr1 = bLogAddr1;                             \
    psParamReg->sExtra.bLogicalAddr0  = bLogAddr0;                            \
}


#define SetDataDma(dwBuffer)                            \
{                                                       \
    register CHANNEL *sChannel;                         \
    sChannel = (CHANNEL *)(DMA_MC_BASE);                \
	sChannel->Control = 0;                              \
	sChannel->StartA = dwBuffer;                        \
    sChannel->EndA = dwBuffer + MCARD_SECTOR_SIZE - 1;  \
    sChannel->Control = MCARD_DMA_ENABLE;               \
}

#if 0
#define SetProParaReg(bCmd, wSectorCount, dwLogAddr, bTpcParam, bCmdParam)  \
{                                                                           \
    sProParamReg.bCmdCode = bCmd;                                           \
    sProParamReg.bDataCount1 = (BYTE)(wSectorCount >> 8);                   \
    sProParamReg.bDataCount0 = (BYTE)(wSectorCount);                        \
    sProParamReg.bDataAddr3 = (BYTE)(dwLogAddr >> 24);                      \
    sProParamReg.bDataAddr2 = (BYTE)(dwLogAddr >> 16);                      \
    sProParamReg.bDataAddr1 = (BYTE)(dwLogAddr >> 8);                       \
    sProParamReg.bDataAddr0 = (BYTE)(dwLogAddr);                            \
    sProParamReg.bTpcParameter  = bTpcParam;                                \
    sProParamReg.bCmdParameter  = bCmdParam;                                \
}
#else
void static inline SetProParaReg(register BYTE bCmd, register WORD wSectorCount,
								 register DWORD dwLogAddr, register BYTE bTpcParam,
								 register BYTE bCmdParam)
{
	register ST_PRO_PARAM_REG *psProParamReg = &sProParamReg;

	psProParamReg->bCmdCode = bCmd;
	if (wSectorCount == 0)
	{

⌨️ 快捷键说明

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