📄 cfm_flash.c
字号:
/*
* File: cfm_flash.h
* Purpose: Flash driver for programming the ColdFire Flash Module
*
* Notes: Based on the SSD CFM driver
*
*/
#include "dbug.h"
#include "flash/cfm_flash.h"
/*
* Compiler specific code relocation section
*/
#ifdef __DCC__
#pragma section CODE ".code_relocation"
#pragma section CONST ".code_relocation"
#endif
/*
* These settings are constant for all current ColdFire
* devices with CFM. The BSP must define __IPSBAR and
* CFM_FLASH_ADDRESS
*/
__relocate_const__
CFM_CONFIG config =
{
(uint32)(&__IPSBAR[0x001D0000]), /* RegBase */
CFM_FLASH_ADDRESS, /* CoreBusBas */
(uint32)(&__IPSBAR[0x04000000]), /* IPSBase */
CFM_BLOCK_SIZE, /* BlockSize */
CFM_BLOCK_NUM, /* BlockNum */
FALSE, /* ISREnable */
FALSE /* BDMEnable */
};
/********************************************************************/
__relocate_const__
uint32 FlashInit[] =
{
0x2F072F06, 0x598F43D7, 0x7C00206F, 0x00142286, 0x1E280031, 0x74001407,
0x206F0010, 0x02820000, 0x000F222F, 0x00182010, 0x0C820000, 0x000B6E30,
0x0C820000, 0x00016D28, 0x5382343B, 0x2A0848C2, 0x4EFB2800, 0x00180018,
0x0018001E, 0x001E001E, 0x0018001E, 0x00180018, 0x00187404, 0x84862282,
0x227C0000, 0x00207420, 0x13820800, 0x74101382, 0x08002240, 0x24290008,
0x2E3C4000, 0x0000CE82, 0x67047402, 0x85972240, 0x13410002, 0x10290002,
0x74001400, 0x02820000, 0x007F7000, 0x1001B480, 0x67047001, 0x81972028,
0x00186704, 0x20174AC8, 0x20174FEF, 0x00042C1F, 0x2E1F4E75, 0x43463243,
0x464D4649, 0x33303046
};
typedef uint32 (*pINIT)(CFM_CONFIG*, uint32, uint32);
pINIT pFlashInit = (pINIT) FlashInit;
/********************************************************************/
__relocate_const__
uint32 FlashProgram[] =
{
0x4FEFFFE0, 0x48EF50F8, 0x0004262F, 0x002843D7, 0x2003286F, 0x0024282F,
0x00302C6F, 0x00344291, 0x02800000, 0x0003660C, 0x202F002C, 0x02800000,
0x0003670A, 0x2EBC0000, 0x04006000, 0x00E42A14, 0x20451228, 0x00027000,
0x2C051001, 0x06860000, 0x00200280, 0x00000080, 0x660A22BC, 0x00000100,
0x600000BE, 0x323CFFDF, 0x3010C280, 0x30817020, 0x20461080, 0x70101080,
0x202C000C, 0x4C2C0800, 0x00105380, 0xC0832600, 0xD6AC0008, 0x7E00606C,
0x4E962046, 0x12107000, 0x10010280, 0x00000080, 0x67EE2244, 0x20112243,
0x22807020, 0x22451340, 0x0024103C, 0x00801080, 0x58845883, 0x202C0014,
0x66381210, 0x70001001, 0x02800000, 0x00206710, 0x70201080, 0x70101080,
0x2EBC0000, 0x03006040, 0x12107000, 0x10010280, 0x00000010, 0x670C7010,
0x10802EBC, 0x00000200, 0x60265887, 0xBEAF002C, 0x658E202C, 0x00146618,
0x4E962046, 0x12107000, 0x10010280, 0x000000C0, 0x0C800000, 0x00C066E8,
0x202C0018, 0x67042017, 0x4AC82017, 0x4CEF50F8, 0x00044FEF, 0x00204E75,
0x43463243, 0x464D4650, 0x33303046
};
typedef uint32 (*pPROGRAM)(CFM_CONFIG*, uint32, uint32, uint32, void (*)(void));
pPROGRAM pFlashProgram = (pPROGRAM) FlashProgram;
/********************************************************************/
__relocate_const__
uint32 PageErase[] =
{
0x4FEFFFE0, 0x48EF50F8, 0x000443D7, 0x4291286F, 0x00242A14, 0x20452C05,
0x12280002, 0x70001001, 0x06860000, 0x0020262F, 0x0028282F, 0x002C2C6F,
0x00300280, 0x00000080, 0x660A22BC, 0x00000100, 0x600000D6, 0x323CFFDF,
0x3010C280, 0x30817020, 0x20461080, 0x70101080, 0x202C000C, 0x4C2C0800,
0x00100283, 0xFFFFF800, 0x5380C083, 0x2600D6AC, 0x00087E00, 0x606C4E96,
0x22461211, 0x70001001, 0x02800000, 0x008067EE, 0x70FF2043, 0x20807040,
0x20451140, 0x0024103C, 0x00801280, 0x06830000, 0x0800202C, 0x00146638,
0x12117000, 0x10010280, 0x00000020, 0x67107020, 0x12807010, 0x12802EBC,
0x00000300, 0x60521211, 0x70001001, 0x02800000, 0x0010670C, 0x70101280,
0x2EBC0000, 0x02006038, 0x5287BE84, 0x6590202C, 0x0014662C, 0x4E962246,
0x12117000, 0x10010280, 0x000000C0, 0x0C800000, 0x00C066E8, 0x206C0008,
0x70FF2080, 0x206C0008, 0x21400008, 0x70101280, 0x202C0018, 0x67042017,
0x4AC82017, 0x4CEF50F8, 0x00044FEF, 0x00204E75, 0x43463243, 0x464D5045,
0x33313046
};
typedef uint32 (*pERASE)(CFM_CONFIG*, uint32, uint32, void (*)(void));
pERASE pPageErase = (pERASE) PageErase;
/********************************************************************/
/*
* Dummy call-back function
*/
__relocate_code__
void
callback(void)
{
/* dummy */
}
/********************************************************************/
__relocate_code__
void
cfm_flash_init(void)
{
pFlashInit(&config, IPSBAR_ADDRESS, CFMCLKD);
/* Clear the CFM protection register */
MCF_CFM_CFMPROT = 0;
}
/********************************************************************/
__relocate_code__
int
cfm_flash_erase(ADDRESS start, int bytes, void (*putchar)(char))
{
ADDRESS addr;
int n;
if (bytes == 0)
return 0;
addr = cfm_flash_page_start(start);
/* Determine number of pages to erase */
n = bytes;
if (n % PGSZ)
n += PGSZ;
n = n / PGSZ;
if (pPageErase(&config, start, n, callback))
return 0;
return (PGSZ * n);
}
/********************************************************************/
__relocate_code__
int
cfm_flash_program(ADDRESS dest, ADDRESS src, int bytes, int erase,
void (*func)(void), void (*putchar)(char))
{
int i;
uint32 size;
CFM_WORD *s, *d;
(void) putchar;
/* Force bytes to align to CFM word size */
size = (uint32)((bytes + CFM_WORD_MASK) & ~CFM_WORD_MASK);
/* Erase device if necessary */
if (erase)
{
if (cfm_flash_erase(dest, bytes, putchar) < bytes)
return 0;
}
/* Program */
if (pFlashProgram(&config, dest, size, src, callback))
return 0;
/* Verify */
s = (CFM_WORD *)src;
d = (CFM_WORD *)dest;
for (i = 0; i < size; i += CFM_WORD_SIZE)
{
if (*s++ != *d++)
return i;
}
/* Call the callback function if one is given */
if (func != NULL)
func();
return size;
}
/********************************************************************/
/*
* Return beginning of page containing addr
*/
__relocate_code__
ADDRESS
cfm_flash_page_start(ADDRESS addr)
{
int i;
for (i = 0; i < CFM_FLASH_PAGES; i++)
{
if (addr >= (ADDRESS)((int)config.CoreBusBase + PGOFST(i)) &&
addr <= (ADDRESS)((int)config.CoreBusBase + PGOFST(i) + (PGSZ - 1)))
{
return (ADDRESS)((int)config.CoreBusBase + PGOFST(i));
}
}
return NULL;
}
/********************************************************************/
/*
* Return end of page containing addr
*/
__relocate_code__
ADDRESS
cfm_flash_page_end(ADDRESS addr)
{
int i;
for (i = 0; i < CFM_FLASH_PAGES; i++) {
if (addr >= (ADDRESS)((int)config.CoreBusBase + PGOFST(i)) &&
addr <= (ADDRESS)((int)config.CoreBusBase + PGOFST(i) + (PGSZ - 1)))
{
return (ADDRESS)((int)config.CoreBusBase + PGOFST(i) + (PGSZ - 1));
}
}
return NULL;
}
/********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -