📄 mx2_spl_readwrite.c
字号:
/*************************************************************************Title: Filename: $Header:$Hardware: MX21Summay:License: The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/Author: Company: Freescale Suzhou Design Center====================Change Log========================$Log:$********************************************************************************////@ingroup NAND_BOOTLOADER///@file mx2_spl_readwrite.c///@brief NAND Flash read/write relative opetator////// @li Read Page From NAND Flash/// @li Read ID From NAND Flash/// @li Read OOB From NAND Flash/// @li NAND Program/// @li NAND Erase//////@author ///@bug///@version $Version$///@section history History/// 19-May-04 Merged from mx2_nand_read.c and mx2_nand_write.c, removed some unuseful functions to reduce code size.//<<<<<Include#ifdef _STANDALONE_#undef IO_ADDRESS#define IO_ADDRESS#define NFC_IO_ADDRESS#include "mx2.h"#else#include <linux/delay.h>#include <linux/errno.h>#include <linux/sched.h>#include <linux/types.h>#include <linux/mtd/mtd.h>#include <linux/mtd/nand.h>#include <linux/mtd/nand_ids.h>#include <linux/interrupt.h>#include <asm/io.h>#include <asm/arch/mx2.h>#endif #include "mx2_nand.h"//>>>>>Include//<<<<<< Private Structure//>>>>>> Private Structure//<<<<<< Global Variable//>>>>>> Global Variable//<<<<<Private Function Declearation//>>>>>Private Function Declearation//<<<<<Body///Call this function when operator MX2 NAND Controlervoid Preset(){ // _reg_NFC_CONFIGURATION=0x10; //unlocked first 2 page buffer //We don't use first 2 page buffer _reg_NFC_CONFIGURATION=0x0002; _reg_NFC_ULOCK_START_BLK=0;// _reg_NFC_ULOCK_END_BLK=NAND_FLASH_BLOCK_NUMBER-1; _reg_NFC_ULOCK_END_BLK=0xFFFF; _reg_NFC_NF_WR_PROT=0x0004; _reg_NFC_NF_CONFIG1=0x000A; _reg_NFC_RAM_BUF_ADDR=0x3; }///@brief Send Command to NAND Flash//////@param command NAND Flash Command///@return @li 0 Success/// @li others Failedu32 NAND_Command(IN u16 command){ _reg_NFC_NF_CONFIG2&=~NAND_FLASH_CONFIG2_INT; _reg_NFC_NAND_FLASH_CMD=command; _reg_NFC_NF_CONFIG2&=~NAND_FLASH_CONFIG2_FCMD; _reg_NFC_NF_CONFIG2|=NAND_FLASH_CONFIG2_FCMD; WAIT((!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT)),100000); // while((!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT))); if(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT)) return ERR_TIME_OUT; return 0;}///@brief Send Address to NAND Flash//////@param addr full address including col and page address and A8///@param cycle send addr need cycle number//////@return @li 0 Success/// @li others Failedu32 NAND_SendAddress(IN u32 addr,IN int cycle){ int i=0; for(i=0;i<cycle;i++) { // Send low half-word _reg_NFC_NF_CONFIG2&=~NAND_FLASH_CONFIG2_INT; if(cycle==4&&i>0) { _reg_NFC_NAND_FLASH_ADDR=(addr>>(i*8+1))&0xFFFF; }else _reg_NFC_NAND_FLASH_ADDR=addr>>i*8; _reg_NFC_NF_CONFIG2&=~NAND_FLASH_CONFIG2_FADD; _reg_NFC_NF_CONFIG2|=NAND_FLASH_CONFIG2_FADD; WAIT(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT),1000); if(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT)) return ERR_TIME_OUT; } return 0;}///@brief Read One Page Data to memory //////@param page Nand Flash Page Number///@param mainbuff main data buff, must large than 512B, /// If NULL,don't copy main data///@param parabuff OOB data buff, must large than 16B/// If NULL,don't copy this.//////@remarks All Address must be align 32bits//////@return @li 0 Success/// @li others Failedu32 NAND_Read_OnePage(IN int page,OUT char * mainbuff,OUT char * parabuff){ u32 * p1; u32 * p2; int i; Preset(); NAND_Command(NAND_CMD_READ0); NAND_SendAddress(page*NAND_FLASH_PAGE_MAIN_SIZE,4); _reg_NFC_NF_CONFIG2&=~NAND_FLASH_CONFIG2_INT; CONFIG2_SET_FDO_PAGE_OUT(); WAIT(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT),100000); if(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT)) return ERR_TIME_OUT; p1=(u32*)(mainbuff); p2=(u32*)( NFC_MAB3_BASE); if(p1!=0) { for(i=0;i<NAND_FLASH_PAGE_MAIN_SIZE/(sizeof(u32));i++) { *p1++=*p2++; } } p1=(u32*)parabuff; p2=(u32*)NFC_SAB3_BASE; if(p1!=0) { for(i=0;i<NAND_FLASH_PAGE_SPARE_SIZE/sizeof(u32);i++) *p1++=*p2++; } return 0; }///@brief Get NAND Flash Chip ID//////@param ID return chip ID///@return @li 0 Success/// @li Others Failedu32 NAND_ReadID(OUT u32 * ID){ Preset(); if(NAND_Command(NAND_CMD_READ_ID)) return -1; if(NAND_SendAddress(0x0,1)) return -1; //CONFIG1_SET_READ(); _reg_NFC_NF_CONFIG2&=~NAND_FLASH_CONFIG2_INT; _reg_NFC_RAM_BUF_ADDR=0x3; CONFIG2_SET_FDO_ID(); WAIT(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT),1000); if(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT)) return ERR_TIME_OUT; *ID=*(volatile u32*)NFC_MAB3_BASE; return 0; }///NAND Program One Page//////@param address Page is programed///@param mainbuff Main data buffer///@param parabuff Para Data Buffer//////@return @li 0 Success/// @li others Failedu32 NAND_Write_OnePage(IN u32 address,IN char * mainbuff,IN char* parabuff ){ int ret=0; int i=0; volatile u32 *p1; volatile u32 *p2; Preset(); _reg_NFC_BLK_ADD_LOCK=address/NAND_FLASH_PAGE_PER_BLOCK; ret=NAND_Command(NAND_CMD_PAGE_PROG); if(ret) return ret; ret=NAND_SendAddress(address*NAND_FLASH_PAGE_MAIN_SIZE,4); if(ret) return ret; p1=(u32*) mainbuff; p2=(u32*) NFC_MAB3_BASE; for(i=0;i<NAND_FLASH_PAGE_MAIN_SIZE/sizeof(u32);i++) *p2++=*p1++; p1=(volatile u32*)parabuff; p2=(volatile u32*)NFC_SAB3_BASE; for(i=0;i<NAND_FLASH_PAGE_SPARE_SIZE/sizeof(u32);i++) *p2++=*p1++; _reg_NFC_NF_CONFIG2=NAND_FLASH_CONFIG2_FDI; WAIT(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT),100000); if(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT)) return ERR_TIME_OUT; ret=NAND_Command(NAND_CMD_PAGE_PROG_CONFIRM_TRUE); if(ret) return ret; ret=NAND_Command(NAND_CMD_READ_STATUS); if(ret) return ret; return 0; }///@brief Program And Verify Data//////@param address Page is programed///@param mainbuff Main data buffer///@param parabuff Para Data Buffer//////@return @li 0 Success/// @li ERR_VERIFY Verify Failed/// @li others Failedu32 NAND_WriteAndVerify_OnePage(IN u32 address,IN char * mainbuff,IN char* parabuff ){ int i=0,ret=0,status, j=0; volatile u32 *p1m, *p1s; volatile u32 *p2m, *p2s; Preset(); _reg_NFC_BLK_ADD_LOCK=address/NAND_FLASH_PAGE_PER_BLOCK; ret=NAND_Command(NAND_CMD_PAGE_PROG); if(ret) return ret; //START Write ret=NAND_SendAddress(address*NAND_FLASH_PAGE_MAIN_SIZE,4); if(ret) return ret; p1m=(u32*) mainbuff; p1s=(volatile u32*)parabuff; p2m=(u32*) NFC_MAB3_BASE; for(i=0;i<512/sizeof(u32);i++) *p2m++=*p1m++; p2s=(volatile u32*)NFC_SAB3_BASE; for(i=0;i<16/sizeof(u32);i++) *p2s++=*p1s++; _reg_NFC_NF_CONFIG2=NAND_FLASH_CONFIG2_FDI; WAIT(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT),100000); if(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT)) return ERR_TIME_OUT; ret=NAND_Command(NAND_CMD_PAGE_PROG_CONFIRM_TRUE); if(ret) return ret; ret=NAND_Command(NAND_CMD_READ_STATUS); if(ret) return ret; // End of Write // Start of Read NAND_Command(NAND_CMD_READ0); ret=NAND_SendAddress(address*NAND_FLASH_PAGE_MAIN_SIZE,4); _reg_NFC_NF_CONFIG2&=~NAND_FLASH_CONFIG2_INT; p1m=(u32*)mainbuff; p1s=(volatile u32*)parabuff; CONFIG2_SET_FDO_PAGE_OUT(); WAIT(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT),100000); if(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT)) return ERR_TIME_OUT; p2m=(u32*)(NFC_MAB3_BASE); for(i=0; i<512/sizeof(u32); i++) { if(*p1m++!=*p2m++) { EUARTputString("Verify error!\N"); return ERR_VERIFY; } } /* p2s=(volatile u32*)NFC_SAB3_BASE; for(i=0; i<16/sizeof(u32); i++) { if(*p1s++!=*p2s++) { EUARTputString("Verify spare error!\n"); return ERR_VERIFY; } }*/ return 0;}///@brief Erase One Block///@param page page will be erased///@return @li 0 Success/// @li Ohters Failedu32 NAND_Erase(IN u32 page){ int ret=0; Preset(); _reg_NFC_BLK_ADD_LOCK=page; ret=NAND_Command(NAND_CMD_BLOCK_ERASE); if(ret) return ret; ret=NAND_SendAddress(page,3); if(ret) return ret; ret=NAND_Command(NAND_CMD_BLOCK_ERASE_CONFIRM); if(ret) return ret; ret=NAND_Command(NAND_CMD_READ_STATUS); if(ret) return ret; }///@brief Read OOB data only//////@param col Col Address will be read///@param page Page will be read///@param parabuff data buffer///@param pcount para data buffer size//////@remarks pcount+col must below 16//////@return @li 0 Success/// @li Othere Failed///u32 NAND_Read_OOB(IN int col,IN int page,OUT char * parabuff,IN int pcount){ u32 * p1; u32 * p2; u32 i; u8 data[16]; Preset(); NAND_Command(NAND_CMD_READ0); NAND_SendAddress(page*NAND_FLASH_PAGE_MAIN_SIZE,4); _reg_NFC_NF_CONFIG2&=~NAND_FLASH_CONFIG2_INT; CONFIG2_SET_FDO_PAGE_OUT(); WAIT(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT),100000); if(!(_reg_NFC_NF_CONFIG2&NAND_FLASH_CONFIG2_INT)) return ERR_TIME_OUT; p1=(u32*)data; p2=(u32*)NFC_SAB3_BASE; if(p1!=0) { for(i=0;i<16/sizeof(u32);i++) *p1++=*p2++; } //because SAB3 don't support 8 bit access for(i=col;i<pcount;i++) parabuff[i-col]=data[i]; return 0; }//>>>>>Body
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -