📄 fburncmd.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 + -