c6701_hw.c

来自「于TI DSP TMS320C67XX实现的嵌入式系统FLASH引导的实现。程序」· C语言 代码 · 共 235 行

C
235
字号
/******************************************************************************/
// Hardware.c
// Written by: Kyle Castille
// Updated by: Michael Haag (6/27/01)
// This program will create a dummy data buffer with an incrementing count
// in internal memory, and then program this data to the AM29LV400 Flash
// which is a 512k x 8/256k x 16, 90 ns Flash memory.
//
// This program assumes that the ARDY interface is used, so no software
// checking is done to detect end of operation for erase or program
//
/******************************************************************************/
#include "datatype.h"
#include "c6701_hw.h"

/****************************************************************************/
/* emif_config :Routine to configure the Emif for operation with */
/* AM29LV400 at CE1. This routine sets the CE1 control register */
/* for a 32 bit asynchronous memory interface with the following */
/* parameters: */
/* Mtype = 010 */
/* Read Setup/Strobe/Hold = 1/21/3 */
/* Write Setup/Strobe/Hold = 2/13/3 */
/* */
/****************************************************************************/
void emif_config()
{
	/* Create Global Control Register field */
	Uint32 global_ctl = EMIF_GBLCTL_RMK(
			EMIF_GBLCTL_NOHOLD_DISABLE,
			EMIF_GBLCTL_SDCEN_DISABLE,
			EMIF_GBLCTL_SSCEN_DISABLE,
			EMIF_GBLCTL_CLK1EN_ENABLE,
			EMIF_GBLCTL_CLK2EN_DISABLE,
			EMIF_GBLCTL_SSCRT_CPUOVR2,
			EMIF_GBLCTL_RBTR8_HPRI);
	Uint32 ce0_control = EMIF_CECTL_RMK(
			EMIF_CECTL_WRSETUP_OF(15),	// 1111
			EMIF_CECTL_WRSTRB_OF(31),	// 111111
			EMIF_CECTL_WRHLD_OF(3),		// 11
			EMIF_CECTL_RDSETUP_OF(15),	// 1111
			EMIF_CECTL_RDSTRB_OF(31),	// 111111
			EMIF_CECTL_MTYPE_ASYNC32,
//			EMIF_CECTL_MTYPE_ASYNC16,
			EMIF_CECTL_RDHLD_OF(3) );	// 11
	/* Create CE1 Control Register field */
	Uint32 ce1_control = EMIF_CECTL_RMK(
			EMIF_CECTL_WRSETUP_OF(15),
			EMIF_CECTL_WRSTRB_OF(31),
			EMIF_CECTL_WRHLD_OF(3),
			EMIF_CECTL_RDSETUP_OF(15),
			EMIF_CECTL_RDSTRB_OF(31),
			EMIF_CECTL_MTYPE_ASYNC32,
//			EMIF_CECTL_MTYPE_ASYNC16,
			EMIF_CECTL_RDHLD_OF(3) );
	EMIF_configArgs(
			EMIF_GBLCTL_OF(global_ctl), /* global control */
			EMIF_CECTL_OF(ce0_control), /* CE0 control */
			EMIF_CECTL_OF(ce1_control), /* 32-bit async mem */
			EMIF_CECTL_OF(0x00000018), /* CE2 control */
			EMIF_CECTL_OF(0x00000018), /* CE3 control */
			EMIF_SDCTL_OF(0x0388F000), /* SDRAM control */
			EMIF_SDTIM_OF(0x00800040) /* SDRAM timing */
			);
}

void C6701_EMIF_init()
{
	  
	EMIF_GBLCTL  = 0x00003019;
								// SDCEN=0: SDCLK is held high
								// SSCEN=0: SSCLK is held high.
								// CLK1EN=1:  CLKOUT1 is enabled to clock.
								// CLK2EN=1:  CLKOUT2 is enabled to clock.
								// MAP1=1:  Map 1 is selected. Internal memory located at address 0.

	EMIF_CECTL0  = 0xFFFF3F03;	// MTYPE=2H: 32-bit-wide asynchronous interface.
								// 512K*32bit SRAM
	EMIF_CECTL1  = 0xFFFF3F13;	// MTYPE=1H: 16-bit-wide asynchronous interface.
								// 256k*16bit FLASH
	
//	EMIF_CECTL2  = ;
//	EMIF_CECTL3  = ;

	EMIF_SDTIM   = 0x00080080;	// defult value
								
	EMIF_SDCTL   = 0x0388F000;	// defult value
}

