📄 fbtcmain.c
字号:
/*******************************************************************************
* Copyright 2004-2005 - Software Design Solutions, Inc. All rights reserved.
*
* Portions of this work have been provided under license with Texas
* Instruments Inc.
*
* $RCSfile: FBTCMain.c,v $
* $Revision: 1.10 $
*
* FlashBurn Target Component main routine. Shared by all FBTCs.
******************************************************************************/
#include <stdio.h>
#include "FBTCBurn.h"
#include "FBTCMain.h"
#include "TargetConfig.h"
/**
* Maximum number of data bytes that may be sent in one buffer.
* Making this number larger (up to 32K) will improve data transfer speed
* at the expense of consuming more target RAM during flash programming
*
* Also, making the entire packet an even multiple of 2 sized
*/
#define MAXDATABYTES (8192 - ARGSIZEBYTES - CMDSIZEBYTES)
/**
* Debug printing support - FBTC will run faster if debug printing is off
*/
#define DBPRINT 0
/**
* Version ID of this FBTC in Major.Minor form.
* Major.Minor is 0.0 to 65535.65535
* (thus if major = 1, minor = 20, then version is 00001.00020
*/
#define FBTCVersionMajor 00003
#define FBTCVersionMinor 00000
/*******************************************************************************
* Static data and functions
******************************************************************************/
/*
* This is the Status Word described in the Comm. Protocol Spec.
*/
static u16 m_ProtocolStatusWord = 0;
/*
* Return the protocol version number
*
* @return - The defined protocol version number
*/
static u16 GetProtocolVersionID(void)
{
return (u16)COMMPROTOCOLVERSION;
}
/**
* Set the protocol status word
*/
static void SetErrorBits(u16 x)
{
m_ProtocolStatusWord &= ~(0x000f);
m_ProtocolStatusWord |= ((x) & 0x000f);
}
/*
* Return the current status word
*
* @return - The current status word
*/
static u16 GetProtocolStatusWord(void)
{
return m_ProtocolStatusWord;
}
/*
* Send a command and a 4 byte integer to the host
*
* @param [in] cmd - Command to send to the host
* @param [in] val - 4-byte integer value to send to the host
*
* @post - theMessage contains a command and a 4 byte integer
*/
static void SendI4ToHost(u16 cmd, u32 val)
{
u16 hi = (val & 0xffff0000) >> 16;
u16 lo = (val & 0x0000ffff);
SetCmd(cmd);
SetArg(0, (u16)hi);
SetArg(1, (u16)lo);
}
/*
* Send a command and a 2 byte integer to the host
*
* @param [in] cmd - Command to send to the host
* @param [in] val - 2-byte integer value to send to the host
*
* @post - theMessage contains a command and a 2 byte integer
*/
static void SendI2ToHost(u16 cmd, u16 val)
{
SetCmd(cmd);
SetArg(0, val);
}
/*
* Send the FBTC version to the host.
*
* @post - theMessage contains the FBTC version number
*/
static void SendVersionID()
{
SetCmd(0x000e);
SetArg(0, FBTCVersionMajor);
SetArg(1, FBTCVersionMinor);
}
/*
* Process a command contained in the global message buffer
*
* @pre - theMessage contains a command
* @post - The command is proccessed
*/
void doCommand()
{
u16 cmd = GetCmd();
/*
* Dispatch to a command processor.
* Each case is essentially a message parser.
* Each case will either completely process
* a simple message, or else call a function
* to handle a more complicated message.
*/
switch(cmd)
{
case FBTC_NOP:
#if DBPRINT
printf("FBTC_NOP\n");
#endif
break;
case FBTC_GET_PROTOCOL_VERSION:
#if DBPRINT
printf("FBTC_GET_PROTOCOL_VERSION: 0x%X\n", GetProtocolVersionID());
#endif
SetErrorBits(CMDOK);
SendI2ToHost(cmd, GetProtocolVersionID());
break;
case FBTC_GET_STATUS:
#if DBPRINT
printf("FBTC_GET_STATUS: 0x%X\n", GetProtocolStatusWord());
#endif
SendI2ToHost(cmd, GetProtocolStatusWord());
break;
case FBTC_ERASE:
#if DBPRINT
printf("FBTC_ERASE ... ");
#endif
InitFlash();
SetErrorBits(CMDOK);
EraseFlash();
SendI2ToHost(cmd, 0);
#if DBPRINT
printf("Done\n");
#endif
break;
case FBTC_GET_BASE_ADDR:
#if DBPRINT
{
u16 hi = (FLBASE & 0xffff0000) >> 16;
u16 lo = (FLBASE & 0x0000ffff);
printf("FBTC_GET_BASE_ADDR: 0x%04X %04X\n", hi, lo);
}
#endif
SetErrorBits(CMDOK);
SendI4ToHost(cmd, (u32)FLBASE);
break;
case FBTC_READ:
/* Note: This command is not currently used by the FlashBurn host
* program, but is supported in the FBTC */
#if DBPRINT
printf("FBTC_READ 0x%X, 0x%X\n", GetArg(0), GetArg(1));
#endif
SetErrorBits(CMDOK);
SendI2ToHost(cmd,
GetFlashVal(U16toU32(GetArg(0), GetArg(1))));
break;
case FBTC_READ_BLOCK:
#if DBPRINT
printf("FBTC_READ_BLOCK 0x%X, 0x%X, 0x%X \n", GetArg(0), GetArg(1),
GetArg(2));
#endif
SetErrorBits(CMDOK);
SendFlashBufToHost(cmd,
U16toU32(GetArg(0), GetArg(1)),
GetArg(2));
break;
case FBTC_WRITE_BEGIN:
#if DBPRINT
printf("FBTC_WRITE_BEGIN 0x%X, 0x%X, 0x%X \n", GetArg(0), GetArg(1),
GetArg(2));
#endif
SetErrorBits(CMDOK);
BurnFlash(U16toU32(GetArg(0), GetArg(1)),
GetDataPtr(),
GetArg(2));
break;
case FBTC_WRITE_CONTINUE:
/* Note: This command is not currently used by the FlashBurn host
* program, but is supported in the FBTC */
#if DBPRINT
printf("FBTC_WRITE_CONTINUE 0x%X\n", GetArg(0));
#endif
SetErrorBits(CMDOK);
BurnFlash(0, /* No offset */
GetDataPtr(),
GetArg(0));
break;
case FBTC_GET_CHECKSUM:
#if DBPRINT
printf("FBTC_GET_CHECKSUM 0x%X, 0x%X, 0x%X, 0x%X \n", GetArg(0),
GetArg(1), GetArg(2), GetArg(3));
#endif
SetErrorBits(CMDOK);
CKSSet(0);
SendI2ToHost(cmd,
CKSAccumBuf(U16toU32(GetArg(0), GetArg(1)),
U16toU32(GetArg(2), GetArg(3))));
break;
case FBTC_USER_DATA:
/*
* Simply accept & toss data.
* This is used internally for timing tests
* It could contain your own proprietary
* commands or data, sort of an escape
* sequence.
*/
#if DBPRINT
printf("FBTC_USER_DATA: 0x%X\n", GetArg(0));
#endif
SetErrorBits(CMDOK);
/* This implementation doesn't do anything
* with the data)
*/
SendI2ToHost(cmd, 0);
break;
case FBTC_GET_FLASHSIZE:
#if DBPRINT
{
u16 hi = (GetFlashSize() & 0xffff0000) >> 16;
u16 lo = (GetFlashSize() & 0x0000ffff);
printf("FBTC_GET_FLASHSIZE: 0x%04X %04X\n", hi, lo);
}
#endif
SetErrorBits(CMDOK);
SendI4ToHost(cmd, GetFlashSize());
break;
case FBTC_SET_BASE_ADDR:
#if DBPRINT
printf("FBTC_SET_BASE_ADDR: 0x%X, 0x%X\n", GetArg(0), GetArg(1));
#endif
SetErrorBits(CMDOK);
// Base address is sent down in 2 parts
SetFlashBase((FLASH_DATA_TYPE*)(PTR_SIZED_INT)U16toU32(GetArg(0), GetArg(1)));
break;
case FBTC_SET_FLASHSIZE:
#if DBPRINT
printf("FBTC_SET_FLASHSIZE: 0x%X, 0x%X\n", GetArg(0), GetArg(1));
#endif
SetErrorBits(CMDOK);
SetFlashSize(U16toU32(GetArg(0), GetArg(1)));
break;
case FBTC_GET_FBTC_VERSION:
#if DBPRINT
printf("FBTC_GET_FBTC_VERSION: %d.%d\n", FBTCVersionMajor,
FBTCVersionMinor);
#endif
SetErrorBits(CMDOK);
SendVersionID();
break;
case FBTC_GET_FLASH_EDIT_PERM:
#if DBPRINT
printf("FBTC_GET_FLASH_EDIT_PERM: 0x%X\n", EDITFLASHPERMIT);
#endif
SetErrorBits(CMDOK);
SendI2ToHost(cmd, EDITFLASHPERMIT);
break;
case FBTC_GET_MAX_BLOCKSIZE:
#if DBPRINT
printf("FBTC_GET_MAX_BLOCKSIZE: 0x%X\n", MAXDATABYTES);
#endif
SetErrorBits(CMDOK);
SendI2ToHost(cmd, MAXDATABYTES);
break;
case FBTC_GET_ERASE_ESTIMATE:
#if DBPRINT
printf("FBTC_GET_ERASE_ESTIMATE: 0x%X\n", ERASEESTIMATE);
#endif
SetErrorBits(CMDOK);
SendI2ToHost(cmd, ERASEESTIMATE);
break;
case FBTC_GET_FLASH_ADDRS:
#if DBPRINT
printf("FBTC_GET_FLASH_ADDRS: 0x%X\n", GetArg(0));
#endif
GetFlashAddresses(GetArg(0));
SetErrorBits(CMDOK);
break;
default:
#if DBPRINT
printf(" *** UNKNOWN CMD: 0x%X\n", cmd);
#endif
break;
}
}
/*******************************************************************************
* Global message buffer and processing function
******************************************************************************/
/**
* Commands for setting and getting portions of a message
*/
/**
* Store a command ID into the command buffer
*
* @param [in] cmd - Command ID to store
*
* @post - The command ID is stored in the buffer
*/
void SetCmd(u16 cmd)
{
if (BYTESPERMAU == 1)
{
/* Message buffer is packed big endian */
theMessage[CMDINDEX] = cmd >> 8;
theMessage[CMDINDEX+1] = cmd & 0x00ff;
}
else
{
theMessage[CMDINDEX] = cmd;
}
}
/**
* Get a command ID from the command buffer
*
* @return - The command ID from the command buffer
*/
u16 GetCmd(void)
{
if (BYTESPERMAU == 1)
{
/* Message buffer is packed big endian */
return ((u16) theMessage[CMDINDEX] << 8) |
((u16) theMessage[CMDINDEX+1]);
}
else
{
return theMessage[CMDINDEX];
}
}
/**
* Set an argument in the command buffer
*
* @param [in] index - Argument index, 0..15
* @param [in] val - Value for the argument
*
* @post - Command buffer contains the given argument
*/
void SetArg(int index, u16 val)
{
if (BYTESPERMAU == 1)
{
/* Message buffer is packed big endian */
int myindex = ARGINDEX + index * 2;
theMessage[myindex] = val >> 8;
theMessage[myindex+1] = val & 0x00ff;
}
else
{
theMessage[ARGINDEX + index] = val;
}
}
/**
* Get an argument value from the command buffer
*
* @param [in] index - Index of the argument value to retrieve, 0..15
*
* @return - The argument value
*/
u16 GetArg(int index)
{
if (BYTESPERMAU == 1)
{
/* Message buffer is packed big endian */
int myindex = ARGINDEX + index * 2;
return ((u16)theMessage[myindex] << 8) |
((u16)theMessage[myindex+1]);
}
else
{
return theMessage[ARGINDEX + index];
}
}
/**
* Get a pointer to the entire command message buffer
*
* @return - Pointer to the command message buffer
*/
MSG_DATA_TYPE *GetMessagePtr(void)
{
return &theMessage[0];
}
/**
* Get a pointer to the data portion of the message
*
* @return - Pointer to the data portion of the command message buffer
*/
MSG_DATA_TYPE *GetDataPtr(void)
{
return &theMessage[DATAINDEX];
}
/**
* Get the data item at the given index within the data
*
* @param [in] index - Zero based index within the data portion of the command
*
* @return - Data at the given index
*/
MSG_DATA_TYPE GetData(int index)
{
return theMessage[DATAINDEX + index];
}
/**
* Set the data item at the given index within the data
*
* @param [in] index - Zero based index within the data portion of the command
* @param [in] val - Value for the data to set
*
* @post - Data at the given index is set
*/
void SetData(int index, MSG_DATA_TYPE val)
{
theMessage[DATAINDEX + index] = val;
}
/**
* Create a U32 value from two U16 values
*
* @param [in] hi - U16 value for MSB
* @param [in] lo - U16 value for LSB
*
* @return The 32 bit value
*/
u32 U16toU32(u16 hi, u16 lo)
{
u32 val;
val = hi;
val <<= 16;
val |= lo;
return val;
}
/**
* The host uses this global message buffer for sending and receiving FBTC
* messages.
*/
MSG_DATA_TYPE theMessage[CMDSIZEBYTES / BYTESPERMAU
+ ARGSIZEBYTES / BYTESPERMAU
+ MAXDATABYTES / BYTESPERMAU] = {0};
/**
* A breakpoint will be set on this global function.
* When the FBTC program hits the breakpoint, the host will detect the halt and
* process any response info that may be in theMessage global buffer.
* When Host wants to send a message to this FBTC, it will store the message
* into theMessage and start this FBTC running.
*/
void doMessageProc()
{
/*
* The compiler will want to delete this function, since it doesn't
* appear to do anything useful. Assigning a value to a volatile variable
* forces optimizer to keep this code.
*/
volatile int FoolTheOptimizer = 0;
}
/**
* Main routine for the FBTC.
*/
void main()
{
/*
* User comfort message.
* Note: runs faster and leaner if no printf used anywhere
*/
#if DBPRINT
printf("Target FBTC Running\n");
#endif
InitFlash();
/*
* Runs forever.
*/
for(;;)
{
doMessageProc(); /* When this returns, a new message from the host */
/* exists in theMessage */
doCommand(); /* Process the new message */
}
/* Never returns ... */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -