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

📄 mal_2k.c

📁 HID-Ukey底层源码实现(st72651芯片) windows上层驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/*-*-*-*-*-*-*-*-*-*-* (C) 2000 STMicroelectronics *-*-*-*-*-*-*-*-*-*-*-*-*-*

PROJECT  : ST7265 Media Access Library
COMPILER : ST7 C

MODULE  :  MAL_All.c
VERSION :  V 0.5

CREATION DATE :  04/12/2000

AUTHOR : Liang Ping
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

DESCRIPTION : All functions except those with individual one

-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

Modification:
	16/05/2002 Patch for NAND Thumb drive

-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	VARIABLES	VARIABLES	VARIABLES	VARIABLES	VARIABLES	VARIABLES
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#include "define.h"
#include "Map_7265.h"
#include "Mconfig.h"		// Media configuration
#include "MSL.h"
#include "MAL_Map.h"
#include "MAL.h"
#include "2K_Mass.h"
#include "DTC_Func.h"
#include "NAND.h"

extern void Deselect(void);

#define USE_CACHE0	0
//#define PAGE2K_BAD

/*-*-*-*-*-*-*-*-*-*-*-*-*-* Variable declaration *-*-*-*-*-*-*-*-*-*-*-*-*-*/
#pragma DATA_SEG SHORT MAL_RAM0	// Frequently used variable
// SMC_Wstate keeps track the state of the SMC writing procedure
// Bits definition:
//	bit0	= 0 actions on new cluster
//			= 1 actions on old cluster
//	bit1-0	= 00 MARKing
//			= 01 COPYing
//			= 10 WRITE to new cluster
//			= 11 WRITE to old cluster
//	bit3-2	= 00 PRE actions
//			= 01 POST actions
//			= 10 HOLE actions
//			= 11 HOLE or FULL actions
/*static*/ unsigned char	SMC_Wstate;		// the state of the SMC writing procedure
#define SMC_OLD_CLUSTER			0x01
#define	SMC_WRITE_FLAG			0x02
#define SMC_PRE_ACTION			0x00
#define SMC_POST_ACTION			0x04
#define SMC_HOLE_ACTION			0x08
#define SMC_FULL_ACTION			0x0C
#define SMC_ERROR_FLAG			0x10
#if ALLOW_OUT_RANGE
#define SMC_OUT_RANGE			(0x20 | SMC_WRITE_FLAG)
#endif

#define SMC_PREMARK			(SMC_PRE_ACTION | !SMC_WRITE_FLAG | !SMC_OLD_CLUSTER)	// 0
#define SMC_PRECOPY			(SMC_PRE_ACTION | !SMC_WRITE_FLAG | SMC_OLD_CLUSTER)	// 1
#define SMC_PRENEWWRITE		(SMC_PRE_ACTION | SMC_WRITE_FLAG | !SMC_OLD_CLUSTER)	// 2
#define SMC_PREOLDWRITE		(SMC_PRE_ACTION | SMC_WRITE_FLAG | SMC_OLD_CLUSTER)		// 3
#define SMC_POSTMARK		(SMC_POST_ACTION | !SMC_WRITE_FLAG | !SMC_OLD_CLUSTER)	// 4
#define SMC_POSTCOPY		(SMC_POST_ACTION | !SMC_WRITE_FLAG | SMC_OLD_CLUSTER)	// 5
#define SMC_POSTNEWWRITE	(SMC_POST_ACTION | SMC_WRITE_FLAG | !SMC_OLD_CLUSTER)	// 6
#define SMC_POSTOLDWRITE	(SMC_POST_ACTION | SMC_WRITE_FLAG | SMC_OLD_CLUSTER)	// 7
#define SMC_PREHOLEMARK		(SMC_HOLE_ACTION | !SMC_WRITE_FLAG | !SMC_OLD_CLUSTER)	// 8
#define SMC_PREHOLECOPY		(SMC_HOLE_ACTION | !SMC_WRITE_FLAG | SMC_OLD_CLUSTER)	// 9
#define SMC_HOLENEWWRITE	(SMC_HOLE_ACTION | SMC_WRITE_FLAG | !SMC_OLD_CLUSTER)	// A
#define SMC_HOLEOLDWRITE	(SMC_HOLE_ACTION | SMC_WRITE_FLAG | SMC_OLD_CLUSTER)	// B
#define SMC_POSTHOLEMARK	(SMC_FULL_ACTION | !SMC_WRITE_FLAG | !SMC_OLD_CLUSTER)	// C
#define SMC_POSTHOLECOPY	(SMC_FULL_ACTION | !SMC_WRITE_FLAG | SMC_OLD_CLUSTER)	// D
#define SMC_FULLNEWWRITE	(SMC_FULL_ACTION | SMC_WRITE_FLAG | !SMC_OLD_CLUSTER)	// E
#define SMC_FULLOLDWRITE	(SMC_FULL_ACTION | SMC_WRITE_FLAG | SMC_OLD_CLUSTER)	// F

unsigned char SMC_Cluster_Size;				// Size of a cluster
											//statuc removed for 2K page
#define LOOKUP_THRESHOLD	250
unsigned char SubBlock;						//block with in a page for 256MB
static unsigned char Col;					//block with in a page for 256MB
unsigned char SMC_Zone;
static unsigned char SMC_Lookup_Zone0;		// Zone of table0
static unsigned char SMC_Lookup_Zone1;		// Zone of table1
static unsigned char SMC_Lookup_Count0;		// Visit count of table0
static unsigned char SMC_Lookup_Count1;		// Visit count of table1
static unsigned short *SMC_Lookup_pTable;	// The pointer of the current table
// When the zone 0 is not in one of two lookup table
// The follow small lookup table keeps the initial few items of zone 0
static unsigned char SMC_Lookup_nCache0;	// number of items in zone 0 Cache
											// number of sectors for MBR, PBR, FAT & Root
static unsigned char flag2k;

#ifdef THUMB_DRIVE
static unsigned char NAND_Chip;				// The current chip number
#endif

#if USE_CACHE0
#ifdef THUMB_DRIVE
#define CACHE0_NUM			16
#else
#define CACHE0_NUM			5
#endif
#define CACHE0_FREE			3
static unsigned short SMC_Lookup_pCache0[CACHE0_NUM];
// The following array is used to cache the free cluster
// for zone 0 when zone 0 is not in the lookup table area
static unsigned short SMC_Lookup_pFree0[CACHE0_FREE];
#endif // USE_CACHE0

static unsigned short SMC_Paddr;
static unsigned short SMC_Raddr;			// An old physical cluster
static unsigned int SMC_Npage;				// data type changed for 2K page.MAx page = 256
static unsigned int SMC_Npage512;			// variable added for 2K dec/inc blocks
unsigned char SMC_Ppage;

unsigned short SMC_Laddr;
unsigned long malPaddr;
unsigned long malRaddr;
//unsigned char malNpage;
unsigned int malNpage;					// data type changed for 2kflash
unsigned int Test_page;		// data type changed for 2kflash

#ifndef THUMB_DRIVE
static unsigned char SMC_4MB;				// The SMC is a 4MB card
#endif
static unsigned char DTC_Error;
static unsigned char DTC_Current_Func;
#define DTC_SMC_READ	0x01
#define DTC_SMC_WRITE	0x02
#define DTC_SMC_FORMAT	0x04

#pragma DATA_SEG MAL_RAM
#ifndef THUMB_DRIVE
static unsigned char SMC_Addr_Bytes;
static unsigned char CardID;				// added for 2K Flash
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-* Variable declaration *-*-*-*-*-*-*-*-*-*-*-*-*-*/

// Buffer for redundant area
typedef struct _SPARE_AREA {
	union {
		unsigned long	dwReserved;
		unsigned short	wReserved[2];
	} R;
	unsigned char	Data_Status;
	unsigned char	Block_Status;
	unsigned short	Block_Address1;
	unsigned char	ECC2[3];
	unsigned short	Block_Address2;
	unsigned char	ECC1[3];
} SPARE_AREA;
static SPARE_AREA	SMC_Spare;

#define	Map_To_DTC_Addr(Target, zone, addr, page)	\
	{	((_UDWORD*)&Target)->byte[3] = LOBYTE((unsigned int)(addr)) | (unsigned char)(page);	\
		((_UDWORD*)&Target)->byte[2] = HIBYTE((unsigned int)(addr));	\
		if (SMC_Cluster_Size == 32) {	\
			if (zone & 1)	\
				((_UDWORD*)&Target)->byte[2] |= 0x80;	\
			((_UDWORD*)&Target)->byte[1] = (unsigned char)zone >> 1;	\
		}	\
		else	\
			((_UDWORD*)&Target)->byte[1] = 0;	\
		((_UDWORD*)&Target)->byte[0] = 0;		\
	} 

#define	Map_To_DTC_Addr256(Target, zone, addr, page, col) \
	{	if (SMC_Cluster_Size == 64) { \
			((_UDWORD*)&Target)->byte[3] = ((unsigned char)(col)); \
			((_UDWORD*)&Target)->byte[2] = LOBYTE((unsigned int)(addr)) | (unsigned char)(page); \
			((_UDWORD*)&Target)->byte[1] = HIBYTE((unsigned int)(addr)); \
			((_UDWORD*)&Target)->byte[0] = zone; \
		} \
		else { \
			((_UDWORD*)&Target)->byte[3] = LOBYTE((unsigned int)(addr)) | (unsigned char)(page);	\
			((_UDWORD*)&Target)->byte[2] = HIBYTE((unsigned int)(addr));	\
			if (SMC_Cluster_Size == 32) { \
				if (zone & 1) \
					((_UDWORD*)&Target)->byte[2] |= 0x80;	\
				((_UDWORD*)&Target)->byte[1] = (unsigned char)zone >> 1;	\
			}	\
			else	\
				((_UDWORD*)&Target)->byte[1] = 0;	\
			((_UDWORD*)&Target)->byte[0] = 0;		\
		}	\
	}
	

#define	Map_DTC_Addr(zone, addr, page)	\
	(SMC_Cluster_Size == 32) ?	\
		/* 11111111				ZZZ:		physical zone				*/ \
		/* 765432109876543210	BBBBBBBBBB: physical cluster address	*/ \
		/* ZZZBBBBBBBBBBPPPPP:	PPPPP:		physical page address		*/ \
		((DWORD)(zone) << 15) | (unsigned int)(addr) | (unsigned char)(page) :	\
		/* 1111														*/ \
		/* 32109876543210	BBBBBBBBBB: physical cluster address	*/ \
		/* BBBBBBBBBBPPPP:	PPPP:		physical page address		*/ \
		(unsigned int)(addr) | (unsigned char)(page);


#pragma CODE_SEG SMC_CODE

//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//	Functions for the NAND Thumb-Drive
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
#ifdef THUMB_DRIVE

// The value expresses number of zone's
// 1=16MB, 2=32MB, 4=64MB, 8=128MB, etc.
// 3=48MB, 5=80MB, 6=96MB, 7=112MB, etc.
static unsigned char Chip_Size[MAX_NUM_NAND];
static unsigned char Cluster_Size[MAX_NUM_NAND];

//#define gZONE(Chip, Zone)	(((Chip)<<4)|Zone)	// Global zone number
//for debug
#define gZONE(Chip, Zone)	(((Chip)<<5)|Zone)	// Global zone number

void NAND_Select(unsigned char iChip)
{
	switch (iChip) {
	case 0:	SELECT_NAND0; break;
	case 1:	SELECT_NAND1; break;
	case 2:	SELECT_NAND2; break;
	case 3:	SELECT_NAND3; break;
	default: DESELECT_NAND; return;
	}
	
	if ((Chip_Size[iChip] >= 4) && (Chip_Size[iChip]< 16))
		DTC_SMC_Address_bytes = 4;
	else if (Chip_Size[iChip] >= 16)
		DTC_SMC_Address_bytes = 5;	//if device is of 256MB
	else
		DTC_SMC_Address_bytes = 3;

	SMC_Cluster_Size = Cluster_Size[iChip];
}

