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

📄 flashwriternor.c

📁 手机中写FLASH的代码
💻 C
📖 第 1 页 / 共 3 页
字号:
// Notes:
//   Callable from C. Registers r0-r3 are *not* preserved.
//
///////////////////////////////////////////////////////////////////////////////
void AMD_Soft_Reset_Flash(ULONG addr)
{  
	// Reset Flash to be in Read Array Mode 
	*((vHwdptr) addr) =  AMD_DEVICE_RESET;
	// return to caller
}

///////////////////////////////////////////////////////////////////////////////
//
// AMD Flash Erase Block
//
// Description:
//   This routine erases the AMD Page specified by the input parameter 
//   address. This routine is common for both the AM29LV017B device and
//   the AM29DL800B device.
//
// Arguments:
//   address - address in chip select to be erased
//
// Assumptions:
//   The AM29LV017B device won't become confused when the addresses required
//   by the AM29DL800B are used.
//
///////////////////////////////////////////////////////////////////////////////
void AMD_Flash_Erase_Block(ULONG blockaddress)
{
	volatile USHORT *address_cs;
	ULONG tmp_ptr;
			
	tmp_ptr  = (ULONG) blockaddress;
	address_cs = (USHORT *) (tmp_ptr & AMD_ADDRESS_CS_MASK);		
	*(address_cs + AMD_CMD0_ADDR) = AMD_ERASE_BLK_CMD0;
	*(address_cs + AMD_CMD1_ADDR) = AMD_ERASE_BLK_CMD1;
	*(address_cs + AMD_CMD2_ADDR) = AMD_ERASE_BLK_CMD2;
	*(address_cs + AMD_CMD0_ADDR) = AMD_ERASE_BLK_CMD3;
	*(address_cs + AMD_CMD1_ADDR) = AMD_ERASE_BLK_CMD4;
	*((vHwdptr) blockaddress) = AMD_ERASE_BLK_CMD5;		
	while (*((vHwdptr)blockaddress) != AMD_ERASE_DONE);
}
 
