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

📄 flash.c

📁 DSP 5409 plc应用程序,调试通过,是用在电力线通讯上的演示程序.
💻 C
📖 第 1 页 / 共 4 页
字号:
//==========================================================================================
// Filename:		Flash.c
//
// Description:		Routines for managing flash access and code images
//
// Copyright (C) 2001 - 2003 Texas Instruments Incorporated
// Texas Instruments Proprietary Information
// Use subject to terms and conditions of TI Software License Agreement
//
// The flash is partitioned into distinct areas for different purposes of operation.
// 
// flash partitioning is:
//   0x000000 - 0x00007F => reserved
//   0x018000 - 0x01FFFF => active code image
//   0x028000 - 0x02FFFF => DSP code download image
//   0x038000 - 0x03FFFF => data logging space
//
// The DSP and MSP cannot have any ROM image existing at address zero so tags are placed
// there indicating status of images
// 0x010000 = DSP code tag address
//
// Tags are image status for active and erasable
//   0xFFFF => the image does not exist, set by default when an erasure occurs
//   0x1248 => the image has been downloaded and should be used to overwrite the current one
//   0x0000 => the image is unused and can be erased
// Note:  Since writing to flash can only be done when bits are changed from a 1 to a 0,
//        the tags are assigned values which allow each succesive value to be written on
//        top of the previous tag value.
//
//	The user code must have its entry point at 0x0080, NO EXCEPTIONS!
//
// Revision History:
//==========================================================================================

//==========================================================================================
// included files
//==========================================================================================
#include "ofdm_modem.h"
#include "ofdm_datatypes.h"
#include "ofdm_functions.h"
#include "intr.h"
#include "Flash.h"

//==========================================================================================
// local definitions for flash management
//==========================================================================================
#define FLASH_IMAGE_LOAD            (0x1248u)
#define FLASH_IMAGE_PROG            (0x028000ul)
#define FLASH_IMAGE_ACTIVE          (0x018000ul)
#define FLASH_IMAGE_BOOT			(0x00FF80ul)
#define FLASH_BOOT_CODE_TAG         (0x3CA5u)
#define FLASH_IMAGE_PROG_TAG_OFFSET (2)
#define FLASH_BOOT_CODE_TAG_OFFSET	(127)
#define FLASH_PROG_CODE_UPPER_LIMIT (0x7FFFul)
#define FLASH_PROG_CODE_LOWER_LIMIT (0x0080ul)
#define FLASH_LOG_BASE_ADDRESS		(0x038000ul)
#define FLASH_LOG_MAX_SIZE			(0x008000ul)
#define ERASED_FLASH_VALUE			(0xFFFFu)
#define DOWN_LOAD_TIMEOUT			(0x4000u)
#define LED_START					(0X80)
#define LED_UPDATE_RATE				(300)

//==========================================================================================
// exported global variables
//==========================================================================================
u16 FlashLEDMask = 0;										// used to output flash status to LED's
u32 FlashLogSize;											// indicates the current size of the data log in flash

//==========================================================================================
// Local function declarations
//==========================================================================================
void RunStateMachine(i16 Target, u32 Address, u16 Data, i16 Operation);
i16  GetBufferCharacter(i16 Position);
void DoEraseSector(i16 Target, u32 SectorAddress);
u16  ReadHexNumber(i16 Digits, i16* Position);
u16  Xlate(u16 Data);
u16  UnXlate(u16 Data);
i16  ValidateFlashModification(void);
void EnableFlashWriteAccess(void);
void DisableFlashWriteAccess(void);
i16  ValidateFlashComponent(void);
void WriteFlash(u32 Address, u16 Data);
u32  GetBaseAddress(i16 Target);
void UpdateStatus(i16 Target);
void ResetProcessor(void);

//==========================================================================================
// state machine function prototypes, each function is a different state
//==========================================================================================
void* SM_Idle(void);  
void* CommandPolling(void);
void* EraseCommandPolling(void);
void* EraseFlash(void);
void* EraseSector(void);
void* WriteFlashData(void);

//==========================================================================================
// globals local to this file hence the static prefix
//==========================================================================================
static u16   StateMachineStatus = FLASH_STATUS_COMPLETE;	// indicates status of the state machine
static void* CurrentState;									// holds current state of the state machine
static i16   TranslationMap[] = {0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15};// for Xlate() and UnXlate()
static i16   EnableFlashWrites;								// a protection flag, must be set to do writes
static u16   FlashProgBuffer[16];							// buffer for DSP program image writes
static u16   FlashLogBuffer[FLASH_LOG_RECORD_MAX_SIZE + 2];	// buffer for flash log writes
static u16   FlashBootBuffer[1];							// the buffer for boot sector writes
static u16   FlashCopyBuffer[1];							// the buffer for copying flash to flash
static u16*  FlashBuffer[FLASH_TARGET_COUNT] = { FlashProgBuffer, 0/* MSP placeholder */, FlashLogBuffer, FlashBootBuffer, FlashCopyBuffer };// pointers to the buffers
static i16   FlashSize[FLASH_TARGET_COUNT];					// size of data in buffers, zero indicates buffer is not busy, negative indicates erase
static i16   WriteTag[FLASH_TARGET_COUNT];					// flags to indicate needed update of tags for images
static i16   CurrentTarget;									// points to the currently active target of the state machine
static u32   FlashLoadAddress[FLASH_TARGET_COUNT];			// current address for current buffer data
static u16	 DownLoadActive;
static u16   DisplayMode;
static u16   Dir;
static u16   TargetStatus[FLASH_TARGET_COUNT];
static struct 
{
	u16  Data;
	u32 Address;
}	StateData;

//==========================================================================================
// Function:		ResetProcessor()		
//
// Description:		Sets the PMST register similar to that of a hard reset and
//                  jumps to the reset vector at 0xFF80.  This function never returns
//
// Revision History:
//==========================================================================================
void ResetProcessor(void)
{
	INTR_GLOBAL_DISABLE();	// Disable Global Interrupts (if they were enabled)

	asm(" STM 0xFFE0, 0x1D");	// reset the PMST register
	asm(" NOP"); 			// wait for changed to take effect
	asm(" NOP"); 
	asm(" NOP"); 
	asm(" NOP"); 
	asm(" NOP"); 
	asm(" B   0xFF80");		// jump to reset vector
}

