Files
m241Neelima/vxworks-6.9/target/src/drv/mem/amd29LV800TMem.c
T
2026-07-30 11:19:44 +05:30

209 lines
5.1 KiB
C

/* 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);
}