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

📄 mal_2k.c

📁 HID-Ukey底层源码实现(st72651芯片) windows上层驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
			return;
		}
		else{
			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;
			} 
			DTC_Error = 0;
			SMC_Write();
			return;
		}
	}
}
#endif

	if (SMC_Wstate & SMC_WRITE_FLAG) {
		if (SMC_Cluster_Size != 64) {
			if(DTC_Error)
				SMC_Npage -= malNpage;
			_MAL_INC_Block_Param(SMC_Npage);
		}
		else {
			if (DTC_Error)			//for 2K page Bad Block
				SMC_Npage512 -= malNpage;//No. of 512 byte pages decremented

			_MAL_INC_Block_Param(SMC_Npage512); 
		}
	}

	DTC_Current_Func = DTC_SMC_WRITE;

	switch (SMC_Wstate) {
	case SMC_PREMARK:		// 0
	case SMC_PRECOPY:		// 1
	case SMC_PREHOLEMARK:	// 8 Never use
	case SMC_PREHOLECOPY:	// 9 Never use
		malNpage = SMC_Cluster_Size - SMC_Npage;
		if (SMC_Cluster_Size != 64){
			if (malNpage > MAL_Block_Numbers) {
				malNpage = (unsigned char)MAL_Block_Numbers;
				SMC_Wstate |= SMC_HOLE_ACTION;
			}
			SMC_Npage = malNpage;	//counter for no. of pages to be written
		}
		else {
			malNpage = ((malNpage * 4) - SubBlock);
			if (malNpage > MAL_Block_Numbers) {
				malNpage = (unsigned char)MAL_Block_Numbers;
				SMC_Wstate |= SMC_HOLE_ACTION;
			//	SMC_Npage = malNPage;
			}
			SMC_Npage512 = malNpage; //for decrement of MAL_Block_Numbers, counter for 512 byte page
			SMC_Npage = (SubBlock + malNpage)/4;  //counter for no. of 2K pages
			if (SMC_Npage == 0 && SubBlock)
				SMC_Npage = 1;
		}
		Test_page = Test_page - malNpage;
		// Launch DTC to write several pages;
		SMC_Wstate |= SMC_WRITE_FLAG;
		_MAL_BufMgr_Download();
		DTC_SMC_Write_USB(0);
		// Now SMC_Wstate = SMC_PRENEWWRITE or SMC_PREOLDWRITE or
		//     SMC_Wstate = SMC_HOLENEWWRITE or SMC_HOLEOLDWRITE
		// SMC_Wstate = 2 : 3 : A : B
		return;

	case SMC_POSTNEWWRITE:	// 6
	case SMC_POSTOLDWRITE:	// 7
		// All data from USB has been written. MAL_Block_Numbers must be 0
		malNpage = (unsigned char)(SMC_Cluster_Size - SMC_Npage);
		SMC_Ppage = SMC_Npage;
		SMC_Wstate &= ~SMC_WRITE_FLAG;		// Clear WRITE flag

Post_Mark_Copy:
		if(SMC_Cluster_Size == 64){
			Col = ((Buffer_Param[0x24] + 0x02) & 0x06);  //get the number of coloumns after write operation

//			malNpage = malNpage - 1;

			if (Col == 0x02)		//set the 1st adr byte for src and destination
				SubBlock = 3;
			else if (Col == 0x04)
				SubBlock = 2;
			else if (Col == 0x06)
				SubBlock = 1;
			else {
				SubBlock = 0;
//				malNpage = malNpage + 1;		// One more big page to copy
			}
		}	// if it is 2K pag

		SMC_Npage = malNpage;
		if (SMC_Wstate & SMC_OLD_CLUSTER) {
			// This was an overwrite operation, copy the remain pages
			//	malRaddr = Map_DTC_Addr(SMC_Zone, SMC_Raddr, SMC_Ppage);
			//			Map_To_DTC_Addr(malRaddr, SMC_Zone, SMC_Raddr, SMC_Ppage);
			if (SMC_Ppage == 0x40 && malNpage == 0) {
				asm	NOP;
				goto Label_SMC_Write_Interrupt;
			}

			SMC_Npage = malNpage;
			Map_To_DTC_Addr256(malRaddr, SMC_Zone, SMC_Raddr, SMC_Ppage,0);//for 2K page
			Map_To_DTC_Addr256(malPaddr, SMC_Zone, SMC_Paddr, SMC_Ppage,0);//for 2K page
			
			if (SMC_Cluster_Size == 64){
				if ((Buffer_Param[0x24]/2+1) > SMC_Npage512) {	// The current big page is complete
					Buffer_Param[0x1A] = 0;		// No pre-copy nor post-copy
					if (SubBlock) {
						SubBlock = 0;
//						malNpage = malNpage + 1;		// One more big page to copy
					}
					else
						asm NOP;
				}
				else {	// Check if the current big page has small pages to copy
					if (SubBlock == 0)
						asm	NOP;
						
					SubBlock = Buffer_Param[0x24]/2 + 1;	// Remain small pages to copy
					Buffer_Param[0x18] = 0;			// Column start addrsss
					Buffer_Param[0x19] = 0;			// Must be 0x0000
					Buffer_Param[0x16] = SubBlock * 2;	// Length of blank area
					Buffer_Param[0x17] = SubBlock * 0x10;	// 0x210, 0x420, 0x630
					Buffer_Param[0x1A] = 3;
					if (malNpage == 0xffff)
						asm	NOP;
//					malNpage = malNpage + 1;		// One more big page to copy
				}
				((unsigned char *)(&(malPaddr)))[3] = 0x00; //col byte is always 0
//				Buffer_Param[0x27] = Buffer_Param[0x25]= 0x00; //col byte is 0 in copypages
			}
			
			// Launch the DTC to copy several pages
			// Copy malNpage pages from malRaddr to malPaddr
			_MAL_BufMgr_Normal();
			DTC_Error = DTC_SMC_Copy_Pages(); 
			DTC_Error--;
			// Now SMC_Wstate = SMC_POSTCOPY; // 5
		}
		else {
			// This was a new cluster operation, mark the remain pages
			// Launch the DTC to several several pages start from malPaddr
//----------------------------------------------------------------
			Buffer_Param[0x25] = ((4 - SubBlock) * 0x10) & 0x30;	// added by HYJ
			malNpage = Test_page / 4;
			SubBlock = Test_page % 4;
//			if (Buffer_Param[0x24] == 0 || SMC_Npage512 > 4 || (Buffer_Param[0x24] + SMC_Npage512) == 4)
//				malNpage = malNpage - 1;			// One more big page to Mark
//			else
//				asm	NOP;

			SMC_Npage = malNpage;
//----------------------------------------------------------------
			DTC_Error = DTC_SMC_Mark_Pages();
			DTC_Error--;
			// Now SMC_Wstate = SMC_POSTMARK;	// 4
		}
		// Mask off this line if DTC interrupts
		goto Label_SMC_Write_Interrupt;
		return;

	case SMC_HOLENEWWRITE:	// A
	case SMC_HOLEOLDWRITE:	// B
		SMC_Ppage += SMC_Npage;
		SMC_Wstate = (SMC_Wstate & SMC_OLD_CLUSTER) | SMC_POST_ACTION;	// Keep OLD flag
		malNpage = SMC_Cluster_Size - SMC_Ppage;	// Pages left to be marked or copied
		goto Post_Mark_Copy;	// The following actions are same as above

	case SMC_POSTMARK:		// 4
	case SMC_POSTCOPY:		// 5
	case SMC_POSTHOLEMARK:	// C
	case SMC_POSTHOLECOPY:	// D
	case SMC_PRENEWWRITE:	// 2
	case SMC_PREOLDWRITE:	// 3
	case SMC_FULLNEWWRITE:	// E
	case SMC_FULLOLDWRITE:	// F
		// Now we have finished one cluster
		SMC_Update_Lookup();

		if (MAL_Block_Numbers == 0) {
			// All data from the USB has been written to the SMC
			MAL_Error = MAL_GOOD;
			MAL_Finish(TRUE); 
			DTC_Current_Func = 0;
			return;
		}

#if ALLOW_OUT_RANGE
		if (Mal_Addr_Out_Range & 0x02) {
			SMC_Wstate = SMC_OUT_RANGE;
			goto Write_Out_Range;
		}
#endif
		// Further more data to be written to the media
#ifdef THUMB_DRIVE
		NAND_INC_Logical_Addr();
#endif

		SMC_Wstate = SMC_FULL_ACTION | SMC_WRITE_FLAG;
		if (SMC_Log2Phy()) {
			// This is an existing cluster
			SMC_Wstate |= SMC_OLD_CLUSTER;
			SMC_Raddr = SMC_Paddr;			// old cluster
			SMC_Paddr = SMC_Get_Free();		// new cluster
		}
		if (SMC_Cluster_Size == 64)
			SMC_Paddr &= 0xffef; //reset the flag for mapped 
		else
			SMC_Paddr &= 0x7FFF;

		SMC_Ppage = 0;

		// the next writing must start from beginning of the cluster
		malNpage = SMC_Cluster_Size;
		if (SMC_Cluster_Size != 64) {
			if (malNpage > MAL_Block_Numbers) {
				SMC_Wstate &= ~0x08;		// change from SMC_FULL_ACTION to SMC_POST_ACTION
				malNpage = (unsigned char)MAL_Block_Numbers;
			}
			//	malPaddr = Map_DTC_Addr(SMC_Zone, SMC_Paddr, 0);
			SMC_Npage = malNpage;
		}
		else {
			malNpage = malNpage * 4; //No. of 2K pages
			if (malNpage > MAL_Block_Numbers){
				SMC_Wstate &= ~0x08;		// change from SMC_FULL_ACTION to SMC_POST_ACTION
				malNpage = (unsigned char)MAL_Block_Numbers;
			}
			SMC_Npage512 = malNpage;		//for decrement of MAL_Block_Numbers   
			SMC_Npage = malNpage / 4;		//counter for 2K pages 
		}
		Test_page = 256 - malNpage;
	//	Map_To_DTC_Addr(malPaddr, SMC_Zone, SMC_Paddr, 0);
		Col = 0x00;
		Buffer_Param[0x25] = 0x00;			//added as it is the start of the cluster

		SMC_Paddr_To_DTC_Addr();

		// Launch DTC to write malPpage pages to malPaddr
		_MAL_BufMgr_Download();
		DTC_SMC_Write_USB(MAL_Block_Finish & 1);

		// Now SMC_Wstate = SMC_POSTNEWWRITE or SMC_POSTOLDWRITE or
		//	   SMC_Wstate = SMC_FULLNEWWRITE or SMC_FULLOLDWRITE
		// SMC_Wstate = 6 : 7 : E : F
		return;

#if ALLOW_OUT_RANGE
	case SMC_OUT_RANGE:
		if (MAL_Block_Numbers == 0) {
			// All data from the USB has been written to the SMC
			MAL_Error = MAL_GOOD;
			MAL_Finish(TRUE);

			DTC_Current_Func = 0;
			return;
		}

Write_Out_Range:
	// assume MAL_Block_Numbers < 256
	//	malNpage = SMC_Cluster_Size;
	//	if (malNpage > MAL_Block_Numbers)
	//		malNpage = (unsigned char)MAL_Block_Numbers;
		SMC_Npage = malNpage = (unsigned char)MAL_Block_Numbers;
		DTC_SMC_Dummy_Write(MAL_Block_Finish & 1);
		return;
#endif
	}
}

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
	MAL_SMC_Write
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
static unsigned char l= 0;
unsigned char SMC_Write(void)
{
	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

	MAL_Block_Numbers_t = MAL_Block_Numbers;
	MAL_Block_Finish = 0;

	//set 1st col adr byte as per the adr issued by the PC
	asm {
		LD		A, SubBlock
		SWAP	A
		LD		Buffer_Param[0x25], A
	}
	Col = SubBlock * 2;					// set 2nd col adr byte

	// Get the physical cluster address
	SMC_Wstate = 0;							// PRE actions, NEW cluster, no WRITE
	if (SMC_Log2Phy()) {					// Check if it is an existing cluster
		SMC_Wstate |= SMC_OLD_CLUSTER;		// Yes, PRECOPY may be necessary
		SMC_Raddr = SMC_Paddr;				// old cluster
		SMC_Paddr = SMC_Get_Free();			// new cluster
	}
	if (SMC_Cluster_Size == 64)
		SMC_Paddr &= 0xffef;				// Reset the flag for mapped 
	else
		SMC_Paddr &= 0x7FFF;

	Map_To_DTC_Addr256(malPaddr, SMC_Zone, SMC_Paddr, 0, 0); //for 2K flash
	DTC_Current_Func = DTC_SMC_WRITE;

	if ((SMC_Ppage) || (SubBlock)) {	//for 2K flash
		// the new pages are not start from beginning of the cluster
//		Buffer_Param[0x25]= Buffer_Param[0x27] = 0x00;	// ALways from the start of the page start copy or mark
		SMC_Npage = malNpage = SMC_Ppage;
		_MAL_BufMgr_Normal();							// switch back to normal mode first
		if (SMC_Wstate & SMC_OLD_CLUSTER) {
			unsigned char Num_subBlock;

			Map_To_DTC_Addr256(malRaddr, SMC_Zone, SMC_Raddr, 0, 0);	//for 2K Flash

			if (SubBlock) {
				malNpage++;
				if (SMC_Ppage == 0)						// only copy <4 small pages
					Buffer_Param[0x1A] = 0x03;			// Flag for Pre-copy
				else
					Buffer_Param[0x1A] = 0x02;			// Flag for Post-copy
			}
			else
				Buffer_Param[0x1A] = 0x0;

			Buffer_Param[0x18] = SubBlock * 2;			// Column start addrsss
			Buffer_Param[0x19] = SubBlock * 0x10;		// 0x210, 0x420, 0x630
			
			Num_subBlock = 4 - SubBlock;
			if (Num_subBlock > MAL_Block_Numbers)
				Num_subBlock = MAL_Block_Numbers;
			Buffer_Param[0x16] = Num_subBlock * 2;		// Length of blank area
			Buffer_Param[0x17] = Num_subBlock * 0x10;	// 0x210, 0x420, 0x630
			
			// Launch the DTC to copy several pages
			// Copy malNpage pages from malRaddr to malPaddr
			DTC_Error = DTC_SMC_Copy_Pages();
			DTC_Error--;

			if (SMC_Cluster_Size == 64) {
				if (SubBlock) {
					Map_To_DTC_Addr256(malRaddr, SMC_Zone, SMC_Raddr, SMC_Ppage, 0); //for 2K Flash
					Map_To_DTC_Addr256(malPaddr, SMC_Zone, SMC_Paddr, SMC_Ppage, 0); //for 2K Flash
				}
//				if (SMC_Ppage != 0)
					((unsigned char *)(&(malPaddr)))[3] = Col;
				Buffer_Param[0x25] = Col << 3;
			}
			// Now SMC_Wstate == SMC_PRECOPY
		}
		else {	// This is a new logical cluster
			// Launch the DTC to mark several pages
			Buffer_Param[0x25] = 0;	// Added by HYJ

			Test_page = 256 - (malNpage * 4) - SubBlock;
			
			DTC_Error = DTC_SMC_Mark_Pages();				// Mark the starting pages
			DTC_Error--;
			
			if (SMC_Cluster_Size == 64) {
				Buffer_Param[0x26] = Buffer_Param[0x12];	//as 0xe6 may contain 2 after markpages

				asm {
					LD		A, SubBlock
					SLL		A
					LD		malPaddr:3, A
					LD		A, SubBlock
					SWAP	A
					LD		Buffer_Param[0x25], A
				}
			}
			// Now SMC_Wstate == SMC_PREMARK
		}

		// Mask off this line if DTC interrupts
		SMC_Write_Interrupt();
	}
	else {
		// the new pages are start from beginning of the cluster
		malNpage = SMC_Cluster_Size;

		if (SMC_Cluster_Size != 64){
			if (malNpage > MAL_Block_Numbers) {
				// Do not write the whole cluster
				malNpage = (unsigned char)MAL_Block_Numbers;
				SMC_Wstate |= SMC_POST_ACTION | SMC_WRITE_FLAG;
			}
			else
				SMC_Wstate |= SMC_FULL_ACTION | SMC_WRITE_FLAG;

			SMC_Npage = malNpage;
		}
		else {
			Map_To_DTC_Addr256(malRaddr, SMC_Zone, SMC_Raddr, 0, 0);	// added by HYJ for 2K Flash
			malNpage = malNpage * 4;
			if (malNpage > MAL_Block_Numbers){
				malNpage = (unsigned char)MAL_Block_Numbers;
				SMC_Wstate |= SMC_POST_ACTION | SMC_WRITE_FLAG;
			}
			else
				SMC_Wstate |= SMC_FULL_ACTION | SMC_WRITE_FLAG;

			SMC_Npage512 = malNpage;
			SMC_Npage = malNpage / 4;
		}
		Test_page = 256 - malNpage;
		// Launch DTC to write malPpage pages to malPaddr
		_MAL_BufMgr_Download();		// Switch to DOWNLOAD mode
		DTC_SMC_Write_USB(0);
		// Now	SMC_Wstate = SMC_POSTNEWWRITE or SMC_POSTOLDWRITE
		//		SMC_Wstate = SMC_FULLNEWWRITE or SMC_FULLOLDWRITE
	}
	return MAL_GOOD;
}

