From 70350338f84596c1c5f42697774250773be52da1 Mon Sep 17 00:00:00 2001
From: "Suren A. Chilingaryan" <csa@suren.me>
Date: Wed, 16 Aug 2017 22:41:23 +0200
Subject: Support HighFlex-based ipecamera

---
 base.c    | 17 ++++++-----------
 cmosis.c  |  2 +-
 private.h | 10 ++++++++--
 reader.c  | 14 +++++++-------
 4 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/base.c b/base.c
index 24682d5..a6c0d91 100644
--- a/base.c
+++ b/base.c
@@ -290,14 +290,6 @@ int ipecamera_reset(pcilib_context_t *vctx) {
 	pcilib_warning("Reset procedure is not implemented");
     }
 
-	// Set default parameters
-    err = pcilib_write_register_by_id(pcilib, control, IPECAMERA_IDLE);
-    if (err) {
-	UNLOCK(run);
-	pcilib_error("Error bringing FPGA in default mode");
-	return err;
-    }
-
     usleep(10000);
 
 
@@ -362,11 +354,14 @@ int ipecamera_start(pcilib_context_t *vctx, pcilib_event_t event_mask, pcilib_ev
      case IPECAMERA_FIRMWARE_UFO5:
 	ctx->dim.width = CMOSIS_WIDTH;
 	ctx->dim.height = CMOSIS_MAX_LINES;
+
+	ctx->data_line_size = (1 + CMOSIS_PIXELS_PER_CHANNEL) * 32; 
 	break;
      case IPECAMERA_FIRMWARE_CMOSIS20:
 	ctx->dim.width = CMOSIS20_WIDTH;
 	ctx->dim.height = CMOSIS20_MAX_LINES;
-	ctx->cmosis_outputs = CMOSIS20_MAX_CHANNELS;
+
+	ctx->data_line_size = (2 + CMOSIS20_PIXELS_PER_CHANNEL) * 32;
 	break;
      default:
 	UNLOCK(run);
@@ -374,7 +369,7 @@ int ipecamera_start(pcilib_context_t *vctx, pcilib_event_t event_mask, pcilib_ev
 	return PCILIB_ERROR_INVALID_REQUEST;
     }
 
-    if (ctx->firmware == IPECAMERA_FIRMWARE_UFO5) {
+    if ((1)||(ctx->firmware == IPECAMERA_FIRMWARE_UFO5)) {
 	GET_REG(output_mode_reg, value);
 	switch (value) {
 	 case IPECAMERA_MODE_16_CHAN_IO:
@@ -388,7 +383,7 @@ int ipecamera_start(pcilib_context_t *vctx, pcilib_event_t event_mask, pcilib_ev
 	    pcilib_error("IPECamera reporting invalid output_mode 0x%lx", value);
 	    return PCILIB_ERROR_INVALID_STATE;
 	}
-    }
+    } 
 
 	// We should be careful here (currently firmware matches format, but this may not be the case in future)
     ipecamera_compute_buffer_size(ctx, ctx->firmware, CMOSIS_FRAME_HEADER_SIZE, ctx->dim.height);
diff --git a/cmosis.c b/cmosis.c
index 0733d84..2bf8504 100644
--- a/cmosis.c
+++ b/cmosis.c
@@ -28,7 +28,7 @@
 #define ipecamera_datacpy(dst, src, bank)   pcilib_datacpy(dst, src, 4, 1, bank->raw_endianess)
 
 //#define IPECAMERA_SIMPLIFIED_READOUT
-//#define IPECAMERA_RETRY_ERRORS
+#define IPECAMERA_RETRY_ERRORS
 #define IPECAMERA_MULTIREAD
 
 
diff --git a/private.h b/private.h
index 2043d7a..12867c3 100644
--- a/private.h
+++ b/private.h
@@ -63,13 +63,18 @@
 #define CMOSIS_WIDTH (CMOSIS_MAX_CHANNELS * CMOSIS_PIXELS_PER_CHANNEL)
 //#define IPECAMERA_MAX_LINES 1088
 #define CMOSIS_MAX_LINES 2048
+
+/*
 #define CMOSIS20_MAX_CHANNELS 8
 #define CMOSIS20_PIXELS_PER_CHANNEL 640
 #define CMOSIS20_WIDTH (CMOSIS20_MAX_CHANNELS * CMOSIS20_PIXELS_PER_CHANNEL)
+*/
+#define CMOSIS20_PIXELS_PER_CHANNEL 320
+#define CMOSIS20_WIDTH (CMOSIS_MAX_CHANNELS * CMOSIS_PIXELS_PER_CHANNEL)
 #define CMOSIS20_MAX_LINES 3840
 
-#define IPECAMERA_FRAME_REQUEST 		0x80000209 // 0x1E9
-#define IPECAMERA_IDLE 				0x80000201 // 0x1E1
+#define IPECAMERA_FRAME_REQUEST 		0x209 // 0x80000209 // 0x1E9
+#define IPECAMERA_IDLE 				0x201 // 0x80000201 // 0x1E1
 #define IPECAMERA_START_INTERNAL_STIMULI 	0x1F1
 
 #define IPECAMERA_MODE_16_CHAN_IO		0
@@ -243,6 +248,7 @@ struct ipecamera_s {
     char saved_header[CMOSIS_FRAME_HEADER_SIZE];	/**< If it happened that the frame header is split between 2 DMA packets, this variable holds the part containing in the first packet */
 #endif /* IPECAMERA_BUG_MULTIFRAME_HEADERS */
 
+    size_t data_line_size;
     ipecamera_image_dimensions_t dim;
 
     pthread_t rthread;
diff --git a/reader.c b/reader.c
index b28c51a..bed5eca 100644
--- a/reader.c
+++ b/reader.c
@@ -61,12 +61,9 @@ int ipecamera_compute_buffer_size(ipecamera_t *ctx, ipecamera_format_t format, s
 
     switch (format) {
      case IPECAMERA_FORMAT_CMOSIS:
-	max_channels = CMOSIS_MAX_CHANNELS;
-	line_size = (1 + CMOSIS_PIXELS_PER_CHANNEL) * 32; 
-	break;
      case IPECAMERA_FORMAT_CMOSIS20:
-	max_channels = CMOSIS20_MAX_CHANNELS;
-	line_size = (1 + CMOSIS20_PIXELS_PER_CHANNEL) * 32 / 2;
+	max_channels = CMOSIS_MAX_CHANNELS;
+	line_size = ctx->data_line_size;
 	break;
      default:
 	pcilib_warning("Unsupported version (%u) of frame format...", format);
@@ -92,6 +89,7 @@ int ipecamera_compute_buffer_size(ipecamera_t *ctx, ipecamera_format_t format, s
 
 
 static int ipecamera_parse_header(ipecamera_t *ctx, ipecamera_payload_t *buf, size_t buf_size) {
+    int err;
     int last = buf[0] & 1;
     int version = (buf[0] >> 1) & 7;
     size_t size = 0, n_lines;
@@ -129,7 +127,9 @@ static int ipecamera_parse_header(ipecamera_t *ctx, ipecamera_payload_t *buf, si
     }
 
     size += CMOSIS_FRAME_HEADER_SIZE;
-    ipecamera_compute_buffer_size(ctx, format, size, n_lines);
+
+    err = ipecamera_compute_buffer_size(ctx, format, size, n_lines);
+    if (err) return 0;
 
 	// Returns total size of found headers or 0 on the error
     return size;
@@ -348,7 +348,7 @@ void *ipecamera_reader_thread(void *user) {
 		if ((!err)&&(value&0x2FFFFFFF)) {
 		    pcilib_warning("Camera stuck in busy, trying to recover...");
 		    GET_REG(control_reg, saved);
-		    SET_REG(control_reg, IPECAMERA_IDLE);
+		    SET_REG(control_reg, IPECAMERA_IDLE|(saved&0xFFFF0000));
 		    while ((value&0x2FFFFFFF)&&(ctx->run_reader)) {
 			usleep(IPECAMERA_NOFRAME_SLEEP);
 		    }
-- 
cgit v1.2.3