/*********************************************************************************/
/* poll_data: Routine to determine if Flash has successfully completed the */
/* program or erase algorithm. This routine will loop until */
/* either the embedded algorithm has successfully completed or */
/* until it has failed. */
/* */
/* Inputs: */
/* prog_ptr : Address just programmed */
/* prog_data: Data just programmed to flash */
/* Return value: */
/* Returns TRUE if passed, or FALSE if failed. */
/* */
/*********************************************************************************/
INT32U poll_data(INT32U *prog_ptr, INT16U prog_data)
{
	INT16U data;
	INT32U fail = FALSE;
	do {
		data = (INT16U) * prog_ptr;
		if (data != prog_data) /* is D7 != Data? */
		{
			if ((data & 0x0020) == 0x0020) /*is D5 = 1 ? */
			{
				data = (INT16U) * prog_ptr;
				if (data != prog_data) /* is D7 = Data? */
					fail = TRUE;
				else
					return TRUE; /* PASS */
			}
		}
		else
			return TRUE; /* PASS */
	} while (!fail);
	return FALSE; /* FAIL */
}

/*********************************************************************************/
/* erase_flash : Routine to erase entire FLASH memory AM29LV400 (512K x 8bit/ */
/* 256k x 16bit) */
/* Inputs: */
/* flash_ptr: Address of the FLASH PEROM */
/* */
/*********************************************************************************/
void flash_chip_erase(INT32U *flash_ptr)
{
	/* Control addresses are left shifted so that */
	/* they appear correctly on the EMIF’s EA[19:2] */
	/* Byte address << 2 == Word Address */
	INT32U *ctrl_addr1 = (INT32U*) ((INT32U)flash_ptr + (0x555 << 2));
	INT32U *ctrl_addr2 = (INT32U*) ((INT32U)flash_ptr + (0x2aa << 2));

	INT32U pass = TRUE;
	
	* ctrl_addr1 = 0x00aa; /* Erase sequence writes to addr1 and addr2 */
	* ctrl_addr2 = 0x0055; /* with this data */
	* ctrl_addr1 = 0x0080;
	* ctrl_addr1 = 0x00aa;
	* ctrl_addr2 = 0x0055;
	* ctrl_addr1 = 0x0010;

	pass = poll_data(flash_ptr, (INT16U) 0xffff);
	
	if (!pass)
	{
		printf("flash chip erase failed !\n\n");
		exit(0);
	}
	return;
	
}

void flash_sector_erase(INT32U *pflash_sector_addr)		//Address bits A17–A12 uniquely select any sector. size of each sector is 4KB
{
		/* Control addresses are left shifted so that */
	/* they appear correctly on the EMIF’s EA[19:2] */
	/* Byte address << 2 == Word Address */
	INT32U * ctrl_addr1 = (INT32U *) ((INT32U)pflash_sector_addr + (0x555 << 2));
	INT32U * ctrl_addr2 = (INT32U *) ((INT32U)pflash_sector_addr + (0x2aa << 2));

	INT32U pass = TRUE;
	
	* ctrl_addr1 = 0x00aa; /* Erase sequence writes to addr1 and addr2 */
	* ctrl_addr2 = 0x0055; /* with this data */
	* ctrl_addr1 = 0x0080;
	* ctrl_addr1 = 0x00aa;
	* ctrl_addr2 = 0x0055;
	*pflash_sector_addr = 0x0030;

	pass = poll_data(pflash_sector_addr, (INT16U) 0xffff);
	
	if (!pass)
	{
		printf("flash sector erase failed!\n\n");
		exit(0);
	}
	return;
}
/********************************************************************************/
/* program_flash: Routine to program FLASH AM29LV800 */
/* Inputs: */
/* flash_ptr : Address of the FLASH */
/* source_ptr : Address of the array containing the code to program */
/* length : Length to be programmed */
/* */
/********************************************************************************/
void flash_word_program(INT16U data, INT32U * flash_ptr)
{
	INT32U pass;
	INT32U *pflash_base_addr;
	INT32U *ctrl_addr1, *ctrl_addr2;
	/* Control addresses are left shifted so that */
	/* they appear correctly on the EMIF’s EA[19:2] */
	/* Byte address << 2 == Word Address */
	
	pflash_base_addr = (INT32U *)FLASH_BASE_ADDR;
	ctrl_addr1 = (INT32U *) ((INT32U)pflash_base_addr + (0x555 << 2));
	ctrl_addr2 = (INT32U *) ((INT32U)pflash_base_addr + (0x2aa << 2));;

	* ctrl_addr1 = 0x00aa;
	* ctrl_addr2 = 0x0055;
	* ctrl_addr1 = 0x00a0;
		
	* flash_ptr = data;
		
	pass = poll_data(flash_ptr, data);
	
	if (!pass)
	{
		printf(" Failed at address %x \n\n", (INT32U) flash_ptr);
		exit(0);
	}
	return;
}

void flash_program(INT32U *pflash, INT16U *pdata, INT32U cnt)
{
	INT32U i;

	for ( i=0; i<cnt; i++)
	{
		flash_word_program(*pdata++, pflash++);
	}
	return;
}

⌨️ 快捷键说明

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