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

📄 flash_nand.c

📁 某个ARM9板子的实际bootloader 对裁剪
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <define.h>#include <board_config.h>//#ifdef FLASH_TYPE_NAND#include <sl2312.h>#include "flash_drv.h"#include "flash_nand_parts.h"//#include <flash_nand_parts.h>// Low level debugging//   1 - command level - prints messages about read/write/erase commands//   2 - hardware level - shows all NAND device I/O dataUINT32 chip0_en=0,nwidth=0,ndirect=0x4000,def_width=0;UINT32 ADD,ADD2,ADD3,ADD4,ADD5;UINT32 opcode=0,nmode=1,ecc_cmp=0;UINT32 info_flash[12];UINT8 ck_buf[512];UINT8 ecc_buf[4];extern int nand_present;extern void FLASH_CTRL_WRITE_REG(unsigned int addr,unsigned int data);extern unsigned int FLASH_CTRL_READ_REG(unsigned int addr);//----------------------------------------------------------------------------// Now that device properties are defined, include magic for defining// accessor type and constants.//----------------------------------------------------------------------------// Information about supported devicesstatic const flash_dev_info_t* flash_dev_info;#define NUM_DEVICES (sizeof(supported_devices)/sizeof(flash_dev_info_t))#define FLASH_BASE BOARD_FLASH_BASE_ADDR//----------------------------------------------------------------------------// Functions that put the flash device into non-read mode must reside// in RAM.void flash_query(void* data) ;static int  flash_erase_block(void* block, unsigned int size);int  flash_program_buf(void* addr, void* data, int len);//----------------------------------------------------------------------------/*unsigned int FLASH_CTRL_READ_REG(unsigned int addr){    unsigned int *base;    unsigned int data;        base = (unsigned int *)(SL2312_FLASH_CTRL_BASE + addr);    data = *base;    return (data);}void FLASH_CTRL_WRITE_REG(unsigned int addr,unsigned int data){    unsigned int *base;        base = (unsigned int *)(SL2312_FLASH_CTRL_BASE + addr);    *base = data;    return;}*/unsigned int FLASH_READ_DMA_REG(unsigned int addr){    unsigned int *base;    unsigned int data;        base = (unsigned int *)(0x67000000 + addr);    data = *base;    return (data);}void FLASH_WRITE_DMA_REG(unsigned int addr,unsigned int data){    unsigned int *base;        base = (unsigned int *)(0x67000000 + addr);    *base = data;    return;}unsigned int StatusCheck(UINT32 chip_en, UINT32 nwidth)                              //status check{	UINT8 status;		RD_STATUS:		FLASH_CTRL_WRITE_REG(NFLASH_ECC_CONTROL, 0x00000000); //set 31b = 0	FLASH_CTRL_WRITE_REG(NFLASH_COUNT, 0x7f000070); //set only command no address and two data		FLASH_CTRL_WRITE_REG(NFLASH_COMMAND_ADDRESS, 0x00000070); //write read status command			opcode = 0x80002000|chip0_en|nwidth|ndirect; //set start bit & 8bits read command	FLASH_CTRL_WRITE_REG(NFLASH_ACCESS, opcode);		while(opcode&0x80000000) //polling flash access 31b	{		opcode=FLASH_CTRL_READ_REG(NFLASH_ACCESS);		flash_delay();	}		status=FLASH_CTRL_READ_REG(NFLASH_DATA);		if(status==0)		goto RD_STATUS;	//printf("\n<--- StatusCheck : %x \n ",status);		if(info_flash[5] < 528)	{		if(status!= 0xC0)			goto RD_STATUS;			if (status == 0xc0)      return  PASS;		else 			 return  FAIL;	}	else	{		if(status!= 0xE0)		goto RD_STATUS;			if (status == 0xe0)      return  PASS;		else 			 return  FAIL;	}}/*void flash_delay(){	int i,j;	for(i=0;i<0x100;i++)		j=i*3+5;}*/// Initialize driver detailsintflash_hwr_init(FLASH_INFO_T *info){    UINT8 id[4];    int i;    flash_query(id);    // Check that flash_id data is matching the one the driver was    // configured for.    // Check manufacturer    if ((id[0] != CYGNUM_FLASH_VENDOR_TOSHIBA)&&(id[0] != CYGNUM_FLASH_VENDOR_SAMSUNG)) {        printf("Can't identify FLASH - manufacturer is: %x\n", id[0]);        return FLASH_ERR_DRV_WRONG_PART;    }    // Look through table for device data    flash_dev_info = supported_devices;    for (i = 0; i < NUM_DEVICES; i++) {        if (flash_dev_info->device_id == id[1])            break;        flash_dev_info++;    }	    // Did we find the device? If not, return error.    if (NUM_DEVICES == i) {        printf("Can't identify FLASH - device is: %x, supported: ", id[1]);        for (i = 0;  i < NUM_DEVICES;  i++) {            printf("%x ", supported_devices[i].device_id);        }        printf("\n");        return FLASH_ERR_DRV_WRONG_PART;    }	info_flash[1] = flash_dev_info->device_size >> 20;	info_flash[2] = flash_dev_info->block_count ;	info_flash[3] = flash_dev_info->block_size / flash_dev_info->page_size;	//info_flash[4] = flash_dev_info->page_size+ (flash_dev_info->page_size>0x200)?64:16;	info_flash[5] = flash_dev_info->page_size;	info_flash[4] = info_flash[5] + (info_flash[5]>0x200?64:16);	info_flash[6] = (flash_dev_info->page_size>0x200)?64:16;	nand_present = 1;	    // Fill in device details    //flash_info.block_size = flash_dev_info->block_size;    //flash_info.blocks = flash_dev_info->block_count;    //flash_info.start = (void *)BOARD_FLASH_BASE_ADDR;    //flash_info.end = (void *)(BOARD_FLASH_BASE_ADDR+ flash_dev_info->device_size );        // Hard wired for now   	info->erase_block 	= (void *)flash_erase_block;    info->program 		= (void *)flash_program_buf;    info->block_size 	= flash_dev_info->block_size;    info->blocks 		= flash_dev_info->block_count;    info->start 		= (void *)FLASH_BASE;    info->end 			= (void *)(FLASH_BASE+ (flash_dev_info->device_size));    info->vendor		= id[0];    info->chip_id		= id[1];    info->sub_id1       = 0;    info->sub_id2       = 0;    return FLASH_ERR_OK;}//----------------------------------------------------------------------------// Map a hardware status to a package errorstatic intflash_hwr_map_error(int e){    return e;}//----------------------------------------------------------------------------// See if a range of FLASH addresses overlaps currently running codestatic boolflash_code_overlaps(void *start, void *end){    extern unsigned char _stext[], _etext[];    return ((((unsigned long)&_stext >= (unsigned long)start) &&             ((unsigned long)&_stext < (unsigned long)end)) ||            (((unsigned long)&_etext >= (unsigned long)start) &&             ((unsigned long)&_etext < (unsigned long)end)));}static voidput_NAND(volatile UINT8 *ROM, UINT8 val){    *ROM = val;#if FLASH_DEBUG > 1    printf("%02x ", val);#endif}//----------------------------------------------------------------------------// Flash Query//// Only reads the manufacturer and part number codes for the first// device(s) in series. It is assumed that any devices in series// will be of the same type.voidflash_query(void* data){	UINT8* id = (UINT8*) data;	UINT32 i, dent_bit;	UINT8 m_code,d_code;		dent_bit=FLASH_CTRL_READ_REG(FLASH_TYPE);	if((dent_bit&0x800)==0x800)		info_flash[11]=16;	else		info_flash[11]=8;			FLASH_CTRL_WRITE_REG(NFLASH_ECC_CONTROL, 0x00000000); 		//set 31b = 0	if((dent_bit&0x00000700)<=0x00000300)		FLASH_CTRL_WRITE_REG(NFLASH_COUNT, 0x7f000100); 		//set only command & address and two data	else		FLASH_CTRL_WRITE_REG(NFLASH_COUNT, 0x7f000300); 		//set only command & address and 4 data		FLASH_CTRL_WRITE_REG(NFLASH_COMMAND_ADDRESS, 0x00000090); 	//write read id command	FLASH_CTRL_WRITE_REG(NFLASH_ADDRESS, 0x00000000); 			//write address 0x00		/* read maker code */	opcode = 0x80002000|chip0_en|nwidth|ndirect; //set start bit & 8bits read command	FLASH_CTRL_WRITE_REG(NFLASH_ACCESS, opcode);	opcode=FLASH_CTRL_READ_REG(NFLASH_ACCESS);	while(opcode&0x80000000) //polling flash access 31b	{		opcode=FLASH_CTRL_READ_REG(NFLASH_ACCESS);		flash_delay();	}	if(nwidth == NFLASH_WiDTH8)	{		m_code=FLASH_CTRL_READ_REG(NFLASH_DATA);		//FLASH_CTRL_WRITE_REG(NFLASH_DATA, 0x00000000);		/* read device code */		opcode = 0x80002000|chip0_en|nwidth|ndirect; //set start bit & 8bits read command		FLASH_CTRL_WRITE_REG(NFLASH_ACCESS, opcode);		opcode=FLASH_CTRL_READ_REG(NFLASH_ACCESS);		while(opcode&0x80000000) //polling flash access 31b		{			opcode=FLASH_CTRL_READ_REG(NFLASH_ACCESS);			flash_delay();		}			d_code = (FLASH_CTRL_READ_REG(NFLASH_DATA)>>8);			dent_bit=FLASH_CTRL_READ_REG(FLASH_TYPE);		if((dent_bit&0x700)>0x300)		{			for(i=0;i<2;i++)			{				//data cycle 3 & 4 ->not use				opcode = 0x80002000|chip0_en|nwidth|ndirect; //set start bit & 8bits read command				FLASH_CTRL_WRITE_REG(NFLASH_ACCESS, opcode);				opcode=FLASH_CTRL_READ_REG(NFLASH_ACCESS);				while(opcode&0x80000000) //polling flash access 31b				{					opcode=FLASH_CTRL_READ_REG(NFLASH_ACCESS);					flash_delay();				}					dent_bit=FLASH_CTRL_READ_REG(NFLASH_DATA);			}		}	}	else	// 16-bit	{		dent_bit = FLASH_CTRL_READ_REG(NFLASH_DATA);		m_code = dent_bit;		d_code = dent_bit>>8;			//data cycle 3 & 4 ->not use		dent_bit=FLASH_CTRL_READ_REG(FLASH_TYPE);		if(((dent_bit&0x700)>0x300)&&(nwidth == NFLASH_WiDTH16))		{			opcode = 0x80002000|chip0_en|nwidth|ndirect; //set start bit & 8bits read command			FLASH_CTRL_WRITE_REG(NFLASH_ACCESS, opcode);			opcode=FLASH_CTRL_READ_REG(NFLASH_ACCESS);			while(opcode&0x80000000) //polling flash access 31b			{				opcode=FLASH_CTRL_READ_REG(NFLASH_ACCESS);				flash_delay();			}				dent_bit=FLASH_CTRL_READ_REG(NFLASH_DATA);		}	}			printf("\rManufacturer's code is %x\n", m_code);	printf("Device code is %x\n", d_code);		id[0] = m_code;	// vendor ID	id[1] = d_code;	// device ID	opcode = 0x4000;	FLASH_CTRL_WRITE_REG(NFLASH_ACCESS,opcode);}//----------------------------------------------------------------------------// Erase Blockstatic intflash_erase_block(void* block, unsigned int size){	UINT32 page_add = (UINT32)block;	page_add -=0x30000000;	page_add = page_add / info_flash[5];		FLASH_CTRL_WRITE_REG(NFLASH_ECC_CONTROL, 0x00000000); //set 31b = 0		if(info_flash[1]>=64)		FLASH_CTRL_WRITE_REG(NFLASH_COUNT, 0x7f0fff21);  //3 address & 2 command	else		FLASH_CTRL_WRITE_REG(NFLASH_COUNT, 0x7f0fff11);  //2 address & 2 command		FLASH_CTRL_WRITE_REG(NFLASH_COMMAND_ADDRESS, 0x0000d060); //write read id command	FLASH_CTRL_WRITE_REG(NFLASH_ADDRESS, page_add); //write address 0x00				/* read maker code */	opcode = 0x80003000|chip0_en|nwidth|ndirect; //set start bit & 8bits write command	FLASH_CTRL_WRITE_REG(NFLASH_ACCESS, opcode);		while(opcode&0x80000000) //polling flash access 31b	{		opcode=FLASH_CTRL_READ_REG(NFLASH_ACCESS);		flash_delay();	}			//printf("\n--->BlockErase: \n");		if(StatusCheck(chip0_en, def_width)!=FAIL)		return FLASH_ERR_OK;	else		return  FLASH_ERR_ERASE;	}//// ECC support - adapted from Linux:////  drivers/mtd/nand_ecc.c////  Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)//                     Toshiba America Electronics Components, Inc.//

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -