📄 k9f1g08.c
字号:
// K9F1G08.c
// NAND FLASH: K9F1G08U0A
#include <string.h>
#include "board.h"
#include "K9F1G08.h"
// K9F1G08U0A 命令字
#define K9F1G_READID 0x90 /* 读器件ID */
#define K9F1G_RESET 0xFF /* 复位芯片 */
#define K9F1G_PGAEREAD1 0x00 /* 页读指令1 */
#define K9F1G_PAGEREAD2 0x30 /* 页读指令2 */
#define K9F1G_RANDOMDATAOUTPUT1 0x05 /* 页内随机读 */
#define K9F1G_RANDOMDATAOUTPUT2 0xE0
#define K9F1G_PAGEPROGRAM1 0x80 /* 页编程指令1 */
#define K9F1G_PAGEPROGRAM2 0x10 /* 页编程指令2 */
#define K9F1G_RANDOMDATAINPUT 0x85 /* 页内随机编程 */
#define K9F1G_BLOCKERASE1 0x60 /* 块擦除指令1 */
#define K9F1G_BLOCKERASE2 0xD0 /* 块擦除指令2 */
#define K9F1G_READSTATUS 0x70 /* 读器件状态 */
#define K9F1G_CACHEPROGRAM1 0x80 /* Cache 编程 */
#define K9F1G_CACHEPROGRAM2 0x15
#define K9F1G_COPYBACKREAD1 0x00 /* 芯片内页拷贝读 */
#define K9F1G_COPYBACKREAD2 0x35
#define K9F1G_COPYBACKPROGRAM1 0x85 /* 芯片内页拷贝编程 */
#define K9F1G_COPYBACKPROGRAM2 0x10
#define K9F1G_BUSY (1<<6) /* 器件忙标志 */
#define K9F1G_OK (1<<0) /* 器件操作成功标志 */
#define MAX_VALIDBLOCK 900
//static uint16 BlockStateTable[2][BLOCKPERCHIP]; // 块状态表: 2Bx1024
//static uint16 ValidBlockTable[2][BLOCKPERCHIP]; // 好块表 : 2Bx1024
static uint16 BlockStateTable[2][1]; // 块状态表: 2Bx1024
static uint16 ValidBlockTable[2][1]; // 好块表 : 2Bx1024
// Column Address 为低12位,
// Row Address 为高16位,
// 地址按: Col(12)_xxxx_Row(16) (lsb->msb) 排列,
// 送地址时先送低地址字节,后送高地址字节
// 芯片复位
void K9F1G_Reset(uint8 Chip)
{
volatile uint8 *CLE;
if(!Chip)
{
CLE = K9F1G08_CLE1;
}
else
{
CLE = K9F1G08_CLE2;
}
*CLE = K9F1G_RESET;
while(K9F1G_chkbusy(Chip)) ;
}
// 读芯片状态
uint8 K9F1G_ReadStatus(uint8 Chip)
{
uint8 temp;
volatile uint8 *CLE;
volatile uint8 *DATA;
if(!Chip)
{
CLE = K9F1G08_CLE1;
DATA = K9F1G08_DATA1;
}
else
{
CLE = K9F1G08_CLE2;
DATA = K9F1G08_DATA2;
}
*CLE = K9F1G_READSTATUS;
//NNOP(2); // CLE to RE Delay: 10ns(min)
temp = *DATA;
return temp;
}
// 判断操作是否完成, 返回FALSE为失败, 返回TRUE为成功
uint8 K9F1G08OK(uint8 Chip)
{
uint8 temp;
while(1)
{
temp = K9F1G_ReadStatus(Chip);
if((temp & K9F1G_BUSY) != 0)
break;
}
temp = K9F1G_ReadStatus(Chip);
if ((temp & K9F1G_OK) == 0)
return TRUE;
else
return FALSE;
}
// 页读, size<=BYTESPERPAGE(2048)+BYTESPERPAGESPARE(64)
uint8 K9F1G_PageRead(uint8 *Buf, uint32 size, uint32 PageIndex, uint8 Chip)
{
uint32 i;
uint32 PageAddr;
volatile uint8 *CLE;
volatile uint8 *ALE;
volatile uint8 *DATA;
if(!Chip)
{
CLE = K9F1G08_CLE1;
ALE = K9F1G08_ALE1;
DATA = K9F1G08_DATA1;
}
else
{
CLE = K9F1G08_CLE2;
ALE = K9F1G08_ALE2;
DATA = K9F1G08_DATA2;
}
PageAddr = PageIndex<<12;
if(Buf != NULL)
{
*CLE = K9F1G_PGAEREAD1;
*ALE = (PageAddr>>0) & 0xFF;
*ALE = (PageAddr>>8) & 0x0F;
*ALE = (PageAddr>>12) & 0xFF;
*ALE = (PageAddr>>20) & 0xFF;
*CLE = K9F1G_PAGEREAD2;
//for(i=0; i<10; i++) ;
while(K9F1G_chkbusy(Chip)) ; // 可以替代上面语句
for(i=0; i<size; i++)
{
Buf[i] = *DATA; // Read Cycle Time: 30ns(min)
}
//NNOP(100);
return TRUE;
}
return FALSE;
}
// 读页附加数据, size<=BYTESPERPAGESPARE(64)
uint8 K9F1G_PageSpareRead(uint8 *Buf, uint32 size, uint32 PageIndex, uint8 Chip)
{
return K9F1G_PageRandRead(Buf, size, BYTESPERPAGE, PageIndex, Chip);
}
// 页内随机读, start+size<=BYTESPERPAGE(2048)+BYTESPERPAGESPARE(64)
uint8 K9F1G_PageRandRead(uint8 *Buf, uint32 size, uint32 start, uint32 PageIndex, uint8 Chip)
{
uint32 i;
uint32 PageAddr;
uint32 PageSpareAddr;
volatile uint8 *CLE;
volatile uint8 *ALE;
volatile uint8 *DATA;
if(!Chip)
{
CLE = K9F1G08_CLE1;
ALE = K9F1G08_ALE1;
DATA = K9F1G08_DATA1;
}
else
{
CLE = K9F1G08_CLE2;
ALE = K9F1G08_ALE2;
DATA = K9F1G08_DATA2;
}
if(Buf != NULL)
{
PageAddr = PageIndex<<12;
*CLE = K9F1G_PGAEREAD1;
*ALE = (PageAddr>>0) & 0xFF;
*ALE = (PageAddr>>8) & 0x0F;
*ALE = (PageAddr>>12) & 0xFF;
*ALE = (PageAddr>>20) & 0xFF;
*CLE = K9F1G_PAGEREAD2;
//for(i=0; i<10; i++) ;
while(K9F1G_chkbusy(Chip)) ; // 可以替代上面语句
PageSpareAddr = start;
*CLE = K9F1G_RANDOMDATAOUTPUT1;
*ALE = (PageSpareAddr>>0) & 0xFF;
*ALE = (PageSpareAddr>>8) & 0x0F;
*CLE = K9F1G_RANDOMDATAOUTPUT2;
//NNOP(2); // CLE to RE Delay: 10ns(min)
for(i=0; i<size; i++)
{
Buf[i] = *DATA; // Read Cycle Time: 30ns(min)
}
return TRUE;
}
return FALSE;
}
// 页编程, size<=BYTESPERPAGE(2048)+BYTESPERPAGESPARE(64)
// 返回FALSE为失败, 返回TRUE为成功
uint8 K9F1G_PageProgram(uint8 *Buf, uint32 size, uint32 PageIndex, uint8 Chip)
{
uint32 i;
uint32 PageAddr;
volatile uint8 *CLE;
volatile uint8 *ALE;
volatile uint8 *DATA;
if(!Chip)
{
CLE = K9F1G08_CLE1;
ALE = K9F1G08_ALE1;
DATA = K9F1G08_DATA1;
}
else
{
CLE = K9F1G08_CLE2;
ALE = K9F1G08_ALE2;
DATA = K9F1G08_DATA2;
}
if(Buf != NULL)
{
PageAddr = PageIndex<<12;
*CLE = K9F1G_PAGEPROGRAM1;
*ALE = (PageAddr>>0) & 0xFF;
*ALE = (PageAddr>>8) & 0x0F;
*ALE = (PageAddr>>12) & 0xFF;
*ALE = (PageAddr>>20) & 0xFF;
for(i=0; i<size; i++)
{
*DATA = Buf[i];
}
*CLE = K9F1G_PAGEPROGRAM2;
while(K9F1G_chkbusy(Chip)) ; // 可以去掉
return K9F1G08OK(Chip);
}
return FALSE;
}
// 编程页附加数据, size<=BYTESPERPAGESPARE(64)
// 返回FALSE为失败, 返回TRUE为成功
uint8 K9F1G_PageSpareProgram(uint8 *Buf, uint32 size, uint32 PageIndex, uint8 Chip)
{
return K9F1G_PageRandProgram(Buf, size, BYTESPERPAGE, PageIndex, Chip);
}
// 页内随机编程, start+size<=BYTESPERPAGE(2048)+BYTESPERPAGESPARE(64)
// 返回FALSE为失败, 返回TRUE为成功
uint8 K9F1G_PageRandProgram(uint8 *Buf, uint32 size, uint32 start, uint32 PageIndex, uint8 Chip)
{
uint32 i;
uint32 PageAddr;
uint32 PageSpareAddr;
volatile uint8 *CLE;
volatile uint8 *ALE;
volatile uint8 *DATA;
if(!Chip)
{
CLE=K9F1G08_CLE1;
ALE=K9F1G08_ALE1;
DATA=K9F1G08_DATA1;
}
else
{
CLE=K9F1G08_CLE2;
ALE=K9F1G08_ALE2;
DATA=K9F1G08_DATA2;
}
if(Buf != NULL)
{
PageAddr = PageIndex<<12;
*CLE = K9F1G_PAGEPROGRAM1;
*ALE = (PageAddr>>0) & 0xFF;
*ALE = (PageAddr>>8) & 0x0F;
*ALE = (PageAddr>>12) & 0xFF;
*ALE = (PageAddr>>20) & 0xFF;
PageSpareAddr = start;
*CLE = K9F1G_RANDOMDATAINPUT;
*ALE = (PageSpareAddr>>0) & 0xFF;
*ALE = (PageSpareAddr>>8) & 0x0F;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -