📄 intel_c3_flash.c
字号:
/*
* File: intel_c3_flash.c
* Purpose: Flash driver for programming Intel Flash devices
*
* Notes: This driver supports a single banks of Intel Flash.
* A bank is defined as one or more of the same Flash
* device connected to a single chip-select.
*/
#include "src/include/dbug.h"
/*
* Compiler specific code relocation section
*/
#ifdef __DCC__
#pragma section CODE ".code_relocation"
#pragma section CONST ".code_relocation"
#elif (defined(__ghs__))
#pragma ghs section text=".code_relocation"
#endif
#include "src/dev/flash/intel_c3_flash.h"
/********************************************************************/
/*
* Global pointer to base of Intel Flash device
*/
#ifdef __MWERKS__
__relocate_data__
#endif
static INTEL_C3_FLASH_CELL *pFlash;
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
void
intel_c3_flash_init(ADDRESS base)
{
pFlash = (INTEL_C3_FLASH_CELL *)base;
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
void
intel_c3_flash_unlock(ADDRESS start, int bytes)
{
int i, unlocked = 0;
if (bytes == 0)
return;
for (i = 0; i < INTEL_C3_FLASH_SECTORS; i++)
{
if (start >= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i)) &&
start <= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i) + (C3_SSIZE(i) - 1)))
{
break;
}
}
bytes += ((int)start - (int)((ADDRESS)pFlash + C3_SOFFSET(i)));
while (unlocked < bytes)
{
/*
* Unlock Block command
*/
pFlash[C3_SADDR(i)] = INTEL_C3_FLASH_CMD_DATA(0x60);
pFlash[C3_SADDR(i)] = INTEL_C3_FLASH_CMD_DATA(0xD0);
unlocked += C3_SSIZE(i);
i++;
}
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
void
intel_c3_flash_lock(ADDRESS start, int bytes)
{
int i, locked = 0;
if (bytes == 0)
return;
for (i = 0; i < INTEL_C3_FLASH_SECTORS; i++)
{
if (start >= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i)) &&
start <= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i) + (C3_SSIZE(i) - 1)))
{
break;
}
}
bytes += ((int)start - (int)((ADDRESS)pFlash + C3_SOFFSET(i)));
while (locked < bytes)
{
/*
* Lock Block command
*/
pFlash[C3_SADDR(i)] = INTEL_C3_FLASH_CMD_DATA(0x60);
pFlash[C3_SADDR(i)] = INTEL_C3_FLASH_CMD_DATA(0x01);
locked += C3_SSIZE(i);
i++;
}
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
void
intel_c3_flash_sector_erase(int n)
{
INTEL_C3_FLASH_CELL status;
/*
* Erase Block command
*/
pFlash[C3_SADDR(n)] = INTEL_C3_FLASH_CMD_DATA(0x20);
pFlash[C3_SADDR(n)] = INTEL_C3_FLASH_CMD_DATA(0xD0);
/*
* Wait for the erase operation to finish
*/
do
{
pFlash[C3_SADDR(n)] = INTEL_C3_FLASH_CMD_DATA(0x70);
status = pFlash[C3_SADDR(n)];
}
while (!(status & INTEL_C3_FLASH_CMD_DATA(0x80)));
/*
* Place back in normal read mode
*/
pFlash[C3_SADDR(n)] = INTEL_C3_FLASH_CMD_DATA(0xFF);
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
int
intel_c3_flash_erase(ADDRESS start, int bytes, void (*putchar)(char))
{
int i, ebytes = 0;
if (bytes == 0)
return 0;
/*
* Unlock the required blocks
*/
intel_c3_flash_unlock(start, bytes);
for (i = 0; i < INTEL_C3_FLASH_SECTORS; i++)
{
if (start >= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i)) &&
start <= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i) + (C3_SSIZE(i) - 1)))
{
break;
}
}
bytes += ((int)start - (int)((ADDRESS)pFlash + C3_SOFFSET(i)));
while (ebytes < bytes)
{
if (putchar != NULL)
{
putchar('.');
}
intel_c3_flash_sector_erase(i);
ebytes += C3_SSIZE(i);
i++;
}
if (putchar != NULL)
{
putchar(10); /* LF */
putchar(13); /* CR */
}
/*
* Lock up
*/
intel_c3_flash_lock(start, bytes);
return ebytes;
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
void
intel_c3_flash_program_cell(INTEL_C3_FLASH_CELL *dst, INTEL_C3_FLASH_CELL data)
{
INTEL_C3_FLASH_CELL status;
*dst = INTEL_C3_FLASH_CMD_DATA(0x40);
*dst = data;
/*
* Wait for program operation to finish
*/
do
{
*dst = INTEL_C3_FLASH_CMD_DATA(0x70);
status = *dst;
}
while (!(status & INTEL_C3_FLASH_CMD_DATA(0x80)));
/*
* Place back in normal read mode
*/
*dst = INTEL_C3_FLASH_CMD_DATA(0xFF);
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
int
intel_c3_flash_program(ADDRESS dest, ADDRESS source,
int bytes, int erase,
void (*func)(void),
void (*putchar)(char))
{
INTEL_C3_FLASH_CELL *src, *dst;
int hashi=1,hashj=0;
char hash[5];
hash[0]=8; /* Backspace */
hash[1]=124;/* "|" */
hash[2]=47; /* "/" */
hash[3]=45; /* "-" */
hash[4]=92; /* "\" */
src = (INTEL_C3_FLASH_CELL *)source;
dst = (INTEL_C3_FLASH_CELL *)dest;
/*
* Erase device if necessary
*/
if (erase)
{
intel_c3_flash_erase(dest, bytes, putchar);
}
/*
* Unlock the required blocks
*/
intel_c3_flash_unlock(dest, bytes);
/*
* Program device
*/
while (bytes > 0)
{
intel_c3_flash_program_cell(dst,*src);
/* Verify Write */
if (*dst == *src)
{
bytes -= INTEL_C3_FLASH_CELL_BYTES;
*dst++, *src++;
if ((putchar != NULL))
{
/* Hash marks to indicate progress */
if (hashj == 0x1000)
{
hashj = -1;
putchar(hash[0]);
putchar(hash[hashi]);
hashi++;
if (hashi == 5)
{
hashi=1;
}
}
hashj++;
}
}
else
break;
}
if (putchar != NULL)
{
putchar(hash[0]);
}
/*
* Leaving now - lock up
*/
intel_c3_flash_lock(dest, bytes);
/*
* If a function was passed in, call it now
*/
if ((func != NULL))
{
func();
}
return ((int)src - (int)source);
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
ADDRESS
intel_c3_flash_sector_start(ADDRESS addr)
{
/*
* Returns beginning of sector containing addr
*/
int i;
for (i = 0; i < INTEL_C3_FLASH_SECTORS; i++)
{
if (addr >= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i)) &&
addr <= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i) + (C3_SSIZE(i) - 1)))
{
return (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i));
}
}
return NULL;
}
/********************************************************************/
#ifdef __MWERKS__
__relocate_code__
#endif
ADDRESS
intel_c3_flash_sector_end(ADDRESS addr)
{
/* Returns end of sector containing ADDRESS */
int i;
for (i = 0; i < INTEL_C3_FLASH_SECTORS; i++)
{
if (addr >= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i)) &&
addr <= (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i) + (C3_SSIZE(i) - 1)))
{
return (ADDRESS)((ADDRESS)pFlash + C3_SOFFSET(i) + (C3_SSIZE(i) - 1));
}
}
return NULL;
}
/********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -