summaryrefslogtreecommitdiffstats
path: root/ipecamera
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@dside.dyndns.org>2011-04-12 02:57:02 +0200
committerSuren A. Chilingaryan <csa@dside.dyndns.org>2011-04-12 02:57:02 +0200
commit39b33ce4be920b19a6b0f694febf8609ae64512b (patch)
treefc058356c3417c871e09bc377243ab3f9b89999a /ipecamera
parentee6ea2f21e2516047db66004fda060a23b152103 (diff)
downloadpcitool-39b33ce4be920b19a6b0f694febf8609ae64512b.tar.gz
pcitool-39b33ce4be920b19a6b0f694febf8609ae64512b.tar.bz2
pcitool-39b33ce4be920b19a6b0f694febf8609ae64512b.tar.xz
pcitool-39b33ce4be920b19a6b0f694febf8609ae64512b.zip
Infrastructure for event API
Diffstat (limited to 'ipecamera')
-rw-r--r--ipecamera/image.c287
-rw-r--r--ipecamera/image.h22
-rw-r--r--ipecamera/ipecamera.h6
-rw-r--r--ipecamera/model.c147
-rw-r--r--ipecamera/model.h110
5 files changed, 572 insertions, 0 deletions
diff --git a/ipecamera/image.c b/ipecamera/image.c
new file mode 100644
index 0000000..e7661b2
--- /dev/null
+++ b/ipecamera/image.c
@@ -0,0 +1,287 @@
+#define _IPECAMERA_IMAGE_C
+#define _BSD_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <assert.h>
+
+#include "../tools.h"
+#include "../error.h"
+
+#include "pcilib.h"
+
+#include "model.h"
+#include "image.h"
+
+#define IPECAMERA_SLEEP_TIME 250000
+
+struct ipecamera_s {
+ pcilib_t *pcilib;
+
+ char *data;
+ size_t size;
+
+ 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 exposure_reg;
+
+ void *buffer;
+};
+
+
+#define FIND_REG(var, bank, name) \
+ ctx->var = pcilib_find_register(pcilib, bank, name); \
+ if (ctx->var == PCILIB_REGISTER_INVALID) { \
+ err = -1; \
+ pcilib_error("Unable to find a %s register", name); \
+ }
+
+
+#define GET_REG(reg, var) \
+ 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; \
+ }
+
+
+void *ipecamera_init(pcilib_t *pcilib) {
+ int err = 0;
+
+ ipecamera_t *ctx = malloc(sizeof(ipecamera_t));
+
+ if (ctx) {
+ ctx->pcilib = pcilib;
+
+ 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(exposure_reg, "cmosis", "exp_time");
+
+ if (err) {
+ free(ctx);
+ return NULL;
+ }
+ }
+
+ return (void*)ctx;
+}
+
+void ipecamera_free(void *vctx) {
+ if (vctx) {
+ ipecamera_t *ctx = (ipecamera_t*)vctx;
+
+ if (ctx->buffer) free(ctx->buffer);
+ free(ctx);
+ }
+}
+
+int ipecamera_reset(void *vctx) {
+ int err;
+ pcilib_t *pcilib;
+ ipecamera_t *ctx = (ipecamera_t*)vctx;
+
+ pcilib_register_t control, status;
+ pcilib_register_value_t value;
+
+ if (!ctx) {
+ pcilib_error("IPECamera imaging is not initialized");
+ return PCILIB_ERROR_NOTINITIALIZED;
+ }
+
+ pcilib = ctx->pcilib;
+ control = ctx->control_reg;
+ status = ctx->status_reg;
+
+ // Set Reset bit to CMOSIS
+ err = pcilib_write_register_by_id(pcilib, control, 5);
+ if (err) {
+ pcilib_error("Error setting CMOSIS reset bit");
+ return err;
+ }
+ usleep(IPECAMERA_SLEEP_TIME);
+
+ // Remove Reset bit to CMOSIS
+ err = pcilib_write_register_by_id(pcilib, control, 1);
+ if (err) {
+ pcilib_error("Error reseting CMOSIS reset bit");
+ return err;
+ }
+ usleep(IPECAMERA_SLEEP_TIME);
+
+ // Special settings for CMOSIS v.2
+ value = 01; err = pcilib_write_register_space(pcilib, "cmosis", 115, 1, &value);
+ if (err) {
+ pcilib_error("Error setting CMOSIS configuration");
+ return err;
+ }
+ usleep(IPECAMERA_SLEEP_TIME);
+
+ value = 07; err = pcilib_write_register_space(pcilib, "cmosis", 82, 1, &value);
+ if (err) {
+ pcilib_error("Error setting CMOSIS configuration");
+ return err;
+ }
+ usleep(IPECAMERA_SLEEP_TIME);
+
+ // This is temporary for verification purposes
+ memset(ctx->data, 0, ctx->size);
+
+ err = pcilib_read_register_by_id(pcilib, status, &value);
+ if (err) {
+ pcilib_error("Error reading status register");
+ return err;
+ }
+
+ if (value != 0x0849FFFF) {
+ pcilib_error("Unexpected value (%lx) of status register", value);
+ return PCILIB_ERROR_VERIFY;
+ }
+
+ return 0;
+}
+
+int ipecamera_start(void *vctx, pcilib_event_t event_mask, pcilib_callback_t cb, void *user) {
+ ipecamera_t *ctx = (ipecamera_t*)vctx;
+
+ if (!ctx) {
+ pcilib_error("IPECamera imaging is not initialized");
+ return PCILIB_ERROR_NOTINITIALIZED;
+ }
+
+ ctx->cb = cb;
+ ctx->cb_user = user;
+
+
+ ctx->event_id = 0;
+
+ ctx->width = 1270;
+ ctx->height = 1088; //GET_REG(lines_reg, lines);
+
+ // allocate memory
+
+ return 0;
+}
+
+
+int ipecamera_stop(void *vctx) {
+ ipecamera_t *ctx = (ipecamera_t*)vctx;
+
+ if (!ctx) {
+ pcilib_error("IPECamera imaging is not initialized");
+ return PCILIB_ERROR_NOTINITIALIZED;
+ }
+
+ return 0;
+}
+
+
+static int ipecamera_get_line(ipecamera_t *ctx, int line) {
+ int err;
+ pcilib_t *pcilib = ctx->pcilib;
+ pcilib_register_value_t ptr, size, value;
+
+ ipecamera_reset((void*)ctx);
+
+ SET_REG(lines_reg, 1);
+
+ SET_REG(control_reg, 149);
+ usleep(IPECAMERA_SLEEP_TIME);
+ CHECK_REG(status_reg, 0x0849FFFF);
+
+ GET_REG(start_reg, ptr);
+ GET_REG(end_reg, size);
+ size -= ptr;
+
+ printf("%i: %i %i\n", line, ptr, size);
+
+ SET_REG(control_reg, 141);
+ usleep(IPECAMERA_SLEEP_TIME);
+ CHECK_REG(status_reg, 0x0849FFFF);
+}
+
+
+static int ipecamera_get_image(ipecamera_t *ctx) {
+ int err;
+ int i;
+ pcilib_t *pcilib = ctx->pcilib;
+
+ for (i = 0; i < 1088; i++) {
+ ipecamera_get_line(ctx, i);
+ }
+
+ ctx->event_id++;
+}
+
+
+int ipecamera_trigger(void *vctx, pcilib_event_t event, size_t trigger_size, void *trigger_data) {
+ int err;
+ pcilib_t *pcilib;
+ ipecamera_t *ctx = (ipecamera_t*)vctx;
+
+ if (!ctx) {
+ pcilib_error("IPECamera imaging is not initialized");
+ return PCILIB_ERROR_NOTINITIALIZED;
+
+ }
+
+ err = ipecamera_get_image(ctx);
+ if (!err) err = ctx->cb(event, ctx->event_id, ctx->cb_user);
+
+ return err;
+}
+
+
+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;
+}
+
+int ipecamera_return(void *ctx, pcilib_event_id_t event_id) {
+ return 0;
+}
diff --git a/ipecamera/image.h b/ipecamera/image.h
new file mode 100644
index 0000000..d174b95
--- /dev/null
+++ b/ipecamera/image.h
@@ -0,0 +1,22 @@
+#ifndef _IPECAMERA_IMAGE_H
+#define _IPECAMERA_IMAGE_H
+
+#include <stdio.h>
+
+#include "pcilib.h"
+
+typedef struct ipecamera_s ipecamera_t;
+
+void *ipecamera_init(pcilib_t *pcilib);
+void ipecamera_free(void *ctx);
+
+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);
+
+void* ipecamera_get(void *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t *size);
+int ipecamera_return(void *ctx, pcilib_event_id_t event_id);
+
+
+#endif /* _IPECAMERA_IMAGE_H */
diff --git a/ipecamera/ipecamera.h b/ipecamera/ipecamera.h
new file mode 100644
index 0000000..8b27516
--- /dev/null
+++ b/ipecamera/ipecamera.h
@@ -0,0 +1,6 @@
+#ifndef _IPECAMERA_H
+#define _IPECAMERA_H
+
+
+
+#endif /* _IPECAMERA_H */
diff --git a/ipecamera/model.c b/ipecamera/model.c
new file mode 100644
index 0000000..4e475b1
--- /dev/null
+++ b/ipecamera/model.c
@@ -0,0 +1,147 @@
+#define _IPECAMERA_MODEL_C
+#include <sys/time.h>
+#include <assert.h>
+
+#include "../tools.h"
+#include "../error.h"
+#include "model.h"
+
+#define ADDR_MASK 0x7F00
+#define WRITE_BIT 0x8000
+#define RETRIES 10
+
+#define READ_READY_BIT 0x20000
+#define READ_ERROR_BIT 0x40000
+
+#define ipecamera_datacpy(dst, src, bank) pcilib_datacpy(dst, src, 4, 1, bank->raw_endianess)
+
+static pcilib_register_value_t ipecamera_bit_mask[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
+
+int ipecamera_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, uint8_t bits, pcilib_register_value_t *value) {
+ uint32_t val;
+ char *wr, *rd;
+ struct timeval start, cur;
+ int retries = RETRIES;
+
+ assert(addr < 128);
+
+ wr = pcilib_resolve_register_address(ctx, bank->write_addr);
+ rd = pcilib_resolve_register_address(ctx, bank->read_addr);
+ if ((!rd)||(!wr)) {
+ pcilib_error("Error resolving addresses of read & write registers");
+ return PCILIB_ERROR_INVALID_ADDRESS;
+ }
+
+retry:
+ val = (addr << 8);
+
+ //printf("%i %x %p %p\n", addr, val, wr, rd);
+
+ ipecamera_datacpy(wr, &val, bank);
+
+ gettimeofday(&start, NULL);
+
+ ipecamera_datacpy(&val, rd, bank);
+ while ((val & READ_READY_BIT) == 0) {
+ gettimeofday(&cur, NULL);
+ if (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > PCILIB_REGISTER_TIMEOUT) break;
+
+ ipecamera_datacpy(&val, rd, bank);
+ }
+
+ if ((val & READ_READY_BIT) == 0) {
+ pcilib_error("Timeout reading register value");
+ return PCILIB_ERROR_TIMEOUT;
+ }
+
+ if (val & READ_ERROR_BIT) {
+ pcilib_error("Error reading register value");
+ return PCILIB_ERROR_FAILED;
+ }
+
+ if (((val&ADDR_MASK) >> 8) != addr) {
+ if (--retries > 0) {
+ pcilib_warning("Address verification failed during register read, retrying (try %i of %i)...", RETRIES - retries, RETRIES);
+ goto retry;
+ }
+ pcilib_error("Address verification failed during register read");
+ return PCILIB_ERROR_VERIFY;
+ }
+
+
+// printf("%i\n", val&ipecamera_bit_mask[bits]);
+
+ *value = val&ipecamera_bit_mask[bits];
+
+ return 0;
+}
+
+int ipecamera_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, uint8_t bits, pcilib_register_value_t value) {
+ uint32_t val;
+ char *wr, *rd;
+ struct timeval start, cur;
+ int retries = RETRIES;
+
+ assert(addr < 128);
+ assert(value < 256);
+
+ wr = pcilib_resolve_register_address(ctx, bank->write_addr);
+ rd = pcilib_resolve_register_address(ctx, bank->read_addr);
+ if ((!rd)||(!wr)) {
+ pcilib_error("Error resolving addresses of read & write registers");
+ return PCILIB_ERROR_INVALID_ADDRESS;
+ }
+
+retry:
+ val = WRITE_BIT|(addr << 8)|(value&0xFF);
+
+ //printf("%i %x %p %p\n", addr, val, wr, rd);
+
+ ipecamera_datacpy(wr, &val, bank);
+
+ gettimeofday(&start, NULL);
+
+ ipecamera_datacpy(&val, rd, bank);
+ while ((val & READ_READY_BIT) == 0) {
+ gettimeofday(&cur, NULL);
+ if (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > PCILIB_REGISTER_TIMEOUT) break;
+
+ ipecamera_datacpy(&val, rd, bank);
+ }
+
+ if ((val & READ_READY_BIT) == 0) {
+ if (--retries > 0) {
+ pcilib_warning("Timeout occured during register write, retrying (try %i of %i)...", RETRIES - retries, RETRIES);
+ goto retry;
+ }
+
+ pcilib_error("Timeout writting register value");
+ return PCILIB_ERROR_TIMEOUT;
+ }
+
+ if (val & READ_ERROR_BIT) {
+ pcilib_error("Error writting register value");
+ return PCILIB_ERROR_FAILED;
+ }
+
+ if (((val&ADDR_MASK) >> 8) != addr) {
+ if (--retries > 0) {
+ pcilib_warning("Address verification failed during register write, retrying (try %i of %i)...", RETRIES - retries, RETRIES);
+ goto retry;
+ }
+ pcilib_error("Address verification failed during register write");
+ return PCILIB_ERROR_VERIFY;
+ }
+
+ if ((val&ipecamera_bit_mask[bits]) != value) {
+ pcilib_error("Value verification failed during register read (%lu != %lu)", val&ipecamera_bit_mask[bits], value);
+ return PCILIB_ERROR_VERIFY;
+ }
+
+ //printf("%i\n", val&ipecamera_bit_mask[bits]);
+
+ return 0;
+}
+
+
+
diff --git a/ipecamera/model.h b/ipecamera/model.h
new file mode 100644
index 0000000..f3f46dd
--- /dev/null
+++ b/ipecamera/model.h
@@ -0,0 +1,110 @@
+#ifndef _IPECAMERA_MODEL_H
+#define _IPECAMERA_MODEL_H
+
+#include <stdio.h>
+
+#include "pcilib.h"
+#include "image.h"
+
+#define IPECAMERA_REGISTER_SPACE 0xfeaffc00
+#define IPECAMERA_REGISTER_WRITE (IPECAMERA_REGISTER_SPACE + 0)
+#define IPECAMERA_REGISTER_READ (IPECAMERA_REGISTER_WRITE + 4)
+
+#ifdef _IPECAMERA_MODEL_C
+pcilib_register_bank_description_t ipecamera_register_banks[] = {
+ { PCILIB_REGISTER_BANK0, 128, IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, PCILIB_BIG_ENDIAN, 8, PCILIB_LITTLE_ENDIAN, "cmosis", "CMOSIS CMV2000 Registers" },
+ { PCILIB_REGISTER_BANK1, 64, PCILIB_DEFAULT_PROTOCOL, IPECAMERA_REGISTER_SPACE, IPECAMERA_REGISTER_SPACE, PCILIB_BIG_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "fpga", "IPECamera Registers" },
+ { 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL }
+};
+
+pcilib_register_description_t ipecamera_registers[] = {
+{1, 0, 16, 1088, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "number_lines", ""},
+{3, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "start1", ""},
+{5, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "start2", ""},
+{7, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "start3", ""},
+{9, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "start4", ""},
+{11, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "start5", ""},
+{13, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "start6", ""},
+{15, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "start7", ""},
+{17, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "start8", ""},
+{19, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "number_lines1", ""},
+{21, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "number_lines2", ""},
+{23, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "number_lines3", ""},
+{25, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "number_lines4", ""},
+{27, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "number_lines5", ""},
+{29, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "number_lines6", ""},
+{31, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "number_lines7", ""},
+{33, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "number_lines8", ""},
+{35, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "sub_s", ""},
+{37, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "sub_a", ""},
+{39, 0, 1, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "color", ""},
+{40, 0, 2, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "image_flipping", ""},
+{41, 0, 2, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "exp_flags", ""},
+{42, 0, 24, 1088, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "exp_time", ""},
+{45, 0, 24, 1088, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "exp_step", ""},
+{48, 0, 24, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "exp_kp1", ""},
+{51, 0, 24, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "exp_kp2", ""},
+{54, 0, 2, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "nr_slopes", ""},
+{55, 0, 8, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "exp_seq", ""},
+{56, 0, 24, 1088, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "exp_time2", ""},
+{59, 0, 24, 1088, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "exp_step2", ""},
+{68, 0, 2, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "nr_slopes2", ""},
+{69, 0, 8, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "exp_seq2", ""},
+{70, 0, 16, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "number_frames", ""},
+{72, 0, 2, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "output_mode", ""},
+{78, 0, 12, 85, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "training_pattern", ""},
+{80, 0, 18, 0x3FFFF,PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "channel_en", ""},
+{89, 0, 8, 96, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "vlow2", ""},
+{90, 0, 8, 96, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "vlow3", ""},
+{100, 0, 14, 16260, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "offset", ""},
+{102, 0, 2, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "pga", ""},
+{103, 0, 8, 32, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "adc_gain", ""},
+{111, 0, 1, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "bit_mode", ""},
+{112, 0, 2, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "adc_resolution", ""},
+{126, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "temp", ""},
+{0, 0, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK1, "spi_conf_input", ""},
+{1, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "spi_conf_output", ""},
+{2, 0, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK1, "spi_clk_speed", ""},
+{3, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "firmware_version", ""},
+{4, 0, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK1, "control", ""},
+{5, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "status", ""},
+{6, 0, 16, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "cmosis_temperature", ""},
+{7, 0, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK1, "temperature_sample_timing", ""},
+{8, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "start_address", ""},
+{9, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "end_address", ""},
+{10, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "last_write_address", ""},
+{11, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "last_write_value", ""},
+{0, 0, 0, 0, 0, 0, NULL, NULL}
+};
+
+pcilib_register_range_t ipecamera_register_ranges[] = {
+ {0, 128, PCILIB_REGISTER_BANK0}, {0, 0, 0}
+};
+
+#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[];
+#endif
+
+#ifdef _IPECAMERA_IMAGE_C
+pcilib_event_api_description_t ipecamera_image_api = {
+ ipecamera_init,
+ ipecamera_free,
+
+ ipecamera_reset,
+ ipecamera_start,
+ ipecamera_stop,
+ ipecamera_trigger,
+
+ ipecamera_get,
+ ipecamera_return
+};
+#else
+extern pcilib_event_api_description_t ipecamera_image_api;
+#endif
+
+int ipecamera_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, uint8_t bits, pcilib_register_value_t *value);
+int ipecamera_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, uint8_t bits, pcilib_register_value_t value);
+
+#endif /* _IPECAMERA_MODEL_H */