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

📄 sst_flash_routines.c

📁 An111 is a quite old flashing equipment. It s the source code to drive old equipment.
💻 C
字号:
/***************************************************************************
   Copyright ARM Limited 1998 - 2003.  All rights reserved.
****************************************************************************

   SST_Flash_Routines.c

   Flash routines for SST Flash devices
   Written for and tested on SST39VF400A Flash devices on an ARM Evaluator-7T

****************************************************************************/

#include "Evaluator.h"
// Various constants
#define TRUE	1
#define FALSE	0
#define PASS	0
#define FAIL	-1

// Command Set Commands
// For erase operations, 6 data values must be written to correct 6 address in sequence.
// For word write, a 3 word sequence is used, followed by the address/data to be written.
#define CMD_ADDR_CYCLE_1			(unsigned int *)((int)FLASH_BASE+(0x5555<<1))
#define CMD_DATA_CYCLE_1			0xAAAA
#define CMD_ADDR_CYCLE_2		    (unsigned int *)((int)FLASH_BASE+(0x2AAA<<1))
#define CMD_DATA_CYCLE_2		    0x5555
#define CMD_ADDR_CYCLE_3			(unsigned int *)((int)FLASH_BASE+(0x5555<<1))
#define ERASE_DATA_CYCLE_3		    0x8080
#define PROG_DATA_CYCLE_3			0xA0A0
#define ERASE_ADDR_CYCLE_4	    	(unsigned int *)((int)FLASH_BASE+(0x5555<<1))
#define ERASE_DATA_CYCLE_4		    0xAAAA
#define ERASE_ADDR_CYCLE_5	    	(unsigned int *)((int)FLASH_BASE+(0x2AAA<<1))
#define ERASE_DATA_CYCLE_5		    0x5555
#define ESECTOR_DATA_CYCLE_6		0x3030
#define EBLOCK_DATA_CYCLE_6			0x5050
#define ECHIP_DATA_CYCLE_6			0x1010

// SST Status masks
#define INVERT_BIT			0x80
#define TOGGLE_BIT			0x40


static int ReadyWait(volatile unsigned int*);

//  This issues a (short sized) command to the Flash device.
//  If multiple parrallel devices are used (eg 2 * 16 bit Flash parts providing 32 bit memory)
//  The command is issued to all devices
static int command(unsigned short command, unsigned int *address)
{
#ifdef fc16x2
    {
		*(volatile unsigned int *)address = ((unsigned int)command | (unsigned int)command<<16);
    }
#endif

#ifdef fc16x1
    {
		*(volatile unsigned short *)address = (unsigned short)command;
    }
#endif

#ifdef fc32x1
    {
		*(volatile unsigned int *)address = (unsigned int)command;
    }
#endif

#ifdef fc8x1
    {
		*(volatile unsigned char *)address = (unsigned char)command;
    }
#endif

#ifdef fc8x2
    {
		*(volatile unsigned short *)address = ((unsigned short)command | (unsigned short)command<<8);
    }
#endif

#ifdef fc8x4
    {
		*(volatile unsigned short *)address = ((unsigned int)command | (unsigned int)command<<8 | (unsigned int)command<<16 | (unsigned int)command<<24);
    }
#endif

    return PASS;
}

// This routine writes a single 32 bit word to Flash.  On entry, it assumes the
// For 16-bit access flash, Little Endian is presumed.

