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

📄 sm_normal.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      : 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 + -