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

📄 fbtcmain.c

📁 基于ti 5402dsk的flashburn程序。
💻 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 + -