📄 flashspecificttr.c
字号:
/*
* COPYRIGHT (c) 1995,2000 TriMedia Technologies Inc.
*
* +-----------------------------------------------------------------+
* | THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED |
* | AND COPIED IN ACCORDANCE WITH THE TERMS AND CONDITIONS OF SUCH |
* | A LICENSE AND WITH THE INCLUSION OF THE THIS COPY RIGHT NOTICE. |
* | THIS SOFTWARE OR ANY OTHER COPIES OF THIS SOFTWARE MAY NOT BE |
* | PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. THE |
* | OWNERSHIP AND TITLE OF THIS SOFTWARE IS NOT TRANSFERRED. |
* +-----------------------------------------------------------------+
*
* Module name : FlashSpecificTTR.c 1.4
*
* Title : Low level flash manipulation routines
*
* Last update : 11:38:50 - 00/06/19
*
* Reviewed :
*
* Revision history :
*
* Description : Implementation of flash access functions
* for Philips TTR board (containing Am29f016B).
*
*/
/*------------------------------- Includes -----------------------------------*/
#include <stdio.h>
#include <tmlib/tmtypes.h>
#include <tmlib/tmFlash.h>
#include <tm1/mmio.h>
/*---------------------------- Physical flash --------------------------------*/
typedef volatile Byte *VAddress;
typedef volatile UInt32 VUInt32;
#define PHY_FLASH_PRIM_BASE_ADDRESS ((VAddress)0xFE400000)
#define PHY_FLASH_SEC_BASE_ADDRESS ((VAddress)0xFF400000)
/* current ttr BSP uses only one bank of flash, therefore
to preserve compatibility use only block of flash here.
There are two banks of RAM on the TTR board, and this
driver is capable of handling both banks.
#define NROF_PHY_BANKS (2)
*/
#define NROF_PHY_BANKS (1)
#define PHY_BANK_SIZE (0x00800000)
#define PHY_BLOCK_SIZE (0x00040000)
#define RETRY_COUNT 20
#define LROUND_DOWN(v,bs) (((UInt) (v)/(UInt) (bs))*(UInt) (bs))
static VAddress BaseAddresses[] = {
PHY_FLASH_PRIM_BASE_ADDRESS,
PHY_FLASH_SEC_BASE_ADDRESS
};
/*----------------------------- Logical flash --------------------------------*/
#define LOG_BLOCK_SIZE (PHY_BLOCK_SIZE)
#define BLOCK_CLUSTER_FACTOR (LOG_BLOCK_SIZE / PHY_BLOCK_SIZE)
#define TOTAL_FLASH_SIZE (PHY_BANK_SIZE * NROF_PHY_BANKS)
Int SZOF_FLASH_BLOCK = LOG_BLOCK_SIZE;
Int NROF_FLASH_BLOCKS = TOTAL_FLASH_SIZE / LOG_BLOCK_SIZE;
/*---------------------------- Reading --------------------------------*/
UInt32
FLASH_read(Pointer address)
{
UInt32 log_address = (UInt32) address;
UInt32 bank_number = log_address / PHY_BANK_SIZE;
UInt32 lf_address = log_address % PHY_BANK_SIZE;
VUInt32 *phy_address = (Pointer)(BaseAddresses[bank_number] + lf_address);
return *phy_address;
}
/* ------- . ------- */
void FLASH_block_read( Pointer address, Pointer image, Int nrof_words )
{
UInt32 log_address = (UInt32) address;
UInt32 bank_number = log_address / PHY_BANK_SIZE;
UInt32 lf_address = log_address % PHY_BANK_SIZE;
UInt32 *phy_address = (UInt32*)(BaseAddresses[bank_number] + lf_address);
Int32 *i = ((Int32*)image);
while (nrof_words--) {
*(i++) = *(phy_address++);
}
}
/*---------------------------- Writing --------------------------------*/
Bool
FLASH_write(Pointer address, UInt32 new_data)
{
Int i;
UInt32 log_address = (UInt32) address;
UInt32 bank_number = log_address / PHY_BANK_SIZE;
UInt32 lf_address = log_address % PHY_BANK_SIZE;
VUInt32 *phy_address = (VUInt32 *)(BaseAddresses[bank_number] + lf_address);
VUInt32 *phy_flashbase = (VUInt32 *)(BaseAddresses[bank_number]);
UInt32 old_data = *phy_address;
if (new_data == old_data) {
return old_data == new_data;
}
for (i=0; i<RETRY_COUNT; i++) {
phy_flashbase[0x555] = 0xAAAAAAAA;
phy_flashbase[0x2AA] = 0x55555555;
phy_flashbase[0x555] = 0xA0A0A0A0;
*phy_address = new_data;
while ( ((*phy_address ^ *phy_address) & 0x40404040)) {}
if (*phy_address == new_data) { return True; }
}
return False;
}
Bool FLASH_block_write( Pointer flash, Pointer image, Int nrof_words )
{
Int32 *f = ((Int32*)flash) + nrof_words;
Int32 *i = ((Int32*)image) + nrof_words;
Bool result;
do {
result = FLASH_write( --f, *(--i) );
} while ((Pointer)f != flash && result);
return result;
}
/*---------------------------- Erasure --------------------------------*/
static Bool
flash_block_erase(UInt block_index)
{
Int i;
UInt32 log_address = block_index * PHY_BLOCK_SIZE;
UInt32 bank_number = log_address / PHY_BANK_SIZE;
UInt32 lf_address = log_address % PHY_BANK_SIZE;
VUInt32* phy_blockbase = (VUInt32*)(BaseAddresses[bank_number] + lf_address);
VUInt32* phy_flashbase = (VUInt32*)(BaseAddresses[bank_number]);
for (i=0; i<RETRY_COUNT; i++) {
phy_flashbase[0x555] = 0xAAAAAAAA;
phy_flashbase[0x2AA] = 0x55555555;
phy_flashbase[0x555] = 0x80808080;
phy_flashbase[0x555] = 0xAAAAAAAA;
phy_flashbase[0x2AA] = 0x55555555;
phy_blockbase[0x000] = 0x30303030;
while ( (*phy_blockbase ^ *phy_blockbase) & 0x40404040) {}
if ((*phy_blockbase) == 0xffffffff) { return True; }
}
return False;
}
Bool
FLASH_block_erase(UInt ab, Bool check_if_necessary)
{
Int i;
if (check_if_necessary) {
UInt *pt = (Pointer) (ab * SZOF_FLASH_BLOCK);
Bool necessary = False;
for (i = 0; i < (SZOF_FLASH_BLOCK / sizeof (UInt)); i++) {
if (FLASH_read(pt++) != 0xffffffff) {
necessary = True;
break;
}
}
if (!necessary) {
return True;
}
}
for ( i= 0; i < BLOCK_CLUSTER_FACTOR; i++ ) {
if(flash_block_erase( ab * BLOCK_CLUSTER_FACTOR + i ) != True)
return False;
}
return True;
}
/*---------------------------- Initialization --------------------------------*/
Bool
FLASH_init()
{
return True;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -