?? bsldemo.c
字號:
/****************************************************************
*
* Copyright (C) 1999-2000 Texas Instruments, Inc.
* Author: Volker Rzehak
*
*----------------------------------------------------------------
* All software and related documentation is provided "AS IS" and
* without warranty or support of any kind and Texas Instruments
* expressly disclaims all other warranties, express or implied,
* including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. Under no
* circumstances shall Texas Instruments be liable for any
* incidental, special or consequential damages that result from
* the use or inability to use the software or related
* documentation, even if Texas Instruments has been advised of
* the liability.
*
* Unless otherwise stated, software written and copyrighted by
* Texas Instruments is distributed as "freeware". You may use
* and modify this software without any charge or restriction.
* You may distribute to others, as long as the original author
* is acknowledged.
*
****************************************************************
*
* Project: MSP430 Bootstrap Loader Demonstration Program
*
* File: BSLDEMO.C
*
* Description:
* This is the main program of the bootstrap loader
* demonstration.
* The main function holds the general sequence to access the
* bootstrap loader and program/verify a file.
* The parsing of the TI TXT file is done in a separate
* function.
*
* A couple of parameters can be passed to the program to
* control its functions. For a detailed description see the
* appendix of the corresponding application note.
*
* History:
* Version 1.00 (05/2000)
* Version 1.10 (08/2000)
* - Help screen added.
* - Additional mass erase cycles added
* (Required for larger flash memories)
* Defined with: #define ADD_MERASE_CYCLES 20
* - Possibility to load a completely new BSL into RAM
* (supposing there is enough RAM) - Mainly a test feature!
* - A new workaround method to cope with the checksum bug
* established. Because this workaround is incompatbile with
* the former one the required TI TXT file is renamed to
* "PATCH.TXT".
* Version 1.11 (09/2000)
* - Added handling of frames with odd starting address
* to BSLCOMM.C. (This is required for loaders with word
* programming algorithm! > BSL-Version >= 1.30)
* - Changed default number of data bytes within one frame
* to 240 bytes (old: 64). Speeds up programming.
* - Always read BSL version number (even if new one is loaded
* into RAM.
* - Fixed setting of warning flag in conjunction with loading
* a new BSL into RAM.
* - Added a byte counter to the programTIText function.
* - Number of mass erase cycles can be changed via command
* line option (-m)
* Version 1.12 (09/2000)
* - Minor fixes and cosmetics.
*
****************************************************************/
#include <string.h>
#include <stdio.h>
#include <windows.h>
#include "bslcomm.h"
/*---------------------------------------------------------------
* Defines:
*---------------------------------------------------------------
*/
/* This definition includes code to load a new BSL into RAM:
* NOTE: Can only be used with devices with sufficient RAM!
* The program flow is changed slightly compared to a version
* without "NEW_BSL" defined.
* The definition also defines the filename of the TI-TXT file
* with the new BSL code.
*/
#define NEW_BSL
/* The "WORKAROUND" definition includes code for a workaround
* required by the first version(s) of the bootstrap loader.
*/
#define WORKAROUND
/* If "DEBUG" is defined, all checked and programmed blocks are
* logged on the screen.
*/
//#define DEBUG
/* Additional mass erase cylces required for (some) F149 devices.
* If ADD_MERASE_CYCLES is not defined only one mass erase
* cycle is executed.
* Remove #define for fixed F149 or F11xx devices.
*/
#define ADD_MERASE_CYCLES 20
/* Error: verification failed: */
#define ERR_VERIFY_FAILED 98
/* Error: erase check failed: */
#define ERR_ERASE_CHECK_FAILED 97
/* Error: unable to open input file: */
#define ERR_FILE_OPEN 96
/* Mask: program data: */
#define ACTION_PROGRAM 0x01
/* Mask: verify data: */
#define ACTION_VERIFY 0x02
/* Mask: erase check: */
#define ACTION_ERASE_CHECK 0x04
/* Mask: transmit password: */
/* Note: Should not be used in conjunction with any other action! */
#define ACTION_PASSWD 0x08
/*---------------------------------------------------------------
* Global Variables:
*---------------------------------------------------------------
*/
char *programName= "MSP430 Bootstrap Loader Demonstration Program";
char *programVersion= "Version 1.12";
/* Max. bytes sent within one frame if parsing a TI TXT file.
* ( >= 16 and == n*16 and <= MAX_DATA_BYTES!)
*/
int maxData= 240;
/* Buffers used to store data transmitted to and received from BSL: */
BYTE blkin [MAX_DATA_BYTES]; /* Receive buffer */
BYTE blkout[MAX_DATA_BYTES]; /* Transmit buffer */
#ifdef WORKAROUND
char *patchFile = "PATCH.TXT";
#endif /* WORKAROUND */
BOOL patchRequired = FALSE;
BOOL patchLoaded = FALSE;
WORD bslVer= 0;
char *newBSLFile= NULL;
struct toDoList
{
unsigned MassErase : 1;
unsigned EraseCheck: 1;
unsigned Program : 1;
unsigned Verify : 1;
unsigned Reset : 1;
unsigned Wait : 1; /* Wait for <Enter> at end of program */
/* (0: no; 1: yes): */
unsigned OnePass : 1; /* Do EraseCheck, Program and Verify */
/* in one pass (TI TXT file is read */
/* only once) */
} toDo;
void *errData= NULL;
int byteCtr= 0;
/*---------------------------------------------------------------
* Functions:
*---------------------------------------------------------------
*/
int preparePatch()
{
int error= ERR_NONE;
#ifdef WORKAROUND
if (patchLoaded)
{
/* Load PC with 0x0220.
* This will invoke the patched bootstrap loader subroutines.
*/
error= bslTxRx(BSL_LOADPC, /* Command: Load PC */
0x0220, /* Address to load into PC */
0, /* No additional data! */
NULL, blkin);
if (error != ERR_NONE) return(error);
BSLMemAccessWarning= 0; /* Error is removed within workaround code */
}
#endif /* WORKAROUND */
return(error);
}
void postPatch()
{
#ifdef WORKAROUND
if (patchLoaded)
{
BSLMemAccessWarning= 1; /* Turn warning back on. */
}
#endif /* WORKAROUND */
}
int verifyBlk(WORD addr, WORD len, unsigned action)
{
int i= 0;
int error= ERR_NONE;
if ((action & (ACTION_VERIFY | ACTION_ERASE_CHECK)) != 0)
{
#ifdef DEBUG
printf("Check starting at %x, %i bytes... ", addr, len);
#endif /* DEBUG */
error= preparePatch();
if (error != ERR_NONE) return(error);
error= bslTxRx(BSL_RXBLK, addr, len, NULL, blkin);
postPatch();
#ifdef DEBUG
printf("Error: %i\n", error);
#endif /* DEBUG */
if (error != ERR_NONE)
{
return(error); /* Cancel, if read error */
}
else
{
for (i= 0; i < len; i++)
{
if ((action & ACTION_VERIFY) != 0)
{
/* Compare data in blkout and blkin: */
if (blkin[i] != blkout[i])
{
printf("Verification failed at %x (%x, %x)\n", addr+i, blkin[i], blkout[i]);
return(ERR_VERIFY_FAILED); /* Verify failed! */
}
continue;
}
if ((action & ACTION_ERASE_CHECK) != 0)
{
/* Compare data in blkin with erase pattern: */
if (blkin[i] != 0xff)
{
printf("Erase Check failed at %x (%x)\n", addr+i, blkin[i]);
return(ERR_ERASE_CHECK_FAILED); /* Erase Check failed! */
}
continue;
} /* if ACTION_ERASE_CHECK */
} /* for (i) */
} /* else */
} /* if ACTION_VERIFY | ACTION_ERASE_CHECK */
return(error);
}
int programBlk(WORD addr, WORD len, unsigned action)
{
int i= 0;
int error= ERR_NONE;
if ((action & ACTION_PASSWD) != 0)
{
return(bslTxRx(BSL_TXPWORD, /* Command: Transmit Password */
addr, /* Address of interupt vectors */
len, /* Number of bytes */
blkout, blkin));
} /* if ACTION_PASSWD */
/* Check, if specified range is erased: */
error= verifyBlk(addr, len, action & ACTION_ERASE_CHECK);
if (error != ERR_NONE)
{
return(error);
}
if ((action & ACTION_PROGRAM) != 0)
{
#ifdef DEBUG
printf("Program starting at %x, %i bytes... ", addr, len);
#endif /* DEBUG */
error= preparePatch();
if (error != ERR_NONE) return(error);
/* Program block: */
error= bslTxRx(BSL_TXBLK, addr, len, blkout, blkin);
postPatch();
#ifdef DEBUG
printf("Error: %i\n", error);
#endif /* DEBUG */
if (error != ERR_NONE)
{
return(error); /* Cancel, if error (ACTION_VERIFY is skipped!) */
}
} /* if ACTION_PROGRAM */
/* Verify block: */
error= verifyBlk(addr, len, action & ACTION_VERIFY);
if (error != ERR_NONE)
{
return(error);
}
return(error);
} /* programBlk */
int programTIText (char *filename, unsigned action)
{
int next= 1;
int error= ERR_NONE;
int linelen= 0;
int linepos= 0;
WORD dataframelen=0;
WORD currentAddr;
char strdata[128];
FILE* infile;
byteCtr= 0;
if ((infile = fopen(filename, "rb")) == 0)
{
errData= filename;
return(ERR_FILE_OPEN);
}
/* Convert data for MSP430, TXT-File is parsed line by line: */
for (next= 1; next>=1; )
{
/* Read one line: */
if ((fgets(strdata, 127, infile) == 0) ||
/* if End Of File or */
(strdata[0] == 'q'))
/* if q (last character in file) */
{ /* => send frame and quit */
if (dataframelen > 0) /* Data in frame? */
{
error= programBlk(currentAddr, dataframelen, action);
byteCtr+= dataframelen; /* Byte Counter */
dataframelen=0;
}
next=0; /* Quit! */
continue;
}
linelen= strlen(strdata);
if (strdata[0] == '@')
/* if @ => new address => send frame and set new addr. */
{
if (dataframelen > 0)
{
error= programBlk(currentAddr, dataframelen, action);
byteCtr+= dataframelen; /* Byte Counter */
dataframelen=0;
}
sscanf(&strdata[1], "%lx\n", ¤tAddr);
continue;
}
/* Transfer data in line into blkout: */
for(linepos= 0;
linepos < linelen-3; linepos+= 3, dataframelen++)
{
sscanf(&strdata[linepos], "%3x", &blkout[dataframelen]);
/* (Max 16 bytes per line!) */
}
if (dataframelen > maxData-16)
/* if frame is getting full => send frame */
{
error= programBlk(currentAddr, dataframelen, action);
byteCtr+= dataframelen; /* Byte Counter */
currentAddr+= dataframelen;
dataframelen=0;
}
if (error != ERR_NONE)
{
next=0; /* Cancel loop, if any error */
}
}
fclose(infile);
return(error);
} /* programTIText */
int txPasswd(char* passwdFile)
{
int i;
if (passwdFile == NULL)
{
/* Send "standard" password to get access to protected functions. */
printf("Transmit Password...\n");
/* Fill blkout with 0xff
* (Flash is completely erased, the contents of all Flash cells is 0xff)
*/
for (i= 0; i < 0x20; i++)
{
blkout[i]= 0xff;
}
return(bslTxRx(BSL_TXPWORD, /* Command: Transmit Password */
0xffe0, /* Address of interupt vectors */
0x0020, /* Number of bytes */
blkout, blkin));
}
else
{
/* Send TI TXT file holding interrupt vector data as password: */
printf("Transmit password file \"%s\"...\n", passwdFile);
return(programTIText(passwdFile, ACTION_PASSWD));
}
} /* txPasswd */
int signOff(int error, BOOL passwd)
{
if (toDo.Reset)
{
bslReset(0); /* Reset MSP430 and start user program. */
}
switch (error)
{
case ERR_NONE:
printf("Programming completed!\n");
break;
case ERR_BSL_SYNC:
printf("ERROR: Syncronization failed!\n");
printf("Device with boot loader connected?\n");
break;
case ERR_VERIFY_FAILED:
printf("ERROR: Verification failed!\n");
break;
case ERR_ERASE_CHECK_FAILED:
printf("ERROR: Erase check failed!\n");
break;
case ERR_FILE_OPEN:
printf("ERROR: Unable to open input file \"%s\"!\n", (char*)errData);
break;
default:
if ((passwd) && (error == ERR_RX_NAK))
/* If last command == transmit password && Error: */
printf("ERROR: Password not accepted!\n");
else
printf("ERROR: Communication Error!\n");
} /* switch */
if (toDo.Wait)
{
printf("Press <ENTER> ...\n"); getchar();
}
comDone(); /* Release serial communication port. */
/* After having released the serial port,
* the target is no longer supplied via this port!
*/
if (error == ERR_NONE)
return(0);
else
return(1);
} /* signOff */
void showHelp()
{
char *help[]=
{
"BSLDEMO [-h] [-c{port}] [-p{file}] [-w] [-1] [-m{num}] [+ecpvrw] {file}",
"",
"The last parameter is required: file name of TI-TXT file to be programmed.",
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -