📄 amd29lv800tmem.c
字号:
/* amd29LV800TMem.c - AMD 29LV800T Flash Memory library *//* Copyright 1984-2001 Wind River Systems, Inc. *//*modification history--------------------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*//*DESCRIPTIONThis 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 theaddress 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 "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); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -