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

📄 mal_2k.c

📁 HID-Ukey底层源码实现(st72651芯片) windows上层驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
			CP		X, #CACHE0_FREE*2-3
			JRNE	shift_free0
		}
		temp = SMC_Lookup_pFree0[0];
	}
#else
	pBad = SMC_Lookup_pTable + 1023;		// the last item
	while (*pBad & 0x01)
		pBad--;

	temp = *pBad;
	*pBad = SMC_Paddr | 0x0001;
#endif // USE_CACHE0

	// ASSUME THIS IS A GOOD ONE
	if (SMC_Cluster_Size != 64)
		SMC_Paddr = temp & 0x7FFF;			// re-allocate a good cluster
	else
		SMC_Paddr = temp & 0xffef;			//different mapping bit for 2K
}

#ifndef THUMB_DRIVE
unsigned char SMC_Read_Capacity(void)
{
	unsigned char	CardID;

	CardID = DTC_SMC_ReadID();

	SMC_4MB = 0;
	MAL_Capacity = 0;
	SMC_Lookup_nCache0 = 0;		// No zone0 cache with card < 64MB
	SMC_Cluster_Size = 16;
	SMC_Addr_Bytes = 3;
	if (CardID == 0xE3 || CardID == 0xE5) {	// 4MB
		SMC_4MB = 1;
		MAL_Capacity = 8000;
	}
	else if (CardID == 0xE6)		// 8MB
		MAL_Capacity = 16000;
	else {
		SMC_Cluster_Size <<= 1;
		if (CardID == 0x73) {		// 16MB
			MAL_Capacity = 32000;
		}
		else if (CardID == 0x75) {	// 32MB
			MAL_Capacity = 64000;
		}
		else if (CardID == 0x76) {	// 64MB
			MAL_Capacity = 128000;
			SMC_Addr_Bytes = 4;
			SMC_Lookup_nCache0 = 4;
		}
		else if (CardID == 0x79) {	// 128MB
			MAL_Capacity = 256000;
			SMC_Addr_Bytes = 4;
			SMC_Lookup_nCache0 = 5;
		}
		else if (CardID == 0xF1){	// 128MB-2K
			MAL_Capacity = 256000;
			SMC_Addr_Bytes = 4; 
			SMC_Cluster_Size <<= 1;
			SMC_Lookup_nCache0 = 5;
		}
		else if (CardID == 0xDA){	// 256MB-2K
			MAL_Capacity = 512000;
			SMC_Addr_Bytes = 5; 
			SMC_Cluster_Size <<= 1;
			SMC_Lookup_nCache0 = 5;
		}
		else
			return MAL_CARD_UNKNOWN;
	}

	DTC_SMC_Address_bytes = SMC_Addr_Bytes;
	return MAL_GOOD;
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#ifndef THUMB_DRIVE
static void SMC_INC_Logical_Addr(void)
{
	SMC_Laddr++; 
/****for 2K Flash*****/	
	SubBlock = 0;
	Buffer_Param[0x01] = 4; 
	Buffer_Param[0x25]= 0;
	
	if (SMC_Laddr >= 1000) {
		SMC_Zone++;
		SMC_Laddr -= 1000;
	}
}

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
void SMC_Get_Logical_Addr(void)
{
	unsigned short EndBlock;

	SMC_Zone = 0;
	if (SMC_Cluster_Size == 32) {
		asm {
			LD		A, MAL_Block_Address:3
			LD		X, MAL_Block_Address:2
			LD		Y, MAL_Block_Address:1
			SRL		Y
			RRC		X
			RRC		A	; 1st shift
			SRL		Y
			RRC		X
			RRC		A	; 2nd shift
			SRL		Y
			RRC		X
			RRC		A	; 3rd shift
			SRL		Y
			RRC		X
			RRC		A	; 4th shift
			SRL		Y
			RRC		X
			RRC		A	; 5th shift
			LD		SMC_Laddr:1, A
			LD		SMC_Laddr, X
		}	// The C line below costs too much
	//	SMC_Laddr = (unsigned int)(MAL_Block_Address >> 5);

		Adjust_Laddr();
		SMC_Ppage = (unsigned char)MAL_Block_Address & 0x001F;
	} 
	else if (SMC_Cluster_Size == 64){ //for 256 MB
		asm {
			LD		A, MAL_Block_Address:2
			LD		X, MAL_Block_Address:1
			LD		SMC_Laddr:1, A
			LD		SMC_Laddr, X
		}	// The C line below costs too much
	//	SMC_Laddr = (unsigned int)(MAL_Block_Address >> 8);

		Adjust_Laddr();
		SMC_Ppage = (unsigned char)MAL_Block_Address & 0x00FF;	// No. of small pages
		SubBlock = (unsigned char) (SMC_Ppage % 4);				// Col. offset in a big page

		SMC_Ppage = SMC_Ppage / 4;//No. of 2K page
	}

	else {
		asm {
			LD		A, MAL_Block_Address:3
			LD		X, MAL_Block_Address:2
			LD		Y, MAL_Block_Address:1
			SRL		Y
			RRC		X
			RRC		A	; 1st shift
			SRL		Y
			RRC		X
			RRC		A	; 2nd shift
			SRL		Y
			RRC		X
			RRC		A	; 3rd shift
			SRL		Y
			RRC		X
			RRC		A	; 4th shift
			LD		SMC_Laddr:1, A
			LD		SMC_Laddr, X
		}	// The C line below costs too much
	//	SMC_Laddr = (unsigned int)(MAL_Block_Address >> 4);
		SMC_Ppage = (unsigned char)MAL_Block_Address & 0x000F;
	}

	if (SMC_Lookup_nCache0 == 0)	// Card < 64MB
		return;						// No cache management needed

	if (SMC_Cluster_Size != 64){
		asm {
			LD		A, MAL_Block_Numbers:1
			LD		X, MAL_Block_Numbers
			ADD		A, SMC_Ppage
			JRNC	sub_1
			INC		X
	sub_1:	SUB		A, #1
			JRNC	shift5
			DEC		X
	shift5:
			SRL		X
			RRC		A		; 1st shift
			SRL		X
			RRC		A		; 2nd shift
			SRL		X
			RRC		A		; 3rd shift
			SRL		X
			RRC		A		; 4th shift
			SRL		X
			RRC		A		; 5th shift
			ADD		A, SMC_Laddr:1
			LD		EndBlock:1, A
			LD		A, X
			ADC		A, SMC_Laddr
			LD		EndBlock, A
		}	// The following C line costs too much
	} 
	else {
		asm {
			LD		A, MAL_Block_Numbers:1
			LD		X, MAL_Block_Numbers
			ADD		A, SMC_Ppage
			JRNC	sub_2
			INC		X
	sub_2:	SUB		A, #1
			JRNC	shift8
			DEC		X
	shift8:	LD		A, X
			ADD		A, SMC_Laddr:1
			LD		EndBlock:1, A
			CLR		A
			ADC		A, SMC_Laddr
			LD		EndBlock, A
		}	// The following C line costs too much
	}
//	EndBlock = SMC_Laddr + ((SMC_Ppage + MAL_Block_Numbers - 1) >> 5);

	if (EndBlock >= 1000) {		// The access will cross the zone boundary
		unsigned char ZoneNext;

		ZoneNext = SMC_Zone + 1;
		if (SMC_Zone == SMC_Lookup_Zone0) {		// current zone hits table0
			if (ZoneNext == SMC_Lookup_Zone1)
				return;

			SMC_Lookup_Update1(ZoneNext);		// update lookup tabke 1 for ZoneNext
		}
		else if (SMC_Zone == SMC_Lookup_Zone1) {// current zone hits table1
			if (ZoneNext == SMC_Lookup_Zone0)
				return;

			SMC_Lookup_Update0(ZoneNext);		// update lookup table 0 for ZoneNext
		}
		else if (ZoneNext == SMC_Lookup_Zone0)	// next zone hits table0
			SMC_Lookup_Update1(SMC_Zone);		// update lookup table 1 for SMC_Zone
		else if (ZoneNext == SMC_Lookup_Zone1)	// next zone hits table1
			SMC_Lookup_Update0(SMC_Zone);		// updata lookup table 0 for SMC_Zone
		else {
			SMC_Lookup_Update0(SMC_Zone);		// updata lookup table 0 for SMC_Zone
			SMC_Lookup_Update1(ZoneNext);		// updata lookup table 1 for ZoneNext
		}
	}
	else {		// The access will not cross the zone boundary
		if (SMC_Zone == SMC_Lookup_Zone0 || SMC_Zone == SMC_Lookup_Zone1)
			return;

#if USE_CACHE0
		if (SMC_Zone == 0 && SMC_Laddr < SMC_Lookup_nCache0) {	// Hit on cache of zone0
			if (EndBlock < SMC_Lookup_nCache0)
				return;
		}
#endif
		// Going to make the lookup table for the new zone
		if (SMC_Lookup_Count0 < SMC_Lookup_Count1)
			SMC_Lookup_Update0(SMC_Zone);
		else
			SMC_Lookup_Update1(SMC_Zone);
	}
}
#endif	// not THUMB_DRIVE

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	Launch the DTC again for reading
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
void SMC_Read_Interrupt()
{
	_MAL_INC_Block_Param(SMC_Npage);	
//	MAL_Block_Numbers -= SMC_Npage;
//	MAL_Block_Address += SMC_Npage;
	if (DTC_Error) {
		_MAL_DEC_Block_Param(malNpage);
	//	MAL_Block_Numbers += malNpage;
	//	MAL_Block_Address -= malNpage;

		MAL_Error = MAL_RD_ERR;
		MAL_Finish(FALSE);

		DTC_Current_Func = 0;
		return;
	}
	if (MAL_Block_Numbers == 0) {
		MAL_Error = MAL_GOOD;
		MAL_Finish(TRUE);

		DTC_Current_Func = 0;
		return;
	}

	// If the previous DTC was reading odd number of pages
	// Clear the buffer manager flags and start from buffer0
	if (SMC_Npage & 1) {
		while (BUFSR & 0x06);		// Wait both buffer are empty
		BUFSR = 0x01;				// Clear Buffer status
		BUFSR = 0;
	}

	// Launch the next burst reading
#ifdef THUMB_DRIVE
	NAND_INC_Logical_Addr();
#else
	SMC_INC_Logical_Addr();
#endif

	if (SMC_Cluster_Size != 64){
		if (SMC_Cluster_Size > MAL_Block_Numbers)
			malNpage = (unsigned char)MAL_Block_Numbers;
		else
			malNpage = SMC_Cluster_Size;
	}
	else		// SMC_Cluster_Size = 64	// for 2k Flash
		if (MAL_Block_Numbers < 0x100)		// No. of small pages = 4 * big pages
			malNpage = (unsigned char)MAL_Block_Numbers;		
		else
			malNpage = 0x100;

	_MAL_BufMgr_Upload();		// Switch to UPLOAD mode

	SMC_Npage = malNpage;
	DTC_Current_Func = DTC_SMC_READ;
	if (SMC_Log2Phy() == 0) {
// WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
		// When the specified location does not exist
		// Have to return all 0xFF in the data block.
		DTC_Read_FF();
		return;
	}

	if (SMC_Paddr & 0x0F) {			// This is a bad cluster
		MAL_Error = MAL_BAD_MEDIUM;	// Too many bad clusters
		MAL_Finish(FALSE);

		DTC_Current_Func = 0;
		return;
	}

//	malPaddr = Map_DTC_Addr(SMC_Zone, SMC_Paddr, SMC_Npage);
//	Map_To_DTC_Addr(malPaddr, SMC_Zone, SMC_Paddr, 0);
	Col = 0;

	SMC_Paddr_To_DTC_Addr();
	DTC_SMC_Read_USB( /* malPaddr, malNpage */ );
}

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	MAL_SMC_Read
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
unsigned char SMC_Read(void)
{
#ifdef THUMB_DRIVE
	Get_Chip_Number();		// Map the MAL address within a chip

// Get the logical cluster address
	NAND_Get_Logical_Addr();		// SMC_Zone:SMC_Laddr:SMC_Ppage = MAL_Block_Address

	NAND_Select(NAND_Chip);			// Enable the chip select of the chip
#else
	DTC_SMC_Address_bytes = SMC_Addr_Bytes;
// Get the logical cluster address
	SMC_Get_Logical_Addr();		// SMC_Zone:SMC_Laddr:SMC_Ppage = MAL_Block_Address
#endif

	if (SMC_Cluster_Size != 64){
		Buffer_Param[0x00] = 0x01;	//flag to recognize 2K or 512 flash
		Buffer_Param[0x25] = 0x00; //1st adr byte to be sent 
	}
	else {
		asm {
			LD		A, SubBlock
			SWAP	A
			LD		Buffer_Param[0x25], A
		}
	//	if (SubBlock == 0) //1st col byte adr for 2K page
	//		Buffer_Param[0x25] = 0x00;
	//	else if (SubBlock == 1)
	//		Buffer_Param[0x25] = 0x10;
	//	else if (SubBlock == 2)
	//		Buffer_Param[0x25] = 0x20;
	//	else
	//		Buffer_Param[0x25] = 0x30;
		Buffer_Param[0x00] = 0x00;			//flag to recognize 2K or 512 flash 
		Buffer_Param[0x01] = (4 - SubBlock);//Number of partial pages to be read
	}

	MAL_Block_Finish = 0;

	if (SMC_Cluster_Size != 64)
		malNpage = SMC_Cluster_Size - SMC_Ppage;
	else {
		asm {
			CLR		malNpage
			LD		A, SMC_Ppage
			SLL		A
			SLL		A
			ADD		A, SubBlock
			NEG		A
			LD		malNpage:1, A
			JRNE	got_Npage
			INC		malNpage
got_Npage:
		}
	//	malNpage = SMC_Ppage * 4 + SubBlock;
	//	malNpage = 0x100 - malNpage;
	}

	if (malNpage > MAL_Block_Numbers)
		malNpage = (unsigned char)MAL_Block_Numbers;//No. of small pages to be read
	
	SMC_Npage = malNpage;
	DTC_Current_Func = DTC_SMC_READ;

	_MAL_BufMgr_Upload();		// Switch to UPLOAD mode

// Get the physical cluster address
	if (SMC_Log2Phy() == 0) {
		// When the specified location does not exist
		// Have to return all 0xFF in the data block.
		DTC_Read_FF();
		return MAL_GOOD;
	}

	if (SMC_Paddr & 0x0F) {			// This is a bad cluster
		MAL_Error = MAL_BAD_MEDIUM;	// Too many bad clusters
		MAL_Finish(FALSE);

		DTC_Current_Func = 0;
		return MAL_Error;
	}

//	Launch the DTC to copy the first data cluster
//	malPaddr = Map_DTC_Addr(SMC_Zone, SMC_Paddr, SMC_Ppage);

	Col = SubBlock * 2; //To get 2nd col. byte

	Map_To_DTC_Addr256(malPaddr, SMC_Zone, SMC_Paddr, SMC_Ppage,Col);
	
//	Map_To_DTC_Addr(malPaddr, SMC_Zone, SMC_Paddr, SMC_Ppage);
	DTC_SMC_Read_USB( /* malPaddr, malNpage */ );

	return MAL_GOOD;
}

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	MAL_Write();	MAL_Write();	MAL_Write();	MAL_Write();
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	Launch the DTC again for writing
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
unsigned char SMC_Write(void);
unsigned short MAL_Block_Numbers_t;
#define PAGE2K_BAD
void SMC_Write_Interrupt()
{
Label_SMC_Write_Interrupt:
			// Some DTC routine is expected to finish with interrupt,
			// but it returns when it finishes.
			// This label is used to simulate the re-enter as interrupt.

#ifdef PAGE2K_BAD
if(SMC_Cluster_Size ==  64){
	if (DTC_Error) {
		if((SMC_Wstate != SMC_PREMARK) && (SMC_Wstate != SMC_PRECOPY)){
			malPaddr = (malPaddr & ~(0x3fff));
			DTC_SMC_Mark_Bad();
			SMC_Lookup_Map_Bad();
			if (SMC_Wstate & SMC_OLD_CLUSTER)
				SMC_Lookup_pTable[1000] = SMC_Paddr | 0x10;
			else
				SMC_Lookup_pTable[SMC_Laddr] = SMC_Paddr | 0x10;

			MAL_Error = MAL_WR_ERR;
			DTC_Error = 0; 
			MAL_Block_Numbers = MAL_Block_Numbers_t;	//ASk for all data in case of failure
			MAL_Finish(FALSE);

⌨️ 快捷键说明

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