original files of m241
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
/* amd29LV800TMem.c - AMD 29LV800T Flash Memory library */
|
||||
|
||||
/* Copyright 1984-2004 Wind River Systems, Inc. */
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01d,13may04,rec move from wrPpmc74xx bsp to drivers
|
||||
01c,22jun01,g_h move sysNvRamGet & sysNvRamSet to sysNvRam.c and make
|
||||
amd29LV800TWrite() , amd29LV800TEraseBlock() & amd29LV800TEraseSector()
|
||||
global.
|
||||
01b,23may01,pch Fix initializations of rmasks[] and lmasks[]
|
||||
01a,22apr01,g_h written
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This library contains routines to manipulate AMD 29LV800T Flash memory.
|
||||
Read and write routines are included.
|
||||
|
||||
The macros NV_RAM_ADRS and NV_RAM_SIZE must be defined to indicate the
|
||||
address and size of the Flash memory.
|
||||
|
||||
This module use the visionWare flash algorithm.
|
||||
|
||||
The AMD 29LV800 access is BITS:16 BUS:64 BOOT:TOP ACCESS:DOUBLE.
|
||||
|
||||
INCLUDES: amd29LV800TMem.h
|
||||
*/
|
||||
|
||||
/* includes */
|
||||
#include "drv/mem/amd29LV800TMem.h"
|
||||
#include "memLib.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
/* locals */
|
||||
LOCAL void iOSync(void){ }
|
||||
|
||||
LOCAL const tFLASH unlock1 = {{ 0xAA00AA, 0xAA00AA }};
|
||||
LOCAL const tFLASH unlock2 = {{ 0x550055, 0x550055 }};
|
||||
LOCAL const tFLASH erase1 = {{ 0x800080, 0x800080 }};
|
||||
LOCAL const tFLASH erase2 = {{ 0x300030, 0x300030 }};
|
||||
LOCAL const tFLASH program = {{ 0xA000A0, 0xA000A0 }};
|
||||
LOCAL const tFLASH readArray = {{ 0xF000F0, 0xF000F0 }};
|
||||
LOCAL const tFLASH erased = {{ (UINT32)-1, (UINT32)-1 }};
|
||||
|
||||
LOCAL const tFLASH rmasks[] = {
|
||||
{{0xffffffff, 0xffffffff}},
|
||||
{{0xffffffff, 0xffffff00}},
|
||||
{{0xffffffff, 0xffff0000}},
|
||||
{{0xffffffff, 0xff000000}},
|
||||
{{0xffffffff, 0x00000000}},
|
||||
{{0xffffff00, 0x00000000}},
|
||||
{{0xffff0000, 0x00000000}},
|
||||
{{0xff000000, 0x00000000}},
|
||||
};
|
||||
LOCAL const tFLASH lmasks[] = {
|
||||
{{0xffffffff, 0xffffffff}},
|
||||
{{0x00ffffff, 0xffffffff}},
|
||||
{{0x0000ffff, 0xffffffff}},
|
||||
{{0x000000ff, 0xffffffff}},
|
||||
{{0x00000000, 0xffffffff}},
|
||||
{{0x00000000, 0x00ffffff}},
|
||||
{{0x00000000, 0x0000ffff}},
|
||||
{{0x00000000, 0x000000ff}},
|
||||
};
|
||||
|
||||
LOCAL tBLOCK blocks[] = {
|
||||
{ 15, 256 },
|
||||
{ 1, 128 },
|
||||
{ 2, 32 },
|
||||
{ 1, 64 }
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* amd29LV800TWrite - write data to the AMD 29LV800T
|
||||
*
|
||||
* This routine write given data to the AMD 29LV800T FLASH device.
|
||||
*
|
||||
* RETURNS: Number of byte writen
|
||||
*
|
||||
* SEE ALSO: amd29LV800TEraseBlock(), amd29LV800TEraseSector()
|
||||
*/
|
||||
|
||||
UINT32 amd29LV800TWrite
|
||||
(
|
||||
volatile UINT8 * pDest,
|
||||
UINT8 * pSource,
|
||||
UINT32 length
|
||||
)
|
||||
{
|
||||
unsigned int originalLength = length;
|
||||
UINT64 mask;
|
||||
tFLASH data;
|
||||
unsigned short n;
|
||||
|
||||
volatile UINT8 *pChip = (volatile UINT8 *)((unsigned int)pDest & ~(0x400000 - 1));
|
||||
|
||||
while (length)
|
||||
{
|
||||
n = ((unsigned int)pDest & (8 - 1));
|
||||
mask = lmasks[n].Integer;
|
||||
|
||||
if ((n + length) < 8)
|
||||
mask &= rmasks[n + length].Integer;
|
||||
|
||||
data.Integer = readUnaligned(pSource) & mask;
|
||||
data.Integer |= *(UINT64 *)pDest & (~mask);
|
||||
pSource += 8;
|
||||
|
||||
*(volatile DOUBLE *)(pChip + 0x2AAA8) = unlock1.Float;
|
||||
iOSync();
|
||||
*(volatile DOUBLE *)(pChip + 0x15550) = unlock2.Float;
|
||||
iOSync();
|
||||
*(volatile DOUBLE *)(pChip + 0x2AAA8) = program.Float;
|
||||
iOSync();
|
||||
*(volatile DOUBLE *)pDest = data.Float;
|
||||
|
||||
while (*(volatile UINT64 *)pDest != data.Integer);
|
||||
|
||||
pDest += 8;
|
||||
length -= min(8 - n, length);
|
||||
}
|
||||
|
||||
*(volatile DOUBLE *)(pDest - 8) = readArray.Float;
|
||||
return originalLength - length;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* amd29LV800TEraseBlock - erase block in the AMD 29LV800T
|
||||
*
|
||||
* This routine erase a block in the AMD 29LV800T FLASH device.
|
||||
*
|
||||
* RETURNS: OK
|
||||
*
|
||||
* SEE ALSO: amd29LV800TWrite(), amd29LV800TEraseSector()
|
||||
*/
|
||||
|
||||
UINT32 amd29LV800TEraseBlock
|
||||
(
|
||||
volatile UINT8 *pChip,
|
||||
volatile UINT8 *pSector
|
||||
)
|
||||
{
|
||||
*(volatile DOUBLE *)(pChip + 0x2AAA8) = unlock1.Float;
|
||||
iOSync();
|
||||
*(volatile DOUBLE *)(pChip + 0x15550) = unlock2.Float;
|
||||
iOSync();
|
||||
*(volatile DOUBLE *)(pChip + 0x2AAA8) = erase1.Float;
|
||||
iOSync();
|
||||
*(volatile DOUBLE *)(pChip + 0x2AAA8) = unlock1.Float;
|
||||
iOSync();
|
||||
*(volatile DOUBLE *)(pChip + 0x15550) = unlock2.Float;
|
||||
iOSync();
|
||||
*(volatile DOUBLE *)pSector = erase2.Float;
|
||||
iOSync();
|
||||
|
||||
while (*(volatile UINT64 *)pSector != erased.Integer);
|
||||
|
||||
*(volatile DOUBLE *)pSector = readArray.Float;
|
||||
|
||||
return (OK);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* amd29LV800TEraseSector - erase sector in the AMD 29LV800T
|
||||
*
|
||||
* This routine erase sector in the AMD 29LV800T FLASH device.
|
||||
*
|
||||
* RETURNS: OK
|
||||
*
|
||||
* SEE ALSO: amd29LV800TWrite(), amd29LV800TEraseBlock()
|
||||
*/
|
||||
|
||||
UINT32 amd29LV800TEraseSector
|
||||
(
|
||||
volatile UINT8 *pSector
|
||||
)
|
||||
{
|
||||
int i, j;
|
||||
volatile UINT8 *pChip = (volatile UINT8 *)((unsigned int)pSector & ~(0x400000 - 1));
|
||||
UINT32 n = pSector - pChip;
|
||||
|
||||
for (i = 0; i < BLOCKS; ++i)
|
||||
{
|
||||
if (n >= (blocks[i].Number * blocks[i].Size * 1024))
|
||||
n -= (blocks[i].Number * blocks[i].Size * 1024);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
j = blocks[i].Number;
|
||||
n = 0x40000;
|
||||
while (n)
|
||||
{
|
||||
amd29LV800TEraseBlock (pChip, pSector);
|
||||
pSector += blocks[i].Size * 1024;
|
||||
n -= blocks[i].Size * 1024;
|
||||
if (!--j)
|
||||
{
|
||||
j = blocks[++i].Number;
|
||||
}
|
||||
}
|
||||
|
||||
return (OK);
|
||||
}
|
||||
Reference in New Issue
Block a user