nand.c

来自「Centrality Atlas II development software」· C语言 代码 · 共 688 行 · 第 1/2 页

C
688
字号
/* * $QNXLicenseC:  * Copyright 2007,2008, QNX Software Systems.   *   * Licensed under the Apache License, Version 2.0 (the "License"). You   * may not reproduce, modify or distribute this software except in   * compliance with the License. You may obtain a copy of the License   * at: http://www.apache.org/licenses/LICENSE-2.0   *   * Unless required by applicable law or agreed to in writing, software   * distributed under the License is distributed on an "AS IS" basis,   * WITHOUT WARRANTIES OF ANY KIND, either express or implied.  *  * This file may contain contributions from others, either as   * contributors under the License or as licensors under other terms.    * Please review this entire file for other proprietary rights or license   * notices, as well as the QNX Development Suite License Guide at   * http://licensing.qnx.com/license-guide/ for other information.  * $  *///#include "atlasii.h"#include "nand.h"extern void Show_LED(int led, int val);extern int 	bootcs;extern int 	updatecs;unsignedcrc16(uint8_t *buf, int len) {        unsigned        crc = 0;        uint8_t           *end;        end = buf + len;        while(buf < end) {                if(crc & 1) crc |= 0x10000;                crc = ((crc>>1) + *buf++) & 0xffff;        }        return(crc);}unsigned nand_init() {	uint8_t			id[4];	uint8_t 			nandcs=0;	dev=&chip_dev;	dev->iobase =_SMDF_MODULE_BASE;	dev->io_brdg = ATLASII_IOBRDG_FLUSH;	dev->io_data = dev->iobase + ATLASII_SM_FIFO_DATA;	dev->io_address = dev->iobase + ATLASII_SM_LOW_ADDR;	dev->io_command = dev->iobase + ATLASII_SM_CMD;	//where we are booting from	if(updatecs==1 && bootcs==7) //booting from SM cardn update to on boards nand	{		*(volatile unsigned char*)(EXT_PIO_BASE+0x1C00)=0x0f;		*(volatile unsigned char*)(EXT_PIO_BASE+0x1E00)=0;		nandcs=3;	}	else if(updatecs==1 && bootcs==0) //booting from on boards nand and update to SM card	{		*(volatile unsigned char*)(EXT_PIO_BASE+0x1C00)=0x0f;		*(volatile unsigned char*)(EXT_PIO_BASE+0x1E00)=0x08;		nandcs=3;	}	else		nandcs=0;	*(volatile unsigned int *)(_RSC_MODULE_BASE+0x4) &= ~0x0F00;	*(volatile unsigned int *)(_RSC_MODULE_BASE+0x4) |= 0x0d00;	if (0 == (in32(dev->iobase+ATLASII_SM_CTRL) & 0x10)) {		*(volatile unsigned int *)(_RSC_MODULE_BASE+0x4) |= 0x1; //CAM_EN	}	out32(dev->iobase+ATLASII_SM_CTRL, in32(dev->iobase+ATLASII_SM_CTRL) & (~0x1));  //IO-Read mode	out32(dev->iobase+ATLASII_SM_CTRL, in32(dev->iobase+ATLASII_SM_CTRL) & (~0x2));  //force 8-bit	out32(dev->iobase+ATLASII_SM_WAIT, 0x1878);  //Set Wait Reg	out32(dev->iobase+ATLASII_SM_FIFO_OP, 0x1);  //Start FIFO	out32(dev->iobase+ATLASII_SM_ECC_SET, 0x0);  //disable hardware ECC	//NAND bank select	ser_putstr((unsigned char *)"bootcs = ");	ser_puthex(bootcs);	ser_putstr((unsigned char *)" updatecs = ");	ser_puthex(updatecs);	ser_putstr((unsigned char *)" nandcs = ");	ser_puthex(nandcs);	ser_putstr((unsigned char *)"\n");	out32(dev->iobase+ATLASII_SM_BANK_SEL,  (~(0x1<<nandcs)) & 0xF);  		//clear all Intrrupt	out32(dev->iobase+ATLASII_SM_INT_STATUS, 0xe);	// Reset the part	nand_write_cmd(dev, NANDCMD_RESET);	if(nand_wait_INT(dev, MAX_RESET_USEC, NAND_STATUS_WT_CMD) != 0)		return -1;   //ser_putstr("NAND: Timeout on RESET\n");	if(nand_read_flashid(dev, id, 4)!=0)		return -1;  //ser_putstr("NAND: Timeout on ReadID\n");	switch(id[1]) {	// 16M	case 0x73:		dev->numblks = 1024;		dev->addrcycles = 3;		break;	// 32M	case 0x75:		dev->numblks = 2048;		dev->addrcycles = 3;		break;	// 64M	case 0x76:		dev->numblks = 4096;		dev->addrcycles = 4;		break;	// 128M	case 0x72: case 0x74: case 0x78: case 0x79:		dev->numblks = 8192;		dev->addrcycles = 4;		break;	default:		ser_putstr((unsigned char *)"nand_init: Unsupported NAND chip\n");		return -1;		break;	}	// We glue to physical pages at the driver and report back their combined size	dev->sparesize     = SPARESIZE;	dev->blksize       = (DATASIZE) * PAGES2BLK;	return(0);}unsigned nand_wait_INT(NAND_CHIP *dev, uint32_t usec, uint32_t sts) {	for(; usec>0 && !(in32(dev->iobase+ATLASII_SM_INT_STATUS)&sts); usec--) ;	if(usec==0)		return -1;	else	{		//clear intr		out32(dev->iobase+ATLASII_SM_INT_STATUS, 				in32(dev->iobase+ATLASII_SM_INT_STATUS) |sts);		return 0;	}}// Accessing the command reg automatically sets ALE=0, CLE=1voidnand_write_cmd(NAND_CHIP *dev, int command) {	//enter to command mode	out32(dev->iobase+ATLASII_SM_DMA_IO_CTRL, NAND_MODE_CMD);	out32(dev->io_command, (uint8_t) command);}int nand_read_flashid(NAND_CHIP *dev, uint8_t *id, int data_cycles){	int i=100000000;	out32(dev->iobase+ATLASII_SM_FIFO_OP, 0x2);  //Reset FIFO	out32(dev->iobase+ATLASII_SM_FIFO_OP, 0x0);  //Reset FIFO	//enter to io read mode	out32(dev->iobase+ATLASII_SM_DMA_IO_CTRL, NAND_MODE_IO_READ);	//set io-len	out32(dev->iobase+ATLASII_SM_DMA_IO_LEN, 0x4);	//set addr num	out32(dev->iobase+ATLASII_SM_ADD_NUM, 0x1);	//set low addr=0;	out32(dev->iobase+ATLASII_SM_LOW_ADDR, 0x0);	//clear intr	out32(dev->iobase+ATLASII_SM_INT_STATUS, 0xf);	//set command	out32(dev->io_command, NANDCMD_IDREAD);  //read id command	out32(dev->iobase+ATLASII_SM_FIFO_OP, 0x1);  //Reset FIFO	//wait command end	while((in32(dev->iobase+ATLASII_SM_FIFO_STATUS) & 0x80) && i--) ;	if(i<=0)		return -1;	*(uint32_t *)id = in32(dev->iobase+ATLASII_SM_FIFO_DATA);	ser_putstr((unsigned char *)"nand_read_flashid: id=");	ser_puthex(*(uint32_t *)id);	ser_putstr((unsigned char *)"\n");	out32(dev->io_brdg, 1);	while (in32(dev->io_brdg));	return (0);}int nand_read_status(NAND_CHIP *dev, uint8_t *databuffer){	out32(dev->iobase+ATLASII_SM_FIFO_OP, 0x2);  //Reset FIFO	out32(dev->iobase+ATLASII_SM_FIFO_OP, 0x0);  //Reset FIFO	//enter to io read mode	out32(dev->iobase+ATLASII_SM_DMA_IO_CTRL, NAND_MODE_IO_READ);	//set addr num	out32(dev->iobase+ATLASII_SM_ADD_NUM, 0);	//set low addr=0;	out32(dev->iobase+ATLASII_SM_HIGH_ADDR, 0x0);	out32(dev->iobase+ATLASII_SM_LOW_ADDR, 0x0);	//set io-len	out32(dev->iobase+ATLASII_SM_DMA_IO_LEN, 0x4);	out32(dev->iobase+ATLASII_SM_FIFO_CTRL, 0x4<<2);	//clear intr	out32(dev->iobase+ATLASII_SM_INT_STATUS, 0xf);	//set command	out32(dev->io_command, NANDCMD_STATUSREAD);  //read status command	out32(dev->iobase+ATLASII_SM_FIFO_OP, 0x1);  //Reset FIFO	//wait command end	if(nand_wait_INT(dev,  MAX_READ_USEC, NAND_STATUS_WT_FIFO) != 0)		return(-1);	else		*(uint32_t *)databuffer = in32(dev->iobase+ATLASII_SM_FIFO_DATA);			out32(dev->io_brdg, 1);	while (in32(dev->io_brdg));	out32(dev->iobase+ATLASII_SM_FIFO_OP, 0x2);  //Reset FIFO	return 0;}//op=0, read data//op=1, read spareint nand_read_page(NAND_CHIP *dev, unsigned page, uint8_t *databuffer, int data_cycles, int op){	if(op==0)	{	//Reset ECC		out32(dev->iobase+ATLASII_SM_ECC_SET, 0x07);		out32(dev->iobase+ATLASII_SM_ECC_SET, 0x05);	}	out32(dev->iobase+ATLASII_SM_FIFO_OP, 0x2);  //Reset FIFO	out32(dev->iobase+ATLASII_SM_FIFO_OP, 0x0);  //Reset FIFO	//enter to io read mode	out32(dev->iobase+ATLASII_SM_DMA_IO_CTRL, NAND_MODE_IO_READ);	//set io-len	out32(dev->iobase+ATLASII_SM_DMA_IO_LEN, data_cycles);	//set addr num	out32(dev->iobase+ATLASII_SM_ADD_NUM, 0x4);	//set low addr=0;	out32(dev->iobase+ATLASII_SM_LOW_ADDR, page<<8);	out32(dev->iobase+ATLASII_SM_HIGH_ADDR, 0);	//clear intr	out32(dev->iobase+ATLASII_SM_INT_STATUS, 0xf);	//set command	if(op==1)		out32(dev->io_command, NANDCMD_SPAREREAD);  //read2 command		else 		out32(dev->io_command, NANDCMD_READ);  //read1 command	out32(dev->iobase+ATLASII_SM_FIFO_OP, 0x1);  //Reset FIFO	//wait command end	if(nand_read_data(dev, databuffer, data_cycles)!=0)		return -1;	return data_cycles;}//op=0, write data//op=1, write spareint nand_write_page(NAND_CHIP *dev, unsigned page, uint8_t *databuffer, int data_cycles, int op){	if(op==0)	{	//Reset ECC		out32(dev->iobase+ATLASII_SM_ECC_SET, 0x07);		out32(dev->iobase+ATLASII_SM_ECC_SET, 0x05);	}		//change the write pointer to either data area or spare area	out32(dev->iobase+ATLASII_SM_DMA_IO_CTRL, NAND_MODE_CMD);	out32(dev->iobase+ATLASII_SM_ADD_NUM, 0x0);	//clear intr	out32(dev->iobase+ATLASII_SM_INT_STATUS, 0xf);	if(op==0)		out32(dev->io_command, NANDCMD_READ);  //read1 command	else		out32(dev->io_command, NANDCMD_SPAREREAD);  //read2 command		//wait for the command end	if(nand_wait_INT(dev, MAX_READ_USEC, NAND_STATUS_WT_CMD) !=0)		return (-1);	out32(dev->iobase+ATLASII_SM_FIFO_OP, 0x2);  //Reset FIFO	out32(dev->iobase+ATLASII_SM_FIFO_OP, 0x0);  //Reset FIFO	//enter to io write mode	out32(dev->iobase+ATLASII_SM_DMA_IO_CTRL, NAND_MODE_IO_WRITE);	//set io-len	out32(dev->iobase+ATLASII_SM_DMA_IO_LEN, data_cycles);	//set addr num	out32(dev->iobase+ATLASII_SM_ADD_NUM, 0x4);	//set low addr=0;	out32(dev->iobase+ATLASII_SM_LOW_ADDR, page<<8);	out32(dev->iobase+ATLASII_SM_HIGH_ADDR, 0);	//clear interrupt	out32(dev->iobase+ATLASII_SM_INT_STATUS, 0xf);	//set command	out32(dev->io_command, NANDCMD_PROGRAM);  //write command		out32(dev->iobase+ATLASII_SM_FIFO_OP, 0x1);  //Reset FIFO	if(nand_write_data(dev, databuffer, data_cycles)!=0)		return -1;	//wait command end	if(nand_wait_INT(dev,  MAX_POST_USEC, NAND_STATUS_WT_IO) != 0)		return(-2);	//enter to command mode	out32(dev->iobase+ATLASII_SM_DMA_IO_CTRL, NAND_MODE_CMD);	out32(dev->iobase+ATLASII_SM_ADD_NUM, 0x0);	//clear interrupt	out32(dev->iobase+ATLASII_SM_INT_STATUS, 0xf);	//set command	out32(dev->io_command, NANDCMD_PROGRAMCONFIRM);  //write confirm command		if(nand_wait_INT(dev,  MAX_POST_USEC, NAND_STATUS_WT_CMD) != 0)		return(-3);	return 0;}int nand_erase_blk(NAND_CHIP *dev, unsigned blk){	out32(dev->iobase+ATLASII_SM_DMA_IO_CTRL, NAND_MODE_CMD);	out32(dev->iobase+ATLASII_SM_ADD_NUM, 0x3);  	//set low addr=0;	out32(dev->iobase+ATLASII_SM_LOW_ADDR, (blk<<5));	out32(dev->iobase+ATLASII_SM_HIGH_ADDR, 0);	//clear interrupt	out32(dev->iobase+ATLASII_SM_INT_STATUS, 0xf);	//set command	out32(dev->io_command, 0xD060);  //blk erase command		//wait command end	if(nand_wait_INT(dev,  MAX_ERASE_USEC, NAND_STATUS_WT_CMD) != 0)		return(-1);	return 0;}// Accessing the data reg automatically sets ALE=0, CLE=0intnand_write_data(NAND_CHIP *dev, uint8_t *databuffer, int data_cycles) {	int i;	volatile unsigned *tmp;	volatile unsigned val;

⌨️ 快捷键说明

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