From fe3f8e3e172818741f32f5ea0bba27f77ca56a1a Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Fri, 14 Aug 2015 03:53:15 +0200 Subject: Add another workaround to handle cameras stuck in busy (disabled and untested) --- private.h | 1 + reader.c | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) 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); } -- cgit v1.2.1