//! Initialises USB interface
//!
//! This must be done before any device may be opened.
//!
//! @return Number of BDM devices found - Always 1!
//!
TBDML_API unsigned char _tbdml_init(void) {
static int firstCall = TRUE;

   print("_tbdml_init(), #%s\n", firstCall?"First call":"Later call");
//   usbdm_gdi_dll_open();

   // May be called multiple times - only init on the first call.
   if (firstCall)
      USBDM_Init();

   firstCall = FALSE;

   // This is a dummy return
   // Device count etc is done later
   return 1;
}
/*
 * Class:     net.sourceforge.usbdm.jni.usbdm
 * Method:    usbdm_init
 * Signature: ()I
 */
JNIEXPORT jint JNICALL
Java_net_sourceforge_usbdm_jni_Usbdm_usbdmInit(JNIEnv *, jclass) {
//	fprintf(stderr, "Java_net_sourceforge_usbdm_jni_Usbdm_init()\n");
	return USBDM_Init();
}
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;
}