summaryrefslogtreecommitdiffstats
path: root/cli.c
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@dside.dyndns.org>2011-03-08 22:46:14 +0100
committerSuren A. Chilingaryan <csa@dside.dyndns.org>2011-03-08 22:46:14 +0100
commit7f97ea07417de4c2ea260e2860e589011c732e04 (patch)
tree5e5dd32f4615a40990f8daf10a96f82f39ca3b83 /cli.c
parent8a33c993a5771b041b67c365378ac40f76365da7 (diff)
downloadipecamera-7f97ea07417de4c2ea260e2860e589011c732e04.tar.gz
ipecamera-7f97ea07417de4c2ea260e2860e589011c732e04.tar.bz2
ipecamera-7f97ea07417de4c2ea260e2860e589011c732e04.tar.xz
ipecamera-7f97ea07417de4c2ea260e2860e589011c732e04.zip
Initial support of IPECamera protocol
Diffstat (limited to 'cli.c')
-rw-r--r--cli.c198
1 files changed, 118 insertions, 80 deletions
diff --git a/cli.c b/cli.c
index adf0f4b..2215c55 100644
--- a/cli.c
+++ b/cli.c
@@ -1,37 +1,25 @@
-/*******************************************************************
- * This is a test program for the IOctl interface of the
- * pciDriver.
- *
- * $Revision: 1.3 $
- * $Date: 2006-11-17 18:49:01 $
- *
- *******************************************************************/
-
-/*******************************************************************
- * Change History:
- *
- * $Log: not supported by cvs2svn $
- * Revision 1.2 2006/10/16 16:56:09 marcus
- * Added nice comment at the start.
- *
- *******************************************************************/
+#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
#include <stdint.h>
#include <stdarg.h>
#include <fcntl.h>
#include <unistd.h>
+#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <errno.h>
#include <alloca.h>
+#include <arpa/inet.h>
#include <getopt.h>
#include "pci.h"
#include "ipecamera.h"
+#include "tools.h"
/* defines */
@@ -48,7 +36,9 @@
#define BLOCK_SIZE 8
#define BENCHMARK_ITERATIONS 128
-//#define FILE_IO
+
+
+typedef uint8_t access_t;
typedef enum {
MODE_INVALID,
@@ -66,6 +56,7 @@ typedef enum {
OPT_MODEL = 'm',
OPT_BAR = 'b',
OPT_ACCESS = 'a',
+ OPT_ENDIANESS = 'e',
OPT_SIZE = 's',
OPT_INFO = 'i',
OPT_BENCHMARK = 'p',
@@ -80,6 +71,7 @@ static struct option long_options[] = {
{"model", required_argument, 0, OPT_MODEL },
{"bar", required_argument, 0, OPT_BAR },
{"access", required_argument, 0, OPT_ACCESS },
+ {"endianess", required_argument, 0, OPT_ENDIANESS },
{"size", required_argument, 0, OPT_SIZE },
{"info", no_argument, 0, OPT_INFO },
{"list", no_argument, 0, OPT_LIST },
@@ -118,14 +110,15 @@ void Usage(int argc, char *argv[], const char *format, ...) {
"\n"
" Addressing:\n"
" -d <device> - FPGA device (/dev/fpga0)\n"
-" -m <model> - Memory model\n"
-" pci - Plain (default)\n"
+" -m <model> - Memory model (autodetected)\n"
+" pci - Plain\n"
" ipecamera - IPE Camera\n"
-" -b <bank> - Data bank (autodetected)\n"
+" -b <bank> - Data/Register bank (autodetected)\n"
"\n"
" Options:\n"
" -s <size> - Number of words (default: 1)\n"
" -a <bitness> - Bits per word (default: 32)\n"
+" -e <l|b> - Endianess Little/Big (default: host)\n"
"\n\n",
argv[0]);
@@ -146,9 +139,9 @@ void Error(const char *format, ...) {
}
-void List(int handle, pcilib_model_t model) {
+void List(pcilib_t *handle, pcilib_model_t model) {
int i;
- pcilib_register_t *registers;
+ pcilib_register_description_t *registers;
const pci_board_info *board_info = pcilib_get_board_info(handle);
@@ -171,18 +164,18 @@ void List(int handle, pcilib_model_t model) {
}
printf("\n");
- registers = pcilib_model_description[model].registers;
+ registers = pcilib_model[model].registers;
if (registers) {
printf("Registers: \n");
- for (i = 0; registers[i].size; i++) {
+ for (i = 0; registers[i].bits; i++) {
const char *mode;
if (registers[i].mode == PCILIB_REGISTER_RW) mode = "RW";
else if (registers[i].mode == PCILIB_REGISTER_R) mode = "R ";
else if (registers[i].mode == PCILIB_REGISTER_W) mode = " W";
else mode = " ";
- printf(" 0x%02x (%2i %s) %s", registers[i].id, registers[i].size, mode, registers[i].name);
+ printf(" 0x%02x (%2i %s) %s", registers[i].addr, registers[i].bits, mode, registers[i].name);
if ((registers[i].description)&&(registers[i].description[0])) {
printf(": %s", registers[i].description);
}
@@ -193,7 +186,7 @@ void List(int handle, pcilib_model_t model) {
}
}
-void Info(int handle, pcilib_model_t model) {
+void Info(pcilib_t *handle, pcilib_model_t model) {
const pci_board_info *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);
@@ -201,7 +194,7 @@ void Info(int handle, pcilib_model_t model) {
}
-int Benchmark(int handle, int bar) {
+int Benchmark(pcilib_t *handle, pcilib_bar_t bar) {
int err;
int i, errors;
void *data, *buf, *check;
@@ -262,7 +255,7 @@ int Benchmark(int handle, int bar) {
for (size = 4 ; size < max_size; size *= 8) {
gettimeofday(&start,NULL);
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
- pcilib_read(buf, handle, bar, 0, size);
+ pcilib_read(handle, bar, 0, size, buf);
}
gettimeofday(&end,NULL);
@@ -273,7 +266,7 @@ int Benchmark(int handle, int bar) {
gettimeofday(&start,NULL);
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
- pcilib_write(buf, handle, bar, 0, size);
+ pcilib_write(handle, bar, 0, size, buf);
}
gettimeofday(&end,NULL);
@@ -282,8 +275,8 @@ int Benchmark(int handle, int bar) {
gettimeofday(&start,NULL);
for (i = 0, errors = 0; i < BENCHMARK_ITERATIONS; i++) {
- pcilib_write(buf, handle, bar, 0, size);
- pcilib_read(check, handle, bar, 0, size);
+ pcilib_write(handle, bar, 0, size, buf);
+ pcilib_read(handle, bar, 0, size, check);
if (memcmp(buf, check, size)) ++errors;
}
gettimeofday(&end,NULL);
@@ -300,8 +293,10 @@ int Benchmark(int handle, int bar) {
free(buf);
}
+#define pci2host16(endianess, value) endianess?
+
-int ReadData(int handle, int bar, unsigned long addr, int n, int access) {
+int ReadData(pcilib_t *handle, pcilib_bar_t bar, uintptr_t addr, size_t n, access_t access, int endianess) {
void *buf;
int i, err;
int size = n * abs(access);
@@ -317,10 +312,10 @@ int ReadData(int handle, int bar, unsigned long addr, int n, int access) {
// buf = alloca(size);
err = posix_memalign( (void**)&buf, 256, size );
-
if ((err)||(!buf)) Error("Allocation of %i bytes of memory have failed", size);
- pcilib_read(buf, handle, bar, addr, size);
+ pcilib_read(handle, bar, addr, size, buf);
+ if (endianess) pcilib_swap(buf, buf, abs(access), n);
for (i = 0; i < n; i++) {
if (i) {
@@ -346,17 +341,26 @@ int ReadData(int handle, int bar, unsigned long addr, int n, int access) {
free(buf);
}
-int ReadRegister(int handle, pcilib_model_t model, const char *reg) {
+int ReadRegister(pcilib_t *handle, pcilib_model_t model, const char *reg) {
+ int err;
int i;
+
+ pcilib_register_value_t value;
- if (!reg) {
- pcilib_register_t *registers = pcilib_model_description[model].registers;
+ if (reg) {
+ err = pcilib_read_register(handle, reg, &value);
+ if (err) printf("Error reading register %s\n", reg);
+ else printf("%s = %i\n", reg, value);
+ } else {
+ pcilib_register_description_t *registers = pcilib_model[model].registers;
if (registers) {
printf("Registers:\n");
- for (i = 0; registers[i].size; i++) {
+ for (i = 0; registers[i].bits; i++) {
if (registers[i].mode & PCILIB_REGISTER_R) {
- printf(" %s = %i [%i]", registers[i].name, 0, registers[i].defvalue);
+ err = pcilib_read_register_by_id(handle, i, &value);
+ if (err) printf(" %s = error reading value [%i]", registers[i].name, registers[i].defvalue);
+ else printf(" %s = %i [%i]", registers[i].name, value, registers[i].defvalue);
}
printf("\n");
}
@@ -367,20 +371,17 @@ int ReadRegister(int handle, pcilib_model_t model, const char *reg) {
}
}
-int ReadRegisterRange(int handle, pcilib_model_t model, int bar, unsigned long addr, int n, int access) {
+int ReadRegisterRange(pcilib_t *handle, pcilib_model_t model, uintptr_t addr, size_t n) {
}
-int WriteData(int handle, int bar, unsigned long addr, int n, int access, char ** data) {
+int WriteData(pcilib_t *handle, pcilib_bar_t bar, uintptr_t addr, size_t n, access_t access, int endianess, char ** data) {
void *buf, *check;
int res, i, err;
int size = n * abs(access);
-
+
err = posix_memalign( (void**)&buf, 256, size );
- if (!err) {
- err = posix_memalign( (void**)&check, 256, size );
- }
- if ((err)||(!buf)||(!check))
- Error("Allocation of %i bytes of memory have failed", size);
+ if (!err) err = posix_memalign( (void**)&check, 256, size );
+ if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", size);
for (i = 0; i < n; i++) {
switch (access) {
@@ -393,12 +394,14 @@ int WriteData(int handle, int bar, unsigned long addr, int n, int access, char *
if (res != 1) Error("Can't parse data value at poition %i, (%s) is not valid hex number", i, data[i]);
}
- pcilib_write(buf, handle, bar, addr, size);
- pcilib_read(check, handle, bar, addr, size);
+ if (endianess) pcilib_swap(buf, buf, abs(access), n);
+ pcilib_write(handle, bar, addr, size, buf);
+ pcilib_read(handle, bar, addr, size, check);
+ if (endianess) pcilib_swap(check, check, abs(access), n);
if (memcmp(buf, check, size)) {
printf("Write failed: the data written and read differ, the foolowing is read back:\n");
- ReadData(handle, bar, addr, n, access);
+ ReadData(handle, bar, addr, n, access, endianess);
exit(-1);
}
@@ -406,32 +409,58 @@ int WriteData(int handle, int bar, unsigned long addr, int n, int access, char *
free(buf);
}
-int WriteRegisterRange(int handle, pcilib_model_t model, int bar, unsigned long addr, int n, int access, char ** data) {
+int WriteRegisterRange(pcilib_t *handle, pcilib_model_t model, uintptr_t addr, size_t n, char ** data) {
}
-int WriteRegister(int handle, pcilib_model_t model, const char *reg, char ** data) {
+int WriteRegister(pcilib_t *handle, pcilib_model_t model, const char *reg, char ** data) {
+ int err;
+ int i;
+
+ unsigned long val;
+ pcilib_register_value_t value;
+
+ if (sscanf(*data, "%li", &val) != 1) {
+ Error("Can't parse data value (%s) is not valid decimal number", data[i]);
+ }
+
+ value = val;
+
+ err = pcilib_write_register(handle, reg, value);
+ if (err) Error("Error writting register %s\n", reg);
+
+ err = pcilib_read_register(handle, reg, &value);
+ if (err) Error("Error reading back register %s for verification\n", reg);
+
+ if (val != value) {
+ Error("Failed to write register %s: %lu is written and %lu is read back", reg, val, value);
+ } else {
+ printf("%s = %i\n", reg, value);
+ }
+
+ return 0;
}
int main(int argc, char **argv) {
+ int i;
+ long itmp;
unsigned char c;
- pcilib_model_t model = (pcilib_model_t)-1;
+ pcilib_model_t model = PCILIB_MODEL_DETECT;
MODE mode = MODE_INVALID;
const char *fpga_device = DEFAULT_FPGA_DEVICE;
- int bar = -1;
+ pcilib_bar_t bar = PCILIB_BAR_DETECT;
const char *addr = NULL;
- unsigned long start = -1;
- int size = 1;
- int access = 4;
+ const char *reg = NULL;
+ uintptr_t start = -1;
+ size_t size = 1;
+ access_t access = 4;
int skip = 0;
+ int endianess = 0;
- int i;
- int handle;
+ pcilib_t *handle;
- const char *reg = NULL;
-
- while ((c = getopt_long(argc, argv, "hilpr::w::d:b:a:s:", long_options, NULL)) != (unsigned char)-1) {
+ while ((c = getopt_long(argc, argv, "hilpr::w::d:m:b:a:s:e:", long_options, NULL)) != (unsigned char)-1) {
extern int optind;
switch (c) {
case OPT_HELP:
@@ -475,11 +504,12 @@ int main(int argc, char **argv) {
else Usage(argc, argv, "Invalid memory model (%s) is specified", optarg);\
break;
case OPT_BAR:
- if ((sscanf(optarg,"%u", &bar) != 1)||(bar < 0)||(bar >= PCILIB_MAX_BANKS)) Usage(argc, argv, "Invalid data bank (%s) is specified", optarg);
+ if ((sscanf(optarg,"%li", &itmp) != 1)||(itmp < 0)||(itmp >= PCILIB_MAX_BANKS)) Usage(argc, argv, "Invalid data bank (%s) is specified", optarg);
+ else bar = itmp;
break;
case OPT_ACCESS:
- if (sscanf(optarg, "%i", &access) != 1) access = 0;
- switch (access) {
+ if (sscanf(optarg, "%li", &itmp) != 1) access = 0;
+ switch (itmp) {
case 8: access = 1; break;
case 16: access = 2; break;
case 32: access = 4; break;
@@ -488,9 +518,19 @@ int main(int argc, char **argv) {
}
break;
case OPT_SIZE:
- if (sscanf(optarg, "%u", &size) != 1)
+ if (sscanf(optarg, "%zu", &size) != 1)
Usage(argc, argv, "Invalid size is specified (%s)", optarg);
break;
+ case OPT_ENDIANESS:
+ if ((*optarg == 'b')||(*optarg == 'B')) {
+ if (ntohs(1) == 1) endianess = 0;
+ else endianess = 1;
+ } else if ((*optarg == 'l')||(*optarg == 'L')) {
+ if (ntohs(1) == 1) endianess = 1;
+ else endianess = 0;
+ } else Usage(argc, argv, "Invalid endianess is specified (%s)", optarg);
+
+ break;
default:
Usage(argc, argv, "Unknown option (%s)", argv[optind]);
}
@@ -503,12 +543,10 @@ int main(int argc, char **argv) {
pcilib_set_error_handler(&Error);
- handle = pcilib_open(fpga_device);
+ handle = pcilib_open(fpga_device, model);
if (handle < 0) Error("Failed to open FPGA device: %s", fpga_device);
- if (model == (pcilib_model_t)-1) {
- model = pcilib_detect_model(handle);
- }
+ model = pcilib_get_model(handle);
switch (mode) {
case MODE_WRITE:
@@ -530,7 +568,7 @@ int main(int argc, char **argv) {
if (addr) {
if (sscanf(addr, "%lx", &start) == 1) {
// check if the address in the register range
- pcilib_register_range_t *ranges = pcilib_model_description[model].ranges;
+ pcilib_register_range_t *ranges = pcilib_model[model].ranges;
for (i = 0; ranges[i].start != ranges[i].end; i++)
if ((start >= ranges[i].start)&&(start <= ranges[i].end)) break;
@@ -538,11 +576,11 @@ int main(int argc, char **argv) {
// register access in plain mode
if (ranges[i].start != ranges[i].end) ++mode;
} else {
- if (pcilib_find_register(model, addr) >= 0) {
+ if (pcilib_find_register(handle, addr) == PCILIB_REGISTER_INVALID) {
+ Usage(argc, argv, "Invalid address (%s) is specified", addr);
+ } else {
reg = addr;
++mode;
- } else {
- Usage(argc, argv, "Invalid address (%s) is specified", addr);
}
}
}
@@ -560,21 +598,21 @@ int main(int argc, char **argv) {
break;
case MODE_READ:
if (addr) {
- ReadData(handle, bar, start, size, access);
+ ReadData(handle, bar, start, size, access, endianess);
} else {
Error("Address to read is not specified");
}
break;
case MODE_READ_REGISTER:
if ((reg)||(!addr)) ReadRegister(handle, model, reg);
- else ReadRegisterRange(handle, model, bar, start, size, access);
+ else ReadRegisterRange(handle, model, start, size);
break;
case MODE_WRITE:
- WriteData(handle, bar, start, size, access, argv + optind);
+ WriteData(handle, bar, start, size, access, endianess, argv + optind);
break;
case MODE_WRITE_REGISTER:
if (reg) WriteRegister(handle, model, reg, argv + optind);
- else WriteRegisterRange(handle, model, bar, start, size, access, argv + optind);
+ else WriteRegisterRange(handle, model, start, size, argv + optind);
break;
}