USBDM_ErrorCode RebootDevice() {
   LOGGING;
   USBDM_ErrorCode rc;

   do {
      log.print("Initialising\n");
      rc = ICP_Init();
      if (rc != BDM_RC_OK) {
         continue;
      }
      log.print("Locating devices\n");
      unsigned devCount;
      rc = ICP_FindUsbdmDevices(&devCount);
      if (rc != BDM_RC_OK) {
         continue;
      }
      log.print("Found %d devices\n", devCount);
      log.print("Opening device\n");
      rc = ICP_Open(0);
      if (rc != BDM_RC_OK) {
         continue;
      }
      log.print("Rebooting device - ignore errors\n");
      ICP_Reboot();
   } while (false);
   log.print("Closing device\n");
   ICP_Close();
   ICP_Exit();
   return rc;
}
USBDM_ErrorCode ProgramDevice(std::string filePath) {
   LOGGING_Q;
   USBDM_ErrorCode rc;

   log.print("Loading file \'%s\'\n", filePath.c_str());
   FlashImagePtr flashImage = FlashImageFactory::createFlashImage(T_ARM);
   rc = flashImage->loadFile(filePath.c_str(), true);
   if (rc != BDM_RC_OK) {
      log.print("main() - Failed to load file, Reason: %s\n", flashImage->getErrorString(rc));
      return rc;
   }
   log.print("Total Bytes = %d\n", flashImage->getByteCount());

   flashImage->fillUnused(flashImage->getLastAllocatedAddress()-flashImage->getFirstAllocatedAddress()+1,
                          flashImage->getFirstAllocatedAddress(), 0xFF);

   do {
      ProgressDialoguePtr progressCallback = ProgressDialogueFactory::create("Accessing Target", flashImage->getByteCount());

      progressCallback->update(0, "Initialising...");
      log.print("Initialising\n");
      rc = ICP_Init();
      if (rc != BDM_RC_OK) {
         continue;
      }
      log.print("Locating devices\n");
      unsigned devCount;
      rc = ICP_FindDevices(&devCount);
      if (rc != BDM_RC_OK) {
         continue;
      }
      log.print("Found %d devices\n", devCount);
      progressCallback->update(0, "Opening device...");
      log.print("Opening device\n");
      rc = ICP_Open(0);
      if (rc != BDM_RC_OK) {
         continue;
      }
      progressCallback->update(0, "Erasing device...");
      log.print("Erasing device\n");
      rc = ICP_MassErase(progressCallback);
      if (rc != BDM_RC_OK) {
         continue;
      }
      progressCallback->update(0, "Programming device...");
      log.print("Programming device\n");
      rc = programFlashImage(flashImage, progressCallback);
      if (rc != BDM_RC_OK) {
         continue;
      }
   } while (false);
   log.print("Closing device\n");
   ICP_Close();
   ICP_Exit();
   return rc;
}
ICP_ErrorType ProgramFlash(const char *hexFileName) {
   LOGGING_Q;
   ICP_ErrorType rc;

   log.print("ProgramFlash() - Loading file \'%s\'\n", hexFileName);
   FlashImage flashImageDescription;
   FlashImage::ErrorCode Flashrc = flashImageDescription.loadS1S9File(hexFileName, true);
   if (Flashrc != FlashImage::SFILE_RC_OK) {
      log.print("main() - Failed to load file, Reason: %s\n", FlashImage::getErrorMessage(Flashrc));
      return ICP_RC_FILE_NOT_FOUND;
   }
   log.print("Total Bytes = %d\n", flashImageDescription.getByteCount());

   do {
      log.print("ProgramFlash() - Initialising\n");
      rc = ICP_Init();
      if (rc != ICP_RC_OK) {
         continue;
      }
      log.print("ProgramFlash() - Locating devices\n");
      unsigned devCount;
      rc = ICP_FindDevices(&devCount);
      if (rc != ICP_RC_OK) {
         continue;
      }
      log.print("ProgramFlash() - Found %d devices\n", devCount);
      log.print("ProgramFlash() - Opening device\n");
      rc = ICP_Open(0);
      if (rc != ICP_RC_OK) {
         continue;
      }
      log.print("ProgramFlash() - Erasing device\n");
      rc = ICP_MassErase();
      if (rc != ICP_RC_OK) {
         continue;
      }
      log.print("ProgramFlash() - Programming device\n");
      rc = loadFile(&flashImageDescription);
      if (rc != ICP_RC_OK) {
         continue;
      }
   } while (false);
   log.print("ProgramFlash() - Closing device\n");
   ICP_Close();
   ICP_Exit();
   return rc;
}