📄 sm_normal.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 : sm.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 "sm.h"
#include "devio.h"
#include "taskid.h"
#include "ui.h"
#if (SM_ENABLE||XD_ENABLE||NAND_ENABLE) //byAlexWang 24jun2007 m2project
/*
// Constant declarations
*/
#define TEMPSECTOR 64
#define ROOTSECTOR 8
#define WRITE_VERIFY DISABLE
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
#define ECC4S_ENABLE ENABLE
#else
#define ECC4S_ENABLE DISABLE
#endif
#define DETECT_ENABLE 0x00000001
#define WRITE_ENABLE 0x00000002
#define ECC_ENABLE 0x00000004
#define TYPE_256_BYTE 0x00000000
#define TYPE_512_BYTE 0x00000008
#define CE_MASK_HIGH 0x00000010
#define ADR_LENGTH_3 0x00000000
#define ADR_LENGTH_4 0x00000020
#define ADR_LENGTH_5 0x00000040
#define CS_NAND 0x00000000
#define CS_SM 0x00000080
#define CS_XD 0x00000100
#define SETTING_SM (CS_SM | CE_MASK_HIGH | TYPE_512_BYTE | ECC_ENABLE | WRITE_ENABLE)
#define SETTING_NAND (CS_NAND | CE_MASK_HIGH | TYPE_512_BYTE | ECC_ENABLE | WRITE_ENABLE)
#define SETTING_XD (CS_XD | CE_MASK_HIGH | TYPE_512_BYTE | ECC_ENABLE | WRITE_ENABLE)
#define IC_SRB 0x00000001
#define IC_ECB 0x00000002
#define IC_SFTCE 0x00000004
#define IC_SMTO 0x00000008
#define IC_CDX 0x00000010
#define IM_SRB 0x00000100
#define IM_ECB 0x00000200
#define IM_SFTCE 0x00000400
#define IM_SMTO 0x00000800
#define IM_CDX 0x00001000
#define IM_ALL 0 /*(IM_SRB | IM_ECB | IM_SFTCE | IM_SMTO | IM_CDX) */
#define PL_HIGH_SRB 0x00010000
#define PL_HIGH_ECB 0x00020000
#define PL_HIGH_SFTCE 0x00040000
#define PL_HIGH_SMTO 0x00080000
#define PL_HIGH_CDX 0x00100000
#define MD_EDGE_SRB 0x01000000
#define MD_EDGE_ECB 0x02000000
#define MD_EDGE_SFTCE 0x04000000
#define MD_EDGE_SMTO 0x08000000
#define MD_EDGE_CDX 0x10000000
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
#define GPIO_DEFINE_0_SM 0x0000ffff
#define GPIO_DEFINE_1_SM 0x00000003
#define GPIO_DEFINE_2_SM 0x00000000
#define GPIO_DEFINE_3_SM 0x00000000
#define GPIO_DEFINE_0_NAND 0x0000ffff
#define GPIO_DEFINE_1_NAND 0x00000001
#define GPIO_DEFINE_2_NAND 0x00000000
#define GPIO_DEFINE_3_NAND 0x00000000
#define GPIO_DEFINE_0_XD 0x0000ffff
#define GPIO_DEFINE_1_XD 0x00000000
#define GPIO_DEFINE_2_XD 0x00000000
#define GPIO_DEFINE_3_XD 0x00000000
#define NAND1_CE 14
#define NAND2_CE 14 // 16 is for earphone detect
#define NAND_CLE 8
#define NAND_ALE 9
#define XD_CE 10
#define XD_ALE 9
#define XD_CLE 8
#define NAND_WP 15
#define XD_WP 15
#else
#define GPIO_DEFINE_0_SM 0x000000f0
#define GPIO_DEFINE_1_SM 0x000001c0
#define GPIO_DEFINE_2_SM 0x00003f82
#define GPIO_DEFINE_3_SM 0x00000060
#define GPIO_DEFINE_0_NAND 0x000000f0
#define GPIO_DEFINE_1_NAND 0x000001c0
#define GPIO_DEFINE_2_NAND 0x00003f82
#define GPIO_DEFINE_3_NAND 0x00000040
#define GPIO_DEFINE_0_XD 0x000000ff
#define GPIO_DEFINE_1_XD 0x00008023
#define GPIO_DEFINE_2_XD 0x00000001
#define GPIO_DEFINE_3_XD 0x00000818
#define NAND1_CE 39
#define NAND2_CE 23
#define NAND_CLE 24
#define NAND_ALE 44
#define NAND_WP 54
#define XD_CE 51
#define XD_ALE 17
#define XD_CLE 16
#define XD_WP 58
#define XD_VCC 52
#endif
#define SEQ_DATA_IN_CMD 0x80 //Sequential Data Input
#define READ_PAGE1_CMD 0x00 //Read fist page (0 to 255 byte)
#define READ_PAGE2_CMD 0x01 //Read second page (256 to 511 byte)
#define READ_PAGE1_CMD_2CYC 0x30 // nand flash read command
#define READ_REDUNDANT_CMD 0x50 //Read Redundant page (512 to 527 byte)
#define READ_ID_CMD 0X90 //Read ID
#define RESET_CMD 0xFF //Reset
#define PAGE_PROG_CMD 0x10 //Write
#define BLOCK_ERASE_CMD_1CYC 0x60 //Block Erase 1st cycle
#define BLOCK_ERASE_CMD_2CYC 0xD0 //Block Erase 2nd cycle
#define READ_STATUS 0x70 //Read Status
#define READ_TIMING_SM 0x00020201
#define WRITE_TIMING_SM 0x00020201
#define READ_TIMING_NAND 0x00020201
#define WRITE_TIMING_NAND 0x00020201
#define READ_TIMING_XD 0x00020201
#define WRITE_TIMING_XD 0x00020201
#define INITIAL_NAND 0x0
#define INITIAL_XD 0x1
#define INITIAL_SM 0x2
#define MAX_LOGBLOCK 0x3e8
#define MAX_BLOCK 0x400
#define MAX_ZONE 0x80
#define TIMEOUT_COUNT 1000000
#define UNUSABLE_BLOCK 1
#define USABLE_BLOCK 0
#define STATUS_FAIL 0x01
#define STATUS_READY 0x40
#define SM_CLOCK 0x1
#define ECC4SEN BIT0 // 1 : enable ECC4S , 0 : disable ECC4S
#define ECC4SRN BIT1 // 0 : reset ECC4S
#define EDN BIT2 // 1 : encode , 0 : decode
//MCARD ECC4S State Register Bit Define
#define MC_ECC4S_STATE_STATE_MASK 0x0000000f
#define ENCODE_NORMAL_COMPLETION 0x00000000
#define DECODE_NO_ERROR 0x00000000
#define DECODE_CORRECTION_IMPOSSIBLE 0x00000001
#define DECODE_CORRECTION_COMPLETED 0x00000003
#define MC_ECC4S_STATE_SERR_MASK 0x000000f0
#define MC_ECC4S_STATE_ERRSTATE_MASK 0x00000f00
#define MC_ECC4S_STATE_READY_MASK 0x0000f000
#define MC_ECC4S_STATE_READY_READY1 0x00001000
#define MC_ECC4S_STATE_READY_READY2 0x00002000
#define MC_ECC4S_STATE_READY_READY3 0x00004000
#define MC_ECC4S_STATE_READY_READY4 0x00008000
#define MC_ECC4S_STATE_CTLSSTATE_MASK 0x00ff0000
#define MC_ECC4S_STATE_CTLSSTATE_IDLE 0
//MCARD ECC4S Error Define
#define NO_ERROR 0
#define CORRECT_COMPLETE 1
#define ENCODE_COMPLETION 2
#define ENCODE_ERROR -1
#define DECODE_ERROR -2
#define DECODE_CORRECT_IMPOSSIBLE -3
#define DECODE_CHECK_TIMEOUT -4
//Multi Die Nand Define
#define MultiDie 1
#define Access_Nand1 2
#define Access_Nand2 4
///
///@defgroup SM SmartMedia and XD
///@ingroup CONSTANT
///@{
/// Unsupport SmartMedia or XD type.
#define TYPE_NOT_SUPPORT -2
/// Wait for SmartMedia or XD's ready signal fail.
#define TIMEOUT -3
/// Wait for FIFO transaction end Fail.
#define IC_SFTCE_TIMEOUT -4
/// Wait for DMA end Fail.
#define DMA_TIMEOUT -5
///@}
/*
// Structure declarations
*/
struct ST_MEDIA_MEAT_TAG
{
BYTE bMaxZone; // Max Zone Size
BYTE bMaxSectorExp;
WORD wMaxSector; // Sectors per block
WORD wMaxBlock; // Blocks per zone
WORD wMaxLogBlock; // LogBlocks perb zone
};
struct ST_MEDIA_MEAT_TABLE_TAG
{
BYTE bID;
struct ST_MEDIA_MEAT_TAG sMediaMeat;
};
struct ST_INFO_TAG
{
BYTE bCurMode;
DWORD dwCurModeSetting;
DWORD dwReadTiming;
DWORD dwWriteTiming;
struct ST_MEDIA_MEAT_TAG *sMediaMeat[2];
WORD wLog2PhyTable[2][MAX_BLOCK * MAX_ZONE];
BYTE bReAssignTable[2][MAX_ZONE];
BYTE bAddrInfo[2][3]; //[n][0] command times, [n][1] read/write command, [n][2] earse command
};
/*
// Type declarations
*/
typedef struct ST_MEDIA_MEAT_TAG ST_MEDIA_MEAT;
typedef struct ST_MEDIA_MEAT_TABLE_TAG ST_MEDIA_MEAT_TABLE;
typedef struct ST_INFO_TAG ST_INFO;
/*
// Variable declarations
*/
static ST_INFO sInfo;
static const ST_MEDIA_MEAT_TABLE sMediaMeatTable_S[] = {
//Id, MaxZone, MaxSectorExp, MaxSector, MaxBlock, MaxLogBlock
{0xe5, 0x01, 0x4, 0x10, 0x200, 0x1f4}, // 4 MB
{0xe6, 0x01, 0x4, 0x10, 0x400, 0x3e8}, // 8 MB
{0x73, 0x01, 0x5, 0x20, 0x400, 0x3e8}, // 16 MB
{0x75, 0x02, 0x5, 0x20, 0x400, 0x3e8}, // 32 MB
{0x76, 0x04, 0x5, 0x20, 0x400, 0x3e8}, // 64 MB
{0x79, 0x08, 0x5, 0x20, 0x400, 0x3e8}, // 128 small MB
{0x71, 0x10, 0x5, 0x20, 0x400, 0x3e8}, // 256 small MB
{0xdc, 0x20, 0x5, 0x20, 0x400, 0x3e8}, // 512 small MB
{0xd3, 0x40, 0x5, 0x20, 0x400, 0x3e8}, // 1 small GB
{0xd5, 0x80, 0x5, 0x20, 0x400, 0x3e8}, // 2 small GB
{0x00, 0x00, 0x0, 0x00, 0x000, 0x000}
};
static const ST_MEDIA_MEAT_TABLE sMediaMeatTable_B[] = {
//Id, MaxZone, MaxSectorExp, MaxSector, MaxBlock, MaxLogBlock
{0xf1, 0x01, 0x8, 0x100, 0x400, 0x3e8}, // 128 big MB
{0xda, 0x02, 0x8, 0x100, 0x400, 0x3e8}, // 256 big MB
{0xdc, 0x04, 0x8, 0x100, 0x400, 0x3e8}, // 512 big MB
// {0xdc, 0x02, 0x9, 0x200, 0x400, 0x3e8}, // 512 big MB
{0xd3, 0x08, 0x8, 0x100, 0x400, 0x3e8}, // 1 big GB
{0xd5, 0x10, 0x8, 0x100, 0x400, 0x3e8}, // 2 big GB
{0x00, 0x00, 0x0, 0x000, 0x000, 0x000}
};
static const ST_MEDIA_MEAT_TABLE sMediaMeatTable_MLC[] = {
//Id, MaxZone, MaxSectorExp, MaxSector, MaxBlock, MaxLogBlock
{0xdc, 0x02, 0x9, 0x200, 0x400, 0x3e8}, // 512 big MB
{0x00, 0x00, 0x0, 0x000, 0x000, 0x000}
};
static DWORD MaxPhyPage ;
static DWORD MaxLogPage ;
static BYTE MultiDieFlag = Access_Nand1 ;
static BYTE MLC = FALSE;
static BYTE PreSMType;
static BYTE CurSMType;
static BYTE bECCCode[3];
static BYTE bRedtData[0x10];
static volatile BOOL blTimeOutFlag;
//static BYTE bTempBuffer[MCARD_SECTOR_SIZE * 256];
//static BYTE bTempBuffer[MCARD_SECTOR_SIZE * 512];
//static BYTE bSmTempBuffer[MCARD_SECTOR_SIZE * 32]; // only small block
static BYTE bDescriptor[2][4] = { "NAND", "XD" }; //{ "NAND", "SM", "XD" };
static const BYTE bCISField[] = {
0x01, 0x03, 0xd9, 0x01, 0xff, 0x18, 0x02, 0xdf, 0x01, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x21,
0x02, 0x04, 0x01, 0x22, 0x02, 0x01, 0x01, 0x22, 0x03, 0x02, 0x04, 0x07, 0x1a, 0x05, 0x01, 0x03,
0x00, 0x02, 0x0f, 0x1b, 0x08, 0xc0, 0xc0, 0xa1, 0x01, 0x55, 0x08, 0x00, 0x20, 0x1b, 0x0a, 0xc1,
0x41, 0x99, 0x01, 0x55, 0x64, 0xf0, 0xff, 0xff, 0x20, 0x1b, 0x0c, 0x82, 0x41, 0x18, 0xea, 0x61,
0xf0, 0x01, 0x07, 0xf6, 0x03, 0x01, 0xee, 0x1b, 0x0c, 0x83, 0x41, 0x18, 0xea, 0x61, 0x70, 0x01,
0x07, 0x76, 0x03, 0x01, 0xee, 0x15, 0x14, 0x05, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x30, 0x2e, 0x30, 0x00, 0xff, 0x14, 0x00, 0xff, 0x00, 0x00
};
#pragma alignvar(4)
/*
// Macro declarations
*/
//#define SM_TIMEOUT_HANDLE
//#define SM_TASK_YIELD
#ifdef SM_TASK_YIELD
#define TASK_YIELD() TaskYield()
#else
#define TASK_YIELD()
#endif
/*
// Static function prototype
*/
static void CommandProcess(void *pMcardDev);
static SWORD Log2PhyTabInit(void);
static BOOL CheckBlockStatus(void);
static BYTE BitCountByte(BYTE bByteData);
static BOOL LoadLogBlockAddr(WORD * pwLogBlockAddr);
static WORD GetEmptyBlock(WORD wZoneNum);
static SWORD ReadRedtData(DWORD dwSectorAddr);
static DWORD GetSameBlock(DWORD dwLogAddr, DWORD dwSectorCount);
static void SetPowerSwitch(BOOL blSwitch);
static void Select(BYTE bMode);
static void DeSelect(void);
static BYTE GetWPFlag(void);
static void SetCommand(BYTE bCommand);
static SWORD Identify(DWORD * pdwTotalSector);
static void SetAddrInfo(BYTE bType);
static void SetControl(void);
static SWORD WaitReady(void);
static void SetAddress(DWORD dwPhyAddr, BYTE bMode);
static void TimeoutHandle(void);
static SWORD FlatRead(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD LogicalRead(DWORD dwLogAddr, DWORD dwSectorCount, DWORD dwBufferAddress);
static SWORD PhysicalRead(DWORD dwPhyAddr, DWORD dwSectorCount, DWORD dwBufferAddress);
static SWORD ReadSector(DWORD dwBufferAddress, WORD wSize);
static SWORD FlatWrite(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr);
static SWORD LogicalWrite(DWORD dwLogAddr, DWORD dwSectorCount, DWORD dwBufferAddress);
static SWORD PhysicalWrite(DWORD dwPhyAddr, DWORD dwSectorCount, DWORD dwBufferAddress,
DWORD dwLogAddr);
static SWORD WriteSector(DWORD dwBufferAddress, WORD wSize);
static SWORD PhysicalErase(DWORD dwPhyAddr);
static SWORD ReadStatus(void);
static void BuildRedtData(DWORD dwLogAddr);
static SWORD CISWrite(DWORD dwBufferAddress);
static SWORD Format(void);
static int CheckWordParity(WORD wBlockAddr);
static int BitXor(DWORD dwVector, DWORD dwSize);
static DWORD RowBlockXor(DWORD dwStartAddr, int RowSize);
static int ECCBitCode(DWORD dwStartAddr, int FristStart, int LastStart, int RowSize);
static DWORD OneRowXor(DWORD dwStartAddr, int FristStart, int LastStart);
static int ColXor(DWORD dwVector, int ColSize);
static void CalECC(DWORD DataAddr);
static void ECC4S_Init(void);
static void ECC4S_Encode(void);
static void ECC4S_Decode(void);
static SWORD ECC4S_Decode_Check(BYTE *pdwBufferAddress);
static SWORD ECC4S_Encode_Check(void);
static void ECC4S_Correct(BYTE *pdwBufferAddress);
static void GpioValueSetting(BYTE value,BYTE num);
/*
// Definition of internal functions
*/
#if ECC4S_ENABLE
static void ECC4S_Init(void)
{
MCARD * sMcard =(MCARD *)MCARD_BASE;
sMcard->McEcc4SC = (EDN | ECC4SRN | ECC4SEN);
}
static void ECC4S_Encode(void)
{
MCARD * sMcard =(MCARD *)MCARD_BASE;
sMcard->McEcc4SC = 0;
sMcard->McEcc4SC = (EDN |ECC4SRN |ECC4SEN) ;
}
static void ECC4S_Decode(void)
{
MCARD * sMcard =(MCARD *)MCARD_BASE;
sMcard->McEcc4SC = 0;
sMcard->McEcc4SC = (ECC4SRN |ECC4SEN) ;
}
static void ECC4S_Correct(BYTE *pdwBufferAddress)
{
register MCARD * sMcard = (MCARD *) MCARD_BASE;
BYTE bErrCount,i,bVal;
BYTE * pbBuffer;
WORD wAddr;
pbBuffer = pdwBufferAddress;
bErrCount = (BYTE)((sMcard->McEcc4SState & MC_ECC4S_STATE_SERR_MASK)>>4);
for(i=0;i<bErrCount;i++)
{
wAddr = (WORD)(sMcard->McEcc4SErr[i] & 0x000003ff);
if(wAddr <=7)
continue;
bVal =(BYTE) ((sMcard->McEcc4SErr[i] & 0x03ff0000)>>16);
pbBuffer[521-wAddr] ^= (BYTE)bVal;
}
}
static SWORD ECC4S_Decode_Check(BYTE *pdwBufferAddress)
{
register MCARD * sMcard = (MCARD *)MCARD_BASE;
SWORD dwRetValue;
DWORD dwCounter = 0x100000;
while((sMcard->McEcc4SState & MC_ECC4S_STATE_STATE_MASK) != DECODE_NO_ERROR)
{
if((sMcard->McEcc4SState & MC_ECC4S_STATE_STATE_MASK) == DECODE_CORRECTION_COMPLETED)
{
ECC4S_Correct(pdwBufferAddress);
MP_DEBUG("ECC4S_Decode_Check correction Complete");
return CORRECT_COMPLETE;
}
else if((sMcard->McEcc4SState & MC_ECC4S_STATE_STATE_MASK) == DECODE_CORRECTION_IMPOSSIBLE)
{
//MP_DEBUG("ECC4S_Decode_Check correction impossible");
return DECODE_CORRECT_IMPOSSIBLE;
}
if(dwCounter == 0)
{
MP_DEBUG("ECC4S_Decode_Check time out");
return DECODE_CHECK_TIMEOUT;
}
dwCounter--;
}
//MP_DEBUG("ECC4S_Decode_Check no error");
return NO_ERROR;
}
static SWORD ECC4S_Encode_Check(void)
{
register MCARD * sMcard = (MCARD *)MCARD_BASE;
SWORD dwRetValue;
DWORD dwCounter = 0x1000;
while((sMcard->McEcc4SState & MC_ECC4S_STATE_STATE_MASK) != ENCODE_NORMAL_COMPLETION)
{
if(dwCounter == 0)
{
MP_DEBUG("ECC4S_Encode_Check time out");
return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -