summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--private.h1
-rw-r--r--reader.c36
2 files changed, 36 insertions, 1 deletions
diff --git a/private.h b/private.h
index 0e16044..38d6dd0 100644
--- a/private.h
+++ b/private.h
@@ -22,6 +22,7 @@
#define IPECAMERA_BUG_MULTIFRAME_PACKETS //**< This is by design, start of packet comes directly after the end of last one in streaming mode */
#define IPECAMERA_BUG_MULTIFRAME_HEADERS //**< UFO Camera operates with 32-byte entities, but some times there is 16-byte padding before the data which may result in spliting the header between 2 DMA packets. We still need to define a minimal number of bytes which are always in the same DMA packet (CMOSIS_ENTITY_SIZE) */
#define IPECAMERA_BUG_REPEATING_DATA //**< 16 bytes repeated at frame offset 4096, the problem start/stop happenning on board restart */
+//#define IPECAMERA_BUG_STUCKED_BUSY //**< DMA may stuck in busy. According to Michele, the work-around is to disable triggering and read all data out. Not checked */
//#define IPECAMERA_BUG_INCOMPLETE_PACKETS //**< Support incomplete packets, i.e. check for frame magic even if full frame size is not reached yet (slow) */
//#define IPECAMERA_ANNOUNCE_READY //**< Announce new event only after the reconstruction is done */
//#define IPECAMERA_CLEAN_ON_START //**< Read all the data from DMA before starting of recording */
diff --git a/reader.c b/reader.c
index b603e47..3e2b444 100644
--- a/reader.c
+++ b/reader.c
@@ -21,6 +21,23 @@
#include "private.h"
#include "reader.h"
+
+#define GET_REG(reg, var) \
+ if (!err) { \
+ err = pcilib_read_register_by_id(pcilib, ctx->reg, &var); \
+ if (err) { \
+ pcilib_error("Error reading %s register", model_info->registers[ctx->reg].name); \
+ } \
+ }
+
+#define SET_REG(reg, val) \
+ if (!err) { \
+ err = pcilib_write_register_by_id(pcilib, ctx->reg, val); \
+ if (err) { \
+ pcilib_error("Error writting %s register", model_info->registers[ctx->reg].name); \
+ } \
+ }
+
//#define CHECK_FRAME_MAGIC(buf) \
// memcmp(buf, ((void*)frame_magic) + 1, sizeof(frame_magic) - 1)
@@ -304,7 +321,12 @@ static int ipecamera_data_callback(void *user, pcilib_dma_flags_t flags, size_t
void *ipecamera_reader_thread(void *user) {
int err;
ipecamera_t *ctx = (ipecamera_t*)user;
-
+#ifdef IPECAMERA_BUG_STUCKED_BUSY
+ pcilib_register_value_t saved, value;
+ pcilib_t *pcilib = ctx->event.pcilib;
+ const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
+#endif /* IPECAMERA_BUG_STUCKED_BUSY */
+
while (ctx->run_reader) {
err = pcilib_stream_dma(ctx->event.pcilib, ctx->rdma, 0, 0, PCILIB_DMA_FLAG_MULTIPACKET, IPECAMERA_DMA_TIMEOUT, &ipecamera_data_callback, user);
if (err) {
@@ -317,6 +339,18 @@ void *ipecamera_reader_thread(void *user) {
ctx->run_reader = 0;
break;
}
+#ifdef IPECAMERA_BUG_STUCKED_BUSY
+ GET_REG(status2_reg, value);
+ if (value&0x2FFFFFFF) {
+ pcilib_warning("Camera stuck in busy, trying to recover...");
+ GET_REG(control_reg, saved);
+ SET_REG(control_reg, IPECAMERA_IDLE);
+ while ((value&0x2FFFFFFF)&&(ctx->run_reader)) {
+ usleep(IPECAMERA_NOFRAME_SLEEP);
+ }
+ return 0;
+ }
+#endif /* IPECAMERA_BUG_STUCKED_BUSY */
usleep(IPECAMERA_NOFRAME_SLEEP);
} else pcilib_error("DMA error while reading IPECamera frames, error: %i", err);
}