summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@dside.dyndns.org>2011-04-12 20:57:41 +0200
committerSuren A. Chilingaryan <csa@dside.dyndns.org>2011-04-12 20:57:41 +0200
commit445d5db0183cf5dc98a33160857f22f012cacea6 (patch)
tree24a86dc05195546cf888c104e604da9eb77b3309
parent39b33ce4be920b19a6b0f694febf8609ae64512b (diff)
downloadipecamera-445d5db0183cf5dc98a33160857f22f012cacea6.tar.gz
ipecamera-445d5db0183cf5dc98a33160857f22f012cacea6.tar.bz2
ipecamera-445d5db0183cf5dc98a33160857f22f012cacea6.tar.xz
ipecamera-445d5db0183cf5dc98a33160857f22f012cacea6.zip
Prototype of IPECamera image protocol
-rw-r--r--cli.c14
-rw-r--r--error.h2
-rw-r--r--ipecamera/image.c318
-rw-r--r--ipecamera/image.h3
-rw-r--r--ipecamera/ipecamera.h17
-rw-r--r--ipecamera/model.h6
-rw-r--r--pci.c37
-rw-r--r--pci.h6
-rw-r--r--pcilib.h23
-rw-r--r--tools.c4
10 files changed, 364 insertions, 66 deletions
diff --git a/cli.c b/cli.c
index 9a54618..03b60c0 100644
--- a/cli.c
+++ b/cli.c
@@ -79,7 +79,7 @@ static struct option long_options[] = {
{"access", required_argument, 0, OPT_ACCESS },
{"endianess", required_argument, 0, OPT_ENDIANESS },
{"size", required_argument, 0, OPT_SIZE },
- {"size", required_argument, 0, OPT_OUTPUT },
+ {"output", required_argument, 0, OPT_OUTPUT },
{"info", no_argument, 0, OPT_INFO },
{"list", no_argument, 0, OPT_LIST },
{"reset", no_argument, 0, OPT_RESET },
@@ -567,7 +567,7 @@ int WriteRegister(pcilib_t *handle, pcilib_model_t model, const char *bank, cons
return 0;
}
-int Grab(pcilib_t *handle, const char *output) {
+int Grab(pcilib_t *handle, const char *event, const char *output) {
int err;
void *data = NULL;
@@ -575,12 +575,14 @@ int Grab(pcilib_t *handle, const char *output) {
FILE *o;
- err = pcilib_grab(handle, PCILIB_ALL_EVENTS, &size, &data, NULL);
+ // ignoring event for now
+
+ err = pcilib_grab(handle, PCILIB_EVENTS_ALL, &size, &data, NULL);
if (err) {
Error("Grabbing event is failed");
}
- if (output) {
+ if (output) {
o = fopen(output, "w");
if (!o) {
Error("Failed to open file \"%s\"", output);
@@ -624,7 +626,7 @@ int main(int argc, char **argv) {
pcilib_t *handle;
- while ((c = getopt_long(argc, argv, "hilpr::w::d:m:b:a:s:e:g:", long_options, NULL)) != (unsigned char)-1) {
+ while ((c = getopt_long(argc, argv, "hilpr::w::g::d:m:b:a:s:e:o:", long_options, NULL)) != (unsigned char)-1) {
extern int optind;
switch (c) {
case OPT_HELP:
@@ -831,7 +833,7 @@ int main(int argc, char **argv) {
pcilib_reset(handle);
break;
case MODE_GRAB:
- Grab(handle, output);
+ Grab(handle, event, output);
break;
}
diff --git a/error.h b/error.h
index 198df3e..bf78a8a 100644
--- a/error.h
+++ b/error.h
@@ -6,12 +6,14 @@ enum {
PCILIB_ERROR_MEMORY,
PCILIB_ERROR_INVALID_ADDRESS,
PCILIB_ERROR_INVALID_BANK,
+ PCILIB_ERROR_INVALID_DATA,
PCILIB_ERROR_TIMEOUT,
PCILIB_ERROR_FAILED,
PCILIB_ERROR_VERIFY,
PCILIB_ERROR_NOTSUPPORTED,
PCILIB_ERROR_NOTFOUND,
PCILIB_ERROR_OUTOFRANGE,
+ PCILIB_ERROR_NOTAVAILABLE,
PCILIB_ERROR_NOTINITIALIZED
} pcilib_errot_t;
diff --git a/ipecamera/image.c b/ipecamera/image.c
index e7661b2..8899627 100644
--- a/ipecamera/image.c
+++ b/ipecamera/image.c
@@ -17,6 +17,10 @@
#include "image.h"
#define IPECAMERA_SLEEP_TIME 250000
+#define IPECAMERA_MAX_LINES 1088
+#define IPECAMERA_DEFAULT_BUFFER_SIZE 10
+
+typedef uint32_t ipecamera_payload_t;
struct ipecamera_s {
pcilib_t *pcilib;
@@ -26,25 +30,30 @@ struct ipecamera_s {
pcilib_callback_t cb;
void *cb_user;
-
- int width;
- int height;
pcilib_event_id_t event_id;
pcilib_register_t control_reg, status_reg;
pcilib_register_t start_reg, end_reg;
- pcilib_register_t lines_reg;
+ pcilib_register_t n_lines_reg, line_reg;
pcilib_register_t exposure_reg;
- void *buffer;
+ int buffer_size;
+ int buf_ptr;
+
+ int width, height;
+
+ ipecamera_pixel_t *buffer;
+ ipecamera_change_mask_t *cmask;
+
+ ipecamera_image_dimensions_t dim;
};
#define FIND_REG(var, bank, name) \
ctx->var = pcilib_find_register(pcilib, bank, name); \
if (ctx->var == PCILIB_REGISTER_INVALID) { \
- err = -1; \
+ err = PCILIB_ERROR_NOTFOUND; \
pcilib_error("Unable to find a %s register", name); \
}
@@ -53,25 +62,36 @@ struct ipecamera_s {
err = pcilib_read_register_by_id(pcilib, ctx->reg, &var); \
if (err) { \
pcilib_error("Error reading %s register", ipecamera_registers[ctx->reg].name); \
- return err; \
}
#define SET_REG(reg, val) \
err = pcilib_write_register_by_id(pcilib, ctx->reg, val); \
if (err) { \
pcilib_error("Error writting %s register", ipecamera_registers[ctx->reg].name); \
- return err; \
- }
+ } \
#define CHECK_REG(reg, check) \
- err = pcilib_read_register_by_id(pcilib, ctx->reg, &value); \
- if (err) { \
- pcilib_error("Error reading %s register", ipecamera_registers[ctx->reg].name); \
- return err; \
- } \
- if (!(check)) { \
- pcilib_error("Unexpected value (%li) of register %s", value, ipecamera_registers[ctx->reg].name); \
- return err; \
+ if (!err) { \
+ err = pcilib_read_register_by_id(pcilib, ctx->reg, &value); \
+ if (err) { \
+ pcilib_error("Error reading %s register", ipecamera_registers[ctx->reg].name); \
+ } \
+ if (!(check)) { \
+ pcilib_error("Unexpected value (%li) of register %s", value, ipecamera_registers[ctx->reg].name); \
+ err = PCILIB_ERROR_INVALID_DATA; \
+ } \
+ }
+
+#define CHECK_VALUE(value, val) \
+ if ((!err)&&(value != val)) { \
+ pcilib_error("Unexpected value (%x) in data stream (%x is expected)", value, val); \
+ err = PCILIB_ERROR_INVALID_DATA; \
+ }
+
+#define CHECK_FLAG(flag, check, ...) \
+ if ((!err)&&(!(check))) { \
+ pcilib_error("Unexpected value (%x) of " flag, __VA_ARGS__); \
+ err = PCILIB_ERROR_INVALID_DATA; \
}
@@ -81,26 +101,26 @@ void *ipecamera_init(pcilib_t *pcilib) {
ipecamera_t *ctx = malloc(sizeof(ipecamera_t));
if (ctx) {
+ memset(ctx, 0, sizeof(ipecamera_t));
+
ctx->pcilib = pcilib;
+ ctx->buffer_size = IPECAMERA_DEFAULT_BUFFER_SIZE;
+ ctx->dim.bpp = sizeof(ipecamera_pixel_t) * 8;
+
ctx->data = pcilib_resolve_data_space(pcilib, 0, &ctx->size);
if (!ctx->data) {
err = -1;
pcilib_error("Unable to resolve the data space");
}
- ctx->buffer = malloc(1088 * 2048 * 2);
- if (!ctx->buffer) {
- err = -1;
- pcilib_error("Unable to allocate ring buffer");
- }
-
FIND_REG(status_reg, "fpga", "status");
FIND_REG(control_reg, "fpga", "control");
FIND_REG(start_reg, "fpga", "start_address");
FIND_REG(end_reg, "fpga", "end_address");
- FIND_REG(lines_reg, "cmosis", "number_lines");
+ FIND_REG(n_lines_reg, "cmosis", "number_lines");
+ FIND_REG(line_reg, "cmosis", "start1");
FIND_REG(exposure_reg, "cmosis", "exp_time");
if (err) {
@@ -115,8 +135,7 @@ void *ipecamera_init(pcilib_t *pcilib) {
void ipecamera_free(void *vctx) {
if (vctx) {
ipecamera_t *ctx = (ipecamera_t*)vctx;
-
- if (ctx->buffer) free(ctx->buffer);
+ ipecamera_stop(ctx);
free(ctx);
}
}
@@ -169,6 +188,14 @@ int ipecamera_reset(void *vctx) {
}
usleep(IPECAMERA_SLEEP_TIME);
+
+ // Set default parameters
+ SET_REG(n_lines_reg, 1);
+ SET_REG(exposure_reg, 0);
+ SET_REG(control_reg, 141);
+
+ if (err) return err;
+
// This is temporary for verification purposes
memset(ctx->data, 0, ctx->size);
@@ -187,6 +214,7 @@ int ipecamera_reset(void *vctx) {
}
int ipecamera_start(void *vctx, pcilib_event_t event_mask, pcilib_callback_t cb, void *user) {
+ int err = 0;
ipecamera_t *ctx = (ipecamera_t*)vctx;
if (!ctx) {
@@ -197,13 +225,28 @@ int ipecamera_start(void *vctx, pcilib_event_t event_mask, pcilib_callback_t cb,
ctx->cb = cb;
ctx->cb_user = user;
-
ctx->event_id = 0;
-
- ctx->width = 1270;
- ctx->height = 1088; //GET_REG(lines_reg, lines);
+ ctx->buf_ptr = 0;
+
+ ctx->dim.width = 1270;
+ ctx->dim.height = 1088; //GET_REG(lines_reg, lines);
+
+ ctx->buffer = malloc(ctx->dim.width * ctx->dim.height * ctx->buffer_size * sizeof(ipecamera_pixel_t));
+ if (!ctx->buffer) {
+ err = PCILIB_ERROR_MEMORY;
+ pcilib_error("Unable to allocate ring buffer");
+ }
- // allocate memory
+ ctx->cmask = malloc(ctx->dim.height * ctx->buffer_size * sizeof(ipecamera_change_mask_t));
+ if (!ctx->cmask) {
+ err = PCILIB_ERROR_MEMORY;
+ pcilib_error("Unable to allocate change-mask buffer");
+ }
+
+ if (err) {
+ ipecamera_stop(ctx);
+ return err;
+ }
return 0;
}
@@ -216,19 +259,87 @@ int ipecamera_stop(void *vctx) {
pcilib_error("IPECamera imaging is not initialized");
return PCILIB_ERROR_NOTINITIALIZED;
}
+
+ if (ctx->buffer) {
+ free(ctx->buffer);
+ ctx->buffer = NULL;
+ }
+
+ if (ctx->cmask) {
+ free(ctx->cmask);
+ ctx->cmask = NULL;
+ }
+
+
+ ctx->event_id = 0;
+ ctx->buf_ptr = 0;
return 0;
}
-static int ipecamera_get_line(ipecamera_t *ctx, int line) {
- int err;
+static int ipecamera_get_payload(ipecamera_t *ctx, ipecamera_pixel_t *pbuf, ipecamera_change_mask_t *cbuf, int line_req, pcilib_register_value_t size, ipecamera_payload_t *payload, pcilib_register_value_t *advance) {
+ int i, j;
+ int err = 0;
+
+ ipecamera_payload_t info = payload[0];
+ int channel = info&0x0F; // 4 bits
+ int line = (info>>4)&0x7FF; // 11 bits
+ // 1 bit is reserved
+ int bpp = (info>>16)&0x0F; // 4 bits
+ int pixels = (info>>20)&0xFF; // 8 bits
+ // 2 bits are reserved
+ int header = (info>>30)&0x03; // 2 bits
+
+ int bytes;
+
+ CHECK_FLAG("payload header magick", header == 2, header);
+ CHECK_FLAG("pixel size, only 10 bits are supported", bpp == 10, bpp);
+ //CHECK_FLAG("row number, should be %li", line == line_req, line, line_req);
+ CHECK_FLAG("relative row number, should be 0", line == 0, line);
+ CHECK_FLAG("channel, limited by 10 channels now", channel < 10, channel);
+ CHECK_FLAG("channel, dublicate entry for channel", ((*cbuf)&(1<<channel)) == 0, channel);
+ CHECK_FLAG("number of pixels, 127 is expected", pixels == 127, pixels);
+
+ bytes = pixels / 3;
+ if (bytes * 3 < pixels) ++bytes;
+
+ CHECK_FLAG("payload data bytes, at least %i are expected", bytes < size, size, bytes);
+
+ for (i = 0; i < bytes; i++) {
+ ipecamera_payload_t data = payload[i + 1];
+ int header = (data>>30)&0x03;
+
+ CHECK_FLAG("payload data magick", header == 3, header);
+
+ for (j = 0; j < 3; j++) {
+ int pix = 3 * i + j;
+
+ if (pix == pixels) break;
+
+ pbuf[channel*pixels + pix] = (data >> (10 * j))&0x3FF;
+ }
+ }
+
+ if (!err) {
+ *cbuf |= (1 << channel);
+ *advance = bytes + 1;
+ }
+
+ return err;
+}
+
+static int ipecamera_get_line(ipecamera_t *ctx, ipecamera_pixel_t *pbuf, ipecamera_change_mask_t *cbuf, int line) {
+ int err = 0;
pcilib_t *pcilib = ctx->pcilib;
- pcilib_register_value_t ptr, size, value;
+ pcilib_register_value_t ptr, size, pos, advance, value;
+ ipecamera_payload_t *linebuf;
+ int column = 0;
ipecamera_reset((void*)ctx);
- SET_REG(lines_reg, 1);
+ SET_REG(n_lines_reg, 1);
+ SET_REG(line_reg, line);
SET_REG(control_reg, 149);
usleep(IPECAMERA_SLEEP_TIME);
@@ -238,24 +349,74 @@ static int ipecamera_get_line(ipecamera_t *ctx, int line) {
GET_REG(end_reg, size);
size -= ptr;
- printf("%i: %i %i\n", line, ptr, size);
+ pcilib_warning("Reading line %i: %i %i\n", line, ptr, size);
+
+ if (size < 6) {
+ pcilib_error("The payload is tool small, we should have at least 5 header dwords and 1 footer.");
+ return PCILIB_ERROR_INVALID_DATA;
+ }
- SET_REG(control_reg, 141);
- usleep(IPECAMERA_SLEEP_TIME);
- CHECK_REG(status_reg, 0x0849FFFF);
+ linebuf = (uint32_t*)malloc(size * sizeof(ipecamera_payload_t));
+ if (linebuf) {
+ //pcilib_memcpy(linebuf, ctx->data + ptr, size * sizeof(ipecamera_payload_t));
+ pcilib_datacpy(linebuf, ctx->data + ptr, sizeof(ipecamera_payload_t), size, pcilib_model[PCILIB_MODEL_IPECAMERA].endianess);
+
+
+ CHECK_VALUE(linebuf[0], 0x51111111);
+ CHECK_VALUE(linebuf[1], 0x52222222);
+ CHECK_VALUE(linebuf[2], 0x53333333);
+ CHECK_VALUE(linebuf[3], 0x54444444);
+ CHECK_VALUE(linebuf[4], 0x55555555);
+
+ if (err) {
+ size = 0;
+ } else {
+ pos = 5;
+ size -= 6;
+ }
+
+ while (size > 0) {
+ err = ipecamera_get_payload(ctx, pbuf, cbuf, line, size, linebuf + pos, &advance);
+ if (err) break;
+
+ pos += advance;
+ size -= advance;
+ }
+
+ CHECK_VALUE(linebuf[pos], 0x0AAAAAAA);
+
+ CHECK_FLAG("payloads changed, we expect exactly 10 channels", *cbuf == 0x3FF, *cbuf);
+
+ free(linebuf);
+ }
+
+ if (!err) {
+ SET_REG(control_reg, 141);
+ usleep(IPECAMERA_SLEEP_TIME);
+ CHECK_REG(status_reg, 0x0849FFFF);
+ }
+
+ return err;
}
static int ipecamera_get_image(ipecamera_t *ctx) {
int err;
int i;
+ int buf_ptr;
pcilib_t *pcilib = ctx->pcilib;
+
+//atomic
+ buf_ptr = ctx->buf_ptr;
+ if (ctx->buf_ptr++ == ctx->buffer_size) ctx->buf_ptr = 0;
+ if (ctx->event_id++ == 0) ctx->event_id = 1;
- for (i = 0; i < 1088; i++) {
- ipecamera_get_line(ctx, i);
+ memset(ctx->buffer + buf_ptr * ctx->dim.width * ctx->dim.height, 0, ctx->dim.width * ctx->dim.height * sizeof(ipecamera_pixel_t));
+ memset(ctx->cmask + buf_ptr * ctx->dim.height, 0, ctx->dim.height * sizeof(ipecamera_change_mask_t));
+
+ for (i = 0; i < ctx->dim.height; i++) {
+ ipecamera_get_line(ctx, ctx->buffer + buf_ptr * ctx->dim.width * ctx->dim.height + i * ctx->dim.width, ctx->cmask + buf_ptr * ctx->dim.height + i, i);
}
-
- ctx->event_id++;
}
@@ -267,7 +428,6 @@ int ipecamera_trigger(void *vctx, pcilib_event_t event, size_t trigger_size, voi
if (!ctx) {
pcilib_error("IPECamera imaging is not initialized");
return PCILIB_ERROR_NOTINITIALIZED;
-
}
err = ipecamera_get_image(ctx);
@@ -276,12 +436,74 @@ int ipecamera_trigger(void *vctx, pcilib_event_t event, size_t trigger_size, voi
return err;
}
+static int ipecamera_resolve_event_id(ipecamera_t *ctx, pcilib_event_id_t evid) {
+ int buf_ptr, diff;
+
+ if ((!evid)||(evid > ctx->event_id)) return -1;
+
+ diff = ctx->event_id - evid;
+ buf_ptr = ctx->buf_ptr - diff - 1;
+ if (buf_ptr < 0) {
+ buf_ptr += ctx->buffer_size;
+ if (buf_ptr < 0) return -1;
+ }
+
+ return buf_ptr;
+}
+
+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;
+
+ if (!ctx) {
+ pcilib_error("IPECamera imaging is not initialized");
+ return NULL;
+ }
+
+
+ buf_ptr = ipecamera_resolve_event_id(ctx, event_id);
-void* ipecamera_get(void *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t *size) {
- if (size) *size = ctx->width * ctx->height * 2;
- return ctx->buffer;
+ //printf("%i %i %i\n", ctx->event_id, event_id, buf_ptr);
+
+ if (buf_ptr < 0) return NULL;
+
+ switch ((ipecamera_data_type_t)data_type) {
+ case IPECAMERA_IMAGE_DATA:
+ if (size) *size = ctx->dim.width * ctx->dim.height * sizeof(ipecamera_pixel_t);
+ return ctx->buffer + buf_ptr * ctx->dim.width * ctx->dim.height;
+ case IPECAMERA_CHANGE_MASK:
+ if (size) *size = ctx->dim.height * sizeof(ipecamera_change_mask_t);
+ return ctx->cmask + buf_ptr * ctx->dim.height;
+ case IPECAMERA_DIMENSIONS:
+ if (size) *size = sizeof(ipecamera_image_dimensions_t);
+ return &ctx->dim;
+ case IPECAMERA_IMAGE_REGION:
+ case IPECAMERA_PACKED_IMAGE:
+ // Shall we return complete image or only changed parts?
+ case IPECAMERA_PACKED_LINE:
+ case IPECAMERA_PACKED_PAYLOAD:
+ pcilib_error("Support for data type (%li) is not implemented yet", data_type);
+ return NULL;
+ default:
+ pcilib_error("Unknown data type (%li) is requested", data_type);
+ return NULL;
+ }
}
-int ipecamera_return(void *ctx, pcilib_event_id_t event_id) {
+
+
+int ipecamera_return(void *vctx, pcilib_event_id_t event_id) {
+ ipecamera_t *ctx = (ipecamera_t*)vctx;
+
+ if (!ctx) {
+ pcilib_error("IPECamera imaging is not initialized");
+ return PCILIB_ERROR_NOTINITIALIZED;
+
+ }
+
+ if (ipecamera_resolve_event_id(ctx, event_id) < 0) {
+ return PCILIB_ERROR_NOTAVAILABLE;
+ }
+
return 0;
}
diff --git a/ipecamera/image.h b/ipecamera/image.h
index d174b95..ede964c 100644
--- a/ipecamera/image.h
+++ b/ipecamera/image.h
@@ -3,6 +3,7 @@
#include <stdio.h>
+#include "ipecamera.h"
#include "pcilib.h"
typedef struct ipecamera_s ipecamera_t;
@@ -15,7 +16,7 @@ int ipecamera_start(void *ctx, pcilib_event_t event_mask, pcilib_callback_t cb,
int ipecamera_stop(void *ctx);
int ipecamera_trigger(void *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data);
-void* ipecamera_get(void *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t *size);
+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);
diff --git a/ipecamera/ipecamera.h b/ipecamera/ipecamera.h
index 8b27516..d54dda2 100644
--- a/ipecamera/ipecamera.h
+++ b/ipecamera/ipecamera.h
@@ -1,6 +1,23 @@
#ifndef _IPECAMERA_H
#define _IPECAMERA_H
+typedef struct {
+ int bpp; /*<< Bits per pixel (8, 16, or 32) as returned by IPECAMERA_IMAGE_DATA */
+ int real_bpp; /*<< Bits per pixel as returned by camera and IPECAMERA_PACKED_IMAGE */
+ int width, height;
+} ipecamera_image_dimensions_t;
+typedef enum {
+ IPECAMERA_IMAGE_DATA = 0,
+ IPECAMERA_DIMENSIONS = 0x8000,
+ IPECAMERA_IMAGE_REGION = 0x8010,
+ IPECAMERA_PACKED_IMAGE = 0x8020,
+ IPECAMERA_PACKED_LINE = 0x8021,
+ IPECAMERA_PACKED_PAYLOAD = 0x8022,
+ IPECAMERA_CHANGE_MASK = 0x8030
+} ipecamera_data_type_t;
+
+typedef uint16_t ipecamera_change_mask_t;
+typedef uint16_t ipecamera_pixel_t;
#endif /* _IPECAMERA_H */
diff --git a/ipecamera/model.h b/ipecamera/model.h
index f3f46dd..a7b7935 100644
--- a/ipecamera/model.h
+++ b/ipecamera/model.h
@@ -81,10 +81,16 @@ pcilib_register_range_t ipecamera_register_ranges[] = {
{0, 128, PCILIB_REGISTER_BANK0}, {0, 0, 0}
};
+pcilib_event_description_t ipecamera_events[] = {
+ {"new_frame", ""},
+ {NULL, NULL}
+};
+
#else
extern pcilib_register_description_t ipecamera_registers[];
extern pcilib_register_bank_description_t ipecamera_register_banks[];
extern pcilib_register_range_t ipecamera_register_ranges[];
+extern pcilib_event_description_t ipecamera_events[];
#endif
#ifdef _IPECAMERA_IMAGE_C
diff --git a/pci.c b/pci.c
index 2a25e0d..0e81992 100644
--- a/pci.c
+++ b/pci.c
@@ -11,6 +11,7 @@
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
+#include <arpa/inet.h>
#include <errno.h>
#include <assert.h>
@@ -279,10 +280,25 @@ pcilib_register_t pcilib_find_register(pcilib_t *ctx, const char *bank, const ch
if ((!strcasecmp(registers[i].name, reg))&&((!bank)||(registers[i].bank == bank_addr))) return i;
}
- return -1;
+ return (pcilib_register_t)-1;
};
+pcilib_event_t pcilib_find_event(pcilib_t *ctx, const char *event) {
+ int i;
+ pcilib_register_bank_t res;
+ unsigned long addr;
+
+ pcilib_model_t model = pcilib_get_model(ctx);
+ pcilib_event_description_t *events = pcilib_model[model].events;
+
+ for (i = 0; events[i].name; i++) {
+ if (!strcasecmp(events[i].name, event)) return (1<<i);
+ }
+
+ return (pcilib_event_t)-1;
+}
+
static int pcilib_map_register_space(pcilib_t *ctx) {
if (!ctx->reg_space) {
@@ -484,7 +500,7 @@ int pcilib_read_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_regi
pcilib_register_value_t buf[n + 1];
err = pcilib_read_register_space_internal(ctx, r->bank, r->addr, n, bits, buf);
- if (b->endianess) {
+ if ((b->endianess == PCILIB_BIG_ENDIAN)||((b->endianess == PCILIB_HOST_ENDIAN)&&(ntohs(1) == 1))) {
pcilib_error("Big-endian byte order support is not implemented");
return PCILIB_ERROR_NOTSUPPORTED;
} else {
@@ -581,7 +597,7 @@ int pcilib_write_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_reg
pcilib_register_value_t buf[n + 1];
memset(buf, 0, (n + 1) * sizeof(pcilib_register_value_t));
- if (b->endianess) {
+ if ((b->endianess == PCILIB_BIG_ENDIAN)||((b->endianess == PCILIB_HOST_ENDIAN)&&(ntohs(1) == 1))) {
pcilib_error("Big-endian byte order support is not implemented");
return PCILIB_ERROR_NOTSUPPORTED;
} else {
@@ -688,6 +704,19 @@ int pcilib_trigger(pcilib_t *ctx, pcilib_event_t event, size_t trigger_size, voi
}
+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) {
+ pcilib_event_api_description_t *api = pcilib_model[ctx->model].event_api;
+ if (!api) {
+ pcilib_error("Event API is not supported by the selected model");
+ return NULL;
+ }
+
+ if (api->get_data)
+ return api->get_data(ctx->event_ctx, event_id, data_type, arg_size, arg, size);
+
+ return NULL;
+}
+
void *pcilib_get_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t *size) {
pcilib_event_api_description_t *api = pcilib_model[ctx->model].event_api;
if (!api) {
@@ -696,7 +725,7 @@ void *pcilib_get_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_da
}
if (api->get_data)
- return api->get_data(ctx->event_ctx, event_id, data_type, size);
+ return api->get_data(ctx->event_ctx, event_id, data_type, 0, NULL, size);
return NULL;
}
diff --git a/pci.h b/pci.h
index 9426c33..e3e5c9a 100644
--- a/pci.h
+++ b/pci.h
@@ -15,9 +15,9 @@ const pci_board_info *pcilib_get_board_info(pcilib_t *ctx);
# include "default.h"
pcilib_model_description_t pcilib_model[3] = {
- { NULL, NULL, NULL, NULL },
- { NULL, NULL, NULL, NULL },
- { ipecamera_registers, ipecamera_register_banks, ipecamera_register_ranges, &ipecamera_image_api }
+ { 4, PCILIB_HOST_ENDIAN, NULL, NULL, NULL, NULL },
+ { 4, PCILIB_HOST_ENDIAN, NULL, NULL, NULL, NULL },
+ { 4, PCILIB_BIG_ENDIAN, ipecamera_registers, ipecamera_register_banks, ipecamera_register_ranges, ipecamera_events, &ipecamera_image_api }
};
pcilib_protocol_description_t pcilib_protocol[3] = {
diff --git a/pcilib.h b/pcilib.h
index 57c68c9..7542131 100644
--- a/pcilib.h
+++ b/pcilib.h
@@ -30,7 +30,8 @@ typedef uint64_t pcilib_event_id_t;
typedef uint32_t pcilib_event_t;
typedef enum {
- PCILIB_LITTLE_ENDIAN = 0,
+ PCILIB_HOST_ENDIAN = 0,
+ PCILIB_LITTLE_ENDIAN,
PCILIB_BIG_ENDIAN
} pcilib_endianess_t;
@@ -63,7 +64,12 @@ typedef enum {
#define PCILIB_REGISTER_BANK1 1
#define PCILIB_REGISTER_BANK2 2
#define PCILIB_REGISTER_BANK3 3
-#define PCILIB_ALL_EVENTS ((pcilib_event_t)-1)
+#define PCILIB_EVENT0 1
+#define PCILIB_EVENT1 2
+#define PCILIB_EVENT2 4
+#define PCILIB_EVENT3 8
+#define PCILIB_EVENTS_ALL ((pcilib_event_t)-1)
+#define PCILIB_EVENT_INVALID ((pcilib_event_t)-1)
typedef struct {
pcilib_register_bank_addr_t addr;
@@ -105,6 +111,11 @@ typedef struct {
} pcilib_register_range_t;
typedef struct {
+ const char *name;
+ const char *description;
+} pcilib_event_description_t;
+
+typedef struct {
int (*read)(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, uint8_t bits, pcilib_register_value_t *value);
int (*write)(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, uint8_t bits, pcilib_register_value_t value);
} pcilib_protocol_description_t;
@@ -121,14 +132,18 @@ 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);
- void* (*get_data)(void *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t *size);
+ 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;
typedef struct {
+ uint8_t access;
+ uint8_t endianess;
+
pcilib_register_description_t *registers;
pcilib_register_bank_description_t *banks;
pcilib_register_range_t *ranges;
+ pcilib_event_description_t *events;
pcilib_event_api_description_t *event_api;
} pcilib_model_description_t;
@@ -151,6 +166,7 @@ char *pcilib_resolve_data_space(pcilib_t *ctx, uintptr_t addr, size_t *size);
pcilib_register_bank_t pcilib_find_bank(pcilib_t *ctx, const char *bank);
pcilib_register_t pcilib_find_register(pcilib_t *ctx, const char *bank, const char *reg);
+pcilib_event_t pcilib_find_event(pcilib_t *ctx, const char *event);
int pcilib_read(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf);
int pcilib_write(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf);
@@ -169,6 +185,7 @@ int pcilib_stop(pcilib_t *ctx);
int pcilib_trigger(pcilib_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data);
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);
/*
* This function is provided to find potentially corrupted data. If the data is overwritten by
* the time return_data is called it will return error.
diff --git a/tools.c b/tools.c
index 21f7736..6076f18 100644
--- a/tools.c
+++ b/tools.c
@@ -196,7 +196,9 @@ void *pcilib_datacpy32(void * dst, void const * src, uint8_t size, size_t n, pci
uint32_t * plDst = (uint32_t *) dst;
uint32_t const * plSrc = (uint32_t const *) src;
- int swap = (endianess == PCILIB_BIG_ENDIAN)?(ntohs(1)!=1):(ntohs(1)==1);
+ int swap = 0;
+
+ if (endianess) swap = (endianess == PCILIB_BIG_ENDIAN)?(ntohs(1)!=1):(ntohs(1)==1);
assert(size == 4); // only 32 bit at the moment