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

📄 fburncmd.c

📁 ti dsp 5402 的BOOT程序。利用此程序实现将代码写入到FLASH 的功能。
💻 C
字号:
/*
 ********************************************************************
 *   (C) COPYRIGHT TEXAS INSTRUMENTS, INC. 2000, 2001
 *   FlashBurn Programming Functions
 *   for FBTC54
 *
 * $Log: FBurnCmd.c,v $
 * Revision 1.11  2001/06/27 17:55:13  heeschen
 * v00.32 Beta Prep
 * Capturing all files to prepare for Beta Release
 *
 * Revision 1.10  2001/04/19 18:56:34  heeschen
 * v00.30 Alpha - Updated comments
 *
 * Revision 1.9  2001/04/19 16:29:01  heeschen
 * v00.30 Snapshot
 * Saving this stuff after massive redesign to remove RTDX dependency.
 * Next step is to clean up, fix comments, and do unit testing.
 *
 */
#include <stdio.h>
#include "fbtc54.h" 
#include <board.h>
#include "fbcmd.h" 


extern u16 theMessage[];

/* --------------------------
 * EXTERNAL MEMORY ADDRESSING
 *         HELPERS
 * --------------------------
 */

	/* Used by the checksum calculator funcs.
	 */
static unsigned long cksum = 0;

	/* Non-zero if flash is erasing.
	 * Changes to zero when we determine
	 * that erasure is complete.
	 */
static int ErsStatus = 0;

    /* flashstart and flashnext are used to track
     * where we are in a "flat" Flash memory.
     * Paging, etc. are handled by helper funcs.
     * flashbaseoverride is 0 normally, but changes
     * if Host sends the Change FLASHSTART Address command.
     * Thus if it's not 0xffffffff, then it should be used
     * instead of the FLBASE value. 
     */  
static unsigned long flashstart = FLBASE;
static unsigned long flashnext =  FLBASE;

	/* These are "override" values, in case the
	 * Host has sent new flash base addr and size.
	 */
static unsigned long flashbaseov = 0xffffffffL;
static unsigned long flashsizeov = 0xffffffffL;

/* Set and get the flash base address
 */
void SetFlashBase(unsigned long val)
{
	flashbaseov = val;
}

unsigned long GetFlashBase(void)
{
	return flashbaseov != 0xffffffffL ? flashbaseov : FLBASE;
}

/* Set and get the flash size
 */
void SetFlashSize(unsigned long val)
{
	flashsizeov = val;
}

unsigned long GetFlashSize(void)
{
	return flashsizeov != 0xffffffffL ? flashsizeov : FLSIZEBYTES;
}

/* Set the External Memory Page Register
 */
void SetPage(u16 pnum)
{
	port2 =  pnum & 0x1f;
}


/* Flash memory addressing on the 54x
 * ----------------------------------
 * Pages are 32K words, starting at 0x8000.
 * Comm Protocol uses a logical address in a
 * "flat" address space. Host also uses
 * 8-bit byte counts instead of word counts.
 *
 * Thus when Host wants 256 bytes written at
 * logical address 0x20004, we need to convert
 * from 0x20004 to page and address within page:
 * 0x20004 = Page 4, addr 4
 */

/* Returns page number given "flat" address.
 */
u16 GetPageNum(unsigned long addr)
{
	return (u16)((addr - GetFlashBase()) / FLPAGELEN);
}

/* Returns the on-page address for a given "flat" address.
 */
u16 *GetPageAddr(unsigned long addr)
{
	unsigned long myoffset = addr - GetFlashBase();
	
	return (u16 *)(GetFlashBase() + (myoffset % FLPAGELEN));
}

/* Returns the remaining # of MAUs
 * on the page for a given "flat" address.
 */
u16 GetPageMAURemaining(unsigned long addr)
{
	unsigned long myoffset = addr - GetFlashBase();

	return FLPAGELEN - (myoffset % FLPAGELEN);
}


/* --------------------------------
 * Flash memory handlers
 * --------------------------------
 */
