//! \brief Erases the currently selected device
//!
//! @param hDlg : handle for dialogue
//!
USBDM_ErrorCode ColdfireUnlockerPanel::eraseDscDevice() {
   unsigned int deviceNumber = 0;
   uint8_t      unlockCommand[1];
   uint8_t      clockDividerValue[1];

   unlockCommand[0]     = unlockInstructionTextControl->GetHexValue();
   clockDividerValue[0] = clockDividerTextControl->GetHexValue();

   print("Erasing JTAG device #%d, Unlock command=%2.2X, Clock Divider=%2.2X\n",
         deviceNumber, unlockCommand[0], clockDividerValue[0]);

   USBDM_ErrorCode rc = BDM_RC_OK;
   do {
      rc = USBDM_SetExtendedOptions(&bdmOptions);
      if (rc != BDM_RC_OK) {
         return rc;
      }
      rc = USBDM_SetTargetTypeWithRetry(T_MC56F80xx);
      if (rc != BDM_RC_OK) {
         return rc;
      }
      USBDM_TargetReset((TargetMode_t)(RESET_SPECIAL|RESET_DEFAULT));
      if (rc != BDM_RC_OK) {
         return rc;
      }
   } while (0);

   deviceNumber = JTAG_Chain::currentDeviceNum;
   JTAG_Chain::reset();
   JTAG_Chain::writeIR(unlockCommand, JTAG_EXIT_SHIFT_DR);
   JTAG_Chain::write(clkdivDrLength, clockDividerValue, JTAG_EXIT_IDLE);
   wxMilliSleep(2000); // Let erase complete
   JTAG_Chain::reset();
   return rc;
}
//! Resets the target to normal or special mode
//!
//! @param target_mode see \ref target_mode_e
//!
//! @return 0 => Success,\n !=0 => Fail
//!
TBDML_API unsigned char _tbdml_target_reset(TargetMode_t targetMode) {

   USBDM_ErrorCode rc;

   rc = USBDM_TargetReset(targetMode);
   // Automatically connect after a reset
   if (rc == BDM_RC_OK)
      rc = USBDM_Connect();
   return rc;
}
USBDM_ErrorCode usbdmInit(TargetType_t targetType = T_CFV1) {
   unsigned int deviceCount;
   unsigned int deviceNum;
   USBDM_ErrorCode rc = USBDM_Init();
   if (rc != BDM_RC_OK) {
      return rc;
   }
   rc = USBDM_FindDevices(&deviceCount);
   print( "usbdmInit(): Usb initialised, found %d device(s)\n", deviceCount);
   print("After USBDM_FindDevices, Time = %f\n", progressTimer->elapsedTime());
   if (rc != BDM_RC_OK) {
      return rc;
   }
   deviceNum  = 0;
   rc = USBDM_Open(deviceNum);
   if (rc != BDM_RC_OK) {
      print( "usbdmInit(): Failed to open %s, device #%d\n", getTargetTypeName(targetType), deviceNum);
      return rc;
   }
   print( "usbdmInit(): Opened %s, device #%d\n", getTargetTypeName(targetType), deviceNum);
   print("After USBDM_Open, Time = %f\n", progressTimer->elapsedTime());
   // Set up sensible default since we can't change this (at the moment)
   USBDM_ExtendedOptions_t bdmOptions = {sizeof(USBDM_ExtendedOptions_t), TARGET_TYPE};
   USBDM_GetDefaultExtendedOptions(&bdmOptions);
   bdmOptions.targetVdd                  = BDM_TARGET_VDD_3V3; // BDM_TARGET_VDD_NONE;
   bdmOptions.autoReconnect              = AUTOCONNECT_ALWAYS; // Aggressively auto-connect
   bdmOptions.guessSpeed                 = FALSE;
   bdmOptions.cycleVddOnConnect          = FALSE;
   bdmOptions.cycleVddOnReset            = FALSE;
   bdmOptions.leaveTargetPowered         = FALSE;
   bdmOptions.bdmClockSource             = CS_DEFAULT;
   bdmOptions.useResetSignal             = FALSE;
   bdmOptions.usePSTSignals              = FALSE;
   bdmOptions.interfaceFrequency         = 1000; // 1MHz
   bdmOptions.powerOnRecoveryInterval    = 100;
   bdmOptions.resetDuration              = 100;
   bdmOptions.resetReleaseInterval       = 100;
   bdmOptions.resetRecoveryInterval      = 100;
   rc = USBDM_SetExtendedOptions(&bdmOptions);
   if (rc != BDM_RC_OK) {
      print( "usbdmInit(): USBDM_SetExtendedOptions() failed\n");
      return rc;
   }
   print("After USBDM_SetExtendedOptions, Time = %f\n", progressTimer->elapsedTime());
   rc = USBDM_SetTargetType(targetType);
   if (rc != BDM_RC_OK) {
      print( "usbdmInit(): USBDM_SetTargetType() failed\n");
      return rc;
   }
   print("After USBDM_SetTargetType, Time = %f\n", progressTimer->elapsedTime());
   USBDM_TargetReset((TargetMode_t)(RESET_DEFAULT|RESET_SPECIAL));
   print("After USBDM_TargetReset, Time = %f\n", progressTimer->elapsedTime());
   if (USBDM_Connect() != BDM_RC_OK) {
      print( "usbdmInit(): Connecting failed - retry\n");
      USBDM_TargetReset((TargetMode_t)(RESET_DEFAULT|RESET_SPECIAL));
      rc = USBDM_Connect();
      if (rc != BDM_RC_OK) {
         print( "targetConnect(): USBDM_SetTargetType() failed\n");
         return rc;
      }
   }
   print("After targetConnect, Time = %f\n", progressTimer->elapsedTime());
   return BDM_RC_OK;
}
//! \brief Does Bulk Erase of Target Flash.
//!
//! @return error code, see \ref FlashError_t
//!
//! @note The target is not reset so current security state persists after erase.
//!
USBDM_ErrorCode HCS12Unsecure::bulkEraseMemory() {
   const uint8_t allOnes        = 0xFF;
   const uint8_t allZeroes      = 0x00;
   uint8_t dummyFlashAddress[]  = {0xFF, 0xFE};
   uint8_t dummyEepromAddress[] = {0x0C, 0x00};
   uint8_t dummyFlashData[]     = {0xFF, 0xFF};
   int timeout;
   uint8_t statValue;
   USBDM_ErrorCode rc;

   print("HCS12Unsecure::bulkEraseMemory():Bulk erasing target...\n");

   // Erase chip
   //=============================

   // Set up flash & eeprom
   rc = initialiseTargetFlash();
   if (rc != BDM_RC_OK) {
      print("HCS12Unsecure::bulkEraseMemory(): initialiseTargetFlash() failed, reason=%s\n",
            USBDM_GetErrorString(rc));
      return rc;
   }

   print("HCS12Unsecure::bulkEraseMemory():Bulk erasing target Flash...\n");
   // Apply Bulk Erase operation to all Flash banks
   USBDM_WriteMemory(1, 1, HCS12DeviceData::getFPROTAddress(),   &allOnes);
   USBDM_WriteMemory(1, 1, HCS12DeviceData::getFSTATAddress(),   &HCS12_clearFlashErrors);
   USBDM_WriteMemory(1, 1, HCS12DeviceData::getFTSTMODAddress(), &allZeroes);
   USBDM_WriteMemory(1, 1, HCS12DeviceData::getFSTATAddress(),   &HCS12_clearFlashErrors);
   USBDM_WriteMemory(1, 1, HCS12DeviceData::getFTSTMODAddress(), &HCS12_FTSTMOD_WRALL);
   USBDM_WriteMemory(2, 2, HCS12DeviceData::getFADDRAddress(),   dummyFlashAddress);
   USBDM_WriteMemory(2, 2, HCS12DeviceData::getFDATAAddress(),   dummyFlashData);
   USBDM_WriteMemory(1, 1, HCS12DeviceData::getFCMDAddress(),    &mMassErase);
   USBDM_WriteMemory(1, 1, HCS12DeviceData::getFSTATAddress(),   &startFlashCommand);

   // Wait for flash command to complete
   timeout = 10;
   do {
      // Mass erase should take ~100ms
      wxMilliSleep(100);
      if (USBDM_ReadMemory(1,1,HCS12DeviceData::getFSTATAddress(),&statValue) != BDM_RC_OK)
         return BDM_RC_FAIL;
      if (timeout-- == 0)
         return BDM_RC_FAIL;
   } while ((statValue & 0xC0) != 0xC0);

   USBDM_WriteMemory(1, 1, HCS12DeviceData::getFTSTMODAddress(), &allZeroes);

   if (hasEEPROM) {
      print("HCS12Unsecure::bulkEraseMemory():Bulk erasing target EEPROM...\n");
      // Apply Bulk Erase operation to EEPROM
      USBDM_WriteMemory(1, 1, HCS12DeviceData::getEPROTAddress(),   &allOnes);
      USBDM_WriteMemory(1, 1, HCS12DeviceData::getESTATAddress(),   &HCS12_clearFlashErrors);
      USBDM_WriteMemory(2, 2, HCS12DeviceData::getEADDRAddress(),   dummyEepromAddress);
      USBDM_WriteMemory(2, 2, HCS12DeviceData::getEDATAAddress(),   dummyFlashData);
      USBDM_WriteMemory(1, 1, HCS12DeviceData::getECMDAddress(),    &mMassErase);
      USBDM_WriteMemory(1, 1, HCS12DeviceData::getESTATAddress(),   &startFlashCommand);

      // Wait for flash command to complete
      timeout = 10;
      do {
         // Mass erase should take ~100ms
         wxMilliSleep(100);
         if (USBDM_ReadMemory(1,1,HCS12DeviceData::getESTATAddress(),&statValue) != BDM_RC_OK)
            return BDM_RC_FAIL;
         if (timeout-- == 0)
            return BDM_RC_FAIL;
      } while ((statValue & 0xC0) != 0xC0);
   }
   USBDM_TargetReset((TargetMode_t)(RESET_HARDWARE|RESET_SPECIAL));

   unsigned long usbdmStatus;
   USBDM_ReadStatusReg(&usbdmStatus);

   if ((usbdmStatus & HC12_BDMSTS_UNSEC) != 0) {
      print("HCS12Unsecure::bulkEraseMemory():Bulk erasing target memory...Complete\n");
      return BDM_RC_OK;
   }
   else {
      print("HCS12Unsecure::bulkEraseMemory():Bulk erasing target memory...Failed!\n");
      return BDM_RC_FAIL;
   }
}