#ifdef THUMB_DRIVE
static unsigned short NAND_Blocks;
#pragma DATA_SEG DEFAULT_RAM
unsigned char Startup_VAR = 0;
extern void SMC_Restore_Parameters(void);
extern unsigned char NAND_Format(void);
unsigned char NAND_Init()
{
	unsigned char iChip, MAL_Status;

	DTC_SMC_Init();

	MAL_Status = NAND_Read_Capacity();

	if (MAL_Status != MAL_GOOD)
		return MAL_Status;

/*******************************************
Get the 2K page Flash on board to remap the Bad clusters in the media
*******************************************/
#ifdef Factory_bad
	for (NAND_Chip = 0; NAND_Chip < MAX_NUM_NAND; NAND_Chip++) {
		if (Cluster_Size[NAND_Chip] != 64)
			continue;

		NAND_Select(NAND_Chip);
		SMC_Cluster_Size = 64;
		malPaddr = 0;
		if (!(DTC_SMC_Chk_Spare(format) & 0x02)) {
			unsigned long *paddr;

			malNpage = 0;
			SubBlock = 1;
			DTC_SMC_Mark_Bad();

			malPaddr = 0x4000;
			malNpage = SMC_Cluster_Size;
			Buffer_Param[0x3e] = (Chip_Size[NAND_Chip]/8); //number of zones

			asm {				//initialise DTC buffer
				CLR		A
				CLR		X
	Clr_Buf0:	LD		(Buffer_0, X), A
				LD		(Buffer_0:256, X), A
				DEC		X
				JRNE	Clr_Buf0
			}

			DTC_SMC_Chk_Spare(init);
			paddr = (unsigned long *) Buffer_0;
			while (*paddr & 0x08) {
				malNpage = 0;
				SubBlock = 1;

⌨️ 快捷键说明

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