📄 according.c
字号:
#include "stdio.h"
#include "stdlib.h"
/*intel 28F128 driver*/
#define FLASH_CMD_RESET 0x00ff
#define FLASH_CMD_BLOCK_ERASE 0x0020
#define FLASH_CMD_ERASE_CONFIRM 0x00D0
#define FLASH_CMD_CLEAR_STATUS 0x0050
#define FLASH_CMD_SUSPEND_ERASE 0x00B0
#define FLASH_CMD_WRITE 0x0040
#define FLASH_CMD_PROTECT 0x0060
#define FLASH_CMD_PROTECT_SET 0x0001
#define FLASH_CMD_PROTECT_CLEAR 0x00D0
#define FLASH_STATUS_DONE 0x0080
/*--------------------------------------------------------------------*
* CPU 时钟周期: 400 Mhz 8270 -- 2.5ns -> 3ns
*---------------------------------------------------------------------*/
#define FS_FLASH_CPU_CLOCK (8)
#define fs_flash_disable_interrupts() (0)
#define fs_flash_enable_interrupts()
static void flashDelay( unsigned long Tns )
{
unsigned long i;
for (i=0; i<Tns/FS_FLASH_CPU_CLOCK; i++)
;
}
/* 1000 纳秒: 写FALSH 时延*/
#define FS_FLASH_DELAY_TIME 20
/* program/erase operation inner algorithm be in progress or have been completed */
/* 最大轮询时间: 将近118 秒*/
#define FS_FLASH_POLL_TIME 10000
#define FS_WRITE_OPT
/*1Mbits/sector*/
#define FS_FLASH_SECTOR_SIZE (128 * 1024)
/*128 sector*/
#define FS_FLASH_SECTOR_COUNT (128)
#define FS_FLASH_SIZE (FS_FLASH_SECTOR_SIZE * FS_FLASH_SECTOR_COUNT)
/*start address*/
#define FS_FLASH_START_ADDRESS (0xFE000000)
/**/
#define FS_FLASH_SECTOR_ADDRESS(sn) (FS_FLASH_START_ADDRESS + (sn) * FS_FLASH_SECTOR_SIZE)
/*对指定的段进行保护处理, 返回0成功*/
static int i28f128_sector_protect(long sector, int prot)
{
volatile unsigned short *addr;
unsigned long start;
addr = (volatile unsigned short*)(FS_FLASH_SECTOR_ADDRESS(sector));
addr[0] = FLASH_CMD_CLEAR_STATUS;
addr[0] = FLASH_CMD_PROTECT;
if(prot)
{
addr[0] = FLASH_CMD_PROTECT_SET;
}
else
{
addr[0] = FLASH_CMD_PROTECT_CLEAR;
}
start = FS_FLASH_POLL_TIME;
flashDelay(FS_FLASH_DELAY_TIME*10000);
while(!(addr[0] & FLASH_STATUS_DONE))
{
flashDelay(FS_FLASH_DELAY_TIME*10000);
if (start-- == 0)
{
printf("Flash protect timeout at sector %d\n", sector);
addr[0] = FLASH_CMD_RESET;
return (-1);
}
}
addr[0] = FLASH_CMD_RESET;
return (0);
}
/*擦除指定段*/
static int i28f128_sector_erase(int sector)
{
int start, last, flag;
unsigned long status;
volatile unsigned short *addr;
start = FS_FLASH_POLL_TIME*10000;
last = start;
addr = (volatile unsigned short *)FS_FLASH_SECTOR_ADDRESS(sector);
/* Disable interrupts which might cause a timeout here */
flag = fs_flash_disable_interrupts();
*addr = FLASH_CMD_CLEAR_STATUS;
*addr = FLASH_CMD_BLOCK_ERASE;
*addr = FLASH_CMD_ERASE_CONFIRM;
/* re-enable interrupts if necessary */
if (flag)
fs_flash_enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
taskDelay (1);
flashDelay(FS_FLASH_DELAY_TIME*10000);
while (((status = *addr) & FLASH_STATUS_DONE) != FLASH_STATUS_DONE)
{
flashDelay(FS_FLASH_DELAY_TIME*10000);
if (start-- == 0)
{
printf("Flash erase timeout at sector %d\n", sector);
*addr = FLASH_CMD_SUSPEND_ERASE;
*addr = FLASH_CMD_RESET;
return -1;
}
}
*addr = FLASH_CMD_RESET;
return 0;
}
/*
* Write 16 bit (short) to flash
*/
static int i28f128_write_short (unsigned long dest, unsigned short data)
{
volatile unsigned short *addr;
unsigned long start;
int flag;
/* Check if Flash is (sufficiently) erased */
if ((*((volatile unsigned short *)dest) & data) != data) {
return (-2);
}
addr = (volatile unsigned short*)(FS_FLASH_SECTOR_ADDRESS(0));
/* Disable interrupts which might cause a timeout here */
flag = fs_flash_disable_interrupts();
*addr = FLASH_CMD_ERASE_CONFIRM;
*addr = FLASH_CMD_WRITE;
*((volatile unsigned short *)dest) = data;
/* re-enable interrupts if necessary */
if (flag)
{
fs_flash_enable_interrupts();
}
/* data polling for D7 */
start = FS_FLASH_POLL_TIME;
/* wait for error or finish */
while(!(addr[0] & FLASH_STATUS_DONE))
{
flashDelay(FS_FLASH_DELAY_TIME);
if (start-- == 0)
{
addr[0] = FLASH_CMD_RESET;
return (-1);
}
}
*addr = FLASH_CMD_RESET;
return (0);
}
/*
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
* 4 - Flash not identified
*/
static int i28f128_sector_writedata(unsigned char *src, int sector)
{
unsigned long addr;
unsigned short data;
int i, rc;
addr = FS_FLASH_SECTOR_ADDRESS(sector);
for (i = 0;i<FS_FLASH_SECTOR_SIZE;i += 2)
{
data = (unsigned short)src[i];
data <<= 8;
data |= (unsigned short)src[i+1];
rc = i28f128_write_short(addr, data);
if (rc != 0)
{
return (rc);
}
addr += 2;
}
return 0;
}
static int i28f128_sector_write(int sectorno, unsigned char *pBuf)
{
int ret;
#ifdef DEBUG_FLASH
printf(" write sector %d\n", sectorno);
#endif
ret = 0;
/*取消段保护*/
i28f128_sector_protect(sectorno, 0);
/*擦除段*/
if (i28f128_sector_erase(sectorno) != 0)
ret = -1;
else
/*写数据*/
if (i28f128_sector_writedata(pBuf, sectorno) != 0)
ret = -2;
/*恢复段保护*/
i28f128_sector_protect(sectorno, 1);
return ret;
}
static char * pflashTempBuffer = NULL;
static int currentsector = -1;
static int UpdateBuffer()
{
if (currentsector < 0)
return 0;
if (pflashTempBuffer == NULL)
return 0;
i28f128_sector_write(currentsector, pflashTempBuffer);
currentsector = -1;
return 0;
}
static int UpdateSector(int newSector)
{
if (newSector != currentsector)
UpdateBuffer();
else
return 0;
if (pflashTempBuffer == NULL)
pflashTempBuffer = (char *)malloc(FS_FLASH_SECTOR_SIZE);
if (pflashTempBuffer == NULL)
return -1;
memcpy(pflashTempBuffer, FS_FLASH_SECTOR_ADDRESS(newSector), FS_FLASH_SECTOR_SIZE);
currentsector = newSector;
return 0;
}
static int i28f128_read(unsigned char * dst, unsigned char * src, unsigned long count)
{
UpdateBuffer();
memcpy(dst, src, count);
}
/*
将src开始的count个字节写到dst开始的flash地址中去
返回值:
0 : 成功
-1: 参数错误
-2:内存错误
*/
static int i28f128_write(unsigned char *src, unsigned char *dst, unsigned long count)
{
unsigned long sectno;
if (count == 0)
return 0;
if (((unsigned long)dst) < FS_FLASH_SECTOR_ADDRESS(0) )
return -1;
if (((unsigned long)dst) + count > FS_FLASH_SECTOR_ADDRESS(FS_FLASH_SECTOR_COUNT) )
return -1;
#ifdef DEBUG_FLASH
printf("write %08X --> %08X, count=%d\n", (unsigned long)src, (unsigned long)dst, count);
#endif
sectno = (((unsigned long)dst) - FS_FLASH_START_ADDRESS) / FS_FLASH_SECTOR_SIZE;
/*第一块,需要特别处理吗*/
if ( (((unsigned long)dst) != FS_FLASH_SECTOR_ADDRESS(sectno) ) ||
( (((unsigned long)dst) + count) < FS_FLASH_SECTOR_ADDRESS(sectno + 1) )
)
{
/*
dst dst+count
|________:________________:____________________|
sectno sectno+1
*/
unsigned long firstsegbytes;
char * pBuf;
int rc;
firstsegbytes = FS_FLASH_SECTOR_SIZE - (((unsigned long)dst) - FS_FLASH_SECTOR_ADDRESS(sectno));
if (firstsegbytes > count)
firstsegbytes = count;
#ifndef FS_WRITE_OPT
/*需要进行读改写操作*/
pBuf = (char *)malloc(FS_FLASH_SECTOR_SIZE);
if (pBuf == NULL)
return -2;
/*读*/
memcpy(pBuf, (char *)FS_FLASH_SECTOR_ADDRESS(sectno), FS_FLASH_SECTOR_SIZE);
/*改*/
memcpy(pBuf + (((unsigned long)dst) - FS_FLASH_SECTOR_ADDRESS(sectno)), src, firstsegbytes);
/*写*/
rc = i28f128_sector_write(sectno, pBuf);
free(pBuf);
#else
if ((rc = UpdateSector(sectno)) != 0)
return -1;
memcpy(pflashTempBuffer + (((unsigned long)dst) - FS_FLASH_SECTOR_ADDRESS(sectno)), src, firstsegbytes);
#endif
if (rc != 0)
return rc;
sectno++;
count -= firstsegbytes;
src += firstsegbytes;
}
/*中间段*/
while (count >= FS_FLASH_SECTOR_SIZE)
{
int rc;
#ifndef FS_WRITE_OPT
rc = i28f128_sector_write(sectno, src);
#else
rc = UpdateSector(sectno);
if (rc == 0)
{
memcpy(pflashTempBuffer, src, FS_FLASH_SECTOR_SIZE);
}
#endif
if (rc != 0)
return rc;
src += FS_FLASH_SECTOR_SIZE;
sectno ++;
count -= FS_FLASH_SECTOR_SIZE;
}
/*最后一段*/
if (count > 0)
{
char * pBuf;
int rc;
#ifndef FS_WRITE_OPT
/*需要进行读改写操作*/
pBuf = (char *)malloc(FS_FLASH_SECTOR_SIZE);
if (pBuf == NULL)
return -2;
/*读*/
memcpy(pBuf, (char *)FS_FLASH_SECTOR_ADDRESS(sectno), FS_FLASH_SECTOR_SIZE);
/*改*/
memcpy(pBuf, src, count);
/*写*/
rc = i28f128_sector_write(sectno, pBuf);
free(pBuf);
#else
if ((rc = UpdateSector(sectno)) != 0)
return -1;
memcpy(pflashTempBuffer, src, count);
#endif
if (rc != 0)
return rc;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -