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

📄 fburncmd.c

📁 ti dsp 6211 的BOOT程序。利用此程序实现将代码写入到FLASH 的功能。
💻 C
字号:
/*********************************************************************
 *          (C) COPYRIGHT TEXAS INSTRUMENTS, INC. 2000, 2001
 * FlashBurn Programming Functions
 *     for FBTC62
 */

/*
 * $Log: FBurnCmd.c,v $
 * Revision 1.12  2001/09/18 18:51:39  heeschen
 * v01.10 update: corrected a bug which made
 * programming time longer than it needed to be.
 *
 * Revision 1.11  2001/04/23 15:52:30  heeschen
 * v00.30 Alpha -- fixed bug found in unit test:
 * there was a problem with burning partial sectors.
 * The bug was introduced when I redesigned the
 * comm. scheme to eliminate RTDX. All is OK now.
 *
 * Revision 1.10  2001/04/19 18:57:04  heeschen
 * v00.30 Alpha - Updated comments
 *
 *
 */

#include <stdio.h>
#include "type.h"
#include "c6211dsk.h"
#include "FBTC62.h"
#include "FBCmd.h"



	/* Local prototype
	 */
static void BurnSector(u8 *data);
static GetFlashBuf(u8 *dest, u8 *flashsrc, u16 nBytes);

	/* Used by the checksum calc functions
	 */
static volatile unsigned long cksum = 0;

    /* flashstart/next are used to track
     * where we are in a "flat" Flash memory.
     * Paging, etc. are handled by helper
     * funcs.
     */  
static volatile u8 *flashstart = (volatile u8 *)FLASH_START;
static volatile u8 *flashnext  = (volatile u8 *)FLASH_START;

	/* These are "override" values, in case the
	 * Host has sent new flash base addr and size.
     * flashbaseov is 0xffffffff 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 FLASH_START value. 
	 */
static volatile u8 *flashbaseov = (u8 *)0xffffffffUL;
static unsigned long flashsizeov =  0xffffffffUL;


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

volatile u8 *GetFlashBase(void)
{
	return flashbaseov != (volatile u8 *)0xffffffffL ?
	                      flashbaseov :
	                      (volatile u8 *)FLASH_START;
}

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

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

void InitFlash(void)
{
	flashstart = GetFlashBase();
	flashnext = flashstart;
}

void SetFlashAddr(u8 *addr)
{
	flashstart = (volatile u8 *)addr;
	flashnext = flashstart;
}


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


/* Burns flash data, starting at flashnext.
 */
void BurnFlash(u8 *data, u16 nBytes)
{
	u8 mybuf[FLASH_WRITE_SIZE];
	unsigned long faddrLong = (unsigned long)flashnext;

	/* If next flash addr. is not aligned on
	 * sector boundary,
	 * then do a read/modify/write of
	 * the current sector addressed by flashnext.
	 * This will get the 1st several bytes of
	 * data into flash.
	 */	
	if((faddrLong % FLASH_WRITE_SIZE) != 0)
	{
	    u8 *pflash = (u8 *)((faddrLong / FLASH_WRITE_SIZE) * FLASH_WRITE_SIZE);
	    u16 n = FLASH_WRITE_SIZE - (faddrLong % FLASH_WRITE_SIZE);
	    
	    n = n > nBytes ? nBytes : n;

		/* Get flash sector
		 */	    
	    GetFlashBuf(mybuf, pflash, FLASH_WRITE_SIZE);
	    /* Copy the data into the right place
	     */
	    memcpy(&mybuf[faddrLong % FLASH_WRITE_SIZE], data, n);
		/* erase / burn the sector again
		 */
		flashnext = pflash;
		BurnSector(&mybuf[0]);
			    
	    /* Update the data & flash pointers.
	     */
	    data += n;
	    nBytes -= n;
	}

	/* Write whole sectors at a time if I can
	 */	
	while(nBytes >= FLASH_WRITE_SIZE)
	{
		BurnSector(data);
		data += FLASH_WRITE_SIZE;
		nBytes -= FLASH_WRITE_SIZE;
	}

	/* Do another read/mod/write thing to take care
	 * of stragglers.
	 * We can assume that flashnext is aligned on a
	 * sector boundary, and that nBytes < sector size
	  */
	if(nBytes > 0)
	{
		/* Get flash sector
		 */	    
	    GetFlashBuf(mybuf, (u8 *)flashnext, FLASH_WRITE_SIZE);
	    /* Copy some data into the right place
	     */
	    memcpy(&mybuf[0], data, nBytes);
		/* erase / burn the sector again
		 */
		BurnSector(&mybuf[0]);
	}
}

/* Writes one sector of bytes to
 * flash, starting at data.
 * nBytes is the actual count of data bytes
 * to write. If n %128 is not 0, then
 * the remainder is padded with zeros.
 */
