From adb36212be886985dbaf397d7d2dd875b3d4aab8 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Sun, 29 Mar 2015 18:05:58 +0200 Subject: Fix frame size computation in ipecamera and few debuging options --- cli.c | 3 ++- ipecamera/data.c | 7 +++++++ ipecamera/events.c | 2 +- ipecamera/ipecamera.c | 36 +++++++++++++++++++++++++++--------- ipecamera/private.h | 8 ++++++-- ipecamera/reader.c | 10 ++++++---- tests/ipecamera/autotrigger.sh | 18 ++++++++++++++++++ 7 files changed, 67 insertions(+), 17 deletions(-) create mode 100755 tests/ipecamera/autotrigger.sh diff --git a/cli.c b/cli.c index ccd3084..052bb3b 100644 --- a/cli.c +++ b/cli.c @@ -1237,7 +1237,8 @@ int GrabCallback(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *us ctx->event_pending = 0; ctx->event_count++; - ctx->missing_count += (info->seqnum - ctx->last_num) - 1; + if (ctx->last_num) + ctx->missing_count += (info->seqnum - ctx->last_num) - 1; ctx->last_num = info->seqnum; if (info->flags&PCILIB_EVENT_INFO_FLAG_BROKEN) { diff --git a/ipecamera/data.c b/ipecamera/data.c index fb29018..bdc067e 100644 --- a/ipecamera/data.c +++ b/ipecamera/data.c @@ -61,6 +61,13 @@ inline static int ipecamera_decode_frame(ipecamera_t *ctx, pcilib_event_id_t eve res = ufo_decoder_decode_frame(ctx->ipedec, ctx->buffer + buf_ptr * ctx->padded_size, ctx->raw_size, pixels, &ctx->frame[buf_ptr].event.meta); // puts("done\n"); if (!res) { +#ifdef IPECAMERA_DEBUG_BROKEN_FRAMES + char name[128]; + sprintf(name, "%s/broken.%4lu", IPECAMERA_DEBUG_BROKEN_FRAMES, ctx->event_id); + FILE *f = fopen("/mnt/frames/broken", "w"); + fwrite(ctx->buffer + buf_ptr * ctx->padded_size, ctx->raw_size, 1, f); + fclose(f); +#endif /* IPECAMERA_DEBUG_BROKEN_FRAMES */ err = PCILIB_ERROR_FAILED; ctx->frame[buf_ptr].event.image_broken = err; goto ready; diff --git a/ipecamera/events.c b/ipecamera/events.c index 3253fc5..8238448 100644 --- a/ipecamera/events.c +++ b/ipecamera/events.c @@ -119,7 +119,7 @@ int ipecamera_next_event(pcilib_context_t *vctx, pcilib_timeout_t timeout, pcili #endif /* IPECAMERA_ANNOUNCE_READY */ usleep(IPECAMERA_NOFRAME_SLEEP); } - } else { + } else { pcilib_calc_deadline(&tv, timeout); #ifdef IPECAMERA_ANNOUNCE_READY diff --git a/ipecamera/ipecamera.c b/ipecamera/ipecamera.c index 1b3d305..f54c29d 100644 --- a/ipecamera/ipecamera.c +++ b/ipecamera/ipecamera.c @@ -97,6 +97,7 @@ pcilib_context_t *ipecamera_init(pcilib_t *pcilib) { FIND_REG(status_reg, "fpga", "status"); FIND_REG(control_reg, "fpga", "control"); + FIND_REG(status2_reg, "fpga", "status2"); FIND_REG(status3_reg, "fpga", "status3"); FIND_REG(n_lines_reg, "cmosis", "cmosis_number_lines"); @@ -304,8 +305,9 @@ int ipecamera_start(pcilib_context_t *vctx, pcilib_event_t event_mask, pcilib_ev if (value&0x1000) ctx->fr_mode = 1; else { ctx->fr_mode = 0; - CHECK_STATUS_REG(); - if (err) return err; + +// CHECK_STATUS_REG(); +// if (err) return err; } ctx->event_id = 0; @@ -659,12 +661,28 @@ int ipecamera_trigger(pcilib_context_t *vctx, pcilib_event_t event, size_t trigg return PCILIB_ERROR_BUSY; } */ -/* - do { - usleep(10); - GET_REG(status3_reg, value); - } while (value&0x20000000); -*/ + + GET_REG(status2_reg, value); + if (value&0x40000000) { +// printf("%x\n", value); +// GET_REG(status3_reg, value); +// printf("3: %x\n", value); +// GET_REG(status_reg, value); +// printf("1: %x\n", value); + +#ifdef IPECAMERA_TRIGGER_WAIT_IDLE + if (IPECAMERA_TRIGGER_WAIT_IDLE) { + struct timeval deadline; + pcilib_calc_deadline(&deadline, IPECAMERA_TRIGGER_WAIT_IDLE); + do { + usleep(IPECAMERA_READ_STATUS_DELAY); + GET_REG(status2_reg, value); + } while ((value&0x40000000)&&(pcilib_calc_time_to_deadline(&deadline) > 0)); + } + if (value&0x40000000) +#endif /* IPECAMERA_TRIGGER_WAIT_IDLE */ + return PCILIB_ERROR_BUSY; + } GET_REG(control_reg, value); SET_REG(control_reg, value|IPECAMERA_FRAME_REQUEST); @@ -672,7 +690,7 @@ int ipecamera_trigger(pcilib_context_t *vctx, pcilib_event_t event, size_t trigg //CHECK_REG(status_reg, IPECAMERA_EXPECTED_STATUS); SET_REG(control_reg, value); - + // We need to compute it differently, on top of that add exposure time and the time FPGA takes to read frame from CMOSIS pcilib_calc_deadline(&ctx->next_trigger, IPECAMERA_NEXT_FRAME_DELAY); return 0; diff --git a/ipecamera/private.h b/ipecamera/private.h index b6fd0f7..db5298e 100644 --- a/ipecamera/private.h +++ b/ipecamera/private.h @@ -4,9 +4,10 @@ #include "ipecamera.h" #define IPECAMERA_BUG_EXTRA_DATA -#define IPECAMERA_BUG_MULTIFRAME_PACKETS +#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_INCOMPLETE_PACKETS #define IPECAMERA_BUG_POSTPONED_READ +#define IPECAMERA_DEBUG_BROKEN_FRAMES "/mnt/frames" //#define IPECAMERA_DEBUG_RAW_PACKETS "/mnt/frames" //#define IPECAMERA_ANNOUNCE_READY //**< announce new event only after the reconstruction is done */ @@ -16,6 +17,9 @@ #define IPECAMERA_SLEEP_TIME 250000 //**< Michele thinks 250 should be enough, but reset failing in this case */ #define IPECAMERA_NEXT_FRAME_DELAY 1000 //**< Michele requires 30000 to sync between End Of Readout and next Frame Req */ #define IPECAMERA_WAIT_FRAME_RCVD_TIME 0 //**< by Uros ,wait 6 ms */ +#define IPECAMERA_TRIGGER_WAIT_IDLE 200000 //**< In trigger call allow specified timeout for camera to get out of busy state. Set 0 to fail immideatly */ +#define IPECAMERA_READ_STATUS_DELAY 1000 //**< According to Uros, 1ms delay needed before consequitive reads from status registers */ + #define IPECAMERA_NOFRAME_SLEEP 100 #define IPECAMERA_NOFRAME_PREPROC_SLEEP 100 @@ -83,7 +87,7 @@ struct ipecamera_s { pcilib_register_t packet_len_reg; pcilib_register_t control_reg, status_reg; - pcilib_register_t status3_reg; + pcilib_register_t status2_reg, status3_reg; pcilib_register_t n_lines_reg; uint16_t line_reg; pcilib_register_t exposure_reg; diff --git a/ipecamera/reader.c b/ipecamera/reader.c index 1f054ae..cad5da8 100644 --- a/ipecamera/reader.c +++ b/ipecamera/reader.c @@ -24,11 +24,10 @@ int ipecamera_compute_buffer_size(ipecamera_t *ctx, size_t lines) { const size_t header_size = 8 * sizeof(ipecamera_payload_t); - const size_t footer_size = 16 * sizeof(ipecamera_payload_t); + const size_t footer_size = 8 * sizeof(ipecamera_payload_t); size_t line_size, raw_size, padded_blocks; - switch (ctx->firmware) { case 4: line_size = IPECAMERA_MAX_CHANNELS * (2 + IPECAMERA_PIXELS_PER_CHANNEL / 3) * sizeof(ipecamera_payload_t); @@ -36,8 +35,9 @@ int ipecamera_compute_buffer_size(ipecamera_t *ctx, size_t lines) { break; default: line_size = (1 + IPECAMERA_PIXELS_PER_CHANNEL) * 32; - raw_size = header_size + lines * line_size - 32 + footer_size; + raw_size = lines * line_size; raw_size *= 16 / ctx->cmosis_outputs; + raw_size += header_size + footer_size; } padded_blocks = raw_size / IPECAMERA_DMA_PACKET_LENGTH + ((raw_size % IPECAMERA_DMA_PACKET_LENGTH)?1:0); @@ -93,7 +93,7 @@ static int ipecamera_data_callback(void *user, pcilib_dma_flags_t flags, size_t size_t real_size; size_t extra_data = 0; #endif /* IPECAMERA_BUG_MULTIFRAME_PACKETS */ - + ipecamera_t *ctx = (ipecamera_t*)user; #if defined(IPECAMERA_BUG_INCOMPLETE_PACKETS)||defined(IPECAMERA_BUG_MULTIFRAME_PACKETS) @@ -185,6 +185,8 @@ static int ipecamera_data_callback(void *user, pcilib_dma_flags_t flags, size_t //bufsize = need; eof = 1; } + +// printf("%lu %lu %lu - %u\n", ctx->event_id, ctx->cur_size, ctx->cur_raw_size, eof); // just rip of padding bufsize = ctx->cur_raw_size - ctx->cur_size; diff --git a/tests/ipecamera/autotrigger.sh b/tests/ipecamera/autotrigger.sh new file mode 100755 index 0000000..1c8f353 --- /dev/null +++ b/tests/ipecamera/autotrigger.sh @@ -0,0 +1,18 @@ +#! /bin/bash + +function pci { + PCILIB_PATH="../../" + LD_LIBRARY_PATH="$PCILIB_PATH" $PCILIB_PATH/pci $* +} + +echo "Starting the grabber" +pci -g -o /dev/null --run-time 12000000 --verbose 10 & +pid=$! + +usleep 100000 +pci -w 9040 80000a01 +usleep 10000000 +pci -w 9040 80000001 + +echo "Waiting grabber to finish" +wait $pid -- cgit v1.2.3