From b70ed8b6ccf17a7c5b4339f05a33471eaf3b33e5 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Thu, 14 Apr 2011 04:21:38 +0200 Subject: Support non-callback way of getting events --- ipecamera/image.c | 40 +++++++++++++++++++++++++++++++++++++++- ipecamera/image.h | 2 ++ ipecamera/model.h | 1 + pci.c | 18 ++++++++++++++++++ pcilib.h | 6 +++++- 5 files changed, 65 insertions(+), 2 deletions(-) diff --git a/ipecamera/image.c b/ipecamera/image.c index 8ad6953..3e320cd 100644 --- a/ipecamera/image.c +++ b/ipecamera/image.c @@ -37,6 +37,7 @@ struct ipecamera_s { void *cb_user; pcilib_event_id_t event_id; + pcilib_event_id_t reported_id; pcilib_register_t control_reg, status_reg; pcilib_register_t start_reg, end_reg; @@ -253,6 +254,7 @@ int ipecamera_start(void *vctx, pcilib_event_t event_mask, pcilib_callback_t cb, ctx->cb_user = user; ctx->event_id = 0; + ctx->reported_id = 0; ctx->buf_ptr = 0; ctx->dim.width = 1270; @@ -303,6 +305,7 @@ int ipecamera_stop(void *vctx) { ctx->event_id = 0; + ctx->reported_id = 0; ctx->buf_ptr = 0; return 0; @@ -504,7 +507,12 @@ int ipecamera_trigger(void *vctx, pcilib_event_t event, size_t trigger_size, voi } err = ipecamera_get_image(ctx); - if (!err) err = ctx->cb(event, ctx->event_id, ctx->cb_user); + if (!err) { + if (ctx->cb) { + err = ctx->cb(event, ctx->event_id, ctx->cb_user); + ctx->reported_id = ctx->event_id; + } + } return err; } @@ -524,6 +532,36 @@ static int ipecamera_resolve_event_id(ipecamera_t *ctx, pcilib_event_id_t evid) return buf_ptr; } +pcilib_event_id_t ipecamera_next_event(void *vctx, pcilib_event_t event_mask) { + int buf_ptr; + pcilib_event_id_t reported; + ipecamera_t *ctx = (ipecamera_t*)vctx; + + if (!ctx) { + pcilib_error("IPECamera imaging is not initialized"); + return PCILIB_EVENT_ID_INVALID; + } + + if (!ctx->started) { + pcilib_error("IPECamera is not in grabbing state"); + return PCILIB_EVENT_ID_INVALID; + } + + if ((!ctx->event_id)||(ctx->reported_id == ctx->event_id)) return PCILIB_EVENT_ID_INVALID; + + // We had an overflow in event counting + if (ctx->reported_id > ctx->event_id) { + do { + if (++ctx->reported_id == 0) ctx->reported_id = 1; + } while (ipecamera_resolve_event_id(ctx, ctx->reported_id) < 0); + } else { + if ((ctx->event_id - ctx->reported_id) > ctx->buffer_size) ctx->reported_id = ctx->event_id - (ctx->buffer_size - 1); + else ++ctx->reported_id; + } + + return ctx->reported_id; +} + void* ipecamera_get(void *vctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size) { int buf_ptr; ipecamera_t *ctx = (ipecamera_t*)vctx; diff --git a/ipecamera/image.h b/ipecamera/image.h index 6b92524..513449f 100644 --- a/ipecamera/image.h +++ b/ipecamera/image.h @@ -13,9 +13,11 @@ int ipecamera_reset(void *ctx); int ipecamera_start(void *ctx, pcilib_event_t event_mask, pcilib_callback_t cb, void *user); int ipecamera_stop(void *ctx); int ipecamera_trigger(void *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data); +pcilib_event_id_t ipecamera_next_event(void *ctx, pcilib_event_t event_mask); void* ipecamera_get(void *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size); int ipecamera_return(void *ctx, pcilib_event_id_t event_id); + #endif /* _IPECAMERA_IMAGE_H */ diff --git a/ipecamera/model.h b/ipecamera/model.h index 07f405a..c3d82e3 100644 --- a/ipecamera/model.h +++ b/ipecamera/model.h @@ -105,6 +105,7 @@ pcilib_event_api_description_t ipecamera_image_api = { ipecamera_stop, ipecamera_trigger, + ipecamera_next_event, ipecamera_get, ipecamera_return }; diff --git a/pci.c b/pci.c index a3f09db..df1025e 100644 --- a/pci.c +++ b/pci.c @@ -688,6 +688,24 @@ int pcilib_stop(pcilib_t *ctx) { return 0; } +pcilib_event_id_t pcilib_get_next_event(pcilib_t *ctx, pcilib_event_t event_mask) { + pcilib_event_api_description_t *api; + + pcilib_model_t model = pcilib_get_model(ctx); + + api = pcilib_model[model].event_api; + if (!api) { + pcilib_error("Event API is not supported by the selected model"); + return PCILIB_ERROR_NOTSUPPORTED; + } + + if (api->next_event) + return api->next_event(ctx->event_ctx, event_mask); + + pcilib_error("Event enumeration is not suppored by API"); + return PCILIB_EVENT_ID_INVALID; +} + int pcilib_trigger(pcilib_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data) { pcilib_event_api_description_t *api; diff --git a/pcilib.h b/pcilib.h index cde33d3..360b9a0 100644 --- a/pcilib.h +++ b/pcilib.h @@ -69,7 +69,8 @@ typedef enum { #define PCILIB_EVENT2 4 #define PCILIB_EVENT3 8 #define PCILIB_EVENTS_ALL ((pcilib_event_t)-1) -#define PCILIB_EVENT_INVALID ((pcilib_event_t)-1) +#define PCILIB_EVENT_INVALID ((pcilib_event_t)-1) +#define PCILIB_EVENT_ID_INVALID 0 typedef struct { pcilib_register_bank_addr_t addr; @@ -132,6 +133,8 @@ typedef struct { int (*start)(void *ctx, pcilib_event_t event_mask, pcilib_callback_t callback, void *user); int (*stop)(void *ctx); int (*trigger)(void *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data); + + pcilib_event_id_t (*next_event)(void *ctx, pcilib_event_t event_mask); void* (*get_data)(void *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size); int (*return_data)(void *ctx, pcilib_event_id_t event_id); } pcilib_event_api_description_t; @@ -185,6 +188,7 @@ int pcilib_stop(pcilib_t *ctx); int pcilib_trigger(pcilib_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data); +pcilib_event_id_t pcilib_get_next_event(pcilib_t *ctx, pcilib_event_t event_mask); void *pcilib_get_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t *size); void *pcilib_get_data_with_argument(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size); /* -- cgit v1.2.3