c2000ware-core-sdk/utilities/tools/f2806x/dfuprog/dfuprog.cpp.orig
2023-06-26 16:14:08 +05:30

1122 lines
37 KiB
C++

//*****************************************************************************
//
// dfuprog.cpp : A simple command-line utility for programming a USB-connected
// TI board running the USB DFU boot loader.
//
// Copyright (c) 2008-2011 Texas Instruments Incorporated. All rights reserved.
// Software License Agreement
//
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
//
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 7611 of the TI Firmware Development Package.
//
//*****************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include "tidfu.h"
#include "tidfuwrap.h"
//*****************************************************************************
//
// Helpful macros for generating output depending upon verbose and quiet flags.
//
//*****************************************************************************
#define VERBOSEPRINT(...) if(g_bVerbose) { printf(__VA_ARGS__); }
#define QUIETPRINT(...) if(!g_bQuiet) { printf(__VA_ARGS__); }
//*****************************************************************************
//
// Globals whose values are set or overridden via command line parameters.
//
//*****************************************************************************
bool g_bVerbose = false;
bool g_bQuiet = false;
bool g_bOverwrite = false;
bool g_bUpload = false;
bool g_bClear = false;
bool g_bBinary = false;
bool g_bEnumOnly = false;
bool g_bDisregardIDs = false;
bool g_bSkipVerify = false;
bool g_bWaitOnExit = false;
bool g_bReset = false;
bool g_bSwitchMode = false;
char *g_pszFile = NULL;
unsigned long g_ulAddress = 0;
unsigned long g_ulAddressOverride = 0xFFFFFFFF;
unsigned long g_ulLength = 0;
int g_iDeviceIndex = 0;
//*****************************************************************************
//
// Exit the application, optionally pausing for a key press first.
//
//*****************************************************************************
void
ExitApp(int iRetcode)
{
//
// Has the caller asked us to pause before exiting?
//
if(g_bWaitOnExit)
{
printf("\nPress any key to exit...\n");
while (!_kbhit())
{
//
// Wait for a key press.
//
}
}
exit(iRetcode);
}
//*****************************************************************************
//
// Display the welcome banner when the program is started.
//
//*****************************************************************************
void
PrintWelcome(void)
{
if(g_bQuiet)
{
return;
}
printf("\nUSB Device Firmware Upgrade Example\n");
printf("Copyright (c) 2008-2011 Texas Instruments Incorporated. All rights reserved.\n\n");
}
//*****************************************************************************
//
// Show help on the application command line parameters.
//
//*****************************************************************************
void
ShowHelp(void)
{
//
// Only print help if we are not in quiet mode.
//
if(g_bQuiet)
{
return;
}
printf("This application may be used to download images to a Texas Instruments\n");
printf("TI microcontroller running the USB Device Firmware Upgrade\n");
printf("boot loader. Additionally, the application can read back the\n");
printf("existing application image or a subsection of flash and store it\n");
printf("either as raw data or wrapped as a DFU-downloadable image.\n\n");
printf("Supported parameters are:\n\n");
printf("-e - Enumerate connected devices, show info then exit.\n");
printf("-m - Switch into DFU mode if device is currently in runtime mode.\n");
printf("-u - Upload an image from the board into the target DFU file.\n");
printf(" If absent, the file will be downloaded to the board.\n");
printf("-c Clear a block of flash. The address and size of the\n");
printf(" block are may be given using -a and -l. If these are\n");
printf(" absent, clears the entire writable area of flash. Trumps -u.\n");
printf("-f <file> - The file name for upload or download use.\n");
printf("-b - Upload binary rather than a DFU-formatted file. (used with -u)\n");
printf("-d - Disregard VID and PID in DFU image to be downloaded.\n");
printf("-s - Skip verification after a download operation.\n");
printf("-a <num> - Set the address the binary will be flashed to or read from.\n");
printf(" If absent, binary files are flashed the default application\n");
printf(" start address for the target. Ignored for DFU files.\n");
printf("-l <num> - Set the upload length (use with -u). If absent, the\n");
printf(" entire writable flash area is uploaded.\n");
printf("-i <num> - Sets the index of the USB DFU device to access if more\n");
printf(" than one is found. If absent, the first device found is used.\n");
printf("-x - Overwrite existing file without prompting. (used with -u)\n");
printf("-r - Reset the target on completion of operation.\n");
printf("-? or -h - Show this help.\n");
printf("-q - Quiet mode. Disable output to stdio.\n");
printf("-w - Wait for a key press before exiting.\n");
printf("-v - Enable verbose output\n\n");
printf("Examples:\n\n");
printf(" dfuprog -f program.bin -a 0x1800\n\n");
printf("Writes binary file program.bin to the device at address 0x1800\n\n");
printf(" dfuprog -i 1 -f program.dfu\n\n");
printf("Writes DFU-formatted file program.dfu to the second connected\n");
printf("device (index 1) at the address found in the DFU file prefix.\n\n");
printf(" dfuprog -u -f appimage.dfu\n\n");
printf("Reads the current board application image into DFU-formatted file\n");
printf("appimage.dfu\n\n");
}
//*****************************************************************************
//
// Parse the command line, extracting all parameters.
//
// Returns 0 on success. On failure, calls ExitApp(1).
//
//*****************************************************************************
int
ParseCommandLine(int argc, char *argv[])
{
int iParm;
bool bShowHelp;
char *pcOptArg;
//
// By default, don't show the help screen.
//
bShowHelp = false;
//
// Walk through each of the parameters in the list, skipping the first one
// which is the executable name itself.
//
for(iParm = 1; iParm < argc; iParm++)
{
//
// Does this look like a valid switch?
//
if(!argv || ((argv[iParm][0] != '-') && (argv[iParm][0] != '/')) ||
(argv[iParm][1] == '\0'))
{
//
// We found something on the command line that didn't look like a
// switch so bomb out.
//
printf("Unrecognized or invalid argument: %s\n", argv[iParm]);
ExitApp(1);
}
else
{
//
// For convenience, get a pointer to the next argument since this
// is often a parameter for a given switch (and since this code was
// converted from a previous version which used getopt which is not
// available in the Windows SDK).
//
pcOptArg = ((iParm + 1) < argc) ? argv[iParm + 1] : NULL;
}
switch(argv[iParm][1])
{
case 'w':
g_bWaitOnExit = true;
break;
case 'c':
g_bClear = true;
break;
case 's':
g_bSkipVerify = true;
break;
case 'd':
g_bDisregardIDs = true;
break;
case 'e':
g_bEnumOnly = true;
break;
case 'u':
g_bUpload = true;
break;
case 'm':
g_bSwitchMode = true;
break;
case 'f':
g_pszFile = pcOptArg;
iParm++;
break;
case 'b':
g_bBinary = true;
break;
case 'a':
g_ulAddressOverride = (unsigned long)strtol(pcOptArg, NULL, 0);
iParm++;
break;
case 'l':
g_ulLength = (unsigned long)strtol(pcOptArg, NULL, 0);
iParm++;
break;
case 'i':
g_iDeviceIndex = (int)strtol(pcOptArg, NULL, 0);
iParm++;
break;
case 'r':
g_bReset = TRUE;
break;
case 'v':
g_bVerbose = TRUE;
break;
case 'q':
g_bQuiet = TRUE;
break;
case 'x':
g_bOverwrite = TRUE;
break;
case '?':
case 'h':
bShowHelp = TRUE;
break;
default:
printf("Unrecognized argument: %s\n", argv[iParm]);
ExitApp(1);
}
}
//
// Show the welcome banner unless we have been told to be quiet.
//
PrintWelcome();
//
// Show the help screen if requested.
//
if(bShowHelp)
{
ShowHelp();
ExitApp(0);
}
//
// Catch various invalid or pointless parameter cases.
//
if(g_bEnumOnly)
{
//
// The -e option causes pretty much all other command line options to
// be ignored so let the user know if they specified something that is
// not going to do anything.
//
if(g_iDeviceIndex || g_ulLength || g_ulAddress || g_bBinary ||
g_pszFile || g_bUpload || g_bClear || g_bSwitchMode)
{
//
// Tell the user what's going on but don't exit since this is not
// a fatal error condition.
//
QUIETPRINT("Some options ignored - irrelevant when used "
"with -e.\n");
}
}
else
{
if(!g_bClear && !g_bSwitchMode)
{
//
// We are performing a download or upload operation. In this case,
// we definitely need a file name.
//
if(!g_pszFile)
{
//
// No file name provided. If we haven't displayed it already,
// show command line help then display the error information.
//
ShowHelp();
QUIETPRINT("ERROR: No file name was specified. Please use -f "
"to provide one.\n");
ExitApp(1);
}
}
}
//
// Tell the caller that everything is OK.
//
return(0);
}
//*****************************************************************************
//
// Dump the information contained within the passed device information structure
// to stdout assuming we are not in quiet mode.
//
//*****************************************************************************
void
DumpDeviceInformation(tTIDFUHandle hHandle, tTIDFUDeviceInfo *psDevInfo)
{
char pcStringBuf[256];
unsigned short usStringLen;
tTIDFUErr eRetcode;
//
// Show the VID and PID for the device.
//
QUIETPRINT("VID: 0x%04x PID: 0x%04x\n", psDevInfo->usVID,
psDevInfo->usPID);
//
// Now query the string descriptors associated with the device and
// display these.
//
// We chicken out here and get an ASCII version of the strings
// in the default language (even though this may not be
// something that can be represented in ASCII). Handling the
// real UNICODE returned by TIDFUDeviceStringGet() is left as
// an exercise to the reader.
//
usStringLen = sizeof(pcStringBuf);
eRetcode = _TIDFUDeviceASCIIStringGet(hHandle, psDevInfo->ucProductString,
pcStringBuf, &usStringLen);
QUIETPRINT("Device Name: %s\n",
(eRetcode == DFU_OK) ? pcStringBuf : "<<Unknown>>");
usStringLen = sizeof(pcStringBuf);
eRetcode = _TIDFUDeviceASCIIStringGet(hHandle,
psDevInfo->ucManufacturerString,
pcStringBuf, &usStringLen);
QUIETPRINT("Manufacturer: %s\n",
(eRetcode == DFU_OK) ? pcStringBuf : "<<Unknown>>");
usStringLen = sizeof(pcStringBuf);
eRetcode = _TIDFUDeviceASCIIStringGet(hHandle,
psDevInfo->ucDFUInterfaceString,
pcStringBuf, &usStringLen);
QUIETPRINT("DFU Interface: %s\n",
(eRetcode == DFU_OK) ? pcStringBuf : "<<Unknown>>");
usStringLen = sizeof(pcStringBuf);
eRetcode = _TIDFUDeviceASCIIStringGet(hHandle, psDevInfo->ucSerialString,
pcStringBuf, &usStringLen);
QUIETPRINT("Serial Num: %s\n",
(eRetcode == DFU_OK) ? pcStringBuf : "<<Unknown>>");
//
// Display other relevant information.
//
QUIETPRINT("Max Transfer: %d bytes\n", psDevInfo->usTransferSize);
QUIETPRINT("Mode: %s\n", psDevInfo->bDFUMode ? "DFU" : "Runtime");
if(psDevInfo->bDFUMode)
{
QUIETPRINT("TI Extensions: %s\n", psDevInfo->bSupportsTIExtensions ?
"Supported" : "Not Supported");
if(psDevInfo->bSupportsTIExtensions)
{
QUIETPRINT("Target: %s revision %c%c\n",
psDevInfo->pcPartNumber,
psDevInfo->cRevisionMajor + 'A',
psDevInfo->cRevisionMinor + '0');
}
}
QUIETPRINT("Attributes:\n");
QUIETPRINT(" Will Detach: %s\n",
((psDevInfo->ucDFUAttributes & DFU_ATTR_WILL_DETACH) ?
"Yes" : "No"));
QUIETPRINT(" Manifest Tolerant: %s\n",
((psDevInfo->ucDFUAttributes & DFU_ATTR_MANIFEST_TOLERANT) ?
"Yes" : "No"));
QUIETPRINT(" Upload Capable: %s\n",
((psDevInfo->ucDFUAttributes & DFU_ATTR_CAN_UPLOAD) ? "Yes" : "No"));
QUIETPRINT(" Download Capable: %s\n",
((psDevInfo->ucDFUAttributes & DFU_ATTR_CAN_DOWNLOAD) ? "Yes" : "No"));
}
//*****************************************************************************
//
// Upload an image from the device identified by the passed handle. The actual
// section of flash to upload and the format to save the upload in is controlled
// by command line parameters via global variables.
//
// Returns 0 on success or a positive error return code on failure.
//
//*****************************************************************************
int
UploadImage(tTIDFUHandle hHandle, tTIDFUParams *psDFU)
{
FILE *fh;
tTIDFUErr eRetcode;
unsigned char *pcFileBuf;
size_t iLen;
int iRetcode;
int iResponse;
errno_t eErr;
QUIETPRINT("Uploading from device to %s...\n", g_pszFile);
//
// We only support upload on devices supporting the TI DFU
// protocol since, on other devices, we have no idea how large an
// uploaded image to expect.
//
if(!psDFU)
{
QUIETPRINT("Target device does not support TI protocol.\n");
return(40);
}
//
// Check if the address has a override value.
//
if(g_ulAddressOverride != 0xFFFFFFFF)
{
g_ulAddress = g_ulAddressOverride;
}
else if(g_ulAddress == 0)
{
//
// Where should we start uploading from? If the start address is not
// specified, assume the start of the writeable area. Upload from
// the application start address.
//
g_ulAddress = psDFU->ulAppStartAddr;
}
//
// How much data must we read? If the length is not specified, set the
// length to be the whole block between the start address and the top of
// the writable area.
//
if(g_ulLength == 0)
{
g_ulLength = psDFU->ulFlashTop - g_ulAddress;
}
//
// Now allocate a buffer large enough to hold the image. We need to add
// space for the 8 byte prefix and 16 byte suffix if we have been asked
// for a DFU-format image.
//
pcFileBuf = (unsigned char *)malloc(g_ulLength + (g_bBinary ? 0 : 24));
if(!pcFileBuf)
{
//
// We can't allocate the memory!
//
QUIETPRINT("Error allocating %d bytes of memory!\n",
g_ulLength + (g_bBinary ? 0 : 24));
return(41);
}
//
// Upload the data into our buffer.
//
eRetcode = _TIDFUUpload(hHandle, pcFileBuf, g_ulAddress,
(g_ulLength + (g_bBinary ? 0 : 24)), g_bBinary, NULL);
if(eRetcode == DFU_OK)
{
//
// We got the image successfully. Have we been given the go-ahead to
// overwrite the output file without a warning?
//
if(!g_bOverwrite)
{
eErr = fopen_s(&fh, g_pszFile, "rb");
if(eErr == 0)
{
//
// We don't need this handle any more so close the file.
//
fclose(fh);
//
// The file exists and we are in quiet mode so fail the
// operation since we can't prompt the user for permission to
// overwrite.
//
if(g_bQuiet)
{
free(pcFileBuf);
return(43);
}
else
{
//
// Prompt the user for permission to overwrite the output
// file.
//
printf("File %s exists. Overwrite? (Y/N): ", g_pszFile);
iResponse = getc(stdin);
if((iResponse != 'y') && (iResponse != 'Y'))
{
//
// The user didn't respond with 'y' or 'Y' so return an
// error and don't overwrite the file.
//
VERBOSEPRINT("User chose not to overwrite output.\n");
free(pcFileBuf);
return(44);
}
printf("Overwriting existing output file.\n");
}
}
}
//
// At this point it is fine for us to open the output file for writing.
//
eErr = fopen_s(&fh, g_pszFile, "wb");
if(eErr != 0)
{
QUIETPRINT("Error opening output file for writing.\n");
iRetcode = 45;
}
else
{
//
// Write the uploaded image to the file.
//
iLen = fwrite(pcFileBuf, 1, (g_ulLength + (g_bBinary ? 0 : 24)), fh);
//
// Did we write the expected amount of data?
//
if(iLen != (g_ulLength + (g_bBinary ? 0 : 24)))
{
//
// No - something went wrong.
//
QUIETPRINT("Error writing output. Write %d bytes, "
"expected %d.\n", iLen,
(g_ulLength + (g_bBinary ? 0 : 24)));
iRetcode = 46;
}
else
{
//
// Life is good. Set an appropriate exit code.
//
iRetcode = 0;
}
//
// Close the output file.
//
fclose(fh);
}
}
else
{
//
// There was an error attempting to upload the image from the device.
//
QUIETPRINT("Error uploading %d bytes from 0x%08x!\n",
g_ulLength + (g_bBinary ? 0 : 24), g_ulAddress);
iRetcode = 42;
}
//
// Free up our image buffer.
//
free(pcFileBuf);
return(iRetcode);
}
//*****************************************************************************
//
// Download an image to the the device identified by the passed handle. The
// image to be downloaded and other parameters related to the operation are
// controlled by command line parameters via global variables.
//
// Returns 0 on success or a positive error return code on failure.
//
//*****************************************************************************
int
DownloadImage(tTIDFUHandle hHandle, tTIDFUParams *psDFU)
{
FILE *fh;
tTIDFUErr eRetcode;
unsigned char *pcFileBuf;
size_t iLen;
size_t iRead;
bool bTIFormat;
QUIETPRINT("Downloading %s to device...\n", g_pszFile);
//
// Check if the address has a override value.
//
if(g_ulAddressOverride != 0xFFFFFFFF)
{
g_ulAddress = g_ulAddressOverride;
}
//
// Does the input file exist?
//
fopen_s(&fh, g_pszFile, "rb");
if(!fh)
{
QUIETPRINT("Unable to open file %s. Does it exist?\n", g_pszFile);
return(10);
}
//
// How big is the file?
//
fseek(fh, 0, SEEK_END);
iLen = ftell(fh);
fseek(fh, 0, SEEK_SET);
//
// Allocate a buffer large enough for the file.
//
pcFileBuf = (unsigned char *)malloc(iLen);
if(!pcFileBuf)
{
QUIETPRINT("Error allocating %d bytes of memory!\n", iLen);
fclose(fh);
return(11);
}
//
// Read the file into our buffer and check that it was correctly read.
//
iRead = fread(pcFileBuf, 1, iLen, fh);
fclose(fh);
if(iRead != iLen)
{
QUIETPRINT("Error reading input file!\n");
free(pcFileBuf);
return(12);
}
//Check to see if its hex
if(pcFileBuf[0] == ':')
{
eRetcode = _TIDFUDownloadHex(hHandle, pcFileBuf, (unsigned long)iLen,
true, NULL);
}
//
// Check to see whether this is a binary or a DFU-wrapped file.
//
eRetcode = _TIDFUIsValidImage(hHandle, pcFileBuf, (unsigned long)iLen, &bTIFormat);
//
// Is the image for the target we are currently talking to?
//
if((eRetcode == DFU_ERR_UNSUPPORTED) && !g_bDisregardIDs)
{
QUIETPRINT("This image does not appear to be valid for the target "
"device.\nUse -d to disregard embedded IDs\n");
free(pcFileBuf);
return(14);
}
if(((eRetcode == DFU_OK) ||
((eRetcode == DFU_ERR_UNSUPPORTED) && g_bDisregardIDs)) &&
bTIFormat)
{
//
// This is a DFU formatted image and either it is intended for the
// target device or the user wants us to ignore the IDs in the file.
// Since it also contains a TI prefix, we can send it to the
// main download function.
//
VERBOSEPRINT("Image contains valid DFU suffix and TI prefix.\n");
VERBOSEPRINT("Downloading image to flash.... ");
eRetcode = _TIDFUDownload(hHandle, pcFileBuf, (unsigned long)iLen, g_bSkipVerify,
g_bDisregardIDs, NULL);
}
else
{
//
// This is not a DFU-formatted file so we download it as a binary. In
// this case, we need to pass the flash address passed by the user or,
// if this was not provided, the application start address that the
// device told us to use when we queried its capabilities earlier.
//
//
// Did the file contain a DFU suffix but no TI prefix? If so,
// we remove the DFU suffix since this doesn't get downloaded. The
// length of the suffix is in the 5th last byte.
//
if((eRetcode == DFU_OK) || (eRetcode == DFU_ERR_UNSUPPORTED))
{
iLen -= pcFileBuf[iLen - 5];
}
VERBOSEPRINT("Image is not fully DFU-wrapped. Downloading as binary\n");
VERBOSEPRINT("Downloading image to flash.... ");
eRetcode = _TIDFUDownloadBin(hHandle, pcFileBuf, (unsigned long)iLen,
g_ulAddress, g_bSkipVerify, NULL);
}
VERBOSEPRINT("Completed.\n");
//
// Free the file buffer memory.
//
free(pcFileBuf);
if(eRetcode != DFU_OK)
{
QUIETPRINT("Error %s (%d) reported during file download\n",
_TIDFUErrorStringGet(eRetcode), eRetcode);
return(13);
}
else
{
return(0);
}
}
//*****************************************************************************
//
// Erase a section of the writeable region of flash. If the "-a" parameter
// was not specified or was specified with address 0, the entire writeable
// region of the target device flash will be erased. If a non-zero address
// is provided, the -l parameter must also specified to set the start address
// and length of the region that will be erased. The start address and length
// must both be integer multiples of 1024.
//
// Returns 0 on success or a positive error return code on failure.
//
//*****************************************************************************
int
ClearFlash(tTIDFUHandle hHandle, tTIDFUParams *psDFU)
{
tTIDFUErr eRetcode;
if(g_ulAddress)
{
QUIETPRINT("Clearing %dKB flash block from address 0x%08x\n",
g_ulLength / 1024, g_ulAddress);
}
else
{
QUIETPRINT("Clearing entire writable region of flash.\n");
}
//
// Erase the required block and verify that the erase completed
// successfully.
//
eRetcode = _TIDFUErase(hHandle, g_ulAddress, g_ulLength, true, NULL);
if(eRetcode != DFU_OK)
{
QUIETPRINT("Error %s (%d) erasing flash!\n",
_TIDFUErrorStringGet(eRetcode), eRetcode);
return(20);
}
else
{
QUIETPRINT("Flash erased successfully.\n");
return(0);
}
}
//*****************************************************************************
//
// The main entry point of the DFU programmer example application.
//
//*****************************************************************************
int
main(int argc,char* argv[])
{
tTIDFUDeviceInfo sDevInfo;
tTIDFUHandle hHandle;
tTIDFUErr eRetcode;
tTIDFUParams sDFU;
tTIDFUParams *psDFU;
int iExitCode;
int iDevIndex;
bool bCompleted;
bool bDeviceFound;
//
// Parse the command line parameters, print the welcome banner and
// tell the user about any errors they made.
//
ParseCommandLine(argc, argv);
//
// Initialize the DFU library.
//
eRetcode = _TIDFUInit();
//
// Could we load the DLL and query all its entry points successfully?
//
if(eRetcode != DFU_OK)
{
//
// Oops - something is wrong with the DFU DLL.
//
if(eRetcode == DFU_ERR_NOT_FOUND)
{
printf("The driver for the USB Device Firmware Upgrade device cannot be found.\n");
printf("Before running this program, please connect the DFU device to this system\n");
printf("and install the device driver when prompted by Windows. The device driver\n");
printf("can be found on the evaluation kit CD or can be found in the package named\n");
printf("\"TI embedded USB drivers\" which may be downloaded from\n");
printf("http://www.ti.com/software_updates.\n\n");
iExitCode = 10;
}
else if(eRetcode == DFU_ERR_INVALID_ADDR)
{
printf("The driver for the USB Device Firmware Upgrade device was found but appears\n");
printf("to be a version which this program does not support. Please download and\n");
printf("install the latest device driver and example applications from the TI\n");
printf("web site to ensure that you are using compatible versions. The drivers\n");
printf("can be found in the package named \"TI embedded USB drivers\" and\n");
printf("the applications can be found in package \"Windows-side examples for USB kits\"\n");
printf("both of which may be downloaded from http://www.ti.com/software_updates.\n\n");
iExitCode = 11;
}
else
{
printf("An error was reported while attempting to load the device driver for the \n");
printf("USB Device Firmware Upgrade device. If this error persists, please download\n");
printf("and reinstall the latest device driver and example applications from the TI\n");
printf("web site. The drivers can be found in the package named \"TI\n");
printf("embedded USB drivers\" and the applications can be found in package \"Windows-side\n");
printf("examples for USB kits\", both of which may be downloaded from\n");
printf("http://www.ti.com/software_updates.\n\n");
iExitCode = 12;
}
//
// Exit now with the appropriate error code.
//
ExitApp(iExitCode);
}
//
// Enumerate the available DFU devices until we find the one we have been
// asked to access.
//
QUIETPRINT("Scanning USB buses for supported DFU devices...\n\n");
iDevIndex = 0;
bCompleted = false;
iExitCode = 0;
bDeviceFound = false;
do
{
//
// Try to open a device.
//
eRetcode = _TIDFUDeviceOpen(iDevIndex, &sDevInfo, &hHandle);
//
// Were we successful?
//
if(eRetcode == DFU_OK)
{
//
// Yes - if we are enumerating, dump information on the device.
//
if(g_bEnumOnly)
{
QUIETPRINT("\n<<<< Device %d >>>>\n\n", iDevIndex);
DumpDeviceInformation(hHandle, &sDevInfo);
}
else
{
//
// Have we found the device we are looking for?
//
if(iDevIndex == g_iDeviceIndex)
{
//
// We have found the required device
//
bDeviceFound = true;
//
// Is the device currently in runtime mode?
//
if(sDevInfo.bDFUMode == FALSE)
{
//
// Have we been asked to switch it into DFU mode?
//
if(g_bSwitchMode)
{
QUIETPRINT("\n<<<< Device %d >>>>\n\n", iDevIndex);
DumpDeviceInformation(hHandle, &sDevInfo);
QUIETPRINT("Switching device into DFU mode.\n");
//
// Yes - switch the device into DFU mode.
//
eRetcode = _TIDFUModeSwitch(hHandle);
//
// Set an appropriate return code.
//
iExitCode = (eRetcode != DFU_OK) ? 0 : 100;
//
// Drop out of the loop.
//
break;
}
else
{
QUIETPRINT("Device is in runtime mode. Switch to "
"DFU mode using '-m' before\n"
"attempting any other operation\n");
}
}
else
{
//
// If we were asked to switch modes and the device is already in
// DFU mode, check that we were passed some other operation to
// perform.
//
if(g_bSwitchMode)
{
QUIETPRINT("Device is already in DFU mode. No "
"switch necessary.\n");
}
//
// If it supports the TI DFU protocol, read back
// some important parameters.
//
if(sDevInfo.bSupportsTIExtensions)
{
//
// Read flash size parameters from the device.
//
eRetcode = _TIDFUParamsGet(hHandle, &sDFU);
if(eRetcode != DFU_OK)
{
QUIETPRINT("Error %s (%d) reading flash "
"parameters.\n",
_TIDFUErrorStringGet(eRetcode),
eRetcode);
}
psDFU = &sDFU;
}
else
{
//
// The device doesn't support the TI
// protocol so set the DFU parameter structure
// pointer to NULL.
//
psDFU = (tTIDFUParams *)0;
}
//
// No errors so far?
//
if(eRetcode == DFU_OK)
{
//
// Have we been asked to clear the flash?
//
if(g_bClear)
{
//
// Yes - clear the required area of flash.
//
iExitCode = ClearFlash(hHandle, psDFU);
}
//
// Yes - have we been asked to upload the current
// image to a file on the host?
//
else if(g_bUpload)
{
//
// Yes - go ahead and perform the upload.
//
iExitCode = UploadImage(hHandle, psDFU);
}
else
{
//
// No - download an image to the device if a
// filename has been provided.
//
if(g_pszFile)
{
iExitCode = DownloadImage(hHandle, psDFU);
}
}
}
//
// At this point, we've done whatever we have been asked
// to do so make sure we exit the loop next time we get
// to the end.
//
bCompleted = true;
}
}
}
//
// We are finished with this device for now.
//
eRetcode = _TIDFUDeviceClose(hHandle, g_bReset);
//
// Move on to look for another device.
//
iDevIndex++;
}
}
while((eRetcode == DFU_OK) && !bCompleted);
//
// Print a final summary of what we found if we are merely enumerating the
// devices.
//
if(g_bEnumOnly)
{
QUIETPRINT("\nFound %d device%s.\n", iDevIndex, (iDevIndex == 1) ? "" : "s");
}
else
{
//
// Did we find the device that the user wanted to talk to?
//
if(!bDeviceFound)
{
//
// No - we couldn't find the requested device.
//
QUIETPRINT("The requested device was not found on the bus.\n");
iExitCode = 1;
}
}
ExitApp(iExitCode);
}