⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 k9f1g08.c

📁 三星新一代2k page的k9f1g8u0a的底层驱动,已应用于工程之中.
💻 C
📖 第 1 页 / 共 2 页
字号:
// 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 + -