int Flash_Write_Word(unsigned int *address, unsigned int data)
{

#ifdef fc32x1	// Enter Write mode, then simply write the word.
		command(CMD_DATA_CYCLE_1, CMD_ADDR_CYCLE_1);
		command(CMD_DATA_CYCLE_2, CMD_ADDR_CYCLE_2);
		command(PROG_DATA_CYCLE_3, CMD_ADDR_CYCLE_3);
		*(volatile unsigned int*)address = data;						//  Write data
		ReadyWait(address);						//  Wait for write to complete.
#endif	

#ifdef fc16x2	// Enter Write mode, then both devices are ready for the data, so simply write the word.
		command(CMD_DATA_CYCLE_1, CMD_ADDR_CYCLE_1);
		command(CMD_DATA_CYCLE_2, CMD_ADDR_CYCLE_2);
		command(PROG_DATA_CYCLE_3, CMD_ADDR_CYCLE_3);
		*(volatile unsigned int*)address = data;						//  Write data
		ReadyWait(address);		
#endif		

#ifdef fc16x1		// ***ASSUMES LITTLE ENDIAN***
   		int i;
   		short shdata;
   		for (i=0;i<2;i++)
   		{
	   		shdata=(short)data;
			command(CMD_DATA_CYCLE_1, CMD_ADDR_CYCLE_1);
			command(CMD_DATA_CYCLE_2, CMD_ADDR_CYCLE_2);
			command(PROG_DATA_CYCLE_3, CMD_ADDR_CYCLE_3);
			*((volatile unsigned short*)address+i) = shdata;//  Write 16 bits of data
			ReadyWait(address);								//  Wait for write to complete.
			data=data>>16;
		}
#endif		

#ifdef fc8x4
   		int i;
   		signed char chdata;
   		for (i=0;i<4;i++)
   		{
	   		chdata=(unsigned char)data;
			command(CMD_DATA_CYCLE_1, CMD_ADDR_CYCLE_1);
			command(CMD_DATA_CYCLE_2, CMD_ADDR_CYCLE_2);
			command(PROG_DATA_CYCLE_3, CMD_ADDR_CYCLE_3);
			*((volatile unsigned char*)address+i) = chdata;//  Write 16 bits of data
			ReadyWait(address);								//  Wait for write to complete.
			data=data>>8;
		}
#endif

#ifdef fc8x2
		#error ("8x2 code not written");
#endif

#ifdef fc8x1
		#error ("8x1 code not written");
#endif


    if (*address != data)  				// Read word back to verify
    	return FAIL;
    else	
    	return PASS;
}


// This function returns base and size to cover all blocks required to hold size bytes from address.
int Flash_Calc_Blocks(unsigned int **address, int *size)
{
	int *endadd;
	int temp;
	int blockmask;
	
	blockmask=(FLASH_BLOCK<<2)-1;
	temp=(int)(*address+*size/4);
	temp=temp & ~blockmask;
	
	endadd=(int *)(temp + FLASH_BLOCK);
	*address=(unsigned int *)((int)*address & ~blockmask);
	*size=((int)endadd-(int)*address);
	
	return PASS;


}

// This function writes an arbitary area of flash.
// It first verfies that the data will fit within the flash address space,
// Then Flash_Write_Word to perform the write.
int Flash_Write_Area(unsigned int *address, int *data, int size)
{
	size=size>>2;		// Convert number of bytes to number of words.
	if ((address >= FLASH_BASE) && ((address+size) <= (FLASH_BASE + FLASH_SIZE)))
	{
		for (;size>0;size--)
		Flash_Write_Word(address++, *(data++));
		return PASS;
	}
	else
	{
		return FAIL;
	}
}


// This function erases a single block, specified by it's base address
// In fact, at the moment 4K "Sectors" are used instead of 64K "Blocks" 
static int Flash_Erase_Block(unsigned int *address)
{
	command(CMD_DATA_CYCLE_1, CMD_ADDR_CYCLE_1);
	command(CMD_DATA_CYCLE_2, CMD_ADDR_CYCLE_2);
	command(ERASE_DATA_CYCLE_3, CMD_ADDR_CYCLE_3);
	command(ERASE_DATA_CYCLE_4, ERASE_ADDR_CYCLE_4);
	command(ERASE_DATA_CYCLE_5, ERASE_ADDR_CYCLE_5);
	command(ESECTOR_DATA_CYCLE_6, address);
	
	ReadyWait(address);					// Wait for erase attempt to complete
    return (PASS);
}

// This function erases all blocks overlapping specified region (via calls to Flash_Erase_Block)
int Flash_Erase_Blocks(unsigned int *address, int size)
{
	unsigned int* limit=address+size/4-1;
	for(;address<=limit;address+=FLASH_BLOCK/4)
		Flash_Erase_Block(address);
	return PASS;
}


// This checks the status register, and loops untill the Flash device is 'ready'
static int ReadyWait(volatile unsigned int* address)
{
	unsigned short value1;
	unsigned short value2;
	
	value1 = *(volatile unsigned short*)address & TOGGLE_BIT;
	do
	{
	value2 = value1;
	value1 = *(volatile unsigned short*)address & TOGGLE_BIT;
	}
	while(value1!=value2);
	
	return PASS;
}

int Flash_Init ()
{
	return PASS;
}

int Flash_Close ()
{
	return PASS;
}


⌨️ 快捷键说明

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