📄 ms.c
字号:
/*
*******************************************************************************
* 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 + -