summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@dside.dyndns.org>2011-07-09 05:33:18 +0200
committerSuren A. Chilingaryan <csa@dside.dyndns.org>2011-07-09 05:33:18 +0200
commit02924fc49641ca9c000054a7a540b6f1eaa0e8f8 (patch)
tree986ba532752d7e19d85f77eea57f15579fe913d5
parent80d999195b2b1896fcd1878a44b0ece474fe678c (diff)
downloadipecamera-02924fc49641ca9c000054a7a540b6f1eaa0e8f8.tar.gz
ipecamera-02924fc49641ca9c000054a7a540b6f1eaa0e8f8.tar.bz2
ipecamera-02924fc49641ca9c000054a7a540b6f1eaa0e8f8.tar.xz
ipecamera-02924fc49641ca9c000054a7a540b6f1eaa0e8f8.zip
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
-rw-r--r--ToDo1
-rw-r--r--cli.c90
-rw-r--r--common.mk3
-rw-r--r--default.c12
-rw-r--r--default.h4
-rw-r--r--dma.c18
-rw-r--r--dma/nwl.c75
-rw-r--r--dma/nwl_register.h94
-rw-r--r--event.c36
-rw-r--r--ipecamera/model.c13
-rw-r--r--ipecamera/model.h126
-rw-r--r--pci.c21
-rw-r--r--pci.h5
-rw-r--r--pcilib.h14
-rw-r--r--register.c151
-rw-r--r--register.h7
16 files changed, 468 insertions, 202 deletions
diff --git a/ToDo b/ToDo
index ca3bdb0..e61ca28 100644
--- a/ToDo
+++ b/ToDo
@@ -1,4 +1,3 @@
-1. Support registers with bit shifts
2. Hint for register value representation in the bank (hex, decimal)
3. Implement software registers
4. Support FIFO reads/writes from/to registers
diff --git a/cli.c b/cli.c
index d323f3a..f4758e7 100644
--- a/cli.c
+++ b/cli.c
@@ -172,7 +172,7 @@ void Error(const char *format, ...) {
void Silence(const char *format, ...) {
}
-void List(pcilib_t *handle, pcilib_model_t model, const char *bank) {
+void List(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, int details) {
int i;
pcilib_register_bank_description_t *banks;
pcilib_register_description_t *registers;
@@ -180,7 +180,7 @@ void List(pcilib_t *handle, pcilib_model_t model, const char *bank) {
const pcilib_board_info_t *board_info = pcilib_get_board_info(handle);
const pcilib_dma_info_t *dma_info = pcilib_get_dma_info(handle);
-
+
for (i = 0; i < PCILIB_MAX_BANKS; i++) {
if (board_info->bar_length[i] > 0) {
printf(" BAR %d - ", i);
@@ -232,7 +232,7 @@ void List(pcilib_t *handle, pcilib_model_t model, const char *bank) {
}
if ((bank)&&(bank != (char*)-1)) banks = NULL;
- else banks = pcilib_model[model].banks;
+ else banks = model_info->banks;
if (banks) {
printf("Banks: \n");
@@ -247,13 +247,13 @@ void List(pcilib_t *handle, pcilib_model_t model, const char *bank) {
}
if (bank == (char*)-1) registers = NULL;
- else registers = pcilib_model[model].registers;
+ else registers = model_info->registers;
if (registers) {
pcilib_register_bank_addr_t bank_addr;
if (bank) {
pcilib_register_bank_t bank_id = pcilib_find_bank(handle, bank);
- pcilib_register_bank_description_t *b = pcilib_model[model].banks + bank_id;
+ pcilib_register_bank_description_t *b = model_info->banks + bank_id;
bank_addr = b->addr;
if (b->description) printf("%s:\n", b->description);
@@ -266,6 +266,17 @@ void List(pcilib_t *handle, pcilib_model_t model, const char *bank) {
const char *mode;
if ((bank)&&(registers[i].bank != bank_addr)) continue;
+ if (registers[i].type == PCILIB_REGISTER_BITS) {
+ if (!details) continue;
+
+ if (registers[i].bits > 1) {
+ printf(" [%2u:%2u] - %s\n", registers[i].offset, registers[i].offset + registers[i].bits, registers[i].name);
+ } else {
+ printf(" [ %2u] - %s\n", registers[i].offset, registers[i].name);
+ }
+
+ continue;
+ }
if (registers[i].mode == PCILIB_REGISTER_RW) mode = "RW";
else if (registers[i].mode == PCILIB_REGISTER_R) mode = "R ";
@@ -273,7 +284,7 @@ void List(pcilib_t *handle, pcilib_model_t model, const char *bank) {
else mode = " ";
printf(" 0x%02x (%2i %s) %s", registers[i].addr, registers[i].bits, mode, registers[i].name);
- if ((registers[i].description)&&(registers[i].description[0])) {
+ if ((details > 0)&&(registers[i].description)&&(registers[i].description[0])) {
printf(": %s", registers[i].description);
}
printf("\n");
@@ -283,7 +294,7 @@ void List(pcilib_t *handle, pcilib_model_t model, const char *bank) {
}
if (bank == (char*)-1) events = NULL;
- else events = pcilib_model[model].events;
+ else events = model_info->events;
if (events) {
printf("Events: \n");
@@ -297,11 +308,11 @@ void List(pcilib_t *handle, pcilib_model_t model, const char *bank) {
}
}
-void Info(pcilib_t *handle, pcilib_model_t model) {
+void Info(pcilib_t *handle, pcilib_model_description_t *model_info) {
const pcilib_board_info_t *board_info = pcilib_get_board_info(handle);
printf("Vendor: %x, Device: %x, Interrupt Pin: %i, Interrupt Line: %i\n", board_info->vendor_id, board_info->device_id, board_info->interrupt_pin, board_info->interrupt_line);
- List(handle, model, (char*)-1);
+ List(handle, model_info, (char*)-1, 0);
}
@@ -567,21 +578,20 @@ int ReadData(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma, p
-int ReadRegister(pcilib_t *handle, pcilib_model_t model, const char *bank, const char *reg) {
+int ReadRegister(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, const char *reg) {
int i;
int err;
const char *format;
pcilib_register_bank_t bank_id;
pcilib_register_bank_addr_t bank_addr;
- pcilib_register_description_t *registers = pcilib_model[model].registers;
pcilib_register_value_t value;
if (reg) {
pcilib_register_t regid = pcilib_find_register(handle, bank, reg);
- bank_id = pcilib_find_bank_by_addr(handle, registers[regid].bank);
- format = pcilib_model[model].banks[bank_id].format;
+ bank_id = pcilib_find_bank_by_addr(handle, model_info->registers[regid].bank);
+ format = model_info->banks[bank_id].format;
if (!format) format = "%lu";
err = pcilib_read_register_by_id(handle, regid, &value);
@@ -593,32 +603,34 @@ int ReadRegister(pcilib_t *handle, pcilib_model_t model, const char *bank, const
printf("\n");
}
} else {
-
- if (registers) {
+ // Adding DMA registers
+ pcilib_get_dma_info(handle);
+
+ if (model_info->registers) {
if (bank) {
bank_id = pcilib_find_bank(handle, bank);
- bank_addr = pcilib_model[model].banks[bank_id].addr;
+ bank_addr = model_info->banks[bank_id].addr;
}
printf("Registers:\n");
- for (i = 0; registers[i].bits; i++) {
- if ((registers[i].mode & PCILIB_REGISTER_R)&&((!bank)||(registers[i].bank == bank_addr))) {
- bank_id = pcilib_find_bank_by_addr(handle, registers[i].bank);
- format = pcilib_model[model].banks[bank_id].format;
+ for (i = 0; model_info->registers[i].bits; i++) {
+ if ((model_info->registers[i].mode & PCILIB_REGISTER_R)&&((!bank)||(model_info->registers[i].bank == bank_addr))&&(model_info->registers[i].type != PCILIB_REGISTER_BITS)) {
+ bank_id = pcilib_find_bank_by_addr(handle, model_info->registers[i].bank);
+ format = model_info->banks[bank_id].format;
if (!format) format = "%lu";
err = pcilib_read_register_by_id(handle, i, &value);
- if (err) printf(" %s = error reading value", registers[i].name);
+ if (err) printf(" %s = error reading value", model_info->registers[i].name);
else {
- printf(" %s = ", registers[i].name);
+ printf(" %s = ", model_info->registers[i].name);
printf(format, value);
}
printf(" [");
- printf(format, registers[i].defvalue);
+ printf(format, model_info->registers[i].defvalue);
printf("]");
+ printf("\n");
}
- printf("\n");
}
} else {
printf("No registers");
@@ -627,11 +639,11 @@ int ReadRegister(pcilib_t *handle, pcilib_model_t model, const char *bank, const
}
}
-int ReadRegisterRange(pcilib_t *handle, pcilib_model_t model, const char *bank, uintptr_t addr, size_t n) {
+int ReadRegisterRange(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, uintptr_t addr, size_t n) {
int err;
int i;
- pcilib_register_bank_description_t *banks = pcilib_model[model].banks;
+ pcilib_register_bank_description_t *banks = model_info->banks;
pcilib_register_bank_t bank_id = pcilib_find_bank(handle, bank);
if (bank_id == PCILIB_REGISTER_BANK_INVALID) {
@@ -726,7 +738,7 @@ int WriteData(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma,
free(buf);
}
-int WriteRegisterRange(pcilib_t *handle, pcilib_model_t model, const char *bank, uintptr_t addr, size_t n, char ** data) {
+int WriteRegisterRange(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, uintptr_t addr, size_t n, char ** data) {
pcilib_register_value_t *buf, *check;
int res, i, err;
unsigned long value;
@@ -750,7 +762,7 @@ int WriteRegisterRange(pcilib_t *handle, pcilib_model_t model, const char *bank,
if (memcmp(buf, check, size)) {
printf("Write failed: the data written and read differ, the foolowing is read back:\n");
- ReadRegisterRange(handle, model, bank, addr, n);
+ ReadRegisterRange(handle, model_info, bank, addr, n);
exit(-1);
}
@@ -759,7 +771,7 @@ int WriteRegisterRange(pcilib_t *handle, pcilib_model_t model, const char *bank,
}
-int WriteRegister(pcilib_t *handle, pcilib_model_t model, const char *bank, const char *reg, char ** data) {
+int WriteRegister(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, const char *reg, char ** data) {
int err;
int i;
@@ -827,9 +839,11 @@ int main(int argc, char **argv) {
long itmp;
unsigned char c;
+ int details = 0;
int quiete = 0;
pcilib_model_t model = PCILIB_MODEL_DETECT;
+ pcilib_model_description_t *model_info;
MODE mode = MODE_INVALID;
const char *type = NULL;
ACCESS_MODE amode = ACCESS_BAR;
@@ -865,7 +879,8 @@ int main(int argc, char **argv) {
mode = MODE_INFO;
break;
case OPT_LIST:
- if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
+ if (mode == MODE_LIST) details++;
+ else if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
mode = MODE_LIST;
break;
@@ -966,6 +981,7 @@ int main(int argc, char **argv) {
if (handle < 0) Error("Failed to open FPGA device: %s", fpga_device);
model = pcilib_get_model(handle);
+ model_info = pcilib_get_model_description(handle);
switch (mode) {
case MODE_WRITE:
@@ -1027,7 +1043,7 @@ int main(int argc, char **argv) {
amode = ACCESS_BAR;
} else if ((isxnumber(addr))&&(sscanf(addr, "%lx", &start) == 1)) {
// check if the address in the register range
- pcilib_register_range_t *ranges = pcilib_model[model].ranges;
+ pcilib_register_range_t *ranges = model_info->ranges;
if (ranges) {
for (i = 0; ranges[i].start != ranges[i].end; i++)
@@ -1069,10 +1085,10 @@ int main(int argc, char **argv) {
switch (mode) {
case MODE_INFO:
- Info(handle, model);
+ Info(handle, model_info);
break;
case MODE_LIST:
- List(handle, model, bank);
+ List(handle, model_info, bank, details);
break;
case MODE_BENCHMARK:
Benchmark(handle, amode, dma, bar, start, size_set?size:0, access);
@@ -1085,15 +1101,15 @@ int main(int argc, char **argv) {
}
break;
case MODE_READ_REGISTER:
- if ((reg)||(!addr)) ReadRegister(handle, model, bank, reg);
- else ReadRegisterRange(handle, model, bank, start, size);
+ if ((reg)||(!addr)) ReadRegister(handle, model_info, bank, reg);
+ else ReadRegisterRange(handle, model_info, bank, start, size);
break;
case MODE_WRITE:
WriteData(handle, amode, dma, bar, start, size, access, endianess, data);
break;
case MODE_WRITE_REGISTER:
- if (reg) WriteRegister(handle, model, bank, reg, data);
- else WriteRegisterRange(handle, model, bank, start, size, data);
+ if (reg) WriteRegister(handle, model_info, bank, reg, data);
+ else WriteRegisterRange(handle, model_info, bank, start, size, data);
break;
case MODE_RESET:
pcilib_reset(handle);
diff --git a/common.mk b/common.mk
index a9ee469..c8d7387 100644
--- a/common.mk
+++ b/common.mk
@@ -22,6 +22,9 @@ SRCC = $(wildcard *.c)
SRC += $(wildcard ipecamera/*.cpp)
SRCC += $(wildcard ipecamera/*.c)
+SRC += $(wildcard dma/*.cpp)
+SRCC += $(wildcard dma/*.c)
+
# Corresponding object files
OBJ = $(addprefix $(OBJDIR)/,$(SRC:.cpp=.o))
OBJ += $(addprefix $(OBJDIR)/,$(SRCC:.c=.o))
diff --git a/default.c b/default.c
index f104879..15ae076 100644
--- a/default.c
+++ b/default.c
@@ -8,30 +8,30 @@
#define default_datacpy(dst, src, access, bank) pcilib_datacpy(dst, src, access, 1, bank->raw_endianess)
-int pcilib_default_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, uint8_t bits, pcilib_register_value_t *value) {
+int pcilib_default_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value) {
int err;
char *ptr;
pcilib_register_value_t val = 0;
int access = bank->access / 8;
- ptr = pcilib_resolve_register_address(ctx, bank->bar, bank->read_addr + addr * access);
+ ptr = pcilib_resolve_register_address(ctx, bank->bar, bank->read_addr + addr);
default_datacpy(&val, ptr, access, bank);
-// printf("%lx %lx\n",val, BIT_MASK(bits));
- *value = val&BIT_MASK(bits);
+// *value = val&BIT_MASK(bits);
+ *value = val;
return 0;
}
-int pcilib_default_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, uint8_t bits, pcilib_register_value_t value) {
+int pcilib_default_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value) {
int err;
char *ptr;
int access = bank->access / 8;
- ptr = pcilib_resolve_register_address(ctx, bank->bar, bank->write_addr + addr * access);
+ ptr = pcilib_resolve_register_address(ctx, bank->bar, bank->write_addr + addr);
default_datacpy(ptr, &value, access, bank);
return 0;
diff --git a/default.h b/default.h
index 927921b..6b2cf93 100644
--- a/default.h
+++ b/default.h
@@ -3,7 +3,7 @@
#include "pcilib.h"
-int pcilib_default_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, uint8_t bits, pcilib_register_value_t *value);
-int pcilib_default_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, uint8_t bits, pcilib_register_value_t value);
+int pcilib_default_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value);
+int pcilib_default_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value);
#endif /* _PCILIB_DEFAULT_H */
diff --git a/dma.c b/dma.c
index c29010b..93dba6c 100644
--- a/dma.c
+++ b/dma.c
@@ -88,12 +88,12 @@ size_t pcilib_stream_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr,
return 0;
}
- if (!ctx->model_info->dma_api) {
+ if (!ctx->model_info.dma_api) {
pcilib_error("DMA Engine is not configured in the current model");
return 0;
}
- if (!ctx->model_info->dma_api->stream) {
+ if (!ctx->model_info.dma_api->stream) {
pcilib_error("The DMA read is not supported by configured DMA engine");
return 0;
}
@@ -108,7 +108,7 @@ size_t pcilib_stream_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr,
return 0;
}
- return ctx->model_info->dma_api->stream(ctx->dma_ctx, dma, addr, size, flags, timeout, cb, cbattr);
+ return ctx->model_info.dma_api->stream(ctx->dma_ctx, dma, addr, size, flags, timeout, cb, cbattr);
}
size_t pcilib_read_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, void *buf) {
@@ -141,12 +141,12 @@ size_t pcilib_push_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, s
return 0;
}
- if (!ctx->model_info->dma_api) {
+ if (!ctx->model_info.dma_api) {
pcilib_error("DMA Engine is not configured in the current model");
return 0;
}
- if (!ctx->model_info->dma_api->push) {
+ if (!ctx->model_info.dma_api->push) {
pcilib_error("The DMA write is not supported by configured DMA engine");
return 0;
}
@@ -161,7 +161,7 @@ size_t pcilib_push_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, s
return 0;
}
- return ctx->model_info->dma_api->push(ctx->dma_ctx, dma, addr, size, flags, timeout, buf);
+ return ctx->model_info.dma_api->push(ctx->dma_ctx, dma, addr, size, flags, timeout, buf);
}
@@ -178,12 +178,12 @@ double pcilib_benchmark_dma(pcilib_t *ctx, pcilib_dma_engine_addr_t dma, uintptr
return 0;
}
- if (!ctx->model_info->dma_api) {
+ if (!ctx->model_info.dma_api) {
pcilib_error("DMA Engine is not configured in the current model");
return -1;
}
- if (!ctx->model_info->dma_api->benchmark) {
+ if (!ctx->model_info.dma_api->benchmark) {
pcilib_error("The DMA benchmark is not supported by configured DMA engine");
return -1;
}
@@ -193,5 +193,5 @@ double pcilib_benchmark_dma(pcilib_t *ctx, pcilib_dma_engine_addr_t dma, uintptr
return -1;
}
- return ctx->model_info->dma_api->benchmark(ctx->dma_ctx, dma, addr, size, iterations, direction);
+ return ctx->model_info.dma_api->benchmark(ctx->dma_ctx, dma, addr, size, iterations, direction);
}
diff --git a/dma/nwl.c b/dma/nwl.c
index f05472c..9d05cd7 100644
--- a/dma/nwl.c
+++ b/dma/nwl.c
@@ -15,20 +15,13 @@
#include "nwl.h"
#include "nwl_defines.h"
+#include "nwl_register.h"
#define NWL_XAUI_ENGINE 0
#define NWL_XRAWDATA_ENGINE 1
#define NWL_FIX_EOP_FOR_BIG_PACKETS // requires precise sizes in read requests
-/*
-pcilib_register_bank_description_t ipecamera_register_banks[] = {
- { PCILIB_REGISTER_DMABANK0, PCILIB_BAR0, 128, PCILIB_DEFAULT_PROTOCOL, DMA_NWL_OFFSET, DMA_NWL_OFFSET, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "%lx", "dma", "NorthWest Logick DMA Engine" },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
-};
-*/
-
-
typedef struct {
pcilib_dma_engine_description_t desc;
@@ -58,6 +51,63 @@ struct nwl_dma_s {
#define nwl_read_register(var, ctx, base, reg) pcilib_datacpy(&var, base + reg, 4, 1, ctx->dma_bank->raw_endianess)
#define nwl_write_register(var, ctx, base, reg) pcilib_datacpy(base + reg, &var, 4, 1, ctx->dma_bank->raw_endianess)
+static int nwl_add_registers(nwl_dma_t *ctx) {
+ int err;
+ size_t n, i, j;
+ int length;
+ const char *names[NWL_MAX_DMA_ENGINE_REGISTERS];
+ uintptr_t addr[NWL_MAX_DMA_ENGINE_REGISTERS];
+
+ // We don't want DMA registers
+ if (pcilib_find_bank_by_addr(ctx->pcilib, PCILIB_REGISTER_BANK_DMA) == PCILIB_REGISTER_BANK_INVALID) return 0;
+
+ err = pcilib_add_registers(ctx->pcilib, 0, nwl_dma_registers);
+ if (err) return err;
+
+ err = pcilib_add_registers(ctx->pcilib, 0, nwl_xrawdata_registers);
+ if (err) return err;
+
+ for (n = 0; nwl_dma_engine_registers[n].bits; n++) {
+ names[n] = nwl_dma_engine_registers[n].name;
+ addr[n] = nwl_dma_engine_registers[n].addr;
+ }
+
+ if (ctx->n_engines > 9) length = 2;
+ else length = 1;
+
+ for (i = 0; i < ctx->n_engines; i++) {
+ for (j = 0; nwl_dma_engine_registers[j].bits; j++) {
+ const char *direction;
+ nwl_dma_engine_registers[j].name = nwl_dma_engine_register_names[i * NWL_MAX_DMA_ENGINE_REGISTERS + j];
+ nwl_dma_engine_registers[j].addr = addr[j] + (ctx->engines[i].base_addr - ctx->base_addr);
+// printf("%lx %lx\n", (ctx->engines[i].base_addr - ctx->base_addr), nwl_dma_engine_registers[j].addr);
+
+ switch (ctx->engines[i].desc.direction) {
+ case PCILIB_DMA_FROM_DEVICE:
+ direction = "r";
+ break;
+ case PCILIB_DMA_TO_DEVICE:
+ direction = "w";
+ break;
+ default:
+ direction = "";
+ }
+
+ sprintf((char*)nwl_dma_engine_registers[j].name, names[j], length, ctx->engines[i].desc.addr, direction);
+ }
+
+ err = pcilib_add_registers(ctx->pcilib, n, nwl_dma_engine_registers);
+ if (err) return err;
+ }
+
+ for (n = 0; nwl_dma_engine_registers[n].bits; n++) {
+ nwl_dma_engine_registers[n].name = names[n];
+ nwl_dma_engine_registers[n].addr = addr[n];
+ }
+
+ return 0;
+}
+
static int nwl_read_engine_config(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, char *base) {
uint32_t val;
@@ -101,6 +151,7 @@ static int nwl_stop_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
pcilib_nwl_engine_description_t *info = ctx->engines + dma;
char *base = ctx->engines[dma].base_addr;
+ return 0;
if (info->desc.addr == NWL_XRAWDATA_ENGINE) {
// Stop Generators
nwl_read_register(val, ctx, ctx->base_addr, TX_CONFIG_ADDRESS);
@@ -182,6 +233,7 @@ pcilib_dma_context_t *dma_nwl_init(pcilib_t *pcilib) {
pcilib_register_bank_t dma_bank = pcilib_find_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA);
if (dma_bank == PCILIB_REGISTER_BANK_INVALID) {
+ free(ctx);
pcilib_error("DMA Register Bank could not be found");
return NULL;
}
@@ -210,6 +262,13 @@ pcilib_dma_context_t *dma_nwl_init(pcilib_t *pcilib) {
pcilib_set_dma_engine_description(pcilib, n_engines, NULL);
ctx->n_engines = n_engines;
+
+ err = nwl_add_registers(ctx);
+ if (err) {
+ free(ctx);
+ pcilib_error("Failed to add DMA registers");
+ return NULL;
+ }
}
return (pcilib_dma_context_t*)ctx;
}
diff --git a/dma/nwl_register.h b/dma/nwl_register.h
new file mode 100644
index 0000000..86515cc
--- /dev/null
+++ b/dma/nwl_register.h
@@ -0,0 +1,94 @@
+/*
+pcilib_register_bank_description_t ipecamera_register_banks[] = {
+ { PCILIB_REGISTER_DMABANK0, PCILIB_BAR0, 128, PCILIB_DEFAULT_PROTOCOL, DMA_NWL_OFFSET, DMA_NWL_OFFSET, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "%lx", "dma", "NorthWest Logick DMA Engine" },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
+};
+*/
+
+ // DMA
+static pcilib_register_description_t nwl_dma_registers[] = {
+ {0x4000, 0, 32, 0, 0x00000011, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_control_and_status", ""},
+ {0x4000, 0, 1, 0, 0x00000011, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_enable", ""},
+ {0x4000, 1, 1, 0, 0x00000011, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_active", ""},
+ {0x4000, 2, 1, 0, 0x00000011, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_pending", ""},
+ {0x4000, 3, 1, 0, 0x00000011, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_mode", ""},
+ {0x4000, 4, 1, 0, 0x00000011, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_user_interrupt_enable", ""},
+ {0x4000, 5, 1, 0, 0x00000011, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_user_interrupt_active", ""},
+ {0x4000, 16, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_s2c_interrupt_status", ""},
+ {0x4000, 24, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_c2s_interrupt_status", ""},
+ {0x8000, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_design_version", ""},
+ {0x8000, 0, 4, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_subversion_number", ""},
+ {0x8000, 4, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_version_number", ""},
+ {0x8000, 28, 4, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_targeted_device", ""},
+ {0x8200, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_transmit_utilization", ""},
+ {0x8200, 0, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_transmit_sample_count", ""},
+ {0x8200, 2, 30, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_transmit_dword_count", ""},
+ {0x8204, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_receive_utilization", ""},
+ {0x8004, 0, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_receive_sample_count", ""},
+ {0x8004, 2, 30, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_receive_dword_count", ""},
+ {0x8208, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_mwr", ""},
+ {0x8008, 0, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_mwr_sample_count", ""},
+ {0x8008, 2, 30, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_mwr_dword_count", ""},
+ {0x820C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_cpld", ""},
+ {0x820C, 0, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_cpld_sample_count", ""},
+ {0x820C, 2, 30, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_cpld_dword_count", ""},
+ {0x8210, 0, 12, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_cpld", ""},
+ {0x8214, 0, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_cplh", ""},
+ {0x8218, 0, 12, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_npd", ""},
+ {0x821C, 0, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_nph", ""},
+ {0x8220, 0, 12, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_pd", ""},
+ {0x8224, 0, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_ph", ""},
+ {0, 0, 0, 0, 0x00000000, 0, 0, 0, NULL, NULL}
+};
+
+ // DMA Engine Registers
+#define NWL_MAX_DMA_ENGINE_REGISTERS 64
+#define NWL_MAX_REGISTER_NAME 128
+static char nwl_dma_engine_register_names[PCILIB_MAX_DMA_ENGINES * NWL_MAX_DMA_ENGINE_REGISTERS][NWL_MAX_REGISTER_NAME];
+static pcilib_register_description_t nwl_dma_engine_registers[] = {
+ {0x0000, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_engine_capabilities", ""},
+ {0x0000, 0, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_present", ""},
+ {0x0000, 1, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_direction", ""},
+ {0x0000, 4, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_type", ""},
+ {0x0000, 8, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_number", ""},
+ {0x0000, 24, 6, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_max_buffer_size", ""},
+ {0x0004, 0, 32, 0, 0x0000C100, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_engine_control", ""},
+ {0x0004, 0, 1, 0, 0x0000C100, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_interrupt_enable", ""},
+ {0x0004, 1, 1, 0, 0x0000C100, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_interrupt_active", ""},
+ {0x0004, 2, 1, 0, 0x0000C100, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_descriptor_complete", ""},
+ {0x0004, 3, 1, 0, 0x0000C100, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_descriptor_alignment_error", ""},
+ {0x0004, 4, 1, 0, 0x0000C100, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_descriptor_fetch_error", ""},
+ {0x0004, 5, 1, 0, 0x0000C100, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_sw_abort_error", ""},
+ {0x0004, 8, 1, 0, 0x0000C100, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_enable", ""},
+ {0x0004, 9, 1, 0, 0x0000C100, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_running", ""},
+ {0x0004, 10, 1, 0, 0x0000C100, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_waiting", ""},
+ {0x0004, 14, 1, 0, 0x0000C100, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_reset_request", ""},
+ {0x0004, 15, 1, 0, 0x0000C100, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_reset", ""},
+ {0x0008, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_next_descriptor", ""},
+ {0x000C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_sw_descriptor", ""},
+ {0x0010, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_last_descriptor", ""},
+ {0x0014, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_active_time", ""},
+ {0x0018, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_wait_time", ""},
+ {0x001C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_counter", ""},
+ {0x001C, 0, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_sample_count", ""},
+ {0x001C, 2, 30, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_dword_count", ""},
+ {0, 0, 0, 0, 0x00000000, 0, 0, 0, NULL, NULL}
+};
+
+/*
+ // XAUI registers
+static pcilib_register_description_t nwl_xaui_registers[] = {
+ {0, 0, 0, 0, 0, 0, 0, NULL, NULL}
+};
+*/
+
+ // XRAWDATA registers
+static pcilib_register_description_t nwl_xrawdata_registers[] = {
+ {0x9100, 0, 1, 0, 0x00000000, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_enable_generator", ""},
+ {0x9104, 0, 16, 0, 0x00000000, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_packet_length", ""},
+ {0x9108, 0, 2, 0, 0x00000003, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_control", ""},
+ {0x9108, 0, 1, 0, 0x00000003, PCILIB_REGISTER_RW, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "xrawdata_enable_checker", ""},
+ {0x9108, 1, 1, 0, 0x00000003, PCILIB_REGISTER_RW, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "xrawdata_enable_loopback", ""},
+ {0x910C, 0, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_data_mistmatch", ""},
+ {0, 0, 0, 0, 0x00000000, 0, 0, 0, NULL, NULL}
+};
diff --git a/event.c b/event.c
index 2eb7fc4..8f00472 100644
--- a/event.c
+++ b/event.c
@@ -23,8 +23,8 @@ pcilib_event_t pcilib_find_event(pcilib_t *ctx, const char *event) {
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;
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
+ pcilib_event_description_t *events = model_info->events;
for (i = 0; events[i].name; i++) {
if (!strcasecmp(events[i].name, event)) return (1<<i);
@@ -37,9 +37,9 @@ pcilib_event_t pcilib_find_event(pcilib_t *ctx, const char *event) {
int pcilib_reset(pcilib_t *ctx) {
pcilib_event_api_description_t *api;
- pcilib_model_t model = pcilib_get_model(ctx);
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
- api = pcilib_model[model].event_api;
+ api = model_info->event_api;
if (!api) {
pcilib_error("Event API is not supported by the selected model");
return PCILIB_ERROR_NOTSUPPORTED;
@@ -54,9 +54,9 @@ int pcilib_reset(pcilib_t *ctx) {
int pcilib_start(pcilib_t *ctx, pcilib_event_t event_mask, void *callback, void *user) {
pcilib_event_api_description_t *api;
- pcilib_model_t model = pcilib_get_model(ctx);
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
- api = pcilib_model[model].event_api;
+ api = model_info->event_api;
if (!api) {
pcilib_error("Event API is not supported by the selected model");
return PCILIB_ERROR_NOTSUPPORTED;
@@ -71,9 +71,9 @@ int pcilib_start(pcilib_t *ctx, pcilib_event_t event_mask, void *callback, void
int pcilib_stop(pcilib_t *ctx) {
pcilib_event_api_description_t *api;
- pcilib_model_t model = pcilib_get_model(ctx);
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
- api = pcilib_model[model].event_api;
+ api = model_info->event_api;
if (!api) {
pcilib_error("Event API is not supported by the selected model");
return PCILIB_ERROR_NOTSUPPORTED;
@@ -88,9 +88,9 @@ int pcilib_stop(pcilib_t *ctx) {
pcilib_event_id_t pcilib_get_next_event(pcilib_t *ctx, pcilib_event_t event_mask, const struct timespec *timeout) {
pcilib_event_api_description_t *api;
- pcilib_model_t model = pcilib_get_model(ctx);
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
- api = pcilib_model[model].event_api;
+ api = model_info->event_api;
if (!api) {
pcilib_error("Event API is not supported by the selected model");
return PCILIB_ERROR_NOTSUPPORTED;
@@ -106,9 +106,9 @@ pcilib_event_id_t pcilib_get_next_event(pcilib_t *ctx, pcilib_event_t event_mask
int pcilib_trigger(pcilib_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data) {
pcilib_event_api_description_t *api;
- pcilib_model_t model = pcilib_get_model(ctx);
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
- api = pcilib_model[model].event_api;
+ api = model_info->event_api;
if (!api) {
pcilib_error("Event API is not supported by the selected model");
return PCILIB_ERROR_NOTSUPPORTED;
@@ -123,7 +123,9 @@ 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;
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
+
+ pcilib_event_api_description_t *api = model_info->event_api;
if (!api) {
pcilib_error("Event API is not supported by the selected model");
return NULL;
@@ -136,7 +138,9 @@ void *pcilib_get_data_with_argument(pcilib_t *ctx, pcilib_event_id_t event_id, p
}
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;
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
+
+ pcilib_event_api_description_t *api = model_info->event_api;
if (!api) {
pcilib_error("Event API is not supported by the selected model");
return NULL;
@@ -149,7 +153,9 @@ void *pcilib_get_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_da
}
int pcilib_return_data(pcilib_t *ctx, pcilib_event_id_t event_id) {
- pcilib_event_api_description_t *api = pcilib_model[ctx->model].event_api;
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
+
+ pcilib_event_api_description_t *api = model_info->event_api;
if (!api) {
pcilib_error("Event API is not supported by the selected model");
return PCILIB_ERROR_NOTSUPPORTED;
diff --git a/ipecamera/model.c b/ipecamera/model.c
index 23715e3..ddf9ee6 100644
--- a/ipecamera/model.c
+++ b/ipecamera/model.c
@@ -21,9 +21,9 @@
//#define IPECAMERA_SIMPLIFIED_READOUT
#define IPECAMERA_MULTIREAD
-static pcilib_register_value_t ipecamera_bit_mask[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
+//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) {
+int ipecamera_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value) {
uint32_t val, tmp[4];
char *wr, *rd;
struct timeval start, cur;
@@ -107,12 +107,13 @@ retry:
return PCILIB_ERROR_VERIFY;
}
- *value = val&ipecamera_bit_mask[bits];
+// *value = val&ipecamera_bit_mask[bits];
+ *value = val&0xFF;
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) {
+int ipecamera_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value) {
uint32_t val, tmp[4];
char *wr, *rd;
struct timeval start, cur;
@@ -196,8 +197,8 @@ retry:
return PCILIB_ERROR_VERIFY;
}
- if ((val&ipecamera_bit_mask[bits]) != value) {
- pcilib_error("Value verification failed during register read (CMOSIS %lu, value: %lu != %lu)", addr, val&ipecamera_bit_mask[bits], value);
+ if ((val&0xFF/*&ipecamera_bit_mask[bits]*/) != value) {
+ pcilib_error("Value verification failed during register read (CMOSIS %lu, value: %lu != %lu)", addr, val/*&ipecamera_bit_mask[bits]*/, value);
return PCILIB_ERROR_VERIFY;
}
diff --git a/ipecamera/model.h b/ipecamera/model.h
index 197671f..da0ac12 100644
--- a/ipecamera/model.h
+++ b/ipecamera/model.h
@@ -13,72 +13,72 @@
#ifdef _IPECAMERA_MODEL_C
pcilib_register_bank_description_t ipecamera_register_banks[] = {
- { PCILIB_REGISTER_BANK0, PCILIB_BAR0, 128, IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, PCILIB_LITTLE_ENDIAN, 8, PCILIB_LITTLE_ENDIAN, "%lu", "cmosis", "CMOSIS CMV2000 Registers" },
- { PCILIB_REGISTER_BANK1, PCILIB_BAR0, 64, PCILIB_DEFAULT_PROTOCOL, IPECAMERA_REGISTER_SPACE, IPECAMERA_REGISTER_SPACE, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "fpga", "IPECamera Registers" },
- { PCILIB_REGISTER_BANK_DMA, PCILIB_BAR0, 0x2000, PCILIB_DEFAULT_PROTOCOL, 0, 0, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "dma", "DMA Registers"},
+ { PCILIB_REGISTER_BANK0, PCILIB_BAR0, 128, IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ , IPECAMERA_REGISTER_WRITE, PCILIB_LITTLE_ENDIAN, 8 , PCILIB_LITTLE_ENDIAN, "%lu" , "cmosis", "CMOSIS CMV2000 Registers" },
+ { PCILIB_REGISTER_BANK1, PCILIB_BAR0, 0x0200, PCILIB_DEFAULT_PROTOCOL , IPECAMERA_REGISTER_SPACE, IPECAMERA_REGISTER_SPACE, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "fpga", "IPECamera Registers" },
+ { PCILIB_REGISTER_BANK_DMA, PCILIB_BAR0, 0xA000, PCILIB_DEFAULT_PROTOCOL , 0, 0, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "dma", "DMA Registers"},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
};
pcilib_register_description_t ipecamera_registers[] = {
-{1, 0, 16, 1088, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines", ""},
-{3, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start1", ""},
-{5, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start2", ""},
-{7, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start3", ""},
-{9, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start4", ""},
-{11, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start5", ""},
-{13, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start6", ""},
-{15, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start7", ""},
-{17, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start8", ""},
-{19, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines1", ""},
-{21, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines2", ""},
-{23, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines3", ""},
-{25, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines4", ""},
-{27, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines5", ""},
-{29, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines6", ""},
-{31, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines7", ""},
-{33, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines8", ""},
-{35, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "sub_s", ""},
-{37, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "sub_a", ""},
-{39, 0, 1, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "color", ""},
-{40, 0, 2, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "image_flipping", ""},
-{41, 0, 2, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_flags", ""},
-{42, 0, 24, 1088, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_time", ""},
-{45, 0, 24, 1088, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_step", ""},
-{48, 0, 24, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_kp1", ""},
-{51, 0, 24, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_kp2", ""},
-{54, 0, 2, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "nr_slopes", ""},
-{55, 0, 8, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_seq", ""},
-{56, 0, 24, 1088, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_time2", ""},
-{59, 0, 24, 1088, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_step2", ""},
-{68, 0, 2, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "nr_slopes2", ""},
-{69, 0, 8, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_seq2", ""},
-{70, 0, 16, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_frames", ""},
-{72, 0, 2, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "output_mode", ""},
-{78, 0, 12, 85, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "training_pattern", ""},
-{80, 0, 18, 0x3FFFF,PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "channel_en", ""},
-{82, 0, 3, 7, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "special_82", ""},
-{89, 0, 8, 96, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "vlow2", ""},
-{90, 0, 8, 96, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "vlow3", ""},
-{100, 0, 14, 16260, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "offset", ""},
-{102, 0, 2, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "pga", ""},
-{103, 0, 8, 32, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "adc_gain", ""},
-{111, 0, 1, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "bit_mode", ""},
-{112, 0, 2, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "adc_resolution", ""},
-{115, 0, 1, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "special_115", ""},
+{1, 0, 16, 1088, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines", ""},
+{3, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start1", ""},
+{5, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start2", ""},
+{7, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start3", ""},
+{9, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start4", ""},
+{11, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start5", ""},
+{13, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start6", ""},
+{15, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start7", ""},
+{17, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "start8", ""},
+{19, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines1", ""},
+{21, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines2", ""},
+{23, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines3", ""},
+{25, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines4", ""},
+{27, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines5", ""},
+{29, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines6", ""},
+{31, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines7", ""},
+{33, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_lines8", ""},
+{35, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "sub_s", ""},
+{37, 0, 16, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "sub_a", ""},
+{39, 0, 1, 1, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "color", ""},
+{40, 0, 2, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "image_flipping", ""},
+{41, 0, 2, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_flags", ""},
+{42, 0, 24, 1088, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_time", ""},
+{45, 0, 24, 1088, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_step", ""},
+{48, 0, 24, 1, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_kp1", ""},
+{51, 0, 24, 1, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_kp2", ""},
+{54, 0, 2, 1, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "nr_slopes", ""},
+{55, 0, 8, 1, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_seq", ""},
+{56, 0, 24, 1088, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_time2", ""},
+{59, 0, 24, 1088, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_step2", ""},
+{68, 0, 2, 1, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "nr_slopes2", ""},
+{69, 0, 8, 1, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "exp_seq2", ""},
+{70, 0, 16, 1, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "number_frames", ""},
+{72, 0, 2, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "output_mode", ""},
+{78, 0, 12, 85, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "training_pattern", ""},
+{80, 0, 18, 0x3FFFF,0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "channel_en", ""},
+{82, 0, 3, 7, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "special_82", ""},
+{89, 0, 8, 96, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "vlow2", ""},
+{90, 0, 8, 96, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "vlow3", ""},
+{100, 0, 14, 16260, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "offset", ""},
+{102, 0, 2, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "pga", ""},
+{103, 0, 8, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "adc_gain", ""},
+{111, 0, 1, 1, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "bit_mode", ""},
+{112, 0, 2, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "adc_resolution", ""},
+{115, 0, 1, 1, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "special_115", ""},
/*{126, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK0, "temp", ""},*/
-{0, 0, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "spi_conf_input", ""},
-{4, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "spi_conf_output", ""},
-{8, 0, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "spi_clk_speed", ""},
-{12, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "firmware_version", ""},
-{16, 0, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "control", ""},
-{20, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "status", ""},
-{24, 0, 16, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "cmosis_temperature", ""},
-{28, 0, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "temperature_sample_timing", ""},
-{32, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "start_address", ""},
-{36, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "end_address", ""},
-{40, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "last_write_address", ""},
-{44, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "last_write_value", ""},
-{0, 0, 0, 0, 0, 0, 0, NULL, NULL}
+{0, 0, 32, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "spi_conf_input", ""},
+{0x10, 0, 32, 0, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "spi_conf_output", ""},
+{0x20, 0, 32, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "spi_clk_speed", ""},
+{0x30, 0, 32, 0, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "firmware_version", ""},
+{0x40, 0, 32, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "control", ""},
+{0x50, 0, 32, 0, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "status", ""},
+{0x60, 0, 16, 0, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "cmosis_temperature", ""},
+{0x70, 0, 32, 0, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "temperature_sample_timing", ""},
+{0x80, 0, 32, 0, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "start_address", ""},
+{0x90, 0, 32, 0, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "end_address", ""},
+{0x100, 0, 32, 0, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "last_write_address", ""},
+{0x110, 0, 32, 0, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK1, "last_write_value", ""},
+{0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL}
};
pcilib_register_range_t ipecamera_register_ranges[] = {
@@ -115,7 +115,7 @@ pcilib_event_api_description_t ipecamera_image_api = {
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);
+int ipecamera_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value);
+int ipecamera_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value);
#endif /* _IPECAMERA_MODEL_H */
diff --git a/pci.c b/pci.c
index 9426658..807e799 100644
--- a/pci.c
+++ b/pci.c
@@ -63,8 +63,8 @@ pcilib_t *pcilib_open(const char *device, pcilib_model_t model) {
if (!model) model = pcilib_get_model(ctx);
- ctx->model_info = pcilib_model + model;
-
+ memcpy(&ctx->model_info, pcilib_model + model, sizeof(pcilib_model_description_t));
+
api = pcilib_model[model].event_api;
if ((api)&&(api->init)) ctx->event_ctx = api->init(ctx);
}
@@ -73,7 +73,7 @@ pcilib_t *pcilib_open(const char *device, pcilib_model_t model) {
}
pcilib_model_description_t *pcilib_get_model_description(pcilib_t *ctx) {
- return ctx->model_info;
+ return &ctx->model_info;
}
const pcilib_board_info_t *pcilib_get_board_info(pcilib_t *ctx) {
@@ -221,8 +221,8 @@ int pcilib_map_register_space(pcilib_t *ctx) {
pcilib_register_bank_t i;
if (!ctx->reg_bar_mapped) {
- pcilib_model_t model = pcilib_get_model(ctx);
- pcilib_register_bank_description_t *banks = pcilib_model[model].banks;
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
+ pcilib_register_bank_description_t *banks = model_info->banks;
for (i = 0; ((banks)&&(banks[i].access)); i++) {
// uint32_t buf[2];
@@ -400,13 +400,18 @@ void pcilib_close(pcilib_t *ctx) {
pcilib_bar_t i;
if (ctx) {
- pcilib_model_t model = pcilib_get_model(ctx);
- pcilib_event_api_description_t *eapi = pcilib_model[model].event_api;
- pcilib_dma_api_description_t *dapi = pcilib_model[model].dma_api;
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
+ pcilib_event_api_description_t *eapi = model_info->event_api;
+ pcilib_dma_api_description_t *dapi = model_info->dma_api;
if ((eapi)&&(eapi->free)) eapi->free(ctx->event_ctx);
if ((dapi)&&(dapi->free)) dapi->free(ctx->dma_ctx);
+ if (ctx->model_info.registers != model_info->registers) {
+ free(ctx->model_info.registers);
+ ctx->model_info.registers = pcilib_model[ctx->model].registers;
+ }
+
while (ctx->kmem_list) {
pcilib_free_kernel_memory(ctx, ctx->kmem_list);
}
diff --git a/pci.h b/pci.h
index 0427c8a..98176ad 100644
--- a/pci.h
+++ b/pci.h
@@ -34,7 +34,8 @@ struct pcilib_s {
pcilib_kmem_list_t *kmem_list;
- pcilib_model_description_t *model_info;
+ size_t num_reg, alloc_reg;
+ pcilib_model_description_t model_info;
pcilib_dma_context_t *dma_ctx;
pcilib_context_t *event_ctx;
@@ -61,6 +62,8 @@ pcilib_protocol_description_t pcilib_protocol[3] = {
{ NULL, NULL }
};
#else
+extern pcilib_model_description_t pcilib_model[];
+
extern void (*pcilib_error)(const char *msg, ...);
extern void (*pcilib_warning)(const char *msg, ...);
diff --git a/pcilib.h b/pcilib.h
index 314cca7..6f831fa 100644
--- a/pcilib.h
+++ b/pcilib.h
@@ -28,7 +28,7 @@ typedef unsigned long pcilib_irq_source_t;
typedef uint8_t pcilib_bar_t; /**< Type holding the PCI Bar number */
typedef uint8_t pcilib_register_t; /**< Type holding the register ID within the Bank */
-typedef uint8_t pcilib_register_addr_t; /**< Type holding the register ID within the Bank */
+typedef uint32_t pcilib_register_addr_t; /**< Type holding the register ID within the Bank */
typedef uint8_t pcilib_register_bank_t; /**< Type holding the register bank number */
typedef uint8_t pcilib_register_bank_addr_t; /**< Type holding the register bank number */
typedef uint8_t pcilib_register_size_t; /**< Type holding the size in bits of the register */
@@ -53,7 +53,9 @@ typedef enum {
typedef enum {
PCILIB_REGISTER_R = 1,
PCILIB_REGISTER_W = 2,
- PCILIB_REGISTER_RW = 3
+ PCILIB_REGISTER_RW = 3,
+ PCILIB_REGISTER_W1C = 4, /**< writting 1 resets the flag */
+ PCILIB_REGISTER_RW1C = 5
} pcilib_register_mode_t;
typedef enum {
@@ -72,7 +74,8 @@ typedef enum {
typedef enum {
PCILIB_REGISTER_STANDARD = 0,
- PCILIB_REGISTER_FIFO
+ PCILIB_REGISTER_FIFO,
+ PCILIB_REGISTER_BITS
} pcilib_register_type_t;
#define PCILIB_BAR_DETECT ((pcilib_bar_t)-1)
@@ -126,6 +129,7 @@ typedef struct {
pcilib_register_size_t offset;
pcilib_register_size_t bits;
pcilib_register_value_t defvalue;
+ pcilib_register_value_t rwmask; /**< 1 - read before write bits, 0 - zero should be written to preserve value */
pcilib_register_mode_t mode;
pcilib_register_type_t type;
@@ -185,10 +189,6 @@ typedef struct {
pcilib_event_api_description_t *event_api;
} pcilib_model_description_t;
-#ifndef _PCILIB_PCI_C
-extern pcilib_model_description_t pcilib_model[];
-#endif /* ! _PCILIB_PCI_C */
-
int pcilib_set_error_handler(void (*err)(const char *msg, ...), void (*warn)(const char *msg, ...));
pcilib_model_t pcilib_get_model(pcilib_t *ctx);
diff --git a/register.c b/register.c
index cb6bd88..1960e18 100644
--- a/register.c
+++ b/register.c
@@ -17,10 +17,50 @@
#include "tools.h"
#include "error.h"
+int pcilib_add_registers(pcilib_t *ctx, size_t n, pcilib_register_description_t *registers) {
+ pcilib_register_description_t *regs;
+ size_t size, n_present, n_new;
+
+ if (!n) {
+ for (n = 0; registers[n].bits; n++);
+ }
+
+
+ if (ctx->model_info.registers == pcilib_model[ctx->model].registers) {
+ for (n_present = 0; ctx->model_info.registers[n_present].bits; n_present++);
+ for (size = 1024; size < 2 * (n + n_present + 1); size<<=1);
+ regs = (pcilib_register_description_t*)malloc(size * sizeof(pcilib_register_description_t));
+ if (!regs) return PCILIB_ERROR_MEMORY;
+
+ ctx->model_info.registers = regs;
+ ctx->num_reg = n + n_present;
+ ctx->alloc_reg = size;
+
+ memcpy(ctx->model_info.registers, pcilib_model[ctx->model].registers, (n_present + 1) * sizeof(pcilib_register_description_t));
+ } else {
+ n_present = ctx->num_reg;
+ if ((n_present + n + 1) > ctx->alloc_reg) {
+ for (size = ctx->alloc_reg; size < 2 * (n + n_present + 1); size<<=1);
+
+ regs = (pcilib_register_description_t*)realloc(ctx->model_info.registers, size * sizeof(pcilib_register_description_t));
+ if (!regs) return PCILIB_ERROR_MEMORY;
+
+ ctx->model_info.registers = regs;
+ ctx->alloc_reg = size;
+ }
+ ctx->num_reg += n;
+ }
+
+ memcpy(ctx->model_info.registers + ctx->num_reg, ctx->model_info.registers + n_present, sizeof(pcilib_register_description_t));
+ memcpy(ctx->model_info.registers + n_present, registers, n * sizeof(pcilib_register_description_t));
+
+ return 0;
+}
+
pcilib_register_bank_t pcilib_find_bank_by_addr(pcilib_t *ctx, pcilib_register_bank_addr_t bank) {
pcilib_register_bank_t i;
- pcilib_model_t model = pcilib_get_model(ctx);
- pcilib_register_bank_description_t *banks = pcilib_model[model].banks;
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
+ pcilib_register_bank_description_t *banks = model_info->banks;
for (i = 0; banks[i].access; i++)
if (banks[i].addr == bank) return i;
@@ -30,7 +70,8 @@ pcilib_register_bank_t pcilib_find_bank_by_addr(pcilib_t *ctx, pcilib_register_b
pcilib_register_bank_t pcilib_find_bank_by_name(pcilib_t *ctx, const char *bankname) {
pcilib_register_bank_t i;
- pcilib_register_bank_description_t *banks = pcilib_model[ctx->model].banks;
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
+ pcilib_register_bank_description_t *banks = model_info->banks;
for (i = 0; banks[i].access; i++)
if (!strcasecmp(banks[i].name, bankname)) return i;
@@ -43,8 +84,8 @@ pcilib_register_bank_t pcilib_find_bank(pcilib_t *ctx, const char *bank) {
unsigned long addr;
if (!bank) {
- pcilib_model_t model = pcilib_get_model(ctx);
- pcilib_register_bank_description_t *banks = pcilib_model[model].banks;
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
+ pcilib_register_bank_description_t *banks = model_info->banks;
if ((banks)&&(banks[0].access)) return (pcilib_register_bank_t)0;
return -1;
}
@@ -62,10 +103,9 @@ pcilib_register_t pcilib_find_register(pcilib_t *ctx, const char *bank, const ch
pcilib_register_t i;
pcilib_register_bank_t bank_id;
pcilib_register_bank_addr_t bank_addr;
-
- pcilib_model_t model = pcilib_get_model(ctx);
-
- pcilib_register_description_t *registers = pcilib_model[model].registers;
+
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
+ pcilib_register_description_t *registers = model_info->registers;
if (bank) {
bank_id = pcilib_find_bank(ctx, bank);
@@ -74,28 +114,36 @@ pcilib_register_t pcilib_find_register(pcilib_t *ctx, const char *bank, const ch
return -1;
}
- bank_addr = pcilib_model[model].banks[bank_id].addr;
+ bank_addr = model_info->banks[bank_id].addr;
}
for (i = 0; registers[i].bits; i++) {
if ((!strcasecmp(registers[i].name, reg))&&((!bank)||(registers[i].bank == bank_addr))) return i;
}
+ if ((ctx->model_info.dma_api)&&(!ctx->dma_ctx)&&(pcilib_get_dma_info(ctx))) {
+ registers = model_info->registers;
+
+ for (; registers[i].bits; i++) {
+ if ((!strcasecmp(registers[i].name, reg))&&((!bank)||(registers[i].bank == bank_addr))) return i;
+ }
+ }
+
return (pcilib_register_t)-1;
};
-static int pcilib_read_register_space_internal(pcilib_t *ctx, pcilib_register_bank_t bank, pcilib_register_addr_t addr, size_t n, uint8_t bits, pcilib_register_value_t *buf) {
+static int pcilib_read_register_space_internal(pcilib_t *ctx, pcilib_register_bank_t bank, pcilib_register_addr_t addr, size_t n, pcilib_register_size_t offset, pcilib_register_size_t bits, pcilib_register_value_t *buf) {
int err;
int rest;
size_t i;
- pcilib_model_t model = pcilib_get_model(ctx);
- pcilib_register_bank_description_t *b = pcilib_model[model].banks + bank;
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
+ pcilib_register_bank_description_t *b = model_info->banks + bank;
assert(bits < 8 * sizeof(pcilib_register_value_t));
if (((addr + n) > b->size)||(((addr + n) == b->size)&&(bits))) {
- pcilib_error("Accessing sregister (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
+ pcilib_error("Accessing register (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
return PCILIB_ERROR_OUTOFRANGE;
}
@@ -109,11 +157,17 @@ static int pcilib_read_register_space_internal(pcilib_t *ctx, pcilib_register_ba
//bits %= b->access;
for (i = 0; i < n; i++) {
- err = pcilib_protocol[b->protocol].read(ctx, b, addr + i, b->access, buf + i);
+ err = pcilib_protocol[b->protocol].read(ctx, b, addr + i, buf + i);
if (err) break;
}
- if ((bits > 0)&&(!err)) err = pcilib_protocol[b->protocol].read(ctx, b, addr + n, bits, buf + n);
+ if ((bits > 0)&&(!err)) {
+ pcilib_register_value_t val = 0;
+ err = pcilib_protocol[b->protocol].read(ctx, b, addr + n, &val);
+
+ val = (val >> offset)&BIT_MASK(bits);
+ memcpy(buf + n, &val, sizeof(pcilib_register_value_t));
+ }
return err;
}
@@ -126,25 +180,31 @@ int pcilib_read_register_space(pcilib_t *ctx, const char *bank, pcilib_register_
return PCILIB_ERROR_INVALID_BANK;
}
- return pcilib_read_register_space_internal(ctx, bank_id, addr, n, 0, buf);
+ return pcilib_read_register_space_internal(ctx, bank_id, addr, n, 0, 0, buf);
}
int pcilib_read_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_register_value_t *value) {
int err;
- size_t i, n, bits;
+ size_t i, n;
+ pcilib_register_size_t bits;
pcilib_register_value_t res;
+ pcilib_register_bank_t bank;
pcilib_register_description_t *r;
pcilib_register_bank_description_t *b;
- pcilib_model_t model = pcilib_get_model(ctx);
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
- r = pcilib_model[model].registers + reg;
- b = pcilib_model[model].banks + r->bank;
+ r = model_info->registers + reg;
+
+ bank = pcilib_find_bank_by_addr(ctx, r->bank);
+ if (bank == PCILIB_REGISTER_BANK_INVALID) return PCILIB_ERROR_INVALID_BANK;
+
+ b = model_info->banks + bank;
n = r->bits / b->access;
bits = r->bits % b->access;
pcilib_register_value_t buf[n + 1];
- err = pcilib_read_register_space_internal(ctx, r->bank, r->addr, n, bits, buf);
+ err = pcilib_read_register_space_internal(ctx, bank, r->addr, n, r->offset, bits, buf);
if ((b->endianess == PCILIB_BIG_ENDIAN)||((b->endianess == PCILIB_HOST_ENDIAN)&&(ntohs(1) == 1))) {
pcilib_error("Big-endian byte order support is not implemented");
@@ -174,24 +234,21 @@ int pcilib_read_register(pcilib_t *ctx, const char *bank, const char *regname, p
}
return pcilib_read_register_by_id(ctx, reg, value);
-
-// registers[reg].bank
-// printf("%li %li", sizeof(pcilib_model[model].banks), sizeof(pcilib_register_bank_description_t));
}
-static int pcilib_write_register_space_internal(pcilib_t *ctx, pcilib_register_bank_t bank, pcilib_register_addr_t addr, size_t n, uint8_t bits, pcilib_register_value_t *buf) {
+static int pcilib_write_register_space_internal(pcilib_t *ctx, pcilib_register_bank_t bank, pcilib_register_addr_t addr, size_t n, pcilib_register_size_t offset, pcilib_register_size_t bits, pcilib_register_value_t rwmask, pcilib_register_value_t *buf) {
int err;
int rest;
size_t i;
- pcilib_model_t model = pcilib_get_model(ctx);
- pcilib_register_bank_description_t *b = pcilib_model[model].banks + bank;
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
+ pcilib_register_bank_description_t *b = model_info->banks + bank;
assert(bits < 8 * sizeof(pcilib_register_value_t));
if (((addr + n) > b->size)||(((addr + n) == b->size)&&(bits))) {
- pcilib_error("Accessing sregister (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
+ pcilib_error("Accessing register (%u regs at addr %u) out of register space (%u registers total)", bits?(n+1):n, addr, b->size);
return PCILIB_ERROR_OUTOFRANGE;
}
@@ -205,11 +262,25 @@ static int pcilib_write_register_space_internal(pcilib_t *ctx, pcilib_register_b
//bits %= b->access;
for (i = 0; i < n; i++) {
- err = pcilib_protocol[b->protocol].write(ctx, b, addr + i, b->access, buf[i]);
+ err = pcilib_protocol[b->protocol].write(ctx, b, addr + i, buf[i]);
if (err) break;
}
- if ((bits > 0)&&(!err)) err = pcilib_protocol[b->protocol].write(ctx, b, addr + n, bits, buf[n]);
+ if ((bits > 0)&&(!err)) {
+ pcilib_register_value_t val = (buf[n]&BIT_MASK(bits))<<offset;
+ pcilib_register_value_t mask = BIT_MASK(bits)<<offset;
+
+ if (~mask&rwmask) {
+ pcilib_register_value_t rval;
+
+ err = pcilib_protocol[b->protocol].read(ctx, b, addr + n, &rval);
+ if (err) return err;
+
+ val |= (rval & rwmask & ~mask);
+ }
+
+ err = pcilib_protocol[b->protocol].write(ctx, b, addr + n, val);
+ }
return err;
}
@@ -222,20 +293,26 @@ int pcilib_write_register_space(pcilib_t *ctx, const char *bank, pcilib_register
return PCILIB_ERROR_INVALID_BANK;
}
- return pcilib_write_register_space_internal(ctx, bank_id, addr, n, 0, buf);
+ return pcilib_write_register_space_internal(ctx, bank_id, addr, n, 0, 0, 0, buf);
}
int pcilib_write_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_register_value_t value) {
int err;
- size_t i, n, bits;
+ size_t i, n;
+ pcilib_register_size_t bits;
+ pcilib_register_bank_t bank;
pcilib_register_value_t res;
pcilib_register_description_t *r;
pcilib_register_bank_description_t *b;
- pcilib_model_t model = pcilib_get_model(ctx);
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
+
+ r = model_info->registers + reg;
+
+ bank = pcilib_find_bank_by_addr(ctx, r->bank);
+ if (bank == PCILIB_REGISTER_BANK_INVALID) return PCILIB_ERROR_INVALID_BANK;
- r = pcilib_model[model].registers + reg;
- b = pcilib_model[model].banks + r->bank;
+ b = model_info->banks + bank;
n = r->bits / b->access;
bits = r->bits % b->access;
@@ -262,7 +339,7 @@ int pcilib_write_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_reg
}
}
- err = pcilib_write_register_space_internal(ctx, r->bank, r->addr, n, bits, buf);
+ err = pcilib_write_register_space_internal(ctx, bank, r->addr, n, r->offset, bits, r->rwmask, buf);
return err;
}
diff --git a/register.h b/register.h
index 1a8daef..b81ae12 100644
--- a/register.h
+++ b/register.h
@@ -4,8 +4,11 @@
#include "pcilib.h"
struct pcilib_protocol_description_s {
- 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);
+ int (*read)(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value);
+ int (*write)(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value);
};
+ // we don't copy strings, they should be statically allocated
+int pcilib_add_registers(pcilib_t *ctx, size_t n, pcilib_register_description_t *registers);
+
#endif /* _PCILIB_REGISTER_H */