📄 29lv160.c
字号:
/*************************************************************************
* FILE NAME VERSION
*
* 29LV160.C 1.0
*
* COMPONENT
*
* Flash Operation such as erase/program
*
************************************************************************/
#include "..\inc\def.h"
#include "..\inc\29lvflash.h"
/*
* attention!! Cache must be closed first
*
*/
/* word addr must be converted to byte addr */
#define FLASH_WR(addr, data) *(volatile UINT16 *)(addr<<1) = (unsigned short)(data)
#define FLASH_BASE 0
#define FLASH_WRITE 0xA0A0
#define FLASH_ERASE_CHIP 0x1010
#define FLASH_ERASE_SECTOR 0x3030
#define FLASH_RESET 0xF0F0
/*
* reset the internal state machine
*
*/
void Flash_Reset(void)
{
FLASH_WR(0, FLASH_RESET);
}
/*
* during internal erase or program cycle
* the DQ6 will toggle
*/
void Check_Toggle_Ready(UINT32 Dst)
{
UINT8 Loop = TRUE;
UINT16 PreData;
UINT16 CurrData;
UINT32 TimeOut = 0;
PreData = *(volatile UINT16 *)Dst;
PreData = PreData & 0x4040;
while((TimeOut< 0x07FFFFFF) && (Loop))
{
CurrData = *(volatile UINT16 *)Dst;
CurrData = CurrData & 0x4040;
if (PreData == CurrData)
Loop = FALSE; /* ready to exit the while loop */
PreData = CurrData;
TimeOut++;
}
}
/*
* DQ7 = the complement of true data is internal cycle
* DQ7 = true data if over
*
*/
void Check_Data_Polling (UINT32 Dst, UINT16 TrueData)
{
UINT8 Loop = TRUE;
UINT16 CurrData;
unsigned long TimeOut = 0;
TrueData = TrueData & 0x8080;
while ((TimeOut< 0x07FFFFFF) && (Loop))
{
CurrData = *(volatile UINT16 *)Dst;
CurrData = CurrData & 0x8080;
if (TrueData == CurrData)
Loop = FALSE; /* ready to exit the while loop */
TimeOut++;
}
}
/*
* Write two char to addr
*
*/
void Flash_Program_One_Word(UINT16 *addr, UINT16 data)
{
Flash_Reset();
/* first 3 cycles */
FLASH_WR(0x5555, 0xaaaa);
FLASH_WR(0x2aaa, 0x5555);
FLASH_WR(0x5555, 0xa0a0);
/* write begin */
*((volatile UINT16 *)addr) = data;
/* wait for finishing */
//Flash_Wait();
Check_Toggle_Ready((UINT32)addr);
}
/*
* Get flash's vid&pid
*
*/
UINT16 Flash_ReadID(void)
{
UINT16 id;
Flash_Reset();
/* command sequence */
FLASH_WR(0x5555, 0xaaaa);
FLASH_WR(0x2aaa, 0x5555);
FLASH_WR(0x5555, 0x9090);
id = *(UINT16 *)(1<<1);
return id;
}
/*
* Polling HW pin
*
*/
void Flash_Wait(void)
{
/* pp16 must be configured as input */
//while( !(IOPDATA&(1<<16)) ); //if pp16 is low, the flash is busy!
}
/*
* Erase WHOLE chip
*
*/
void Flash_Erase_Chip(void)
{
Flash_Reset();
/* 6 write cycles */
FLASH_WR(0x5555, 0xaaaa);
FLASH_WR(0x2aaa, 0x5555);
FLASH_WR(0x5555, 0x8080);
FLASH_WR(0x5555, 0xaaaa);
FLASH_WR(0x2aaa, 0x5555);
FLASH_WR(0x5555, FLASH_ERASE_CHIP);
/* wait for finishing */
//Flash_Wait();
Check_Toggle_Ready(0);
}
/*
* Write -len- data to addr within flash space
*
*/
void Flash_Write(char *addr, char *data, int len)
{
int i;
for(i=0; i<len/2; i++)
{
Flash_Program_One_Word((UINT16 *)addr, *((UINT16 *)data));
addr += 2;
data += 2;
}
}
/*
* dst must be within the sector's address ragne
* dst is byte address
*/
void Flash_Erase_Sector(UINT32 dst)
{
Flash_Reset();
FLASH_WR(0x5555, 0xaaaa);
FLASH_WR(0x2aaa, 0x5555);
FLASH_WR(0x5555, 0x8080);
FLASH_WR(0x5555, 0xaaaa);
FLASH_WR(0x2aaa, 0x5555);
FLASH_WR(dst>>1, 0x3030); //sector addr from A12(word addr)
/* wait for finishing */
//Flash_Wait();
Check_Toggle_Ready(dst);
}
/*
* Verify
*
*/
int Flash_Verify(char *addr, char *data, int len)
{
int i;
for(i=0; i<len/2; i++)
{
Flash_Program_One_Word((UINT16 *)addr, *((UINT16 *)data));
if ( *(UINT16 *)addr!= *((UINT16 *)data) ) return -1;
addr += 2;
data += 2;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -