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

📄 am29xxxx.c

📁 motorola自己开发的针对coldfire 5272的Dbug bootloader程序
💻 C
字号:
/*
 * File:		src/dev/flash/am29xxxx.c
 * Purpose:		Firmware Flash API driver for AM29XXXX Flash.
 *
 * Notes:       This driver supports a single type (AM29XXXX) and
 *              width of FLASH.  The type and width support is done
 *              at compilation.  It supports multiple banks of same-
 *              width Flash, as well as consecutive/contiguous banks.
 *
 */

#include "src/include/dbug.h"
#include "src/dev/flash/am29xxxx.h"

/********************************************************************/

/*
 * If AM29XXXX_EXTRA_INCLUDE is defined, then include the
 * appropriate file.  This is a method for including other
 * types/definitions without modifying this file.
 */
#ifdef   AM29XXXX_EXTRA_INCLUDE
#define  AM29XXXX_XINCLUDE
#include AM29XXXX_EXTRA_INCLUDE
#undef   AM29XXXX_XINCLUDE
#endif

/********************************************************************/

/*
 * The AMD29F010   FLASH devices.  These devices are  128K x 8.
 * The AMD29F040   FLASH devices.  These devices are  512K x 8.
 * The AMD29F080   FLASH devices.  These devices are 1024K x 8.
 * The AMD29F016   FLASH devices.  These devices are 2048K x 8.
 * The AMD29LV004  FLASH devices.  These devices are  512K x 8.
 * The AMD29PL160  FLASH devices.  These devices are 2048K x 8.
 *
 * Note:  This driver supports one of the following configurations
 * for these devices.  Possible configurations are:
 *
 *      1 AMD29F0XX   as a single  8-bit memory device
 *      2 AMD29F0XXs  as a single 16-bit memory device
 *      4 AMD29F0XXs  as a single 32-bit memory device
 *      1 AMD29F800   as a single  8-bit memory device
 *      2 AMD29F800s  as a single 32-bit memory device
 *      2 AMD29LV004s as a single 16-bit memory device
 *      1 AMD29PL160  as a single 16-bit memory device
 *
 * One of the following C pre-processor define statements must
 * exist at compilation time:
 *
 * #define AM29XXXX_8BIT
 * #define AM29XXXX_16BIT
 * #define AM29XXXX_32BIT
 *
 * One of the following C pre-processor define statements must
 * exist at compilation time:
 *
 * #define AM29XXXX_AM29F010
 * #define AM29XXXX_AM29F040
 * #define AM29XXXX_AM29F080
 * #define AM29XXXX_AM29F016
 * #define AM29XXXX_AM29F800B
 * #define AM29XXXX_AM29F800T
 * #define AM29XXXX_AM29LV004BB
 * #define AM29XXXX_AM29LV004BT
 * #define AM29XXXX_AM29PL160CB8
 * #define AM29XXXX_AM29PL160CT8
 * #define AM29XXXX_AM29PL160CB16
 * #define AM29XXXX_AM29PL160CT16
 *
 * IMPORTANT:  It is not possible to execute any of these routines
 * if the code for these routines is in the FLASH itself.  This is
 * because these routines change the mode of the device so that reads
 * from it are not always possible.  The code must be executed out of
 * RAM.
 */

/*
 * WARNING:  To eliminate playing alot of games with the linker
 * to properly treat this PIC driver, the two routines/symbols
 * AM29XXXX_start and AM29XXXX_end are used to determine the 
 * start and end of the FLASH PIC driver in ROM/FLASH so that it
 * can be copied out to RAM and then executed.  In other words,
 * any modifications/additions must be between these two functions!
 */

/********************************************************************/

void
am29xxxx_start (void)
{
}

/********************************************************************/

/*
 * If AM29XXXX_EXTRA_CODE is defined, then include the
 * appropriate file.  This is a method for including other
 * code without modifying this file.  Keep in mind that all
 * code will need to be self contained!!!
 */
#ifdef   AM29XXXX_EXTRA_CODE
#define  AM29XXXX_XCODE
#include AM29XXXX_EXTRA_CODE
#undef   AM29XXXX_XCODE
#endif

/********************************************************************/
int
am29xxxx_write(AM29XXXX *AM29XXXX_PT,
	FLASH *fwflash,
	void (*func)(void),
	void (*putchar)(int))
{

  	int blockindex, blocksz, index, cellindex, sector_size;
	int written,done,timeouts;
	int hashi=1,hashj=0;
	int hash[8];
	AM29XXXX_CELL * source;
	AM29XXXX_CELL rdata, temp, manuf,id;

	hash[0]=8;	/* Backspace BS*/
	hash[1]=124;/* "|" */
	hash[2]=47; /* "/" */
	hash[3]=45; /* "-" */
	hash[4]=92; /* "\" */
	hash[5]=42; /* "*" */
	hash[6]=32; /* space SP*/
	hash[7]=10; /* line feed LF */


	/*
	 * Step 1) Identify the flash as AM29XXXX.
	 */
	AM29XXXX_WR_CMD1_AUTOSELECT(AM29XXXX_PT);
	AM29XXXX_WR_CMD2_AUTOSELECT(AM29XXXX_PT);
	AM29XXXX_WR_CMD3_AUTOSELECT(AM29XXXX_PT);

	manuf=0;
	id=0;
	manuf = AM29XXXX_RD_MANUF(AM29XXXX_PT);
	id = AM29XXXX_RD_ID(AM29XXXX_PT);

	AM29XXXX_WR_CMD1_READ(AM29XXXX_PT);
	AM29XXXX_WR_CMD2_READ(AM29XXXX_PT);
	AM29XXXX_WR_CMD3_READ(AM29XXXX_PT);

	if ((manuf & 0x00FF) != (AM29XXXX_AMD_CODE & 0x00FF))
		return -1;
	
	if ((id & 0x00FF) != (AM29XXXX_DEVICE_CODE & 0x00FF))
		return -2;

	/*
	 * Step 2) Point to the beginning sector and data block.
	 */
#ifdef AM29XXXX_VARIABLE_SECTOR
		AM29XXXX_sector_index(fwflash->sect, cellindex);
#else
	cellindex = fwflash->sect * AM29XXXX_SECTOR_SIZE;
#endif
	blockindex = 0;
	blocksz = 0;
	source = (AM29XXXX_CELL *)fwflash->blockptr[0];

	done = FALSE;
	written = 0;
	while (!done)
	{
#ifdef AM29XXXX_VARIABLE_SECTOR
		AM29XXXX_sector_size(fwflash->sect, sector_size);
#else
		sector_size = AM29XXXX_SECTOR_SIZE;
#endif


		/*
		 * Step 3) Erase the sector.
		 */
		AM29XXXX_WR_CMD1_SECTORERASE(AM29XXXX_PT);
		AM29XXXX_WR_CMD2_SECTORERASE(AM29XXXX_PT);
		AM29XXXX_WR_CMD3_SECTORERASE(AM29XXXX_PT);
		AM29XXXX_WR_CMD4_SECTORERASE(AM29XXXX_PT);
		AM29XXXX_WR_CMD5_SECTORERASE(AM29XXXX_PT);
		AM29XXXX_WR_CELL(AM29XXXX_PT, cellindex, AM29XXXX_SECTORERASE_CMD6); 

		do temp = AM29XXXX_RD_CELL(AM29XXXX_PT, cellindex);
		while ((temp & AM29XXXX_SECTORERASE_DONE) != AM29XXXX_SECTORERASE_DONE);

		/*
		 * Step 4) Place device into read mode again
		 */
		AM29XXXX_WR_CMD1_READ(AM29XXXX_PT);
		AM29XXXX_WR_CMD2_READ(AM29XXXX_PT);
		AM29XXXX_WR_CMD3_READ(AM29XXXX_PT);

		/*
		 * Step 5) Program the Flash with the data contained in RAM.
		 */
		for (index = 0; index < sector_size; ++index)
		{
			if (*source != AM29XXXX_port_value(0xFF))
			{
			   	
				if ((putchar != NULL))
				{	
					/* Hash marks to indicate progress */
					if (hashj == 1500)
					{
						hashj = -1;
						putchar(hash[0]);
						putchar(hash[hashi]);
								
						hashi++;
						if (hashi == 5)	
						{
							hashi=1;				
						}
			
					}
					hashj++;
				}

				/*
				 * Perform the Byte Program command sequence.
				 */
				AM29XXXX_WR_CMD1_BYTEPROG(AM29XXXX_PT);
				AM29XXXX_WR_CMD2_BYTEPROG(AM29XXXX_PT);
				AM29XXXX_WR_CMD3_BYTEPROG(AM29XXXX_PT);
				AM29XXXX_WR_CELL(AM29XXXX_PT, cellindex, *source);

				/*
				 * Poll to make sure it is done before continuing...
				 */
				timeouts = 0;
				while (TRUE)
				{
					rdata = AM29XXXX_RD_CELL(AM29XXXX_PT, cellindex);

					if ((rdata & AM29XXXX_DATA_POLL_MASK) ==
						(*source & AM29XXXX_DATA_POLL_MASK))
					{
						break;
					}
					else
					{
						rdata = AM29XXXX_RD_CELL(AM29XXXX_PT, cellindex);

						if (rdata & AM29XXXX_TIME_EXCEEDED)
						{
							rdata = AM29XXXX_RD_CELL(AM29XXXX_PT, cellindex);

							if ((rdata & AM29XXXX_DATA_POLL_MASK) ==
								(*source & AM29XXXX_DATA_POLL_MASK))
							{
								break;
							}

							if (++timeouts > 1024)
							{
								break;
							}
						}
					}
				}
			}

			/*
			 * Verify write and increment bytes written counter.
			 */
			if (AM29XXXX_RD_CELL(AM29XXXX_PT, cellindex) == *source)
			{
				written += sizeof(AM29XXXX_CELL);
				blocksz += sizeof(AM29XXXX_CELL);

				++cellindex;
				++source;

				if (blocksz >= fwflash->blocksz)
				{
					blocksz = 0;
					source = (AM29XXXX_CELL *)fwflash->blockptr[++blockindex];

					if (blockindex >= fwflash->numblocks)
					{
						done = TRUE;
						break;
					}
				}

				if ((fwflash->blocksz != 0) && (written >= fwflash->blocksz))
				{
					if ((putchar != NULL))
					{	
						putchar(hash[0]);
						putchar(hash[5]);
						putchar(hash[6]);
					}
					done = TRUE;
				}
			}
			else
			{
				done = TRUE;
				break;
			}
		}

		if (++fwflash->sect >= AM29XXXX_SECTORS)
		{
			/* Place the device back in the read mode. */
			AM29XXXX_WR_CMD1_READ(AM29XXXX_PT);
			AM29XXXX_WR_CMD2_READ(AM29XXXX_PT);
			AM29XXXX_WR_CMD3_READ(AM29XXXX_PT);
			fwflash->sect = 0;
			cellindex = 0;
			AM29XXXX_PT += (AM29XXXX_sectors * AM29XXXX_SECTOR_SIZE);
			/* done = TRUE; */
		}
		
		if ((putchar != NULL))
		{	
			putchar(hash[0]);
			putchar(hash[5]);
			putchar(hash[6]);
		
		}

	}/*while(!done)*/

		
	/* In the case that updbug is the caller, the address of the new ROM
	 * Monitor's entrance point is passed in and execution of the new Monitor
	 * begins
	 */
	if ((func != NULL))
	{
		putchar(hash[7]);
		func();
	}
	return written;
}

/********************************************************************/

void
am29xxxx_end (void)
{
	/*
	 * This function is empty and at the END of all code so that it
	 * can be used to compute the size of the code contained in this
	 * driver.
 	 */
}

/********************************************************************/

⌨️ 快捷键说明

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