void InitFlash(void)
{
	flashstart = GetFlashBase();
	flashnext = flashstart;
}

void SetFlashAddr(unsigned long addr)
{
	flashstart = addr;
	flashnext = flashstart;
}


volatile u16 *GetNextFlashAddr(void)
{
	return (volatile u16 *)flashnext;
}

/* Flash is accesed via external memory
 * pages.
 * For the STMicro Flash (M29W400),
 * we must program 1 word at a time.
 */
void BurnFlash(u16 *data, u16 nBytes)
{
	/* Convenient pointers for sending
	 * commands to flash chip.
	 */
	volatile u16 *p5 = (u16 *)(GetFlashBase()+0x5555UL);
	volatile u16 *pA = (u16 *)(GetFlashBase()+0x2AAAUL);

	volatile u16 *pBurn;
	u16 page, pagelast;
	unsigned long timeoutcount;
	int nWords = nBytes >> 1;

	if(nWords <= 0)
		return;
		
	/* Set paging and enable flash access
	 */	
	page = GetPageNum(flashnext);
	pagelast = GetPageNum(flashnext + nWords - 1);
  			
	FlashEnable();

	if(pagelast == page)
	{
		/* All words to be written are
		 * within the same page.
		 */
		pBurn = GetPageAddr(flashnext);
		flashnext += nWords; /* For next time */

		while(nWords-- > 0)
		{
			SetPage(0);
			
			*p5 = 0xaa;
			*pA = 0x55;
			*p5 = 0xa0;

			SetPage(page);
			*pBurn = *data;
            
            timeoutcount = 0;
			do timeoutcount += 1;
			while(*pBurn != *data && timeoutcount < 0xffff);						
            
            if(timeoutcount == 0xffff)
            	break;
            	
			pBurn++;
			data++;
		}
	}
	else
	{
		/* Programming crosses at least
		 * one page boundary.
		 */
		while(nWords-- > 0)
		{
			page = GetPageNum(flashnext);
			pBurn = GetPageAddr(flashnext);
			SetPage(0);
			
			*p5 = 0xaa;
			*pA = 0x55;
			*p5 = 0xa0;

			SetPage(page);
			*pBurn = *data;

			timeoutcount = 0;
			do timeoutcount += 1;
			while(*pBurn != *data && timeoutcount != 0xffff);						
            if(timeoutcount == 0xffff)
            	break;

			data++;
			flashnext++;
		}
	}
  
	SetPage(0);
	FlashDisable();
}


void CheckFlashErase(void)
{
	while(ErsStatus != 0)
	{
		FlashEnable();
		SetPage(0);
		if(*((u16 *)GetFlashBase()) == 0xffff)
		{
			ErsStatus = 0;
		}
		FlashDisable();
	}
}

void EraseFlash(void)
{
	volatile u16 *p5 = (u16 *)(GetFlashBase()+0x5555UL);
	volatile u16 *pA = (u16 *)(GetFlashBase()+0x2AAAUL);

	InitFlash();

	/* Set page to 0 and enable flash access
	 */	
	FlashEnable();
	SetPage(0);

	/* Erase chip
	 * It takes about 2.5 secs for this,
	 * according to specs for the STMicro
	 * M29W400. 
	 */
	*p5 = 0xAA;
	*pA = 0x55;
	*p5 = 0x80;
	*p5 = 0xAA;
	*pA = 0x55;
	*p5 = 0x10;
	
	FlashDisable();

 	ErsStatus = 1;
	
	CheckFlashErase();  // returns when erase is done
}


/* This is not used by FlashBurn. In fact, it hasn't
 * even been tested...
 */ 
void EraseFlashSector(u16 sector)
{
	volatile u16 *p5 = (u16 *)(GetFlashBase()+0x5555UL);
	volatile u16 *pA = (u16 *)(GetFlashBase()+0x2AAAUL);
	volatile u16 *pBase = (u16 *)GetFlashBase();
	unsigned long timeoutcount;

    if(sector > 7)
        return;
    
	InitFlash();

	/* Set page to 0 and enable flash access
	 */	
	FlashEnable();
	SetPage(0);

	/* Erase sector
	 * It takes about ?? secs for this,
	 * according to specs for the STMicro
	 * M29W400. 
	 */
	*p5 = 0xAA;
	*pA = 0x55;
	*p5 = 0x80;
	*p5 = 0xAA;
	*pA = 0x55;
	
	SetPage(sector);
	
	*pBase = 0x30;

	/* Simpleminded (and possibly dangerous)
	 * delay to wait for erasure to complete.
	 */
    timeoutcount = 0;
	do
	{
		timeoutcount += 1;
	}
	while(*pBase != 0xffff && timeoutcount < 0xfffff);						

	SetPage(0);
	FlashDisable();
	
	return;
}
 

/* ------------------
 * Checksum Functions
 * ------------------
 */
void CKSSet(u16 val)
{
	cksum = val;
}
	
u16 CKSGet(void)
{
	return (u16)cksum;
}

	/* bufptr is start address in flash memory,
	 * len is length in 8-bit Bytes!
	 */	
u16 CKSAccumBuf(unsigned long bufptr, unsigned long len)
{
	u16 page;
	u16 *pPage;
	long n;
	len /= BYTESPERMAU;  // MAUs
	
	while(len > 0)
	{
		/* How many bytes can I read from this page?
		 */	
		page = GetPageNum(bufptr);
		n = GetPageMAURemaining(bufptr);
		if(n > len)
		{
			n = len;
		}
		len -= n;    /* for next time thru */ 
	
		/* Set paging and enable flash access
		 */
		pPage = GetPageAddr(bufptr);
		bufptr += n;

		SetPage(page);
		FlashEnable();

		/* Accumulate bytes into the checksum
		 */
		while(n-- > 0)
		{
			unsigned long val = *pPage++;
			cksum += val >> 8;          //MSB
			if(cksum >= 65536)
			{
				cksum += 1;
				cksum &= 0xffff;
			} 
			cksum += val & 0x000000ff;  // LSB
			if(cksum >= 65536)
			{
				cksum += 1;
				cksum &= 0xffff;
			} 
		}
            
        SetPage(0);
	    FlashDisable();
	}
	return (u16)cksum;
}


u16 GetFlashVal(unsigned long addr)
{
	u16 myval;
	
	FlashEnable();
	SetPage(GetPageNum(addr));
	myval = *GetPageAddr(addr);
	FlashDisable();
	
	return myval;
}

void SendFlashBufToHost(u16 cmd, unsigned long addr, u16 bytecount)
{
	u16 *pagememptr;
	u16 pagestart, pagelast;
	u16 i, n;

	pagestart = GetPageNum(addr);
	pagelast = GetPageNum(addr+bytecount/BYTESPERMAU-1);

	// Prepare the response message header
	theMessage[CMDINDEX] = cmd;     
	theMessage[ARGINDEX+0] = bytecount;

	FlashEnable();
	if(pagestart == pagelast)
	{
		// All desired data are in same page.
		SetPage(pagestart);
		pagememptr = GetPageAddr(addr);
		n = bytecount / 2;
		for(i=0; i<n; i+=1)
		{
			theMessage[DATAINDEX+i] = *pagememptr++;
	    }
	}
	else
	{
		// Desired data cross at least one
		// page boundary
		u16 len = bytecount / 2;
		u16 n;
		u16 *dataptr; 

		dataptr = &theMessage[DATAINDEX];     

		while(len > 0)
		{
			/* How many bytes can I read from this page?
			 */	
			pagestart = GetPageNum(addr);
			n = GetPageMAURemaining(addr);
			if(n > len)
			{
				n = len;
			}
			len -= n;    /* for next time thru */ 
		
			/* Set paging and enable flash access
			 */
			pagememptr = GetPageAddr(addr);
			addr += n;  /* also for next time thru */
	
			SetPage(pagestart);	
			while(n-- > 0)
			{
				*dataptr++ = *pagememptr++;
			}
		}
	}
	
	SetPage(0);
	FlashDisable();
}

⌨️ 快捷键说明

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