//==========================================================================================
// Function:		InitFlash()		
//
// Description:		initializes globals and initial state, checks for flash operation
//                  and updates MSP code if needed base on MSP tag value
//
// Revision History:
//==========================================================================================
void InitFlash(void)
{
	u32 j;
	i16 i;
	u16 BootCode[] = {										// the boot code, copies flash to RAM and executes
//	/* 0xFF80 */ 0xF073u,	// FF80: B FF80					; branch to self, debug bring up
//	/* 0xFF81 */ 0xFF80u,
	/* 0xFF80 */ 0xF495u,	// FF80: NOP					; non debug bring up
	/* 0xFF81 */ 0xF495u,	// FF81: NOP
	/* 0xFF82 */ 0x771Du,	// FF82: STM FFE8h, PMST		; set PMST to overlay RAM in program space
	/* 0xFF83 */ 0xFFE8u,
	/* 0xFF84 */ 0xF495u,	// FF84: NOP
	/* 0xFF85 */ 0xF495u,	// FF85: NOP
	/* 0xFF86 */ 0xF495u,	// FF86: NOP
	/* 0xFF87 */ 0xF495u,	// FF87: NOP
	/* 0xFF88 */ 0xF495u,	// FF88: NOP
	/* 0xFF89 */ 0xF495u,	// FF89: NOP
	/* 0xFF8A */ 0xF495u,	// FF8A: NOP
	/* 0xFF8B */ 0x7708u,	// FF8B: STM 	0, 8h			; point accumulator A to downloaded program image tag
	/* 0xFF8C */ 0x0000u,
	/* 0xFF8D */ 0x7709u,	// FF8D: STM 	0, 9h
	/* 0xFF8E */ 0x0000u,
	/* 0xFF8F */ 0x770Au,	// FF8F: STM 	0, ah
	/* 0xFF90 */ 0x0000u,
	/* 0xFF91 */ 0xF3C0u,	// FF91: XOR 	B, B			; clear accumulator B
	/* 0xFF92 */ 0x7E0Bu,	// FF92: READA 	bh				; read the tag value into lower word of accumulator B
	/* 0xFF93 */ 0xF310u,	// FF93: SUB 	#0, B			; check tag for active download
	/* 0xFF94 */ 0x0000u,
	/* 0xFF95 */ 0xF84Du,	// FF95: BC		LOAD_NEW, BEQ	; if an active tag, load the new image
	/* 0xFF96 */ 0xFF9Fu,
	/* 0xFF97 */ 0x7708u,	// FF97: STM 	0, 8h		 	; load address of old image
	/* 0xFF98 */ 0x0000u,
	/* 0xFF99 */ 0x7709u,	// FF99: STM 	0, 9h
	/* 0xFF9A */ 0x0000u,
	/* 0xFF9B */ 0x770Au,	// FF9B: STM 	0, ah
	/* 0xFF9C */ 0x0000u,
	/* 0xFF9D */ 0xF073u,	// FF9D: B 		DO_LOAD			; start loading the old image
	/* 0xFF9E */ 0xFFA5u,
							//      LOAD_NEW
	/* 0xFF9F */ 0x7708u,	// FF9F: STM	0, 8h			; load address of new image
	/* 0xFFA0 */ 0x0000u,
	/* 0xFFA1 */ 0x7709u,	// FFA1: STM	0, 9h
	/* 0xFFA2 */ 0x0000u,
	/* 0xFFA3 */ 0x770Au,	// FFA3: STM	0, ah
	/* 0xFFA4 */ 0x0000u,
							//      DO_LOAD
	/* 0xFFA5 */ 0x7711u,	// FFA5: STM #80h, AR1			; initialize ar1 to point to beginning of ram too
	/* 0xFFA6 */ 0x0080u,
	/* 0xFFA7 */ 0xF495u,	// FFA7: NOP					; stall for debugging
	/* 0xFFA8 */ 0xF495u,	// FFA8: NOP
	/* 0xFFA9 */ 0xF070u,	// FFA9: RPT #7F7Fh				; load number of words to copy from flash - 1
	/* 0xFFAA */ 0x0000u,
	/* 0xFFAB */ 0x7E91u,	// FFAB: READA *AR1+			; copy from flash (in acc a) to data space (in ar1)
	/* 0xFFAC */ 0xF495u,	// FFAC: NOP
	/* 0xFFAD */ 0xF495u,	// FFAD: NOP
	/* 0xFFAE */ 0xF495u,	// FFAE: NOP
	/* 0xFFAF */ 0xF495u,	// FFAF: NOP
	/* 0xFFB0 */ 0xF495u,	// FFB0: NOP
	/* 0xFFB1 */ 0x771Du,	// FFB1: STM 00E8h,PMST			; set PMST to execute from RAM also
	/* 0xFFB2 */ 0x00E8u,
	/* 0xFFB3 */ 0xF495u,	// FFB3: NOP
	/* 0xFFB4 */ 0xF495u,	// FFB4: NOP
	/* 0xFFB5 */ 0xF495u,	// FFB5: NOP
	/* 0xFFB6 */ 0xF495u,	// FFB6: NOP
	/* 0xFFB7 */ 0xF495u,	// FFB7: NOP
	/* 0xFFB8 */ 0xF495u,	// FFB8: NOP
	/* 0xFFB9 */ 0xF495u,	// FFB9: NOP
	/* 0xFFBA */ 0xF073u,	// FFBA: B 0x0080				; branch to user code at user reset vector
	/* 0xFFBB */ 0x0080u };
	u16 BootCodeLength = 0xFFBBu - 0xFF80u + 1;				// number of instruction words in boot code

	// patch the download image tag address into the assembly code
	BootCode[12] = (u16)((FLASH_IMAGE_PROG + FLASH_IMAGE_PROG_TAG_OFFSET) & 0xFFFFul);
	BootCode[14] = (u16)(((FLASH_IMAGE_PROG + FLASH_IMAGE_PROG_TAG_OFFSET) >> 16) & 0x007Ful);
	BootCode[16] = 0u;

	// patch the tag value for loading into the assembly code
	BootCode[20] = (u16)(FLASH_IMAGE_LOAD);

	// patch the active image base address into the assembly code
	BootCode[24] = (u16)((FLASH_IMAGE_ACTIVE + FLASH_PROG_CODE_LOWER_LIMIT) & 0xFFFFul);
	BootCode[26] = (u16)(((FLASH_IMAGE_ACTIVE + FLASH_PROG_CODE_LOWER_LIMIT) >> 16) & 0x007Ful);
	BootCode[28] = 0u;

	// patch the new image base address into the assembly code
	BootCode[32] = (u16)((FLASH_IMAGE_PROG + FLASH_PROG_CODE_LOWER_LIMIT) & 0xFFFFul);
	BootCode[34] = (u16)(((FLASH_IMAGE_PROG + FLASH_PROG_CODE_LOWER_LIMIT) >> 16) & 0x007Ful);
	BootCode[36] = 0u;

	// patch the download count
	BootCode[42] = (u16)(FLASH_PROG_CODE_UPPER_LIMIT - FLASH_PROG_CODE_LOWER_LIMIT);

	DownLoadActive = 0;										// clear the downloading flag
	Dir = 0;												// initialize direction of indicators
	FlashLEDMask = 0;										// initialize the indicator
	
	for(i = 0; i < FLASH_TARGET_COUNT; i++)					// loop through all targets clearing state data
	{
		FlashLoadAddress[i] = 0;
		FlashSize[i]        = 0;
		WriteTag[i]         = 0;
		TargetStatus[i]     = 0;
	}

	CurrentTarget = 0;										// initialize target counter
	CurrentState = SM_Idle;									// initialize the state machine state
  
	if(ValidateFlashComponent() != 0)						// a quick check to believe everything is OK
	{
		FlashLEDMask = 0xFF;								// indicate failure
		AssignLEDs(FlashLEDMask);							// forces output
		for(;;);											// lock up the system
	}

// FORCE ERASE -- if the following line of code is uncommented, the flash will be erased on boot
//	RunStateMachine(FLASH_TARGET_BOOT, 0, ERASED_FLASH_VALUE, -1);	// erase the flash

	for(j = 0; j < BootCodeLength; j++)						// loop through all boot code
	{
		if(BootCode[j] != ReadFlash(0xFF80u + j))			// if code word fails to compare with expected
		{
			RunStateMachine(FLASH_TARGET_BOOT, FLASH_BOOT_CODE_TAG_OFFSET, 0, 1);	// invalidate the boot tag
			break;											// exit the loop
		}
	}
															// if boot code appears corrupted or missing
	if(ReadFlash(GetBaseAddress(FLASH_TARGET_BOOT) + FLASH_BOOT_CODE_TAG_OFFSET) != FLASH_BOOT_CODE_TAG)
	{
		RunStateMachine(FLASH_TARGET_BOOT, 0, ERASED_FLASH_VALUE, -2);	// erase the boot sector
  
		// copy the boot code to flash
		for(j = 0; j < BootCodeLength; j++)					// loop through all boot code
		{													// copy this word of the boot code
			RunStateMachine(FLASH_TARGET_BOOT, j, BootCode[j], 1);
		}
    
															// update the boot code tag
		RunStateMachine(FLASH_TARGET_BOOT, FLASH_BOOT_CODE_TAG_OFFSET, FLASH_BOOT_CODE_TAG, 1);
	}
															// if need to update DSP code image
	if(ReadFlash(GetBaseAddress(FLASH_TARGET_PROG) + FLASH_IMAGE_PROG_TAG_OFFSET) == FLASH_IMAGE_LOAD)
	{
		// erase the DSP active sector
		RunStateMachine(FLASH_TARGET_COPY, 0, ERASED_FLASH_VALUE, -2);	// erase this sector
    
		// copy the DSP code to low flash
		for(j = FLASH_PROG_CODE_LOWER_LIMIT; j <= FLASH_PROG_CODE_UPPER_LIMIT; j++)	// loop through all code space
		{													// copy this word of the code image
			RunStateMachine(FLASH_TARGET_COPY, j, ReadFlash(GetBaseAddress(FLASH_TARGET_PROG) + j), 1);
		}

		// update the DSP code image tag
		RunStateMachine(FLASH_TARGET_PROG, FLASH_IMAGE_PROG_TAG_OFFSET, 0, 1);
		ResetProcessor();									// run the newly loaded code
	}
															// if need to update MSP code image
	// by definition, the download image for the DSP will have been cleared by this point  
	// initialize flash log size variable by running through the linked list
	FlashLogSize = 0;										// point to beginning of log records list
	do														// loop through log records
	{
		j = ReadFlash(FlashLogSize + FLASH_LOG_BASE_ADDRESS);	// get high word of succeeding record pointer
		j <<= 16;											// move it into the high word
		j += ReadFlash(FlashLogSize + FLASH_LOG_BASE_ADDRESS + 1);	// get low word of succeeding record pointer
 
		if(j != 0xFFFFFFFFul)								// if not at end of linked list
		{
			if(j <= FlashLogSize || j >= FLASH_LOG_MAX_SIZE)	// if the linked list appears corrupt
			{
				uFlashLogStatus = FLASH_STATUS_TIMEOUT;		// set the log status
				break;										// exit the loop
			}
			FlashLogSize = j;								// move to the next record in the list

⌨️ 快捷键说明

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