static void BurnSector(u8 *data)
{
	/* Snapshot EMIF global reg.
	 */
	unsigned volatile int myemif = *(unsigned volatile int *)EMIF_CE1;
	u8 *src_ptr = data;
	u16 timeout;
	u8 c;
		
	/* Code to prep ATMEL AT29LV010A
	 * 1MBit (128K X 8) Flash Memory
	 * for writing 128 bytes.
	 */
    /* Set External Flash for byte-addressability
     */
    *(unsigned volatile int *)EMIF_CE1 = CE1_8; /* EMIF CE1 control, 8bit async */

	*(volatile char *)FLASH_ADR1 = (char)FLASH_KEY1;
	*(volatile char *)FLASH_ADR2 = (char)FLASH_KEY2;
	*(volatile char *)FLASH_ADR1 = (char)FLASH_KEY3;

	/* Must burn 128 bytes for this to work.
	 */		
	memcpy((void *)flashnext, src_ptr, FLASH_WRITE_SIZE);
	flashnext += FLASH_WRITE_SIZE - 1;
	src_ptr += FLASH_WRITE_SIZE - 1;
	
	/* Spin here 'til programming completes
	 */
	c = *src_ptr++;
	timeout = 0;
	do timeout += 1;
	while(*flashnext != c && timeout < (u16)0xffff);
	
	flashnext++;
	
	/* Burn of 128 bytes should now be complete.
	 */
    /* Restore EMIF global reg.
     */
    *(unsigned volatile int *)EMIF_CE1 = myemif; /* EMIF CE1 control, 32bit async */
}


/* The Flash Erase function uses
 * the ATMEL algorithm to erase the
 * entire chip.
 */

void EraseFlash(void)
{
	/* Snapshot EMIF global reg.
	 */
	unsigned volatile int myemif = *(unsigned volatile int *)EMIF_CE1;
	u16 timeout;
			
	/* Code to erase ATMEL AT29LV010A
	 * 1MBit (128K X 8) Flash Memory
	 */
    /* Set External Flash for byte-addressability
     */
    *(unsigned volatile int *)EMIF_CE1 = CE1_8; /* EMIF CE1 control, 8bit async */

	*(volatile char *)FLASH_ADR1 = (char)FLASH_KEY1;
	*(volatile char *)FLASH_ADR2 = (char)FLASH_KEY2;
	*(volatile char *)FLASH_ADR1 = (char)FLASH_KEY4;

	*(volatile char *)FLASH_ADR1 = (char)FLASH_KEY1;
	*(volatile char *)FLASH_ADR2 = (char)FLASH_KEY2;
	*(volatile char *)FLASH_ADR1 = (char)FLASH_KEY5;
	
	/* Spin here 'til erasing completes
	 * ATLMEL docs tell me that 20 millisecs
	 * will do the trick. I will just spin for a
	 * little while here, and assume that ample time
	 * is consumed by Host/DSP communications.
	 */
	timeout = 0;
	do timeout += 1;
	while(timeout != 0xffff);
	
    /* Restore EMIF global reg.
     */
    *(unsigned volatile int *)EMIF_CE1 = myemif; /* EMIF CE1 control, 32bit async */
		
	return;
}

void CKSSet(u16 val)
{
	cksum = val;
}
	
u16 CKSGet(void)
{
	return (u16)cksum;
}
		
u16 CKSAccumBuf(unsigned char *buf, unsigned int len)
{
    /* Set External Flash for byte-addressability
     */
    *(unsigned volatile int *)EMIF_CE1 = CE1_8; /* EMIF CE1 control, 8bit async */
   
	while(len-- > 0)
	{
		cksum += *buf++;
		if(cksum > (unsigned long)0x0000ffff)
		{
			cksum += 1;
			cksum &= (unsigned long)0x0000ffff;
		} 
	}
    /* Set External Flash for word-addressability
     */
    *(unsigned volatile int *)EMIF_CE1 = CE1_32; /* EMIF CE1 control, 32bit async */
	
	return (u16)cksum;
}


u8 GetFlashVal(unsigned long addr)
{
	u8 myval;
	
    /* Set External Flash for byte-addressability
     */
    *(unsigned volatile int *)EMIF_CE1 = CE1_8; /* EMIF CE1 control, 8bit async */
	myval = *(u8 *)addr ;
    *(unsigned volatile int *)EMIF_CE1 = CE1_32; /* EMIF CE1 control, 32bit async */
	
	return myval;
}

void SendFlashBufToHost(u16 cmd, unsigned long addr, u16 bytecount)
{
    u8 *pflash = (u8 *)addr;
    u16 n = bytecount > 256 ? 256 : bytecount;

	StoreCmd(cmd);     
	StoreArg(0, bytecount);	
    
	GetFlashBuf(GetData(), pflash, n);
}

static GetFlashBuf(u8 *dest, u8 *flashsrc, u16 nBytes)
{
    *(unsigned volatile int *)EMIF_CE1 = CE1_8; /* EMIF CE1 control, 8bit async */
	memcpy(dest, flashsrc, nBytes);
    *(unsigned volatile int *)EMIF_CE1 = CE1_32; /* EMIF CE1 control, 32bit async */
}

⌨️ 快捷键说明

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