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

📄 sflash.c

📁 基于mips CPU
💻 C
字号:
#include <common.h>#ifdef CONFIG_SERIAL_FLASH#include <asm/inca-ip.h>#include <serial_flash.h>extern uint incaip_get_fpiclk (void);#define SERIAL_FLASH_CHIPSELECT_0       *INCA_IP_Ports_P1_OUT &= ~(1 << 16); \                                        *INCA_IP_SSC1_SCC_CON_PRG &= ~INCA_IP_SSC1_SCC_CON_PRG_EN; \                                        *INCA_IP_SSC1_SCC_CON_PRG |= INCA_IP_SSC1_SCC_CON_PRG_HB;       /* MSB First */ \                                        *INCA_IP_SSC1_SSC_BR = 1; \                                        *INCA_IP_SSC1_SCC_CON_OPR |= INCA_IP_SSC1_SCC_CON_OPR_EN;#define SERIAL_FLASH_CHIPSELECT_1       *INCA_IP_Ports_P1_OUT |= (1 << 16); \                                        *INCA_IP_SSC1_SCC_CON_PRG &= ~INCA_IP_SSC1_SCC_CON_PRG_EN; \                                        *INCA_IP_SSC1_SCC_CON_PRG &= ~INCA_IP_SSC1_SCC_CON_PRG_HB;      /* LSB First */ \                                        *INCA_IP_SSC1_SSC_BR |= INCA_IP_SSC1_SSC_BR_BR_VALUE((incaip_get_fpiclk()>>1)/BAUD_RATE-1); \                                        *INCA_IP_SSC1_SCC_CON_OPR |= INCA_IP_SSC1_SCC_CON_OPR_EN;#define SF_WRITE_ENABLE         SERIAL_FLASH_CHIPSELECT_0; \                                ssc_write(SERIAL_FLASH_WREN); \                                SERIAL_FLASH_CHIPSELECT_1;#define SF_WRITE_DISABLE        SERIAL_FLASH_CHIPSELECT_0; \                                ssc_write(SERIAL_FLASH_WRDI); \                                SERIAL_FLASH_CHIPSELECT_1;#define SF_WRITE_ADDR(value)    ssc_write((value & 0xFF0000) >> 16); \                                ssc_write((value & 0x00FF00) >> 8); \                                ssc_write(value & 0x0000FF);/************************************************************************ * Function name:	SF_init * Description	:	Initializes the port that will be used to chip-			select the serial flash * Input value	:	none * Return value	:	none ***********************************************************************/void SF_init(void){	/* Port 1.16 is used for the serial flash memory */	*INCA_IP_Ports_P1_ALTSEL |= (1 << 16);	/* P1.16 set to GPIO */	*INCA_IP_Ports_P1_DIR |= (1 << 16);	/* P1.16 direction output */	*INCA_IP_Ports_P1_OUT |= (1 << 16);	/* Chipselect is at high */	return;}/************************************************************************ * Function name:	SF_wait * Description	:	Waits until the write in progress bit WIP in			in the status register is reset, or until			timeout, which ever occurs first * Input value	:	timeout in milliseconds * Return value	:	0 on success ***********************************************************************/int SF_wait (ulong timeout){	/* sr holds the status register reading */	uchar sr;	/* Timeout variables */	ulong start, now, last;		SERIAL_FLASH_CHIPSELECT_0;		ssc_write (SERIAL_FLASH_RDSR);	/* NOTE: TIMEOUT HAS TO BE ACCOUNTED FOR */		last = get_timer(0);	start = get_timer(0);	while (1)	{		ssc_write(0x00);		ssc_read(&sr);			/* Check if the instruction is completed */		if ((sr & SERIAL_FLASH_SR_WIP) != SERIAL_FLASH_SR_WIP &&		    (sr & SERIAL_FLASH_SR_WEL) != SERIAL_FLASH_SR_WEL) {			break;		}		if ((now = get_timer(start)) > timeout)		{			SERIAL_FLASH_CHIPSELECT_1;			return SFLASH_TIMOUT;		}		/* Show that we are waiting, print a . every second */		if ((get_timer(last)) > CFG_HZ)		{			putc('.');			last = get_timer(0);		}	}	SERIAL_FLASH_CHIPSELECT_1;	return SFLASH_OK;}/************************************************************************ * Function name:	SF_read_ID * Input value	:	None * Return value	:	0 on success ***********************************************************************/int SF_read_id (ulong *id){	uchar temp[3];	SERIAL_FLASH_CHIPSELECT_0;	ssc_write(SERIAL_FLASH_RDID);	ssc_write(0x00);	ssc_read(temp);	ssc_write(0x00);	ssc_read(temp+1);	ssc_write(0x00);	ssc_read(temp+2);	SERIAL_FLASH_CHIPSELECT_1;	*id = 0x000000;	*id |= (temp[0] << 16);	*id |= (temp[1] << 8);	*id |= temp[2];	return SFLASH_OK;}/************************************************************************ * Function name:	SF_read_status_register * Input value	:	pointer to a char to hold the status register			value * Return value	:	0 on success ***********************************************************************/int SF_read_status_register (uchar *sr){	SERIAL_FLASH_CHIPSELECT_0;	ssc_write(SERIAL_FLASH_RDSR);	ssc_write(0x00);	ssc_read(sr);	SERIAL_FLASH_CHIPSELECT_1;	return SFLASH_OK;}/************************************************************************ * Function name:	SF_write_status_register * Input value	:	Value to be written * Return value	:	0 on success ***********************************************************************/int SF_write_status_register (uchar sr){	SF_WRITE_ENABLE;	SERIAL_FLASH_CHIPSELECT_0;	ssc_write(SERIAL_FLASH_WRSR);	ssc_write(sr);	SERIAL_FLASH_CHIPSELECT_1;		return SF_wait(SERIAL_FLASH_WRSR_TIMEOUT);}/************************************************************************ * Function name:	SF_page_program * Description	:	programs at address 'addr', 'size' bytes from 			'result'. In case more that 256 bytes are sent,			the the last 256 bytes are programmed. * Input value	:	address addr, number of bytes to be programmed, 			and a pointer to where the source data is stored * Return value	:	0 on success, 1 on failure ***********************************************************************/int SF_page_program (ulong addr, ulong size, uchar *data){	unsigned int i;	SF_WRITE_ENABLE;	SERIAL_FLASH_CHIPSELECT_0;		ssc_write(SERIAL_FLASH_PP);	SF_WRITE_ADDR(addr);		for (i = 0; i < size; i++)	{		ssc_write(data[i]);	}		SERIAL_FLASH_CHIPSELECT_1;	return SF_wait(SERIAL_FLASH_PP_TIMEOUT);}/************************************************************************ * Function name:	SF_sector_erase * Description	:	Erases the sector of memory which contains the			address 'addr'. Assumes that a check whether			this sector is protected was done by the calling			function. * Input value	:	address addr * Return value	:	0 on success, 1 on failure ***********************************************************************/int SF_sector_erase (ulong addr){	SF_WRITE_ENABLE;	SERIAL_FLASH_CHIPSELECT_0;	ssc_write(SERIAL_FLASH_SE);	SF_WRITE_ADDR(addr);	SERIAL_FLASH_CHIPSELECT_1;		putc('.');	return SF_wait(SERIAL_FLASH_SE_TIMEOUT);}/************************************************************************ * Function name:	SF_bulk_erase * Description	:	Erases the entire flash except for the protected			sectors * Input value	:	None * Return value	:	0 on success, 1 on failure ***********************************************************************/int SF_bulk_erase (void){	unsigned int i;	unsigned char sr;	SF_WRITE_ENABLE;	SERIAL_FLASH_CHIPSELECT_0;	ssc_write(SERIAL_FLASH_BE);	SERIAL_FLASH_CHIPSELECT_1;	/* With bulk erase, the timeout is 160 seconds, more than the 	   ulong get_timer function can handle.  Instead of using 	   ulong long type that will introduce unnecessary overhead	   on other function, I split the entire wait for the bulk 	   erase into 4 wait calls */		putc('.');	for (i = 0; i < 4; i++)	{		if (SF_wait(SERIAL_FLASH_BE_SUB_TIMEOUT) == SFLASH_OK)		{			return SFLASH_OK;			break;		}	}	return SFLASH_TIMOUT;}/************************************************************************ * Function name:	SF_read * Description	:	reads 'size' bytes into 'result' from flash 			memory starting at address 'addr'.  * Input value	:	address addr, size to be read, and a pointer			to where the read data will be stored * Return value	:	0 on success, 1 on failure ***********************************************************************/int SF_read (ulong addr, ulong size, uchar *result){	int i;			SERIAL_FLASH_CHIPSELECT_0;		ssc_write(SERIAL_FLASH_READ);	SF_WRITE_ADDR(addr);	for (i = 0; i < size; i++)	{		ssc_write(0x00);		ssc_read(result + i);	}		SERIAL_FLASH_CHIPSELECT_1;	return SFLASH_OK;}/************************************************************************ * Function name:	SF_fast_read * Description	:	reads 'size' bytes into 'result' from flash 			memory starting at address 'addr'.  Does not			allows indefinite loop reading of memory! * Input value	:	address addr, size to be read, and a pointer			to where the read data will be stored * Return value	:	0 on success, 1 on failure ***********************************************************************/int SF_fast_read (ulong addr, ulong size, uchar *result){	unsigned int i;		SERIAL_FLASH_CHIPSELECT_0;		ssc_write(SERIAL_FLASH_READ);	SF_WRITE_ADDR(addr);		for (i = 0; i < size; i++)	{		ssc_write(0x00);		ssc_read(result + i);	}		SERIAL_FLASH_CHIPSELECT_1;	return SFLASH_OK;}/************************************************************************ * Function name:	SF_block_protect * Input value	:	char with the three Block protect bits * Return value	:	0 on success ***********************************************************************/int SF_block_protect (uchar bp){	uchar sr;/*	SF_read_status_register(&sr);*/	SERIAL_FLASH_CHIPSELECT_0;	ssc_write(SERIAL_FLASH_RDSR);	ssc_write(0x00);	ssc_read(sr);	ssc_write(0x00);	ssc_read(sr);	SERIAL_FLASH_CHIPSELECT_1;	sr &= ~SERIAL_FLASH_SR_BP_MASK;	sr |= SERIAL_FLASH_SR_BP(bp);	return SF_write_status_register(sr);}#endif /* CONFIG_SERIAL_FLASH */

⌨️ 快捷键说明

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