unsigned char NAND_Capacity(unsigned char iChip)
{
	unsigned char CardID;
	unsigned char ChipSize, ClusterSize;

	NAND_Select(iChip);
	CardID = DTC_SMC_ReadID();
	Deselect();				// Deselect the NAND flash

	ClusterSize = 32;

	if (CardID == 0x73)			// 16MB
		ChipSize = 1;
	else if (CardID == 0x75)	// 32MB
		ChipSize = 2;
	else if (CardID == 0x76)	// 64MB
		ChipSize = 4;
	else if (CardID == 0x79)	// 128MB
		ChipSize = 8;
	else if	(CardID == 0xF1) {	// 128MB-2K
		ChipSize = 8;
		ClusterSize = 64;
	}
	else if(CardID == 0xda){	// 256MB-2K
		ChipSize = 16;
		ClusterSize = 64;
	}
	else if(CardID == 0xdc){	// 512MB-2K
		ChipSize = 32;
		ClusterSize = 64;
	}
	else
		ChipSize = 0;

	Chip_Size[iChip] = ChipSize;
	Cluster_Size[iChip] = ClusterSize;

	return ChipSize;
}

unsigned char NAND_Read_Capacity(void)
{
	unsigned char iChip;
	unsigned char TotalSize;

	TotalSize = 0;
	for (iChip = 0; iChip < MAX_NUM_NAND; iChip++)
		TotalSize += NAND_Capacity(iChip);

	if (TotalSize == 0 || Chip_Size[0] == 0)
		return MAL_CARD_UNKNOWN;

	asm {
		CLR		A
		LD		MAL_Capacity:3, A
		LD		MAL_Capacity, A
		LD		A, TotalSize
		LD		X, #125
		MUL		X, A
		LD		MAL_Capacity:1, X
		LD		MAL_Capacity:2, A
	}
//	MAL_Capacity = (unsigned long)TotalSize * 32000L;
	if (TotalSize <= (32 >> 4))			// <= 32MB
		SMC_Lookup_nCache0 = 0;			// No zone0 cache with card < 64MB
	else
		SMC_Lookup_nCache0 = 5;			// Use the maximum value

	return MAL_GOOD;
}

void Get_Chip_Number(void)
{
	unsigned char iChip;
	unsigned long Boundary;

	NAND_Chip = 0;
	for (iChip = 0; iChip < MAX_NUM_NAND; iChip++) {
		asm {
			CLR		A
			LD		Boundary:3, A
			LD		Boundary, A
			LD		X, iChip
			LD		A, (Chip_Size,X)
			LD		X, #125
			MUL		X, A
			LD		Boundary:1, X
			LD		Boundary:2, A
		}
		// Boundary = (unsigned long)Chip_Size[iChip] * 32000L;
		if (MAL_Block_Address < Boundary)
			break;

		MAL_Block_Address -= Boundary;
		NAND_Chip++;
	}
	SMC_Cluster_Size = Cluster_Size[NAND_Chip];
}