///////////////////////////////////////////////////////////////////////////////
//
// AMD Flash Erase All
//
// Description:
//   This routine erases the entire AMD Chip.
//   This routine is common for both the AM29LV017B device and
//   the AM29DL800B device.
//
// Arguments:
//   address - chip select address  to be erased
//
// Assumptions:
//   The AM29LV017B device won't become confused when the addresses required
//   by the AM29DL800B are used.
//
///////////////////////////////////////////////////////////////////////////////
void AMD_Flash_Erase_All(ULONG address)
{
	volatile USHORT *psAddress;
	volatile USHORT *address_cs;
	ULONG tmp_ptr;
	USHORT tmp;
	
	psAddress = (USHORT *)address;
	tmp_ptr  = (ULONG) address;
	address_cs = (USHORT *) (tmp_ptr & AMD_ADDRESS_CS_MASK);	
	*(address_cs + AMD_CMD0_ADDR) = AMD_ERASE_CMD0;
	*(address_cs + AMD_CMD1_ADDR) = AMD_ERASE_CMD1;
	*(address_cs + AMD_CMD2_ADDR) = AMD_ERASE_CMD2;										
	*(address_cs + AMD_CMD0_ADDR) = AMD_ERASE_CMD3;
	*(address_cs + AMD_CMD1_ADDR) = AMD_ERASE_CMD4;
	*(address_cs + AMD_CMD2_ADDR) = AMD_ERASE_CMD5;
										
	while (1)
	{
		tmp = *psAddress; 
		if(tmp & BIT7) 
		{
			break;
		}  else
		{
			if(tmp & BIT5)             // Exceeded Time Limit
			{
				tmp = *psAddress; 
				if(tmp & BIT7) 
				{
					break; 
				}  else
				{
					AMD_Soft_Reset_Flash((ULONG) psAddress);
				}	
			}
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
//
// AMD Flash Write
//
// Description:
//   This routine writes data to flash memory starting at the specified 
//   parameter address.
//
// Arguments:
//   plAddress - address to be erased
//   ulData    - data to be written
///////////////////////////////////////////////////////////////////////////////
int AMD_Flash_Write( ULONG *plAddress, USHORT ulData )
{
	volatile USHORT *psAddress;
	volatile USHORT *address_cs;
	USHORT tmp;
	ULONG tmp_ptr;

	// Lower WORD.
	psAddress = (USHORT *)plAddress;
	tmp_ptr  = (ULONG) plAddress;
	address_cs = (USHORT *) (tmp_ptr & AMD_ADDRESS_CS_MASK);

    *((vHwdptr)address_cs + AMD_CMD0_ADDR) = AMD_PROG_CMD0;
    *((vHwdptr)address_cs + AMD_CMD1_ADDR) = AMD_PROG_CMD1;
    *((vHwdptr)address_cs + AMD_CMD2_ADDR) = AMD_PROG_CMD2;
	
	*psAddress = ulData;

	// Wait for ready.
	while (1)
	{
		tmp = *psAddress; 
		if( (tmp & BIT7)  == (ulData & BIT7)) 
		{
			break;
		}
		else
		{
			if(tmp & BIT5)             // Exceeded Time Limit
			{
				tmp = *psAddress; 
				if( (tmp & BIT7)  == (ulData & BIT7)) 
				{
					break; 
				}
				else
				{
				  	AMD_Soft_Reset_Flash((ULONG) psAddress);
			      	return 1;
				}	
			}
		}
	}
    // Return Read Mode 
	AMD_Soft_Reset_Flash((ULONG) psAddress);
	// Verify the data.
	if (*psAddress != ulData)
	{
     	return 1;
	}
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
//
// AMD Flash Optimized Write
//
// Description:
//   This routine writes an array of data to flash memory starting beginning 
//   at the specified parameter address.
//
// Arguments:
//   plAddress - address to begin writing
//   ulData[]  - data array to be written
//   length    - length of data array 
//
// Return:
//   int - 0 Success
//		 - 1 Fail 
//
///////////////////////////////////////////////////////////////////////////////
int AMD_Flash_Optimized_Write(ULONG *plAddress, USHORT ulData[], ULONG ullength )
{
	volatile USHORT *psAddress;			//
	volatile USHORT *address_cs;		//
	volatile USHORT *psBlockAddress;
	volatile USHORT *psPollingAddress;	//
	USHORT           usPollingData;     //
	USHORT           tmp;               //
	ULONG tmp_ptr;
	USHORT i;					

    // Adjust the timings for Writes
	tmp_ptr  = (ULONG) plAddress;
	psAddress = (USHORT *)plAddress;
	address_cs = (USHORT *) (tmp_ptr & AMD_ADDRESS_CS_MASK);           
	// Block Address WORD.
	psBlockAddress = (USHORT *)(tmp_ptr &= 0xFFFF0000);                // 64KB Sectors
	// Write the Write Buffer Load command
    *((vHwdptr)address_cs + AMD_CMD0_ADDR) = AMD_WRT_BUF_LOAD_CMD0;    
    *((vHwdptr)address_cs + AMD_CMD1_ADDR) = AMD_WRT_BUF_LOAD_CMD1;    
    *((vHwdptr)address_cs + AMD_CMD2_ADDR) = AMD_WRT_BUF_LOAD_CMD2;    	
	// Write Length 
	*psBlockAddress = (USHORT) (ullength-1);
	// Write Data 
	for(i=0; i<ullength; i++)
	{
		*psAddress = ulData[i];
        usPollingData    = ulData[i];                                  // store polling data
		psPollingAddress = psAddress;                                  // store polling address
		psAddress++;
	}
    // Program Buffer to Flash Confirm Write 
	*psBlockAddress = AMD_WRT_BUF_CONF_CMD0;                         

	psAddress = psPollingAddress;    // set polling address to last loaded location 
	                                 // (minimizes edits to "borrowed" polling routine)s	
	// Wait for ready.
	while (1)
	{
		tmp = *psAddress; 
		if((tmp & BIT7)  == (usPollingData & BIT7)) 
		{
			break;
		}  else
		{
			if(tmp & BIT5)             // Exceeded Time Limit
			{
				tmp = *psAddress; 
				if( (tmp & BIT7)  == (usPollingData & BIT7)) 
				{
					break; 
				}  else
				{
				  	AMD_Soft_Reset_Flash((ULONG) psAddress);
			      	return 1;
				}	
			}
			if(tmp & BIT1)             // Write Buffer Loaded Incorrectly
			{
				tmp = *psAddress; 
				if( (tmp & BIT7)  == (usPollingData & BIT7)) 
				{
					break; 
				}  else
				{
				  	AMD_Write_Buf_Abort_Reset_Flash ((ULONG) psAddress);
			      	return 1;
				}	
			}
		}
	}	
	// Put chip back into read array mode.
	AMD_Soft_Reset_Flash((ULONG) psBlockAddress);
	// Verify Written Data 
	psAddress = (USHORT *)plAddress;
	for(i=0; i<ullength; i++)
	{
	 	if(*psAddress != ulData[i])
        {
			return 1;
        }
		psAddress++;
	}		
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
//
// AMD Write Buf Abort Reset Flash  
//
// Description:
//   Resets the flash device when in a write buffer abort state.
//
// C Syntax:
//   void AMD_Soft_Reset_Flash(ULONG addr);
//
// Arguments:
//   r0: Any valid address in a flash memory sector.
//
// Notes:
//   Callable from C. Registers r0-r3 are *not* preserved.
//
///////////////////////////////////////////////////////////////////////////////
void AMD_Write_Buf_Abort_Reset_Flash( ULONG plAddress )
{  
	volatile USHORT *address_cs;
	ULONG tmp_ptr;

	// Lower WORD.
	tmp_ptr  = (ULONG) plAddress;
	address_cs = (USHORT *) (tmp_ptr & AMD_ADDRESS_CS_MASK);           
	// Reset Flash to be in Read Array Mode 
    *((vHwdptr)address_cs + AMD_CMD0_ADDR) = AMD_WRT_BUF_ABORT_RESET_CMD0;
    *((vHwdptr)address_cs + AMD_CMD1_ADDR) = AMD_WRT_BUF_ABORT_RESET_CMD1;
    *((vHwdptr)address_cs + AMD_CMD2_ADDR) = AMD_WRT_BUF_ABORT_RESET_CMD2;
	// return to caller
	return;
}

///////////////////////////////////////////////////////////////////////////////
//
// Enable Flash Write Protection
//
// Description:
//				Wiggles the EMIFS WP# signal high to write to Flash devices
//				Control for older EVM's and TEB's also included
///////////////////////////////////////////////////////////////////////////////
void Enable_Flash_WP(void)
{
	ULONG nMIFConfReg;
	ULONG volatile  *pMIFConfReg = (ULONG volatile *) MIF_CONFIG_REG;
	// Enable write protection in the Memory Interface, bit 0 low.
	nMIFConfReg = *pMIFConfReg;
	nMIFConfReg &= 0xFFFFFFFE;
	*pMIFConfReg = nMIFConfReg; 			
	return;
}

///////////////////////////////////////////////////////////////////////////////
//
// Disable Flash Write Protection
//
///////////////////////////////////////////////////////////////////////////////
void Disable_Flash_WP(void)
{
	ULONG nMIFConfReg;
	ULONG volatile  *pMIFConfReg = (ULONG volatile *) MIF_CONFIG_REG;	
	// Disable write protection in FPGA, bit 2 high.
	#if (TICFG_PROC_VER!=HELENDC_V1)		// HelenDC
		#ifdef TICFG_EVM_PRESENT	
			unsigned char volatile  *pDIPSwitchReg = (unsigned char volatile *) FPGA_DIP_SWITCH_REG;
			unsigned char nDIPSwitchReg;
			nDIPSwitchReg = *pDIPSwitchReg;
			nDIPSwitchReg |= 0x04;
			*pDIPSwitchReg = nDIPSwitchReg;
		#endif 
	#endif
	// Disable write protection in TC, bit 0 high.
	nMIFConfReg = *pMIFConfReg;
	nMIFConfReg |= 0x00000001;
	*pMIFConfReg = nMIFConfReg; 				
	return;
}

///////////////////////////////////////////////////////////////////////////////
//
// DownloadToNORFlash
//
// Description:
//   Copies RAM Memory region to Flash region
//
// Arguments:
//   ULONG *startWriteAddress   - Base address of the data to be copied
//   USHORT *startReadAddress   - Base address of the destination address 
//   ULONG  size	            - Number of bytes to copy
//
// Return:
//   Flash Programming Status 
//
// Assumptions:
//   Flash addresses are always on a halfword boundary, and the byte count
//   is always even.
//
///////////////////////////////////////////////////////////////////////////////
void  DownloadToNORFlash(ULONG startWriteAddress,	//R0 Intel Strata Address 
					 ULONG startReadAddress,	//R1 SDRAM Address 
					 ULONG size,				//R2
					 ULONG statusAddress,     	//R3 status address 
   				 	 enum NORFlashType flash_id)
{   
	ULONG  flash_addr;
	long  SizeInBytes;
	ULONG  sdram_src;
	USHORT flash_data;
	USHORT opt_array[16];   //For buffered writes to specific devices 
	ULONG  i;
	
	SizeInBytes = size;
	flash_addr = startWriteAddress;
	sdram_src = startReadAddress;	
	//Print what flash type was found
		
	// Disable flash write protection
	Disable_Flash_WP();
	// Erase the flash where the image will sit	
	EraseNORFlash(flash_addr, SizeInBytes, flash_id);	                   
	//Write to the Flash in this loop		
	printf("Writing the Flash\n");
	while (SizeInBytes > 0)
  	{
    	if((User_Flash_Optimized_Write == 
    		(int (*)(ULONG *, USHORT[], ULONG)) Flash_Do_Nothing) 
			|| (SizeInBytes < 32) || (flash_addr%32))
		{
			flash_data = *((USHORT *) sdram_src);      
			(*User_Flash_Write)((ULONG *) flash_addr, flash_data);      		
			SizeInBytes   -= 2;
			flash_addr += 2;
			sdram_src  += 2;
		}
		else
		{
			for(i = 0; i<16; i++)	 // <- *** INTEL Specific 
			{
				opt_array[i] = *((USHORT *) sdram_src);		  
				sdram_src += 2;
			}										
			(*User_Flash_Optimized_Write)((ULONG *)flash_addr, opt_array, i);
			SizeInBytes -= (i*2);
			flash_addr += (i*2);		
		}
		if ((flash_addr & 0xFFFC0000) == flash_addr)
		{
			printf("Flashed 0x%08X bytes of 0x%08X total bytes\n", (flash_addr - startWriteAddress), size);
		}		 		 		
  	}
  	// Enable flash write protection
  	Enable_Flash_WP();
  	
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//
//Main
//
//	Purpose:
//	Generates some messaging about the tool, Detects Flash devices, Detects OMAP device, 
/////////////////////////////////////////////////////////////////////////////////////////////////
ULONG main(void)
{  
	ULONG  flash_base_addr = (gp_vars->WriteAddress & 0xFFC00000); // Round to 4MB Boundaries 
	enum NORFlashType nor_flash_id;
	
	//point REad Address at whereever the image section is mapped into
	gp_vars->ReadAddress = (ULONG) &image;
	
	printinfo(gp_vars->Size, gp_vars->ReadAddress, gp_vars->WriteAddress);		

	//Try to ID as a NOR Flash first, then a NAND if a NOR can't be found at our address
	nor_flash_id = IdentifyNORFlash(flash_base_addr);		
	if(nor_flash_id == FLASH_NOT_FOUND)		//Try to find a NAND Flash
	{
		printf("No Flash devices have been found\n");
	} else 		//Found a NOR device
	{
		printNORflashtype(nor_flash_id);	
		DownloadToNORFlash(gp_vars->WriteAddress, 
							gp_vars->ReadAddress, 
							gp_vars->Size, 
							(ULONG) gp_vars, 
							nor_flash_id);
		printf("Flash writing completed!\n");  	
	}	
	return 0;  
}

⌨️ 快捷键说明

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