aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Firmware/dfuprog/dfuprog.cpp
diff options
context:
space:
mode:
authorRoy Ben-Shabat <Roy@Twine-s.com>2019-01-01 17:28:19 +0200
committerRoy Ben-Shabat <Roy@Twine-s.com>2019-01-01 17:28:19 +0200
commit25f5e6ddef7ef2fa0a747305847eeb4ceee5a2c9 (patch)
tree600a6623f866d48a522406b4d93e5f213d290c61 /Software/Visual_Studio/Firmware/dfuprog/dfuprog.cpp
parent9a3114908dd0a4f61fc959ef0f352b2b6255a652 (diff)
downloadTango-25f5e6ddef7ef2fa0a747305847eeb4ceee5a2c9.tar.gz
Tango-25f5e6ddef7ef2fa0a747305847eeb4ceee5a2c9.zip
Added tango firmware update lib.
Diffstat (limited to 'Software/Visual_Studio/Firmware/dfuprog/dfuprog.cpp')
-rw-r--r--Software/Visual_Studio/Firmware/dfuprog/dfuprog.cpp1113
1 files changed, 1113 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Firmware/dfuprog/dfuprog.cpp b/Software/Visual_Studio/Firmware/dfuprog/dfuprog.cpp
new file mode 100644
index 000000000..62ad3abc3
--- /dev/null
+++ b/Software/Visual_Studio/Firmware/dfuprog/dfuprog.cpp
@@ -0,0 +1,1113 @@
+//*****************************************************************************
+//
+// dfuprog.cpp : A simple command-line utility for programming a USB-connected
+// Tiva board running the USB DFU boot loader.
+//
+// Copyright (c) 2008-2017 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 2.1.4.178 of the Tiva Firmware Development Package.
+//
+//*****************************************************************************
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <conio.h>
+#include <windows.h>
+#include "lmdfu.h"
+#include "lmdfuwrap.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-2017 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("Tiva 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(tLMDFUHandle hHandle, tLMDFUDeviceInfo *psDevInfo)
+{
+ char pcStringBuf[256];
+ unsigned short usStringLen;
+ tLMDFUErr 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 LMDFUDeviceStringGet() is left as
+ // an exercise to the reader.
+ //
+ usStringLen = sizeof(pcStringBuf);
+ eRetcode = _LMDFUDeviceASCIIStringGet(hHandle, psDevInfo->ucProductString,
+ pcStringBuf, &usStringLen);
+ QUIETPRINT("Device Name: %s\n",
+ (eRetcode == DFU_OK) ? pcStringBuf : "<<Unknown>>");
+
+
+ usStringLen = sizeof(pcStringBuf);
+ eRetcode = _LMDFUDeviceASCIIStringGet(hHandle,
+ psDevInfo->ucManufacturerString,
+ pcStringBuf, &usStringLen);
+ QUIETPRINT("Manufacturer: %s\n",
+ (eRetcode == DFU_OK) ? pcStringBuf : "<<Unknown>>");
+
+ usStringLen = sizeof(pcStringBuf);
+ eRetcode = _LMDFUDeviceASCIIStringGet(hHandle,
+ psDevInfo->ucDFUInterfaceString,
+ pcStringBuf, &usStringLen);
+ QUIETPRINT("DFU Interface: %s\n",
+ (eRetcode == DFU_OK) ? pcStringBuf : "<<Unknown>>");
+
+ usStringLen = sizeof(pcStringBuf);
+ eRetcode = _LMDFUDeviceASCIIStringGet(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->bSupportsTivaExtensions ?
+ "Supported" : "Not Supported");
+ if(psDevInfo->bSupportsTivaExtensions)
+ {
+ 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(tLMDFUHandle hHandle, tLMDFUParams *psDFU)
+{
+ FILE *fh;
+ tLMDFUErr 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 Tiva 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 Tiva 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 = _LMDFUUpload(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(tLMDFUHandle hHandle, tLMDFUParams *psDFU)
+{
+ FILE *fh;
+ tLMDFUErr eRetcode;
+ unsigned char *pcFileBuf;
+ size_t iLen;
+ size_t iRead;
+ bool bTivaFormat;
+
+ 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 whether this is a binary or a DFU-wrapped file.
+ //
+ eRetcode = _LMDFUIsValidImage(hHandle, pcFileBuf, (unsigned long)iLen, &bTivaFormat);
+
+ //
+ // 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)) &&
+ bTivaFormat)
+ {
+ //
+ // 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 Tiva prefix, we can send it to the
+ // main download function.
+ //
+ VERBOSEPRINT("Image contains valid DFU suffix and Tiva prefix.\n");
+ VERBOSEPRINT("Downloading image to flash.... ");
+ eRetcode = _LMDFUDownload(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 Tiva 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 = _LMDFUDownloadBin(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",
+ _LMDFUErrorStringGet(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(tLMDFUHandle hHandle, tLMDFUParams *psDFU)
+{
+ tLMDFUErr 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 = _LMDFUErase(hHandle, g_ulAddress, g_ulLength, true, NULL);
+
+ if(eRetcode != DFU_OK)
+ {
+ QUIETPRINT("Error %s (%d) erasing flash!\n",
+ _LMDFUErrorStringGet(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[])
+{
+ tLMDFUDeviceInfo sDevInfo;
+ tLMDFUHandle hHandle;
+ tLMDFUErr eRetcode;
+ tLMDFUParams sDFU;
+ tLMDFUParams *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 = _LMDFUInit();
+
+ //
+ // 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 windows_drivers\n");
+ printf("directory of your TivaWare installation.\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 windows_drivers directory of your TivaWare\n");
+ printf("installation and the applications can be found in package \"Windows-side\n");
+ printf("examples for USB kits\" which may be downloaded from the web site at\n");
+ printf("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 windows_drivers directory of your\n");
+ printf("TivaWare installation and the applications can be found in package\n");
+ printf("\"Windows-side examples for USB kits\" 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 = _LMDFUDeviceOpen(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 = _LMDFUModeSwitch(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 Tiva DFU protocol, read back
+ // some important parameters.
+ //
+ if(sDevInfo.bSupportsTivaExtensions)
+ {
+ //
+ // Read flash size parameters from the device.
+ //
+ eRetcode = _LMDFUParamsGet(hHandle, &sDFU);
+ if(eRetcode != DFU_OK)
+ {
+ QUIETPRINT("Error %s (%d) reading flash "
+ "parameters.\n",
+ _LMDFUErrorStringGet(eRetcode),
+ eRetcode);
+ }
+ psDFU = &sDFU;
+ }
+ else
+ {
+ //
+ // The device doesn't support the Tiva
+ // protocol so set the DFU parameter structure
+ // pointer to NULL.
+ //
+ psDFU = (tLMDFUParams *)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 = _LMDFUDeviceClose(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);
+}
+