diff --git a/indi-asi/asi_camera_test.cpp b/indi-asi/asi_camera_test.cpp index a9034ea4c..c30a02f8a 100644 --- a/indi-asi/asi_camera_test.cpp +++ b/indi-asi/asi_camera_test.cpp @@ -27,6 +27,134 @@ #include #include "pthread.h" #include +#include +#include + +void probe_usb_system() +{ + printf("\n=== USB Subsystem Diagnostics ===\n"); + + // Run dmesg to check for recent USB errors + printf("\nChecking recent USB messages from dmesg:\n"); + FILE *fp = popen("dmesg | grep -i usb | tail -n 10", "r"); + if (fp) + { + char buffer[256]; + while (fgets(buffer, sizeof(buffer), fp)) + printf("%s", buffer); + pclose(fp); + } + else + fprintf(stderr, "Failed to run dmesg command\n"); + + // Get USB device information + printf("\nUSB device information:\n"); + fp = popen("lsusb -v 2>/dev/null | grep -A 2 -B 2 \"ZWO\"", "r"); + if (fp) + { + char buffer[256]; + while (fgets(buffer, sizeof(buffer), fp)) + printf("%s", buffer); + pclose(fp); + } + else + fprintf(stderr, "Failed to run lsusb command\n"); + + // Check USB controller status + printf("\nUSB Controller Status:\n"); + fp = popen("lspci -v | grep -A 4 USB", "r"); + if (fp) + { + char buffer[256]; + while (fgets(buffer, sizeof(buffer), fp)) + printf("%s", buffer); + pclose(fp); + } + else + fprintf(stderr, "Failed to get USB controller status\n"); + + // Check USB device kernel driver + printf("\nUSB Device Kernel Driver:\n"); + DIR *dir; + struct dirent *ent; + dir = opendir("/sys/bus/usb/devices"); + if (dir) + { + while ((ent = readdir(dir))) + { + if (ent->d_name[0] != '.') + { + char path[256]; + char buffer[256]; + + // Check manufacturer + snprintf(path, sizeof(path), "/sys/bus/usb/devices/%s/manufacturer", ent->d_name); + FILE *f = fopen(path, "r"); + if (f) + { + if (fgets(buffer, sizeof(buffer), f)) + { + if (strstr(buffer, "ZWO")) + { + printf("Found ZWO device at: %s\n", ent->d_name); + + // Check driver + snprintf(path, sizeof(path), "/sys/bus/usb/devices/%s/driver", ent->d_name); + char driver_path[256]; + ssize_t len = readlink(path, driver_path, sizeof(driver_path) - 1); + if (len != -1) + { + driver_path[len] = '\0'; + printf("Driver: %s\n", basename(driver_path)); + } + + // Check speed + snprintf(path, sizeof(path), "/sys/bus/usb/devices/%s/speed", ent->d_name); + f = fopen(path, "r"); + if (f) + { + if (fgets(buffer, sizeof(buffer), f)) + printf("Speed: %s", buffer); + fclose(f); + } + + // Check power + snprintf(path, sizeof(path), "/sys/bus/usb/devices/%s/power/", ent->d_name); + DIR *power_dir = opendir(path); + if (power_dir) + { + struct dirent *power_ent; + while ((power_ent = readdir(power_dir))) + { + if (strcmp(power_ent->d_name, "control") == 0 || + strcmp(power_ent->d_name, "autosuspend") == 0) + { + char power_path[512]; + snprintf(power_path, sizeof(power_path), "%s%s", path, power_ent->d_name); + f = fopen(power_path, "r"); + if (f) + { + if (fgets(buffer, sizeof(buffer), f)) + printf("Power %s: %s", power_ent->d_name, buffer); + fclose(f); + } + } + } + closedir(power_dir); + } + } + } + fclose(f); + } + } + } + closedir(dir); + } + else + fprintf(stderr, "Failed to access USB device information in sysfs\n"); + + printf("\n================================\n"); +} void print_usage() { @@ -43,6 +171,7 @@ void print_usage() printf(" 3: Luma 8-bit\n"); printf(" -e Exposure time in milliseconds (default: 100)\n"); printf(" -n Number of images to capture (minimum: 1, default: 1)\n"); + printf(" -t USB traffic value (0-100, default: 40)\n"); printf(" -? Show this help message\n"); } @@ -52,10 +181,11 @@ int main(int argc, char *argv[]) int CamNum = 0, bin = 1, imageFormat = 0; int exp_ms = 100; int capture_count = 1; + int usb_traffic = 40; // Default USB traffic value // Parse command line arguments int opt; - while ((opt = getopt(argc, argv, "c:w:h:b:f:e:n:?")) != -1) + while ((opt = getopt(argc, argv, "c:w:h:b:f:e:n:t:?")) != -1) { switch (opt) { @@ -95,6 +225,14 @@ int main(int argc, char *argv[]) return -1; } break; + case 't': + usb_traffic = atoi(optarg); + if (usb_traffic < 0 || usb_traffic > 100) + { + fprintf(stderr, "USB traffic value must be between 0 and 100.\n"); + return -1; + } + break; case '?': print_usage(); return 0; @@ -206,60 +344,158 @@ int main(int argc, char *argv[]) ASISetControlValue(CamNum, ASI_GAIN, 0, ASI_FALSE); ASISetControlValue(CamNum, ASI_EXPOSURE, exp_ms * 1000, ASI_FALSE); - ASISetControlValue(CamNum, ASI_BANDWIDTHOVERLOAD, 40, ASI_FALSE); + ASISetControlValue(CamNum, ASI_BANDWIDTHOVERLOAD, usb_traffic, ASI_FALSE); + printf("USB traffic set to: %d\n", usb_traffic); for(int capture = 1; capture <= capture_count; capture++) { ASI_EXPOSURE_STATUS status; + bool capture_success = false; + int retry_count = 0; + const int max_retries = 3; printf("Capturing image %d of %d...\n", capture, capture_count); - ASIStartExposure(CamNum, ASI_FALSE); - usleep(10000); - status = ASI_EXP_WORKING; - while(status == ASI_EXP_WORKING) + while (!capture_success && retry_count < max_retries) { - ASIGetExpStatus(CamNum, &status); - } + if (retry_count > 0) + { + printf("Retrying capture (attempt %d of %d)...\n", retry_count + 1, max_retries); + // Add a longer delay between retries + usleep(500000); // 500ms delay + } - if(status == ASI_EXP_SUCCESS) - { - ASIGetDataAfterExp(CamNum, imgBuf, imgSize); + // Get USB traffic before starting exposure + long usb_traffic = 0; + ASI_BOOL is_auto = ASI_FALSE; + ASIGetControlValue(CamNum, ASI_BANDWIDTHOVERLOAD, &usb_traffic, &is_auto); + printf("Current USB traffic: %ld\n", usb_traffic); + + // Start exposure + ASI_ERROR_CODE exp_result = ASIStartExposure(CamNum, ASI_FALSE); + if (exp_result != ASI_SUCCESS) + { + fprintf(stderr, "Failed to start exposure (error code: %d). ", exp_result); + switch(exp_result) + { + case ASI_ERROR_INVALID_ID: + fprintf(stderr, "Invalid camera ID\n"); + break; + case ASI_ERROR_CAMERA_CLOSED: + fprintf(stderr, "Camera is closed\n"); + break; + case ASI_ERROR_CAMERA_REMOVED: + fprintf(stderr, "Camera was removed\n"); + break; + case ASI_ERROR_INVALID_MODE: + fprintf(stderr, "Invalid mode\n"); + break; + case ASI_ERROR_EXPOSURE_IN_PROGRESS: + fprintf(stderr, "Exposure already in progress\n"); + break; + default: + fprintf(stderr, "Unknown error\n"); + } - char filename[32]; - snprintf(filename, sizeof(filename), "image_%03d.raw", capture); - printf("Image successfully captured. Writing to %s...\n", filename); + // Probe USB system for diagnostic information + probe_usb_system(); + + retry_count++; + continue; + } - FILE *output = fopen(filename, "wb"); - if (output) + // Initial delay + usleep(10000); + status = ASI_EXP_WORKING; + + // Monitor exposure progress + time_t start_time = time(NULL); + int progress_counter = 0; + while(status == ASI_EXP_WORKING) { - int n = 0; - for (int i = 0; i < imgSize; i += n) - n = fwrite(imgBuf + i, 1, imgSize - i, output); - fclose(output); + ASIGetExpStatus(CamNum, &status); + + // Print progress every second + if (time(NULL) - start_time > progress_counter) + { + progress_counter++; + printf("Exposure in progress... %d seconds elapsed\n", progress_counter); + + // Check USB traffic during exposure + ASIGetControlValue(CamNum, ASI_BANDWIDTHOVERLOAD, &usb_traffic, &is_auto); + printf("USB traffic during exposure: %ld\n", usb_traffic); + } + + usleep(100000); // 100ms delay between checks + } + + if(status == ASI_EXP_SUCCESS) + { + ASI_ERROR_CODE data_result = ASIGetDataAfterExp(CamNum, imgBuf, imgSize); + if (data_result != ASI_SUCCESS) + { + fprintf(stderr, "Failed to get image data (error code: %d)\n", data_result); + + // Probe USB system for diagnostic information + probe_usb_system(); + + retry_count++; + ASIStopExposure(CamNum); + continue; + } + + char filename[32]; + snprintf(filename, sizeof(filename), "image_%03d.raw", capture); + printf("Image successfully captured. Writing to %s...\n", filename); + + FILE *output = fopen(filename, "wb"); + if (output) + { + int n = 0; + for (int i = 0; i < imgSize; i += n) + n = fwrite(imgBuf + i, 1, imgSize - i, output); + fclose(output); + capture_success = true; + } + else + { + fprintf(stderr, "Failed to open %s for writing!\n", filename); + retry_count++; + } } else { - fprintf(stderr, "Failed to open %s for writing!\n", filename); - ASIStopExposure(CamNum); - ASICloseCamera(CamNum); - if(imgBuf) - delete[] imgBuf; - return -1; + fprintf(stderr, "Exposure failed (status: %d). ", status); + switch(status) + { + case ASI_EXP_FAILED: + fprintf(stderr, "General exposure failure\n"); + break; + case ASI_EXP_IDLE: + fprintf(stderr, "Exposure was not started\n"); + break; + default: + fprintf(stderr, "Unknown status\n"); + } + + // Probe USB system for diagnostic information + probe_usb_system(); + + retry_count++; } + + ASIStopExposure(CamNum); } - else + + if (!capture_success) { - fprintf(stderr, "Failed to capture image %d: %d\n", capture, status); - ASIStopExposure(CamNum); + fprintf(stderr, "Failed to capture image %d after %d attempts\n", capture, max_retries); ASICloseCamera(CamNum); if(imgBuf) delete[] imgBuf; return -1; } - ASIStopExposure(CamNum); - // If we have more images to capture, add a small delay if(capture < capture_count) usleep(100000); // 100ms delay between captures