// Pre-declarations
void SMC_Copy_Lookup_Cache0();
void SMC_Convert_Lookup(unsigned short *LUT);
/*
void show_LED(void)
{
	PDDR |= 0x01;
	PDDR |= 0x04;
	if ((SMC_Lookup_Zone0 & 0xF0) == 0)
		PDDR &= ~0x01;
	if ((SMC_Lookup_Zone0 & 0xF0) == 0x10)
		PDDR &= ~0x04;
	if ((SMC_Lookup_Zone1 & 0xF0) == 0)
		PDDR &= ~0x01;
	if ((SMC_Lookup_Zone1 & 0xF0) == 0x10)
		PDDR &= ~0x04;
}
*/
void NAND_Lookup_Updates(unsigned char Zone)
{
	malRaddr = 1024;		// number of clusters in the zone
	malNpage = SMC_Cluster_Size;
	if (SMC_Cluster_Size == 64) {
		Buffer_Param[0x00] = 0x00;	//flag to differnetiate between 2K and 512
		Buffer_Param[0x02] = 0x00;	//1st cmd for 2k
		Buffer_Param[0x03] = 0xe3;	// adr for page byte
	}
	else {
		Buffer_Param[0x00] = 0x01;	//flag to differnetiate between 2K and 512
		Buffer_Param[0x02] = 0x50;	//1st cmd for 512
		Buffer_Param[0x03] = 0xe4;	// adr for page byte
	}
//	Map_To_DTC_Addr(malPaddr, Zone, 0, 0);	//commented for 2k
	Map_To_DTC_Addr256(malPaddr, Zone, 0, 0,2);	//new for 2K page 
	DTC_SMC_Map_Zone(SMC_Lookup_pTable);
	SMC_Convert_Lookup(SMC_Lookup_pTable);

	Deselect();				// Deselect the NAND flash
}

void NAND_Lookup_Update0(unsigned char Chip, unsigned char Zone)
{
	NAND_Select(Chip);

	SMC_Lookup_pTable = SMC_Lookup_Table0;
#if USE_CACHE0
	if (SMC_Lookup_Zone0 == 0)
		SMC_Copy_Lookup_Cache0();
#endif
	SMC_Lookup_Count0 = 0;
	SMC_Lookup_Zone0 = gZONE(Chip, Zone);

//show_LED();

	NAND_Lookup_Updates(Zone);
}

//#pragma NO_OVERLAP
void NAND_Lookup_Update1(unsigned char Chip, unsigned char Zone)
{
	NAND_Select(Chip);

	SMC_Lookup_pTable = SMC_Lookup_Table1;
#if USE_CACHE0
	if (SMC_Lookup_Zone1 == 0)
		SMC_Copy_Lookup_Cache0();
#endif
	SMC_Lookup_Count1 = 0;
	SMC_Lookup_Zone1 = gZONE(Chip, Zone);

//show_LED();

	NAND_Lookup_Updates(Zone);
}

static void NAND_INC_Logical_Addr(void)
{
	SMC_Laddr++;

/*----for 2K Flash-----	*/
	SubBlock = 0; //For next logical adr col offset is 0
	Buffer_Param[0x01] = 4; //No. of cols in Read operation is resetted
	Buffer_Param[0x25] = 0; //Col offset 0
	
	if (SMC_Laddr >= 1000) {
		SMC_Zone++;
		if (SMC_Cluster_Size != 64) {
			if (SMC_Zone == Chip_Size[NAND_Chip]) {
				goto common;
			//	SMC_Zone = 0;
			//	NAND_Chip++;
			//	while (Chip_Size[NAND_Chip] == 0)
			//		NAND_Chip++;		// Skip the bad of not exist chip
			//	NAND_Select(NAND_Chip);
			}
		}
		else {
			if (SMC_Zone == (Chip_Size[NAND_Chip] / 8)){
common:			SMC_Zone = 0;
				NAND_Chip++;
				while (Chip_Size[NAND_Chip] == 0)
					NAND_Chip++;
				NAND_Select(NAND_Chip);
			}
		}
		SMC_Laddr -= 1000;
	}
}

void Adjust_Laddr(void)
{
	while (SMC_Laddr >= 1000) {
		SMC_Zone++;
		SMC_Laddr -= 1000;
	}
}

void NAND_Get_Logical_Addr(void)
{
	unsigned short EndBlock;
	unsigned char SMC_Ppage512; //for claculating Endblock

	SMC_Zone = 0;
	SubBlock = 0; //initialise 
//	if (MAL_Block_Address == 0x2f)
//		asm nop;

	if (SMC_Cluster_Size == 32){
		asm {
			LD		A, MAL_Block_Address:3
			LD		X, MAL_Block_Address:2
			LD		Y, MAL_Block_Address:1

⌨️ 快捷键说明

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