diff --git a/source/CaptureDeviceSpecific/ISDevices/usb_is_device_communications.cpp b/source/CaptureDeviceSpecific/ISDevices/usb_is_device_communications.cpp index 11aeb37..a201e8f 100644 --- a/source/CaptureDeviceSpecific/ISDevices/usb_is_device_communications.cpp +++ b/source/CaptureDeviceSpecific/ISDevices/usb_is_device_communications.cpp @@ -98,7 +98,9 @@ enum is_twl_capture_command { IS_TWL_CAP_CMD_GET_ENC_DEC_SEEDS = 0x04, IS_TWL_CAP_CMD_GET_SERIAL = 0x13, IS_TWL_CAP_CMD_UNLOCK_COMMS = 0x1C, + IS_TWL_CAP_CMD_GENERIC_INFO = 0x80, IS_TWL_CAP_CMD_MNTR = 0x81, + IS_TWL_CAP_CMD_POWER_ON_OFF = 0x82, IS_TWL_CAP_CMD_ASK_CAPTURE_INFORMATION = 0x83, IS_TWL_CAP_CMD_SCTG = 0x84, IS_TWL_CAP_CMD_TCZC = 0x85, @@ -1076,6 +1078,8 @@ int ResetCPUStart(is_device_device_handlers* handlers, const is_device_usb_devic return ResetCPUEmulatorGeneral(handlers, true, device_desc); case IS_NITRO_CAPTURE_DEVICE: return SendWriteCommand(handlers, IS_NITRO_CAP_CMD_SET_RESET_CPU_ON, NULL, 0, device_desc); + case IS_TWL_CAPTURE_DEVICE: + return SendWriteCommandU32(handlers, IS_TWL_CAP_CMD_POWER_ON_OFF, 0x00070082, device_desc); default: return 0; } @@ -1087,6 +1091,8 @@ int ResetCPUEnd(is_device_device_handlers* handlers, const is_device_usb_device* return ResetCPUEmulatorGeneral(handlers, false, device_desc); case IS_NITRO_CAPTURE_DEVICE: return SendWriteCommand(handlers, IS_NITRO_CAP_CMD_SET_RESET_CPU_OFF, NULL, 0, device_desc); + case IS_TWL_CAPTURE_DEVICE: + return SendWriteCommandU32(handlers, IS_TWL_CAP_CMD_POWER_ON_OFF, 0x00000082, device_desc); default: return 0; } diff --git a/source/CaptureDeviceSpecific/ISDevices/usb_is_twl_acquisition_capture.cpp b/source/CaptureDeviceSpecific/ISDevices/usb_is_twl_acquisition_capture.cpp index 06f6773..43aac2f 100644 --- a/source/CaptureDeviceSpecific/ISDevices/usb_is_twl_acquisition_capture.cpp +++ b/source/CaptureDeviceSpecific/ISDevices/usb_is_twl_acquisition_capture.cpp @@ -94,6 +94,31 @@ static int process_frame_and_read(CaptureData* capture_data, CaptureReceived* ca return 0; } +static int CaptureResetHardware(CaptureData* capture_data, std::chrono::time_point &clock_last_reset) { + is_device_device_handlers* handlers = (is_device_device_handlers*)capture_data->handle; + const is_device_usb_device* usb_device_desc = (const is_device_usb_device*)capture_data->status.device.descriptor; + bool reset_hardware = capture_data->status.reset_hardware; + capture_data->status.reset_hardware = false; + int ret = LIBUSB_SUCCESS; + if(!reset_hardware) + return ret; + const auto curr_time = std::chrono::high_resolution_clock::now(); + const std::chrono::duration diff = curr_time - clock_last_reset; + // Do not reset too fast... In general. + if(diff.count() < RESET_TIMEOUT) + return ret; + clock_last_reset = curr_time; + + ret = ResetCPUStart(handlers, usb_device_desc); + if(ret < 0) + return ret; + ret = ResetCPUEnd(handlers, usb_device_desc); + if(ret < 0) + return ret; + default_sleep(SLEEP_RESET_TIME_MS); + return ret; +} + int initial_cleanup_twl_capture(const is_device_usb_device* usb_device_desc, is_device_device_handlers* handlers) { //EndAcquisition(handlers, usb_device_desc, false, 0, CAPTURE_SCREENS_BOTH); return LIBUSB_SUCCESS; @@ -118,6 +143,7 @@ void is_twl_acquisition_capture_main_loop(CaptureData* capture_data, ISDeviceCap bool audio_enabled = true; bool reprocess = false; std::chrono::time_point clock_last_frame = std::chrono::high_resolution_clock::now(); + std::chrono::time_point clock_last_reset = std::chrono::high_resolution_clock::now(); float last_frame_length = 0.0; int ret = 0; uint32_t video_address = 0; @@ -175,6 +201,11 @@ void is_twl_acquisition_capture_main_loop(CaptureData* capture_data, ISDeviceCap default_sleep((last_frame_length * 1000) / SLEEP_FRAME_DIVIDER); else default_sleep(DEFAULT_FRAME_TIME_MS / SLEEP_FRAME_DIVIDER); + ret = CaptureResetHardware(capture_data, clock_last_reset); + if(ret < 0) { + capture_error_print(true, capture_data, "Hardware Reset: Failed"); + return; + } } } if(!is_acquisition_off)