--- /dev/null
+AXIS_BUILDTYPE=crisv32-axis-linux-gnu
--- /dev/null
+HowTo ADCM_v2\r
+=============\r
+\r
+Alle Skripte / Software befindet sich im TRB0 /home/hadaq/mboehmer/ !\r
+\r
+Anschalten: Board zieht ca. 2A in Vollbestückung, im konfigurierten Betrieb ca. 2.8A. Netzteil wird heiss!\r
+\r
+TRB: ./load_xilinx.sh\r
+\r
+Initialisieren: ./setaddress_sn000 -> TRBnet-Adresse 0x42 wird zugewiesen\r
+\r
+APVs klarmachen: ./init_apvs\r
+\r
+APVs syncen: ./trbbang T 3 0 aa bb cccc\r
+\r
+Sync-Event abholen: ./trbbang I 0 aa bb cccc\r
+\r
+Triggern: ./trbbang T 0 X aa bb cccc\r
+\r
+X: 0 -> RAW128 mode (all channels raw)\r
+ 1 -> PED128 mode (all channels pedestal corrected)\r
+ 2 -> PED128THR mode (mode 1 + threshold comparison)\r
+ 3 -> reserved\r
+ 4 -> NC64PED64\r
+ 5 -> NC64\r
+ 6 -> NC64GOOD\r
+ 7 -> NC64THR\r
+\r
+############################################################################################\r
+\r
+Datenformat:\r
+\r
+D[31] 0 -> Daten, 1 -> Debug\r
+D[30:28] sector number\r
+D[27:25] module number\r
+D[24:21] APV number\r
+D[20:14] channel number\r
+D[13:0] ADC data\r
+\r
+Debug:\r
+\r
+D[30:28] sector number\r
+D[27:25] module number\r
+D[24:21] APV number\r
+D[20] bad buffer\r
+D[19] buffer not valid\r
+D[18] frame counter error\r
+D[17] row error\r
+D[16] APV error bit set\r
+D[15:12] number of frames requested\r
+D[11:8] current frame number\r
+D[7:0] row information (if available)\r
+\r
+\r
+\r
+\r
+\r
+\r
+############################################################################################\r
+\r
+Es gibt vier Kontrollregister im APV, die die Boardkonfiguration beeinflussen:\r
+\r
+0xc0: [31] RESET_SYS\r
+ [30] RESET_APV\r
+ [29] RESET_ADC\r
+ [26] POWERDOWN_ADC1\r
+ [25] POWERDOWN_ADC0\r
+ [24] reserved, do not use\r
+ [16] LED auf Backplane :-)\r
+ [15:0] APV_ON\r
+\r
+0xc1: [31] reset PLL ADC1\r
+ [27:24] Phase PLL ADC1\r
+ [23] reset PLL ADC0\r
+ [19:16] Phase PLL ADC0\r
+ [14:12] debug output select ADC1\r
+ [10:8] debug output select ADC0\r
+ [7] reset PLL 40MHz\r
+ [3:0] Phase CLK ADC / APV\r
+ \r
+0xc2: [31:28] maximum number of APV frames / event (= 0x3)\r
+ [23:20] TODO hardware trigger 2\r
+ [19:16] DELAY hardware trigger 2\r
+ [15:12] TODO hardware trigger 1\r
+ [11:8] DELAY hardware trigger 1\r
+ [7:4] TODO hardware trigger 0\r
+ [3:0] DELAY hardware trigger 0\r
+ \r
+0xc3: [31:24] BitHigh setting\r
+ [23:16] BitLow setting\r
+ [15:8] FlatHigh setting\r
+ [7:0] FlatLow setting\r
+\r
+\r
--- /dev/null
+AXIS_USABLE_LIBS = UCLIBC GLIBC
+include $(AXIS_TOP_DIR)/tools/build/Rules.axis
+
+#CFLAGS = -pipe -g -ansi -pedantic -Wall
+CFLAGS = -pipe -g -Wall -Winline -O3 -finline-functions -finline-limit=600000 #-DHEXMODE
+
+CPPFLAGS =
+
+INCDIR = -I.
+
+LDFLAGS =
+LIBDIR = -L.
+LOADLIBES = -ltrbnet
+
+# ------------ Libaries ------------------------------------------------
+
+AR = ar-cris
+ARFLAGS = -srv
+
+# ------------ Install -------------------------------------------------
+
+BIN.OBJS =
+LIB.OBJS =
+INC.OBJS =
+
+BIN_DIR =
+LIB_DIR =
+INC_DIR =
+
+# ------------ Objects -------------------------------------------------
+
+TARGETS = trbcmd pulser
+
+trbcmd.OBJS = trbcmd.o
+
+pulser.OBJS = pulser.o
+
+# ------------ Library-Objects ----------------------------------------
+
+LIB_TARGETS = libtrbnet.a
+
+libtrbnet.OBJS = port.o fs_fpga_int_mem.o trberror.o trbnet.o
+
+# ------------ Suffix Rules -------------------------------------------
+
+.SUFFIXES:
+
+# ----- C Code ---------
+%.o: %.c
+ $(CC) $< -c $(CPPFLAGS) $(CFLAGS) $(INCDIR) -o $@
+
+.SUFFIXES: .o .c
+
+# ------------ Targets -------------------------------------------------
+
+all: $(TARGETS) $(LIB_TARGETS)
+
+trbcmd: $(trbcmd.OBJS) libtrbnet.a
+ @echo LINKING $@
+ $(CC) $(trbcmd.OBJS) $(LDFLAGS) $(LIBDIR) $(LOADLIBES) -o $@
+ @echo DONE!
+
+pulser: $(pulser.OBJS) libtrbnet.a
+ @echo LINKING $@
+ $(CC) $(pulser.OBJS) $(LDFLAGS) $(LIBDIR) $(LOADLIBES) -o $@
+ @echo DONE!
+
+libtrbnet.a: $(libtrbnet.OBJS)
+ @echo CREATING library $@
+ $(AR) $(ARFLAGS) $@ $^
+ @echo DONE!
+
+lib: $(LIB_TARGETS)
+
+distclean: clean
+ rm -f $(TARGETS) $(LIB_TARGETS)
+ rcsclean -u
+
+clean:
+ rm -f *.o core core.*
+ rcsclean
+
+# ------------ Dependencies --------------------------------------------
+
+port.o: port.h port.c
+
+fs_fpga_int_mem.o: fs_fpga_int_mem.h fs_fpga_int_mem.c port.h
+
+trberror.o: trberror.h trberror.c
+
+trbnet.o: trbnet.h trbnet.c trberror.h fs_fpga_int_mem.h port.h
+
+trbcmd.o: trbcmd.c trbnet.h port.h trberror.h fs_fpga_int_mem.h
+
+pulser.o: pulser.c trbnet.h port.h trberror.h
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "fs_fpga_int_mem.h"
+
+/* clean exit when Ctrl-C is pressed */
+void ctrl_c_catched()
+{
+ close_ports();
+#if DEBUG
+ fprintf(stderr, "got ctrl-c and close gpio\n");
+#endif
+ exit(0);
+}
+
+/* writes a 32bit word to a given address on a given device */
+void write32_to_FPGA(uint16_t address, uint32_t value)
+{
+ /* set address RW_WRITE */
+ set_value_single(address & 0x7fff);
+ set_value(value);
+ writePC(0x10000);
+ writePC(0);
+}
+
+/* reads a 32bit word from a given address on a given device */
+int read32_from_FPGA(uint16_t address, uint32_t* value)
+{
+ /* set address RW_WRITE */
+ set_value_single(address | 0x8000);
+
+ *value = ((readPB() << 16));
+ writePC(0x10000);
+ writePC(0);
+ writePC(0x10000);
+ writePC(0);
+ *value |= (readPB() & 0xffff);
+ writePC(0x10000);
+ writePC(0);
+
+ return 0;
+}
+
+/* reads a 32bit word from a given address on a given device */
+int read32_from_FPGA_dma(uint16_t fifo_address,
+ uint32_t* values,
+ uint32_t size)
+{
+ uint32_t tmp;
+ uint32_t *start = NULL;
+
+ /* write maximum length to control register of fifo */
+ write32_to_FPGA(fifo_address, size);
+
+ /* set address RW_WRITE */
+ set_value_single(fifo_address | 0x8000);
+
+ start = values;
+ do {
+ tmp = readPB() << 16;
+ strobe();
+ strobe(); /* (will be optimized away) */
+ tmp |= (readPB() & 0xffff);
+ strobe();
+ *values++ = tmp;
+ } while(tmp & 0x01000000);
+
+ return (values - start) - 1;
+}
--- /dev/null
+#ifndef FS_FPGA_INT_H
+#define FS_FPGA_INT_H
+
+#include <stdint.h>
+#include <port.h>
+
+#define RW_READ 1
+#define RW_WRITE 0
+
+void ctrl_c_catched();
+void write32_to_FPGA(uint16_t address, uint32_t value);
+int read32_from_FPGA(uint16_t address, uint32_t* value);
+int read32_from_FPGA_dma(uint16_t fifo_address,
+ uint32_t* values,
+ uint32_t size);
+
+/* rw strobe. Raises PC(16) for a short time */
+static inline void strobe()
+{
+ setbitsPC(0x10000);
+ clrbitsPC(0x10000);
+}
+
+/* sends reset for communication logic PC(17,16)=11 */
+static inline void com_reset()
+{
+ setbitsPC(0x30000);
+ clrbitsPC(0x30000);
+}
+
+/* waits until PB(16) goes high, maximum 100 cycles */
+static inline int wait_for_valid()
+{
+ unsigned int timeout = 0;
+
+#if DEBUG
+ fprintf(stderr, "is_valid PORT_B\n");
+#endif
+
+ do {
+ if ((readPB() & 0x10000) != 0) {
+ return 0;
+ }
+ } while (timeout++ < 100);
+
+ com_reset();
+#if DEBUG
+ fprintf(stderr, "Error, I didnt get 'is_valid'\n");
+#endif
+
+ return -1;
+}
+
+/* waits until PB(16) goes low, maximum 100 cycles */
+static inline int wait_for_not_valid()
+{
+ unsigned int timeout = 0;
+
+#if DEBUG
+ fprintf(stderr, "is_not_valid PORT_B\n");
+#endif
+
+ do {
+ if ((readPB() & 0x10000) == 0) {
+ return 0;
+ }
+ } while (timeout++ < 100);
+
+ com_reset();
+#if DEBUG
+ fprintf(stderr, "Error, I didnt get 'is_not_valid'\n");
+#endif
+
+ return -1;
+}
+
+/* sends two strobes, hsb then lsb of value */
+static inline void set_value(uint32_t value)
+{
+ writePC((value>>16)+0x10000);
+ writePC(0);
+ writePC((value & 0xffff) + 0x10000);
+ writePC(0);
+}
+
+/* sends one strobe, lsb of value only */
+static inline void set_value_single(uint16_t value)
+{
+ writePC(value + 0x10000);
+ writePC(0);
+}
+
+/* sends address to device, wrapper for set_value */
+static inline void set_address(uint8_t dir, uint16_t address)
+{
+
+ if (dir == RW_READ) {
+ set_value_single(address | 0x8000);
+ } else {
+ set_value_single(address & 0x7fff);
+ }
+}
+
+#endif
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/mman.h>
+
+#include "port.h"
+
+/* SET OE[1-read/write, 0 - only read]
+ pA - 8bits, pB,C,D,E-18bits */
+#define GPIOB_OE_PINS 0x0
+#define GPIOC_OE_PINS 0x3ffff
+#define GPIO_OFFSET (0x1a000 / sizeof(uint32_t))
+
+volatile uint32_t* GPIO_PTR = NULL;
+volatile uint32_t* GPIOA_OUT_OFFSET = NULL;
+volatile uint32_t* GPIOA_IN_OFFSET = NULL;
+volatile uint32_t* GPIOA_OE_OFFSET = NULL;
+volatile uint32_t* GPIOB_OUT_OFFSET = NULL;
+volatile uint32_t* GPIOB_IN_OFFSET = NULL;
+volatile uint32_t* GPIOB_OE_OFFSET = NULL;
+volatile uint32_t* GPIOC_OUT_OFFSET = NULL;
+volatile uint32_t* GPIOC_IN_OFFSET = NULL;
+volatile uint32_t* GPIOC_OE_OFFSET = NULL;
+volatile uint32_t* GPIOD_OUT_OFFSET = NULL;
+volatile uint32_t* GPIOD_IN_OFFSET = NULL;
+volatile uint32_t* GPIOD_OE_OFFSET = NULL;
+volatile uint32_t* GPIOE_OUT_OFFSET = NULL;
+volatile uint32_t* GPIOE_IN_OFFSET = NULL;
+volatile uint32_t* GPIOE_OE_OFFSET = NULL;
+
+int init_ports()
+{
+ int memfd;
+ uint32_t *mem = NULL;
+
+ memfd = open("/dev/mem", O_RDWR);
+ if (memfd < 0) {
+ perror("Cant open memory device");
+ return -1;
+ }
+
+ mem = mmap((void*)0,
+ 2 * 4 * 4 * 8192,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ memfd,
+ 0xb0000000);
+
+ if ((void*)mem == MAP_FAILED) {
+ perror("Error mem-map");
+ return -1;
+ }
+
+ /* GPIO */
+ GPIO_PTR = mem + GPIO_OFFSET;
+
+ GPIOA_OUT_OFFSET = (0x00 + GPIO_PTR);
+ GPIOA_IN_OFFSET = (0x04 / sizeof(uint32_t)) + GPIO_PTR;
+ GPIOA_OE_OFFSET = (0x08 / sizeof(uint32_t)) + GPIO_PTR;
+ GPIOB_OUT_OFFSET = (0x20 / sizeof(uint32_t)) + GPIO_PTR;
+ GPIOB_IN_OFFSET = (0x24 / sizeof(uint32_t)) + GPIO_PTR;
+ GPIOB_OE_OFFSET = (0x28 / sizeof(uint32_t)) + GPIO_PTR;
+ GPIOC_OUT_OFFSET = (0x30 / sizeof(uint32_t)) + GPIO_PTR;
+ GPIOC_IN_OFFSET = (0x34 / sizeof(uint32_t)) + GPIO_PTR;
+ GPIOC_OE_OFFSET = (0x38 / sizeof(uint32_t)) + GPIO_PTR;
+ GPIOD_OUT_OFFSET = (0x40 / sizeof(uint32_t)) + GPIO_PTR;
+ GPIOD_IN_OFFSET = (0x44 / sizeof(uint32_t)) + GPIO_PTR;
+ GPIOD_OE_OFFSET = (0x48 / sizeof(uint32_t)) + GPIO_PTR;
+ GPIOE_OUT_OFFSET = (0x50 / sizeof(uint32_t)) + GPIO_PTR;
+ GPIOE_IN_OFFSET = (0x54 / sizeof(uint32_t)) + GPIO_PTR;
+ GPIOE_OE_OFFSET = (0x58 / sizeof(uint32_t)) + GPIO_PTR;
+
+ close(memfd);
+
+ /* set Output Enable */
+ /* read all bits on portB */
+ *(GPIOB_OE_OFFSET) = GPIOB_OE_PINS;
+ /* write portC[17-0] */
+ *(GPIOC_OE_OFFSET) = GPIOC_OE_PINS;
+
+ return 0;
+}
+
+void close_ports()
+{
+ *(GPIOB_OE_OFFSET) = 0x0;
+ *(GPIOC_OE_OFFSET) = 0x0;
+
+ GPIO_PTR = NULL;
+ GPIOA_OUT_OFFSET = NULL;
+ GPIOA_IN_OFFSET = NULL;
+ GPIOA_OE_OFFSET = NULL;
+ GPIOB_OUT_OFFSET = NULL;
+ GPIOB_IN_OFFSET = NULL;
+ GPIOB_OE_OFFSET = NULL;
+ GPIOC_OUT_OFFSET = NULL;
+ GPIOC_IN_OFFSET = NULL;
+ GPIOC_OE_OFFSET = NULL;
+ GPIOD_OUT_OFFSET = NULL;
+ GPIOD_IN_OFFSET = NULL;
+ GPIOD_OE_OFFSET = NULL;
+ GPIOE_OUT_OFFSET = NULL;
+ GPIOE_IN_OFFSET = NULL;
+ GPIOE_OE_OFFSET = NULL;
+}
--- /dev/null
+#ifndef PORT_H
+#define PORT_H
+
+#include <stdint.h>
+
+extern volatile uint32_t* GPIO_PTR;
+
+extern volatile uint32_t* GPIOA_OUT_OFFSET;
+extern volatile uint32_t* GPIOA_IN_OFFSET;
+extern volatile uint32_t* GPIOA_OE_OFFSET;
+
+extern volatile uint32_t* GPIOB_OUT_OFFSET;
+extern volatile uint32_t* GPIOB_IN_OFFSET;
+extern volatile uint32_t* GPIOB_OE_OFFSET;
+
+extern volatile uint32_t* GPIOC_OUT_OFFSET;
+extern volatile uint32_t* GPIOC_IN_OFFSET;
+extern volatile uint32_t* GPIOC_OE_OFFSET;
+
+extern volatile uint32_t* GPIOD_OUT_OFFSET;
+extern volatile uint32_t* GPIOD_IN_OFFSET;
+extern volatile uint32_t* GPIOD_OE_OFFSET;
+
+extern volatile uint32_t* GPIOE_OUT_OFFSET;
+extern volatile uint32_t* GPIOE_IN_OFFSET;
+extern volatile uint32_t* GPIOE_OE_OFFSET;
+
+#define GPIO_PA 0x00
+#define GPIO_PB 0x20 / sizeof(uint32_t)
+#define GPIO_PC 0x30 / sizeof(uint32_t)
+#define GPIO_PD 0x40 / sizeof(uint32_t)
+#define GPIO_PE 0x50 / sizeof(uint32_t)
+
+int init_ports();
+void close_ports();
+
+static inline void close_ports_special(uint32_t portBOE, uint32_t portCOE)
+{
+ *GPIOB_OE_OFFSET = portBOE;
+ *GPIOC_OE_OFFSET = portCOE;
+}
+
+static inline uint32_t readPA()
+{
+ return (*GPIOA_IN_OFFSET );
+}
+
+static inline void writePA(uint8_t data)
+{
+ *GPIOA_OUT_OFFSET = data;
+}
+
+static inline void setbitsPA(uint32_t bitmask)
+{
+ *GPIOA_OUT_OFFSET |= (bitmask );
+}
+
+static inline void clrbitsPA(uint32_t bitmask)
+{
+ *GPIOA_OUT_OFFSET &= ~(bitmask );
+}
+
+
+static inline uint32_t readPB()
+{
+ return (*GPIOB_IN_OFFSET );
+}
+
+static inline void writePB(uint32_t data)
+{
+ *GPIOB_OUT_OFFSET = (data );
+}
+
+static inline void setbitsPB(uint32_t bitmask)
+{
+ *GPIOB_OUT_OFFSET |= (bitmask);
+}
+
+static inline void clrbitsPB(uint32_t bitmask)
+{
+ *GPIOB_OUT_OFFSET &= ~(bitmask);
+}
+
+
+static inline uint32_t readPC()
+{
+ return (*GPIOC_IN_OFFSET );
+}
+
+static inline void writePC(uint32_t data)
+{
+ *GPIOC_OUT_OFFSET = (data );
+}
+
+static inline void setbitsPC(uint32_t bitmask)
+{
+ *GPIOC_OUT_OFFSET |= (bitmask );
+}
+
+static inline void clrbitsPC(uint32_t bitmask)
+{
+ *GPIOC_OUT_OFFSET &= ~(bitmask);
+}
+
+static inline uint32_t readPD()
+{
+ return (*GPIOD_IN_OFFSET );
+}
+
+static inline void writePD(uint32_t data)
+{
+ *GPIOD_OUT_OFFSET = (data );
+}
+
+static inline void setbitsPD(uint32_t bitmask)
+{
+ *GPIOD_OUT_OFFSET |= (bitmask );
+}
+
+static inline void clrbitsPD(uint32_t bitmask)
+{
+ *GPIOD_OUT_OFFSET &= ~(bitmask );
+}
+
+
+static inline uint32_t readPE()
+{
+ return (*GPIOE_IN_OFFSET );
+}
+
+static inline void writePE(uint32_t data)
+{
+ *GPIOE_OUT_OFFSET = (data );
+}
+
+static inline void setbitsPE(uint32_t bitmask)
+{
+ *GPIOE_OUT_OFFSET |= (bitmask );
+}
+
+static inline void clrbitsPE(uint32_t bitmask)
+{
+ *GPIOE_OUT_OFFSET &= ~(bitmask );
+}
+
+
+static inline uint32_t readPort(uint32_t port)
+{
+ return *(GPIO_PTR + port + 4 / sizeof(uint32_t));
+}
+
+static inline void writePort(uint32_t port, uint32_t value)
+{
+ *(GPIO_PTR + port) = (value );
+}
+
+static inline void setbitsPort(uint32_t port, uint32_t bitmask)
+{
+ *(GPIO_PTR + port) |= (bitmask);
+}
+
+static inline void clrbitsPort(uint32_t port, uint32_t bitmask)
+{
+ *(GPIO_PTR + port) &= ~(bitmask);
+}
+
+static inline void microdelay(unsigned int del)
+{
+ unsigned int i;
+ unsigned int calibrated_del = del * 10;
+ for (i = 0; i < calibrated_del; i++) {
+ }
+}
+
+#endif
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <limits.h>
+
+#include <libgen.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <trbnet.h>
+#include <trberror.h>
+
+#define bufferSize 16385
+
+/* ------ MAIN ---------------------------------------------------------- */
+
+static FILE *hldFile = NULL;
+static unsigned int evtCounter = 0;
+
+static void atexit0()
+{
+ if (hldFile != NULL) {
+ fclose(hldFile);
+ }
+
+ fprintf(stderr, "%d Triggers were send\n", evtCounter);
+}
+
+static void sigHandler(int sig)
+{
+ if (sig == SIGTERM) fprintf(stderr, "caught SIGTERM\n");
+ if (sig == SIGINT) fprintf(stderr, "caught SIGINT\n");
+
+ exit(128 + sig);
+}
+
+void usage(const char *progName)
+{
+ printf("Usage: %s [-h] [-d level] [-f outFileName] [-n numEvents]\n",
+ progName);
+ printf("Options:\n");
+ printf(" -h give this help\n");
+ printf(" -d turn on Debugging Information\n");
+ printf(" -f outFileName\n");
+ printf(" -n process numEvents triggers\n");
+}
+
+int main(int argc, char ** argv)
+{
+ char hldFileName[256] = "pulser.hld";
+ uint16_t trgNumber = 0;
+ unsigned int numEvts = UINT_MAX;
+ uint32_t buffer[bufferSize];
+ sigset_t blockSet;
+ int size;
+ int writeToStdout = 0;
+ int i;
+
+ trb_debug = 0;
+
+ /* Parse Arguments */
+ while ((i = getopt(argc, argv, "+hd:f:n:")) != -1) {
+ switch (i) {
+ case '?':
+ usage(basename(argv[0]));
+ exit(EXIT_FAILURE);
+ case 'h':
+ usage(basename(argv[0]));
+ exit(EXIT_SUCCESS);
+ case 'd':
+ trb_debug = strtoul(optarg, NULL, 0);
+ break;
+ case 'f':
+ strncpy(hldFileName, optarg, 256);
+ break;
+ case 'n':
+ numEvts = strtoul(optarg, NULL, 0);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* open port */
+ init_ports();
+
+ /* Open HLD-File */
+ if (strncmp(hldFileName, "stdout", 256) != 0) {
+ hldFile = fopen(hldFileName, "w");
+ if (hldFile == NULL) {
+ perror("File Open");
+ }
+ } else {
+ writeToStdout = 1;
+ }
+
+ /* Set Signalhandler */
+ atexit(atexit0);
+ signal(SIGINT, sigHandler);
+ signal(SIGTERM, sigHandler);
+
+ /* Set signal mask for blocking */
+ sigemptyset(&blockSet);
+ sigaddset(&blockSet, SIGINT);
+ sigaddset(&blockSet, SIGTERM);
+
+ /* Loop Triggers */
+ while(evtCounter < numEvts) {
+ /* Block signals */
+ sigprocmask(SIG_BLOCK, &blockSet, NULL);
+
+ /* Send Trigger and get Data */
+ if (trb_send_trigger(0, 0, 0xcc, 0xdd, 0xaabb) != -1) {
+ exit(EXIT_FAILURE);
+ }
+
+ size = trb_ipu_data_read(0, 0xcc, 0xdd, 0xaabb, buffer, bufferSize);
+ if (size == -1) {
+ exit(EXIT_FAILURE);
+ }
+
+ if (writeToStdout == 1) {
+ fprintf(stdout, "Trigger# %d\n", trgNumber);
+ for (i = 0; i < size; i++) {
+ fprintf(stdout, "0x%08x\n", buffer[i]);
+ }
+ } else {
+ if (fwrite((void*)buffer, 4, size, hldFile) != size) {
+ perror("Writing to File failed");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* Unblock signals */
+ sigprocmask(SIG_UNBLOCK, &blockSet, NULL);
+
+ trgNumber++;
+ evtCounter++;
+ if (evtCounter % 100 == 0) {
+ fprintf(stderr, "%d triggers send\n", trgNumber);
+ }
+ }
+
+ exit(EXIT_SUCCESS);
+}
--- /dev/null
+mboehmer load_xilix.sh for reset
+
+adcmodule addresse: 0xfa00 oder 0x42
+lesetest: 0x8021
+schreibtest: 0x8000
+schreibtest: 0x8002
+invalid: 0x8001
+
+Blocktranfer: 0xa000 - 0xbfff lesen und schreiben
+
+#Test in Frankfurt: trb128
+
+
+# Daten Auslesen:
+#Init:
+./trbnet -d1 T 3 0 0xaa 0xbb 0x0008
+./trbnet -d1 I 0 0xaa 0xbb 0x0008
+
+#Hier loop machen, dabei Trigger hochzaehlen, trigger = 9, 10, 11, 12, ...
+./trbnet -d1 T 0 0 0xaa 0xbb 0xtrigger
+./trbnet -d1 I 0 0xaa 0xbb 0x0trigger
+
--- /dev/null
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <libgen.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <trbnet.h>
+#include <trberror.h>
+#include <fs_fpga_int_mem.h>
+
+#ifndef HEXMODE
+#define HEXMODE 0
+#endif
+
+static int hexMode = HEXMODE;
+
+/* ------ MAIN ---------------------------------------------------------- */
+
+void usage(const char *progName)
+{
+ printf("Usage: %s [-h] [-n number] [-d level] [-H] <COMMAND>\n", progName);
+ printf("Options:\n");
+ printf(" -h give this help\n");
+ printf(" -n repeat COMMAND number times, -1 = endless loop\n");
+ printf(" -d turn on Debugging Information\n");
+ printf(" level 1: TRB_Package debugging\n");
+ printf(" level 2: +FIFO debugging\n");
+ printf(" -D FIFO DMA-Mode\n");
+ printf(" -l lazy-mode: skip most consistency-checks of packages\n");
+ printf(" -H hex-mode: all following arguments will be interpreted "
+ "as hexadecimal\n numbers\n");
+ printf("Commands:\n");
+ printf(" r <trbaddress> <register> -> read register\n");
+ printf(" w <trbaddress> <register> <data> -> write register\n");
+ printf(" rm <trbaddress> <register> <size> <mode> "
+ "-> read register-memory\n");
+ printf(" wm <trbaddress> <register> <mode> <file> "
+ "-> write to register-memory from ASCII-file ('-' = stdin)\n");
+ printf(" i <trbaddress> -> read unique ID\n");
+ printf(" s <uid> <endpoint> <trbaddress> -> set trb-address\n");
+ printf(" T <input> <type> <random> <info> <number> -> trigger by "
+ "slowcontrol\n");
+ printf(" I <type> <random> <info> <number> -> read IPU data "
+ "slowcontrol\n");
+ printf(" f <channel> -> flush FIFO of "
+ "channel\n");
+ printf(" R <register> -> "
+ "read register of the FPGA"
+ " \n");
+ printf(" W <register> <value> -> "
+ "write to register of the FPGA"
+ " \n");
+}
+
+int main(int argc, char ** argv)
+{
+ uint16_t trb_address = 0;
+ uint16_t reg_address = 0;
+ int cmdCtr = 0;
+ int repeat = 1;
+ int i;
+
+ trb_debug = 0;
+ trb_lazy = 0;
+
+ /* Parse Arguments */
+ while ((i = getopt(argc, argv, "+hn:d:DlH")) != -1) {
+ switch (i) {
+ case '?':
+ usage(basename(argv[0]));
+ exit(EXIT_FAILURE);
+ case 'h':
+ usage(basename(argv[0]));
+ exit(EXIT_SUCCESS);
+ case 'n':
+ repeat = strtol(optarg, NULL, 0);
+ break;
+ case 'd':
+ trb_debug = strtoul(optarg, NULL, 0);
+ break;
+ case 'D':
+ trb_dma = 1;
+ break;
+ case 'l':
+ trb_lazy = 1;
+ break;
+ case 'H':
+ hexMode = 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* open port */
+ init_ports();
+
+ if (argc - optind < 1) {
+ usage(basename(argv[0]));
+ exit(EXIT_FAILURE);
+ }
+
+ while ((repeat == -1) || (cmdCtr++ < repeat)) {
+
+ if (strcmp(argv[optind], "w") == 0) {
+
+ /*******************************************/
+ /* Register Write */
+ /*******************************************/
+
+ uint32_t value = 0;
+
+ if (argc - optind != 4) {
+ usage(basename(argv[0]));
+ exit(EXIT_FAILURE);
+ }
+
+ trb_address = strtoul(argv[optind + 1], NULL, hexMode == 1 ? 16 : 0);
+ reg_address = strtoul(argv[optind + 2], NULL, hexMode == 1 ? 16 : 0);
+ value = strtoul(argv[optind + 3], NULL, hexMode == 1 ? 16 : 0);
+
+ /* DEBUG Info */
+ if (trb_debug > 0) {
+ fprintf(stderr,
+ "Command: WRITE: trb_address: 0x%04x, reg_address: 0x%04x, "
+ "value: 0x%08x\n",
+ trb_address, reg_address, value);
+ }
+
+ if (trb_register_write(trb_address, reg_address, value) == -1) {
+ trb_error("write failed");
+ exit(EXIT_FAILURE);
+ }
+ } else if (strcmp(argv[optind], "r") == 0) {
+
+ /*******************************************/
+ /* Register Read */
+ /*******************************************/
+
+ int status = 0;
+ uint32_t data[256];
+
+ if (argc - optind != 3) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ trb_address = strtoul(argv[optind + 1], NULL, hexMode == 1 ? 16 : 0);
+ reg_address = strtoul(argv[optind + 2], NULL, hexMode == 1 ? 16 : 0);
+
+ /* DEBUG Info */
+ if (trb_debug > 0) {
+ fprintf(stderr,
+ "Command: READ: trb_address: 0x%04x, "
+ "reg_address: 0x%04x\n",
+ trb_address, reg_address);
+ }
+
+ status = trb_register_read(trb_address, reg_address, data, 256);
+ if (status == -1) {
+ trb_error("read failed");
+ exit(EXIT_FAILURE);
+ }
+
+ for (i = 0; i < status; i += 2) {
+ fprintf(stdout, "%s%04x %s%08x\n",
+ hexMode == 1 ? "" : "0x",
+ data[i],
+ hexMode == 1 ? "" : "0x",
+ data[i + 1]);
+ }
+ } else if (strcmp(argv[optind], "rm") == 0) {
+
+ /*******************************************/
+ /* Register Read Memory */
+ /*******************************************/
+
+ uint32_t *data = NULL;
+ uint16_t size = 0;
+ uint8_t option = 0;
+ int status;
+ unsigned int i;
+
+ if (argc - optind != 5) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ trb_address = strtoul(argv[optind + 1], NULL, hexMode == 1 ? 16 : 0);
+ reg_address = strtoul(argv[optind + 2], NULL, hexMode == 1 ? 16 : 0);
+ size = strtoul(argv[optind + 3], NULL, hexMode == 1 ? 16 : 0);
+ option = strtoul(argv[optind + 4], NULL, hexMode == 1 ? 16 : 0);
+
+ /* DEBUG Info */
+ if (trb_debug > 0) {
+ fprintf(stderr,
+ "Command: READ_MEM: trb_address: 0x%04x, "
+ "reg_address: 0x%04x, "
+ "size: 0x%04x, "
+ "option: %d\n",
+ trb_address, reg_address, size, option);
+ }
+
+ if ((data = malloc(sizeof(uint32_t) * size)) == NULL) abort();
+
+ status =
+ trb_register_read_mem(trb_address, reg_address, option, data, size);
+ if (status == -1) {
+ trb_error("read_mem failed");
+ if (data != NULL) free(data);
+ exit(EXIT_FAILURE);
+ }
+
+ for (i = 0; i < status; i++) {
+ fprintf(stdout, "%s%04x %s%08x\n",
+ hexMode == 1 ? "" : "0x", reg_address + i,
+ hexMode == 1 ? "" : "0x", data[i]);
+ }
+
+ if (data != NULL) free(data);
+ } else if (strcmp(argv[optind], "wm") == 0) {
+
+ /*******************************************/
+ /* Register Write Memory */
+ /*******************************************/
+
+ FILE *file = NULL;
+ uint32_t *data = NULL;
+ unsigned int dataSize = 64;
+ char *buffer = NULL;
+ size_t len = 0;
+ char *fileName = NULL;
+ uint8_t option = 0;
+ unsigned int size = 0;
+ int status;
+
+ if (argc - optind != 5) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ trb_address = strtoul(argv[optind + 1], NULL, hexMode == 1 ? 16 : 0);
+ reg_address = strtoul(argv[optind + 2], NULL, hexMode == 1 ? 16 : 0);
+ option = strtoul(argv[optind + 3], NULL, hexMode == 1 ? 16 : 0);
+ fileName = argv[optind + 4];
+
+ /* Open inputFile and read Data into buffer */
+ if (strcmp(fileName, "-") == 0) {
+ file = stdin;
+ } else {
+ file = fopen(fileName, "r");
+ if (file == NULL) {
+ perror("Error opening file");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if ((data = malloc(sizeof(uint32_t) * dataSize)) == NULL) abort();
+ while (getline(&buffer, &len, file) != -1) {
+ if (size >= dataSize) {
+ dataSize += 64;
+ if ((data = realloc(data, sizeof(uint32_t) * dataSize)) == NULL) {
+ abort();
+ }
+ }
+ data[size++] = strtoul(buffer, NULL, hexMode == 1 ? 16 : 0);
+ }
+ if (buffer != NULL) free(buffer);
+
+ /* DEBUG Info */
+ if (trb_debug > 0) {
+ fprintf(stderr,
+ "Command: WRITE_MEM: trb_address: 0x%04x, "
+ "reg_address: 0x%04x, "
+ "option: %d, "
+ "size: 0x%04x\n",
+ trb_address, reg_address, option, size);
+ }
+
+ status = trb_register_write_mem(trb_address, reg_address, option,
+ data, size);
+ if (data != NULL) free(data);
+
+ if (status == -1) {
+ trb_error("write register-memory failed");
+ exit(EXIT_FAILURE);
+ }
+ } else if (strcmp(argv[optind], "i") == 0) {
+
+ /*******************************************/
+ /* ReadUId */
+ /*******************************************/
+
+ uint32_t uidBuffer[128];
+ unsigned int size;
+
+ if (argc - optind != 2) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ trb_address = strtoul(argv[optind + 1], NULL, hexMode == 1 ? 16 : 0);
+
+ /* DEBUG Info */
+ if (trb_debug > 0) {
+ fprintf(stderr,
+ "Command: READ_UID: trb_address: 0x%04x\n",
+ trb_address);
+ }
+
+ size = trb_read_uid(trb_address, uidBuffer, 128);
+ if (size == -1) {
+ trb_error("read_uid failed");
+ exit(EXIT_FAILURE);
+ }
+
+ for (i = 0; (i < size) && (i < 128); i += 3) {
+ fprintf(stdout, "%s%08x%08x %s%02x\n",
+ hexMode == 1 ? "" : "0x",
+ uidBuffer[i],
+ uidBuffer[i + 1],
+ hexMode == 1 ? "" : "0x",
+ uidBuffer[i + 2]);
+ }
+ } else if (strcmp(argv[optind], "s") == 0) {
+
+ /*******************************************/
+ /* SetAddress */
+ /*******************************************/
+
+ uint64_t uid = 0;
+ uint8_t endpoint = 0;
+ uint16_t trb_address = 0;
+
+ if (argc - optind != 4) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ uid = strtoull(argv[optind + 1], NULL, hexMode == 1 ? 16 : 0);
+ endpoint = strtoul(argv[optind + 2], NULL, hexMode == 1 ? 16 : 0);
+ trb_address = strtoul(argv[optind + 3], NULL, hexMode == 1 ? 16 : 0);
+
+ /* DEBUG Info */
+ if (trb_debug > 0) {
+ fprintf(stderr,
+ "Command: SET_ADDRESS: "
+ "uid: 0x%016llx, "
+ "endpoint: 0x%02x, "
+ "trb_address: 0x%04x\n",
+ uid, endpoint, trb_address);
+ }
+
+ if (trb_set_address(uid, endpoint, trb_address) == -1) {
+ trb_error("set_address failed");
+ exit(EXIT_FAILURE);
+ }
+ } else if (strcmp(argv[optind], "T") == 0) {
+
+ /*******************************************/
+ /* Fake trigger function (ADCM specific) */
+ /*******************************************/
+
+ uint8_t input = 0;
+ uint8_t type = 0;
+ uint8_t random = 0;
+ uint8_t info = 0;
+ uint16_t number = 0;
+
+ if (argc - optind != 6) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ input = strtoul(argv[optind + 1], NULL, hexMode == 1 ? 16 : 0) & 0x03;
+ type = strtoul(argv[optind + 2], NULL, hexMode == 1 ? 16 : 0) & 0x0f;
+ random = strtoul(argv[optind + 3], NULL, hexMode == 1 ? 16 : 0);
+ info = strtoul(argv[optind + 4], NULL, hexMode == 1 ? 16 : 0);
+ number = strtoul(argv[optind + 5], NULL, hexMode == 1 ? 16 : 0);
+
+ /* DEBUG Info */
+ if (trb_debug > 0) {
+ fprintf(stderr,
+ "Command: SEND_TRIGGER: "
+ "input: 0x%01x, "
+ "type: 0x%01x, "
+ "random: 0x%02x, "
+ "info: 0x%02x, "
+ "number: 0x%04x\n",
+ input, type, random, info, number);
+ }
+
+ if (trb_send_trigger(input, type, info, random, number) == -1) {
+ trb_error("send trigger failed");
+ exit(EXIT_FAILURE);
+ }
+ } else if (strcmp(argv[optind], "I") == 0) {
+
+ /*******************************************/
+ /* IPU channel readout */
+ /*******************************************/
+
+ uint32_t buffer[4096];
+ uint8_t type = 0;
+ uint8_t random = 0;
+ uint8_t info = 0;
+ uint16_t number = 0;
+ int size = 0;
+
+ if (argc - optind != 5) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ type = strtoul(argv[optind + 1], NULL, hexMode == 1 ? 16 : 0) & 0x0f;
+ random = strtoul(argv[optind + 2], NULL, hexMode == 1 ? 16 : 0);
+ info = strtoul(argv[optind + 3], NULL, hexMode == 1 ? 16 : 0);
+ number = strtoul(argv[optind + 4], NULL, hexMode == 1 ? 16 : 0);
+
+ /* DEBUG Info */
+ if (trb_debug > 0) {
+ fprintf(stderr,
+ "Command: READ_IPU_DATA: "
+ "type: 0x%01x, "
+ "random: 0x%02x, "
+ "info: 0x%02x, "
+ "number: 0x%04x\n",
+ type, random, info, number);
+ }
+ size = trb_ipu_data_read(type, info, random, number, buffer, 4096);
+ if (size == -1) {
+ trb_error("ipu read data failed");
+ exit(EXIT_FAILURE);
+ }
+
+ for (i = 0; i < size; i++) {
+ fprintf(stdout, "0x%08x\n", buffer[i]);
+ }
+ } else if (strcmp(argv[optind], "f") == 0) {
+
+ /*******************************************/
+ /* Flush FIFO Channel */
+ /*******************************************/
+
+ int status;
+ uint8_t channel = 0;
+
+ if (argc - optind != 2) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ channel = strtoul(argv[optind + 1], NULL, hexMode == 1 ? 16 : 0);
+ if (trb_debug > 0) {
+ fprintf(stderr, "Command: FIFO_FLUSH_CHANNEL #%d\n", channel);
+ }
+
+ status = trb_fifo_flush(channel);
+ if (status == -1) {
+ trb_error("flush channel failed");
+ exit(EXIT_FAILURE);
+ }
+ } else if (strcmp(argv[optind], "R") == 0) {
+
+ /*******************************************/
+ /* Read FIFO Register */
+ /*******************************************/
+
+ uint32_t value = 0;
+ uint16_t reg_address = 0;
+
+ if (argc - optind != 2) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ reg_address = strtoul(argv[optind + 1], NULL, hexMode == 1 ? 16 : 0);
+
+ read32_from_FPGA(reg_address, &value);
+ fprintf(stdout, "%s%04x %s%04x\n",
+ hexMode == 1 ? "" : "0x", reg_address,
+ hexMode == 1 ? "" : "0x", value);
+
+ } else if (strcmp(argv[optind], "W") == 0) {
+
+ /*******************************************/
+ /* Write FIFO Register */
+ /*******************************************/
+
+ uint32_t value = 0;
+ uint16_t reg_address = 0;
+
+ if (argc - optind != 3) {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ reg_address = strtoul(argv[optind + 1], NULL, hexMode == 1 ? 16 : 0);
+ value = strtoul(argv[optind + 2], NULL, hexMode == 1 ? 16 : 0);
+
+ write32_to_FPGA(reg_address, value);
+
+ /*
+ fprintf(stdout, "%s%04x %s%04x\n",
+ hexMode == 1 ? "" : "0x", reg_address,
+ hexMode == 1 ? "" : "0x", value);
+ */
+ } else {
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+
+ } /* end repeat loop */
+
+ exit(EXIT_SUCCESS);
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "trberror.h"
+
+/* Error Handling */
+
+int trb_errno = TRB_NONE;
+uint64_t trb_statusbits = 0;
+
+void trb_error(const char *s)
+{
+ if (s != NULL) {
+ fprintf(stderr, "%s: %s\n", s, trb_strerror(trb_errno));
+ } else {
+ fprintf(stderr, "%s\n", trb_strerror(trb_errno));
+ }
+
+ /* Print Statusbits */
+ if (trb_errno == TRB_TERM_ERRBIT) {
+ fprintf(stderr, "%s\n", trb_statusbits_str(trb_statusbits));
+ }
+}
+
+const char* trb_strerror(int errno)
+{
+ static const char errorstring[][80] = {
+ "No Error",
+ "TX Busy",
+ "FIFO Not Empty",
+ "FIFO Timeout",
+ "FIFO Error, invalid H0 header(s)",
+ "FIFO Error, invalid sequenze-number",
+ "FIFO Error, invalid read-data-mode",
+ "FIFO Broken-Package",
+ "FIFO Invalid-Content (no TERMINATION)",
+ "FAILED WAIT_IS_VALID",
+ "FAILED WAIT_IS_NOT_VALID",
+ "User-Buffer Overflow",
+ "Invalid Channel",
+ "Invalid number of Packages returned",
+ "TERMINATION ErrorBit(s) set",
+ "Invalid TRB-Address",
+ "Invalid Data-Buffer Length",
+ "Endpoint not reached"
+ };
+
+ if (errno < 18) {
+ return errorstring[errno];
+ } else {
+ return "Unknown Errno";
+ }
+}
+
+const char* trb_statusbits_str(uint64_t statusbits)
+{
+ static const char commonStatusBits[16][64] = {
+ "Endpoint not reached",
+ "Coll: collision detected",
+ "WordMiss: word missing",
+ "Checksum: checksum error",
+ "DontKnow: dont understand",
+ "BufferMatch: buffer mismatch",
+ "", "", "", "", "", "", "", "", "", ""
+ };
+
+ static const char ch0StatusBits[16][64] = {
+ "Ch0_TrigCtr: trigger counter mismatch",
+ "",
+ "",
+ "",
+ "Ch0_BufferHalfFull: data-buffers half full",
+ "Ch0_BuffersFull: data-buffers almost full"
+ "", "", "", "", "", "", "", "", "", ""
+ };
+
+ static const char ch1StatusBits[16][64] = {
+ "Ch1_TrigNum: trigger number mismatch",
+ "Ch1_TrigCode: trigger code / random mismatch",
+ "Ch1_Length: wrong length",
+ "Ch1_NoAnswer: answer missing",
+ "",
+ "",
+ "",
+ "",
+ "Ch1_NotFound: not found"
+ "", "", "", "", "", "", "", ""
+ };
+
+ static const char ch2StatusBits[16][64] = {
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", ""
+ };
+
+ static const char ch3StatusBits[16][64] = {
+ "Ch3_Address: unknown address",
+ "Ch3_TimeOut: timeout error",
+ "Ch3_NoData: no more data"
+ "", "", "", "", "", "", "", "", "", "", "", "", ""
+ };
+
+ static const char *chStatusBits[4] = {
+ &ch0StatusBits[0][0],
+ &ch1StatusBits[0][0],
+ &ch2StatusBits[0][0],
+ &ch3StatusBits[0][0]
+ };
+
+ static char buffer[2048] = "";
+ unsigned int i;
+ uint8_t channel = (statusbits & 0x700000000LL) >> 32;
+
+ if (channel >= 4) {
+ snprintf(buffer, 2048, "INVALID ChannelId %d", channel);
+ return buffer;
+ }
+
+ snprintf(buffer, 2048,
+ "CommonStatusBits: 0x%04x, Channel#%d StatusBits: 0x%04x\n",
+ (uint16_t)(statusbits & 0x0000ffffLL),
+ channel,
+ (uint16_t)((statusbits & 0xffff0000LL) >> 16));
+ for (i = 0; i < 16; i++) {
+ if (((statusbits & 0xffffLL) & (0x01LL << i)) != (i != 0 ? 0 : 1)) {
+ strncat(buffer, " ", 2048);
+ strncat(buffer, commonStatusBits[i], 2048);
+ strncat(buffer, "\n", 2048);
+ }
+ }
+ for (i = 0; i < 16; i++) {
+ if ((((statusbits & 0xffff0000LL) >> 16) & (0x01LL << i)) != 0) {
+ strncat(buffer, " ", 2048);
+ strncat(buffer, chStatusBits[channel] + 64 * i, 2048);
+ strncat(buffer, "\n", 2048);
+ }
+ }
+
+ return buffer;
+}
--- /dev/null
+#ifndef TRBERROR_H
+#define TRBERROR_H
+
+#include <stdint.h>
+
+typedef enum {
+ TRB_NONE = 0,
+ TRB_TX_BUSY = 1,
+ TRB_FIFO_NOT_EMPTY = 2,
+ TRB_FIFO_TIMEOUT = 3,
+ TRB_FIFO_HEADERS = 4,
+ TRB_FIFO_SEQUENZ = 5,
+ TRB_FIFO_INVALID_MODE = 6,
+ TRB_FIFO_BROKEN_PACKAGE = 7,
+ TRB_FIFO_INVALID_CONTENT = 8,
+ TRB_FAILED_WAIT_IS_VALID = 9,
+ TRB_FAILED_WAIT_IS_NOT_VALID = 10,
+ TRB_USER_BUFFER_OVF = 11,
+ TRB_INVALID_CHANNEL = 12,
+ TRB_INVALID_PKG_NUMBER = 13,
+ TRB_TERM_ERRBIT = 14,
+ TRB_INVALID_ADDRESS = 15,
+ TRB_INVALID_LENGTH = 16,
+ TRB_ENDPOINT_NOT_REACHED = 17
+} TRB_ERROR;
+
+extern int trb_errno;
+
+extern uint64_t trb_statusbits;
+
+void trb_error(const char *s);
+
+const char* trb_strerror(int errno);
+
+const char* trb_statusbits_str(uint64_t statusbits);
+
+#endif
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <fs_fpga_int_mem.h>
+#include <trberror.h>
+
+#include "trbnet.h"
+
+/* TRBNet Header word definitions */
+#define SHIFT_HEADER_TYPE 0x0000
+#define MASK_HEADER_TYPE (0x0007 << SHIFT_HEADER_TYPE)
+#define SHIFT_HEADER_REPLY 0x0003
+#define MASK_HEADER_REPLY (0x0001 << SHIFT_HEADER_REPLY)
+#define SHIFT_HEADER_CHANNEL 0x0004
+#define MASK_HEADER_CHANNEL (0x0003 << SHIFT_HEADER_CHANNEL)
+
+/* TRBNet Header types */
+#define HEADER_DAT 0x0000
+#define HEADER_HDR 0x0001
+#define HEADER_EOB 0x0002
+#define HEADER_TRM 0x0003
+#define HEADER_EXT 0x0004
+#define HEADER_ACK 0x0005
+#define HEADER_SIG 0x0006
+#define HEADER_ILL 0x0007
+
+/* Header Word definitions */
+#define SHIFT_SEQNR 4
+#define MASK_SEQNR (0xff << SHIFT_SEQNR)
+#define SHIFT_DATATYPE 0
+#define MASK_DATATYPE (0xf << SHIFT_DATATYPE)
+
+/* FIFO Masks */
+#define SHIFT_FIFO_VALID 24
+#define MASK_FIFO_VALID (0x1 << SHIFT_FIFO_VALID)
+#define SHIFT_FIFO_TYPE 16
+#define MASK_FIFO_TYPE (0x3 << SHIFT_FIFO_TYPE)
+
+/* FIFO Types */
+#define FIFO_TYPE_IS_HEADER 2
+
+/* FIFO STATUS definitions */
+#define MASK_FIFO_FULL (0x01 << 16)
+#define MASK_FIFO_EMPTY (0x01 << 17)
+#define MASK_FIFO_LEVEL 0x03ff
+
+/* Channel Registers */
+
+/* Registers inside Virtex FPGA -> TRBnet endpoint (channel N) */
+#define CHANNEL_N_START_WRITE 0x0100
+#define CHANNEL_N_TARGET_ADDRESS 0x0101
+#define CHANNEL_N_SENDER_ERROR 0x0102
+#define CHANNEL_N_SENDER_DATA 0x0103
+#define CHANNEL_N_SENDER_FIFO_STATUS 0x0104
+#define CHANNEL_N_SENDER_STATUS 0x010f
+#define CHANNEL_N_RECEIVER_DATA 0x0203
+#define CHANNEL_N_RECEIVER_FIFO_STATUS 0x0204
+#define CHANNEL_N_API_STATUS 0x0300
+
+/* Registers inside Virtex FPGA -> TRBnet endpoint (channel 0) */
+#define CHANNEL_0_SENDER_CONTROL 0x0110
+#define CHANNEL_0_TARGET_ADDRESS 0x0111
+#define CHANNEL_0_SENDER_ERROR 0x0112
+#define CHANNEL_0_SENDER_DATA 0x0113
+#define CHANNEL_0_SENDER_FIFO_STATUS 0x0114
+#define CHANNEL_0_SENDER_STATUS 0x011f
+#define CHANNEL_0_RECEIVER_DATA 0x0213
+#define CHANNEL_0_RECEIVER_FIFO_STATUS 0x0214
+#define CHANNEL_0_API_STATUS 0x0310
+
+/* Registers inside Virtex FPGA -> TRBnet endpoint (channel 1) */
+#define CHANNEL_1_SENDER_CONTROL 0x0130
+#define CHANNEL_1_TARGET_ADDRESS 0x0131
+#define CHANNEL_1_SENDER_ERROR 0x0132
+#define CHANNEL_1_SENDER_DATA 0x0133
+#define CHANNEL_1_SENDER_FIFO_STATUS 0x0134
+#define CHANNEL_1_SENDER_STATUS 0x013f
+#define CHANNEL_1_RECEIVER_DATA 0x0233
+#define CHANNEL_1_RECEIVER_FIFO_STATUS 0x0234
+#define CHANNEL_1_API_STATUS 0x0330
+
+/* Registers inside Virtex FPGA -> TRBnet endpoint (channel 2) */
+#define CHANNEL_2_SENDER_CONTROL 0x0150
+#define CHANNEL_2_TARGET_ADDRESS 0x0151
+#define CHANNEL_2_SENDER_ERROR 0x0152
+#define CHANNEL_2_SENDER_DATA 0x0153
+#define CHANNEL_2_SENDER_FIFO_STATUS 0x0154
+#define CHANNEL_2_SENDER_STATUS 0x015f
+#define CHANNEL_2_RECEIVER_DATA 0x0253
+#define CHANNEL_2_RECEIVER_FIFO_STATUS 0x0254
+#define CHANNEL_2_API_STATUS 0x0350
+
+/* Registers inside Virtex FPGA -> TRBnet endpoint (channel 3) */
+#define CHANNEL_3_SENDER_CONTROL 0x0170
+#define CHANNEL_3_TARGET_ADDRESS 0x0171
+#define CHANNEL_3_SENDER_ERROR 0x0172
+#define CHANNEL_3_SENDER_DATA 0x0173
+#define CHANNEL_3_SENDER_FIFO_STATUS 0x0174
+#define CHANNEL_3_SENDER_STATUS 0x017f
+#define CHANNEL_3_RECEIVER_DATA 0x0273
+#define CHANNEL_3_RECEIVER_FIFO_STATUS 0x0274
+#define CHANNEL_3_API_STATUS 0x0370
+
+/* SENDER_STATUS definitions */
+#define MASK_TX_RUNNING 0x00000001
+
+/* Commands supported for packages */
+#define CMD_REGISTER_READ 0x08
+#define CMD_REGISTER_READ_MEM 0x0a
+#define CMD_REGISTER_WRITE 0x09
+#define CMD_REGISTER_WRITE_MEM 0x0b
+#define CMD_NETADMINISTRATION 0x0f
+
+/* Network administration commands */
+#define NET_READUNIQUEID 0x5e1d
+#define NET_SETADDRESS 0x5ead
+#define NET_ACKADDRESS 0xacad
+#define SHORT_TRANSFER 0x0100
+
+/* Other */
+#define MAX_TIME_OUT 500
+#define DATA_BUFFER_SIZE 8192
+
+
+/* ---------------------------------------------------------------------- */
+
+unsigned int trb_debug = 0;
+unsigned int trb_lazy = 0;
+unsigned int trb_dma = 0;
+
+/* Declaration of a TRB-Package */
+
+typedef struct {
+ uint16_t H0;
+ uint16_t F0;
+ uint16_t F1;
+ uint16_t F2;
+ uint16_t F3;
+} TRB_Package;
+
+/* Status-Bit definitions */
+
+typedef enum {
+ Status_C_EndReached = 0, /* endpoint reached */
+ Status_C_Coll = 1, /* collision detected, */
+ Status_C_WordMiss = 2, /* word missing, */
+ Status_C_Checksum = 3, /* checksum error, */
+ Status_C_DontKnow = 4, /* dont understand, */
+ Status_C_BufferMatch = 5 /* buffer mismatch */
+} Status_Common;
+
+typedef enum {
+ Status_Ch0_TrigCtr = 0, /* trigger counter mismatch */
+ Status_Ch0_BufferHalfFull = 4, /* buffers half full */
+ Status_Ch0_BuffersFull = 5 /* buffers almost full */
+} Status_CH0;
+
+typedef enum {
+ Status_Ch1_TrigNum = 0, /* trigger number mismatch */
+ Status_Ch1_TrigCode = 1, /* trigger code / random mismatch */
+ Status_Ch1_Length = 2, /* wrong length */
+ Status_Ch1_NoAnswer = 3, /* answer missing */
+ Status_Ch1_NotFound = 8 /* not found */
+} Status_CH1;
+
+typedef enum {
+ Status_Ch2_NONE = 0
+} Status_CH2;
+
+typedef enum {
+ Status_Ch3_Address = 0, /* unknown address */
+ Status_Ch3_TimeOut = 4, /* timeout */
+ Status_Ch3_NoData = 5 /* nomoredata */
+} Status_CH3;
+
+/* ------ Internal Functions -------------------------------------------- */
+
+static void TRB_Package_dump(const TRB_Package* pkg)
+{
+ switch ((pkg->H0 & MASK_HEADER_TYPE) >> SHIFT_HEADER_TYPE) {
+ case HEADER_DAT:
+ fprintf(stderr, "H0: 0x%04x --> DATA channel: %01d reply: %01d\n",
+ pkg->H0,
+ (pkg->H0 & MASK_HEADER_CHANNEL) >> SHIFT_HEADER_CHANNEL,
+ (pkg->H0 & MASK_HEADER_REPLY) >> SHIFT_HEADER_REPLY);
+ fprintf(stderr, "F0: 0x%04x --> data0\n", pkg->F0);
+ fprintf(stderr, "F1: 0x%04x --> data1\n", pkg->F1);
+ fprintf(stderr, "F2: 0x%04x --> data2\n", pkg->F2);
+ fprintf(stderr, "F3: 0x%04x --> data3\n", pkg->F3);
+ break;
+
+ case HEADER_HDR:
+ fprintf(stderr, "H0: 0x%04x --> HEADER channel: %01d reply: %01d\n",
+ pkg->H0,
+ (pkg->H0 & MASK_HEADER_CHANNEL) >> SHIFT_HEADER_CHANNEL,
+ (pkg->H0 & MASK_HEADER_REPLY) >> SHIFT_HEADER_REPLY);
+ fprintf(stderr, "F0: 0x%04x --> source address\n", pkg->F0);
+ fprintf(stderr, "F1: 0x%04x --> target address\n", pkg->F1);
+ fprintf(stderr, "F2: 0x%04x --> reserved\n", pkg->F2);
+ fprintf(stderr, "F3: 0x%04x --> sequence: 0x%02x datatype: 0x%01x\n",
+ pkg->F3,
+ (pkg->F3 & MASK_SEQNR) >> SHIFT_SEQNR,
+ (pkg->F3 & MASK_DATATYPE) >> SHIFT_DATATYPE);
+ break;
+
+ case HEADER_EOB:
+ fprintf(stderr, "H0: 0x%04x --> EOB channel: %01d reply: %01d\n",
+ pkg->H0,
+ (pkg->H0 & MASK_HEADER_CHANNEL) >> SHIFT_HEADER_CHANNEL,
+ (pkg->H0 & MASK_HEADER_REPLY) >> SHIFT_HEADER_REPLY);
+ fprintf(stderr, "F0: 0x%04x --> checksum\n", pkg->F0);
+ fprintf(stderr, "F1: 0x%04x --> reseved\n", pkg->F1);
+ fprintf(stderr, "F2: 0x%04x --> data count\n", pkg->F2);
+ fprintf(stderr, "F3: 0x%04x --> buffer number\n", pkg->F3);
+ break;
+
+ case HEADER_TRM:
+ fprintf(stderr, "H0: 0x%04x --> TERM channel: %01d reply: %01d\n",
+ pkg->H0,
+ (pkg->H0 & MASK_HEADER_CHANNEL) >> SHIFT_HEADER_CHANNEL,
+ (pkg->H0 & MASK_HEADER_REPLY) >> SHIFT_HEADER_REPLY);
+ fprintf(stderr, "F0: 0x%04x --> checksum\n", pkg->F0);
+ fprintf(stderr, "F1: 0x%04x --> statusbits channel\n", pkg->F1);
+ fprintf(stderr, "F2: 0x%04x --> statusbits common\n", pkg->F2);
+ fprintf(stderr, "F3: 0x%04x --> sequence: 0x%02x datatype: 0x%01x\n",
+ pkg->F3,
+ (pkg->F3 & MASK_SEQNR) >> SHIFT_SEQNR,
+ (pkg->F3 & MASK_DATATYPE) >> SHIFT_DATATYPE);
+ break;
+
+ case HEADER_EXT:
+ fprintf(stderr, "H0: 0x%04x --> EXT channel: %01d reply: %01d\n",
+ pkg->H0,
+ (pkg->H0 & MASK_HEADER_CHANNEL) >> SHIFT_HEADER_CHANNEL,
+ (pkg->H0 & MASK_HEADER_REPLY) >> SHIFT_HEADER_REPLY);
+ fprintf(stderr, "F0: 0x%04x --> reserved\n", pkg->F0);
+ fprintf(stderr, "F1: 0x%04x --> reserved\n", pkg->F1);
+ fprintf(stderr, "F2: 0x%04x --> reserved\n", pkg->F2);
+ fprintf(stderr, "F2: 0x%04x --> reserved\n", pkg->F3);
+ break;
+
+ case HEADER_ACK:
+ fprintf(stderr, "H0: 0x%04x --> ACK channel: %01d reply: %01d\n",
+ pkg->H0,
+ (pkg->H0 & MASK_HEADER_CHANNEL) >> SHIFT_HEADER_CHANNEL,
+ (pkg->H0 & MASK_HEADER_REPLY) >> SHIFT_HEADER_REPLY);
+ fprintf(stderr, "F0: 0x%04x --> reserved\n", pkg->F0);
+ fprintf(stderr, "F1: 0x%04x --> lenght of buffer\n", pkg->F1);
+ fprintf(stderr, "F2: 0x%04x --> reserved\n", pkg->F2);
+ fprintf(stderr, "F2: 0x%04x --> buffer number\n", pkg->F3);
+ break;
+
+ case HEADER_SIG:
+ fprintf(stderr, "H0: 0x%04x --> SIGNAL channel: %01d reply: %01d\n",
+ pkg->H0,
+ (pkg->H0 & MASK_HEADER_CHANNEL) >> SHIFT_HEADER_CHANNEL,
+ (pkg->H0 & MASK_HEADER_REPLY) >> SHIFT_HEADER_REPLY);
+ fprintf(stderr, "F0: 0x%04x --> reserved\n", pkg->F0);
+ fprintf(stderr, "F1: 0x%04x --> reserved\n", pkg->F1);
+ fprintf(stderr, "F2: 0x%04x --> reserved\n", pkg->F2);
+ fprintf(stderr, "F2: 0x%04x --> reserved\n", pkg->F3);
+ break;
+
+ case HEADER_ILL:
+ fprintf(stderr, "H0: 0x%04x --> ILLEGAL channel: %01d reply: %01d\n",
+ pkg->H0,
+ (pkg->H0 & MASK_HEADER_CHANNEL) >> SHIFT_HEADER_CHANNEL,
+ (pkg->H0 & MASK_HEADER_REPLY) >> SHIFT_HEADER_REPLY);
+ fprintf(stderr, "F0: 0x%04x --> ignore\n", pkg->F0);
+ fprintf(stderr, "F1: 0x%04x --> ignore\n", pkg->F1);
+ fprintf(stderr, "F2: 0x%04x --> ignore\n", pkg->F2);
+ fprintf(stderr, "F2: 0x%04x --> ignore\n", pkg->F3);
+ break;
+
+ default:
+ fprintf(stderr, "INVALID\n");
+ }
+}
+
+static int trb_wait_tx_not_busy(uint8_t channel)
+{
+ uint32_t tmp = 0;
+ unsigned int timeout = 0;
+
+ if (channel >= 4) {
+ trb_errno = TRB_INVALID_CHANNEL;
+ return -1;
+ }
+
+ while (timeout < MAX_TIME_OUT) {
+ read32_from_FPGA(CHANNEL_N_SENDER_STATUS | ((channel * 2 + 1) << 4), &tmp);
+ if ((tmp & MASK_TX_RUNNING) == 0) {
+ return 0;
+ }
+ timeout++;
+ }
+
+ /* timeout occurred */
+ trb_errno = TRB_TX_BUSY;
+ return -1;
+}
+
+static int trb_init_transfer(uint8_t channel)
+{
+ uint32_t tmp = 0;
+
+ if (channel >= 4) {
+ trb_errno = TRB_INVALID_CHANNEL;
+ return -1;
+ }
+
+ /* Check for TX not Busy, wait MAX_TIMEOUT */
+ if (trb_wait_tx_not_busy(3) == -1) {
+ return -1;
+ }
+
+ /* Check receiver FIFO empty*/
+ read32_from_FPGA(CHANNEL_N_RECEIVER_FIFO_STATUS | ((channel * 2 + 1) << 4),
+ &tmp);
+ if ((tmp & MASK_FIFO_EMPTY) == 0) {
+ trb_errno = TRB_FIFO_NOT_EMPTY;
+ /* clear fifo ???*/
+ return -1;
+ }
+
+ /* No Errors */
+ return 0;
+}
+
+enum FIFO_READ_MODE {
+ FIFO_MODE_NONE,
+ FIFO_MODE_REG_READ,
+ FIFO_MODE_REG_READ_MEM,
+ FIFO_MODE_REG_WRITE,
+ FIFO_MODE_IPU_DATA,
+ FIFO_MODE_UID,
+ FIFO_MODE_SET_ADDRESS
+};
+
+static int trb_fifo_read(uint8_t channel,
+ int mode,
+ uint32_t data[],
+ unsigned int size)
+{
+ static uint32_t dataBuffer[DATA_BUFFER_SIZE];
+ uint32_t *tmp = dataBuffer;
+ int dma_size;
+
+ TRB_Package package;
+ int headerType = 0;
+ uint32_t fifoBuffer = 0;
+ unsigned int counter = 0;
+ unsigned int dataCtr = 0;
+ int packageCtr = -1;
+ unsigned int endPointCtr = 0;
+
+ unsigned int timeout = 0;
+
+ /* Determin FIFO-Address */
+ if (channel >= 4) {
+ trb_errno = TRB_INVALID_CHANNEL;
+ return -1;
+ }
+ fifoBuffer = CHANNEL_N_RECEIVER_DATA | ((channel * 2 + 1) << 4);
+
+ /* Check for FIFO Ready */
+ timeout = 0;
+
+ if (trb_dma == 1) {
+ /* DMA-Readout */
+ do {
+ dma_size =
+ read32_from_FPGA_dma(fifoBuffer, tmp, DATA_BUFFER_SIZE);
+ } while ((dma_size == 0) && (++timeout < MAX_TIME_OUT));
+ } else {
+ /* Standard */
+ do {
+ read32_from_FPGA(fifoBuffer, tmp);
+ } while (((*tmp & MASK_FIFO_VALID) == 0) && (++timeout < MAX_TIME_OUT));
+ }
+
+ if (timeout >= MAX_TIME_OUT) {
+ trb_errno = TRB_FIFO_TIMEOUT;
+ return -1;
+ }
+
+ /* Read FIFO-Buffer, copy to User-Buffer */
+ while ((*tmp & MASK_FIFO_VALID) != 0) {
+ if (((*tmp & MASK_FIFO_TYPE) >> SHIFT_FIFO_TYPE)
+ == FIFO_TYPE_IS_HEADER) {
+ if ((counter % 5) == 0) {
+ /* New Package begins */
+ if (trb_debug > 0) {
+ fprintf(stderr,
+ "-------------------------------------------------\n");
+ }
+ packageCtr++;
+ counter = 0;
+ } else {
+ /* Error: invalid buffer content, flush FIFO-BUFFER and exit */
+ trb_fifo_flush(channel);
+ trb_errno = TRB_FIFO_BROKEN_PACKAGE;
+ return -1;
+ }
+ } else {
+ /* Data Word */
+ if ((trb_lazy == 0) &&
+ (((*tmp & MASK_FIFO_TYPE) >> SHIFT_FIFO_TYPE) !=
+ (counter - 1) % 2)) {
+ /* Error: invalid sequence (not 0, 1, .), flush FIFO-BUFFER and exit */
+ trb_fifo_flush(channel);
+ trb_errno = TRB_FIFO_BROKEN_PACKAGE;
+ return -1;
+ }
+ }
+
+ switch (counter) {
+ case 0:
+ package.H0 = *tmp;
+ break;
+ case 1:
+ package.F0 = *tmp;
+ break;
+ case 2:
+ package.F1 = *tmp;
+ break;
+ case 3:
+ package.F2 = *tmp;
+ break;
+ case 4:
+ package.F3 = *tmp;
+ break;
+ default:
+ abort();
+ }
+
+ /* DEBUG INFO */
+ if (trb_debug > 1) {
+ fprintf(stderr, "FIFO_%03d: 0x%08x\n",
+ packageCtr * 5 + counter, *tmp);
+ }
+
+ counter++;
+
+ if (counter % 5 == 0) {
+ /* End of Package, validate package and retrieve data */
+
+ /* Determine H0 HeaderType */
+ headerType = (package.H0 & MASK_HEADER_TYPE) >> SHIFT_HEADER_TYPE;
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ TRB_Package_dump(&package);
+ fprintf(stderr, "-------------------------------------------------\n");
+ }
+
+ /* First package (TRB-Header), headerType must be HDR or TRM */
+ if (trb_lazy == 0) {
+ if (packageCtr == 0) {
+ if (!((headerType == HEADER_HDR) | (headerType == HEADER_TRM))) {
+ trb_fifo_flush(channel);
+ trb_errno = TRB_FIFO_INVALID_CONTENT;
+ return -1;
+ }
+ }
+
+ /* Check Header H0 */
+ if (((package.H0 & MASK_HEADER_REPLY) >> SHIFT_HEADER_REPLY
+ != 0x01) ||
+ ((package.H0 & MASK_HEADER_CHANNEL) >> SHIFT_HEADER_CHANNEL
+ != channel)) {
+
+ /* Error Package inconsistencies, flush FIFO-BUFFER and exit */
+ trb_fifo_flush(channel);
+ trb_errno = TRB_FIFO_HEADERS;
+ return -1;
+ }
+ }
+
+ /* Get Data F0 - F3 and store it in User-Data-Buffer if requested */
+ if (headerType != HEADER_TRM) {
+ switch (mode) {
+
+ case FIFO_MODE_NONE:
+ break;
+
+ case FIFO_MODE_REG_READ:
+
+ switch (headerType) {
+ case HEADER_HDR:
+ if ((packageCtr - endPointCtr * 2) != 0) {
+ trb_fifo_flush(channel);
+ trb_errno = TRB_FIFO_INVALID_CONTENT;
+ return -1;
+ }
+ if (dataCtr < size) {
+ data[dataCtr++] = (uint32_t)package.F0;
+ } else {
+ trb_fifo_flush(channel);
+ trb_errno = TRB_USER_BUFFER_OVF;
+ return -1;
+ }
+ break;
+
+ case HEADER_DAT:
+ if ((packageCtr - endPointCtr * 2) != 1) {
+ trb_fifo_flush(channel);
+ trb_errno = TRB_FIFO_INVALID_CONTENT;
+ }
+ if (dataCtr < size) {
+ data[dataCtr++] = (((uint32_t)package.F1 << 16) |
+ ((uint32_t)package.F2));
+ endPointCtr++;
+ } else {
+ trb_fifo_flush(channel);
+ trb_errno = TRB_USER_BUFFER_OVF;
+ return -1;
+ }
+ break;
+
+ default:
+ trb_fifo_flush(channel);
+ trb_errno = TRB_FIFO_INVALID_CONTENT;
+ return -1;
+ }
+
+ break;
+
+ case FIFO_MODE_REG_READ_MEM:
+ if (packageCtr > 0) {
+ if (headerType != HEADER_DAT) {
+ trb_fifo_flush(channel);
+ trb_errno = TRB_FIFO_INVALID_CONTENT;
+ return -1;
+ }
+ if (dataCtr < size) {
+ data[dataCtr++] = (((uint32_t)package.F1 << 16) |
+ ((uint32_t)package.F2));
+ } else {
+ trb_fifo_flush(channel);
+ trb_errno = TRB_USER_BUFFER_OVF;
+ return -1;
+ }
+ }
+ break;
+
+ case FIFO_MODE_REG_WRITE:
+ if (packageCtr > 1) {
+ trb_fifo_flush(channel);
+ trb_errno = TRB_INVALID_PKG_NUMBER;
+ return -1;
+ }
+ break;
+
+ case FIFO_MODE_IPU_DATA:
+ if (packageCtr > 0) {
+ if (headerType != HEADER_DAT) {
+ trb_fifo_flush(channel);
+ trb_errno = TRB_FIFO_INVALID_CONTENT;
+ return -1;
+ }
+ if ((dataCtr + 1) < size) {
+ data[dataCtr++] = (((uint32_t)package.F0 << 16) |
+ ((uint32_t)package.F1));
+ data[dataCtr++] = (((uint32_t)package.F2 << 16) |
+ ((uint32_t)package.F3));
+ } else {
+ trb_fifo_flush(channel);
+ trb_errno = TRB_USER_BUFFER_OVF;
+ return -1;
+ }
+ }
+ break;
+
+ case FIFO_MODE_UID:
+ {
+ static uint32_t uidLow;
+ static uint32_t uidHigh;
+
+ switch (headerType) {
+ case HEADER_HDR:
+ if ((packageCtr - endPointCtr * 3) != 0) {
+ trb_fifo_flush(channel);
+ trb_errno = TRB_FIFO_INVALID_CONTENT;
+ return -1;
+ }
+ break;
+
+ case HEADER_DAT:
+ if ((packageCtr - endPointCtr * 3) == 1) {
+ uidHigh = (((uint32_t)package.F0 << 0) |
+ ((uint32_t)package.F1 << 16));
+ uidLow = (((uint32_t)package.F2 << 0) |
+ ((uint32_t)package.F3 << 16));
+ break;
+ }
+
+ if ((packageCtr - endPointCtr * 3) == 2) {
+ if ((dataCtr + 3) < size) {
+ /* store uid and endPoint in userDataBuffer */
+ data[dataCtr++] = uidLow;
+ data[dataCtr++] = uidHigh;
+ data[dataCtr++] = (uint32_t)package.F0;
+ endPointCtr++;
+ } else {
+ trb_fifo_flush(channel);
+ trb_errno = TRB_USER_BUFFER_OVF;
+ return -1;
+ }
+ break;
+ }
+
+ default:
+ trb_fifo_flush(channel);
+ trb_errno = TRB_FIFO_INVALID_CONTENT;
+ return -1;
+ }
+ }
+ break;
+
+ case FIFO_MODE_SET_ADDRESS:
+ if ((packageCtr == 1) && (headerType == HEADER_DAT)) {
+ if (package.F0 != NET_ACKADDRESS) {
+ trb_fifo_flush(channel);
+ return -1;
+ }
+ }
+
+ if (packageCtr > 1) {
+ trb_fifo_flush(channel);
+ trb_errno = TRB_INVALID_PKG_NUMBER;
+ return -1;
+ }
+
+ dataCtr++;
+ break;
+
+ default:
+ trb_fifo_flush(channel);
+ trb_errno = TRB_FIFO_INVALID_MODE;
+ return -1;
+ }
+ }
+ }
+
+ /* Read Next Word */
+ if (trb_dma == 1) {
+ tmp++;
+ } else {
+ read32_from_FPGA(fifoBuffer, tmp);
+ }
+ }
+
+ if (trb_lazy == 0) {
+ /* Check whether last package is complete */
+ if ((packageCtr >= 0) && (counter != 5)) {
+ trb_errno = TRB_FIFO_BROKEN_PACKAGE;
+ return -1;
+ }
+
+ /* Check whether last package is a TERMINATION Package */
+ if (headerType != HEADER_TRM) {
+ trb_errno = TRB_FIFO_INVALID_CONTENT;
+ return -1;
+ }
+
+ /* Check StatusBits of TerminationPackage */
+ if ((package.F2 != 0x0001) ||
+ (package.F1 != 0x0000)) {
+
+ trb_statusbits =
+ ((uint64_t)channel << 32) |
+ ((uint64_t)package.F1 << 16) |
+ ((uint64_t)package.F2 << 0);
+ trb_errno = TRB_TERM_ERRBIT;
+ return -1;
+ }
+ }
+
+ return dataCtr;
+}
+
+/* ----- Global Functions ----------------------------------------------- */
+
+int trb_fifo_flush(uint8_t channel)
+{
+ uint32_t tmp;
+ uint32_t fifoAddress;
+ unsigned int counter = 0;
+
+ if (channel >= 4) {
+ trb_errno = TRB_INVALID_CHANNEL;
+ return -1;
+ }
+
+ /* DEBUG INFO */
+ if (trb_debug > 1) {
+ fprintf(stderr, "Flushing FIFO of channel# %d\n", channel);
+ }
+
+ fifoAddress = CHANNEL_N_RECEIVER_DATA | ((channel * 2 + 1) << 4);
+ do {
+ read32_from_FPGA(fifoAddress, &tmp);
+ /* DEBUG INFO */
+ if ((trb_debug > 1) && ((tmp & MASK_FIFO_VALID) != 0)) {
+ fprintf(stderr, "FIFO_%03d: 0x%08x\n", counter, tmp);
+ counter++;
+ }
+ } while ((tmp & MASK_FIFO_VALID) != 0);
+
+ return 0;
+}
+
+int trb_register_read(uint16_t trb_address,
+ uint16_t reg_address,
+ uint32_t *data,
+ unsigned int size)
+{
+ int status = 0;
+
+ /* Init transfer */
+ if (trb_init_transfer(3) == -1) {
+ return -1;
+ }
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ fprintf(stderr, "Init_Transfer done.\n");
+ }
+
+ /* Build up package and start transfer */
+ write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address);
+ write32_to_FPGA(CHANNEL_3_SENDER_ERROR, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, reg_address);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_READ);
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ fprintf(stderr, "CMD_REGISTER_READ started.\n");
+ }
+
+ status = trb_fifo_read(3, FIFO_MODE_REG_READ, data, size);
+
+ if ((status > 0) && (status % 2 != 0)) {
+ trb_errno = TRB_INVALID_PKG_NUMBER;
+ return -1;
+ }
+
+ return status;
+}
+
+int trb_register_read_mem(uint16_t trb_address,
+ uint16_t reg_address,
+ uint8_t option,
+ uint32_t *data,
+ uint16_t size)
+{
+ uint16_t length;
+
+ /* Do not allow broadcasts within this function */
+ if (trb_address >= 0xff00) {
+ trb_errno = TRB_INVALID_ADDRESS;
+ return -1;
+ }
+
+ /* check size and set reading-mode */
+ length = size & 0x7fff;
+ if ((size == 0) || (size != length)) {
+ trb_errno = TRB_INVALID_LENGTH;
+ return -1;
+ }
+ length = length | (option == 0 ? 0x8000 : 0x0000);
+
+ /* Init transfer */
+ if (trb_init_transfer(3) == -1) {
+ return -1;
+ }
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ fprintf(stderr, "Init_Tranfer done.\n");
+ }
+
+ /* Build up package and start transfer */
+ write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address);
+ write32_to_FPGA(CHANNEL_3_SENDER_ERROR, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, reg_address);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, length);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_READ_MEM);
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ fprintf(stderr, "CMD_REGISTER_READ_MEM started.\n");
+ }
+
+ return trb_fifo_read(3, FIFO_MODE_REG_READ_MEM, data, size);
+}
+
+int trb_register_write(uint16_t trb_address,
+ uint16_t reg_address,
+ uint32_t value)
+{
+ /* Init transfer */
+ if (trb_init_transfer(3) == -1) {
+ return -1;
+ }
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ fprintf(stderr, "Init_Transfer done.\n");
+ }
+
+ /* Build up package */
+ write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address);
+ write32_to_FPGA(CHANNEL_3_SENDER_ERROR, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, reg_address);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, (value >> 16) & 0xffff);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, value & 0xffff);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_WRITE);
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ fprintf(stderr, "CMD_REGISTER_WRITE started.\n");
+ }
+
+ return trb_fifo_read(3, FIFO_MODE_REG_WRITE, NULL, 0);
+}
+
+int trb_register_write_mem(uint16_t trb_address,
+ uint16_t reg_address,
+ uint8_t option,
+ const uint32_t *data,
+ uint16_t size)
+{
+ uint16_t config;
+ uint16_t i;
+
+ /* check size and set write-mode */
+ config = size & 0x7fff;
+ if ((size == 0) || (size != config)) {
+ trb_errno = TRB_INVALID_LENGTH;
+ return -1;
+ }
+ config = config | (option == 0 ? 0x8000 : 0x0000);
+
+ /* Init transfer */
+ if (trb_init_transfer(3) == -1) {
+ return -1;
+ }
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ fprintf(stderr, "Init_Transfer done.\n");
+ }
+
+ /* Build up package */
+ write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address);
+ write32_to_FPGA(CHANNEL_3_SENDER_ERROR, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, reg_address);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, config);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000);
+ for (i = 0; i < size; i++) {
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, (data[i] >> 16) & 0xffff);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, data[i] & 0xffff);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000);
+ }
+ write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_WRITE_MEM);
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ fprintf(stderr, "CMD_REGISTER_WRITE_MEM started.\n");
+ }
+
+ return trb_fifo_read(3, FIFO_MODE_REG_WRITE, NULL, 0);
+}
+
+int trb_read_uid(uint16_t trb_address,
+ uint32_t* uidBuffer,
+ unsigned int size)
+{
+ int status;
+
+ /* Init transfer */
+ if (trb_init_transfer(3) == -1) {
+ return -1;
+ }
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ fprintf(stderr, "Init_Transfer done.\n");
+ }
+
+ /* Build up package and start transfer */
+ write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address);
+ write32_to_FPGA(CHANNEL_3_SENDER_ERROR, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, NET_READUNIQUEID);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_NETADMINISTRATION);
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ fprintf(stderr, "CMD_READ_UNIQUE_ID started.\n");
+ }
+
+ status = trb_fifo_read(3, FIFO_MODE_UID, (uint32_t*)uidBuffer, size);
+
+ if ((status > 0) && (status % 3 != 0)) {
+ trb_errno = TRB_INVALID_PKG_NUMBER;
+ return -1;
+ }
+
+ return status;
+}
+
+
+int trb_set_address(uint64_t uid,
+ uint8_t endpoint,
+ uint16_t trb_address)
+{
+ int status;
+
+ /* check for valid TRBnet address to be assigned */
+ if (trb_address >= 0xff00 ) {
+ trb_errno = TRB_INVALID_ADDRESS;
+ return -1;
+ }
+
+ /* Init transfer */
+ if (trb_init_transfer(3) == -1) {
+ return -1;
+ }
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ fprintf(stderr, "Init_Transfer done.\n");
+ }
+
+ /* Build up package and start transfer */
+ write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, 0xffff); /* always broadcast */
+ write32_to_FPGA(CHANNEL_3_SENDER_ERROR, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, NET_SETADDRESS);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, (uint16_t)(uid));
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, (uint16_t)(uid >> 16));
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, (uint16_t)(uid >> 32));
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, (uint16_t)(uid >> 48));
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, endpoint);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, trb_address);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_NETADMINISTRATION);
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ fprintf(stderr, "CMD_SETADDRESS started.\n");
+ }
+
+ status = trb_fifo_read(3, FIFO_MODE_SET_ADDRESS, NULL, 0);
+ if (status == -1) return -1;
+
+ if (status != 2) {
+ trb_errno = TRB_ENDPOINT_NOT_REACHED;
+ return -1;
+ }
+
+
+ return 0;
+}
+
+int trb_ipu_data_read(uint8_t type,
+ uint8_t trg_info,
+ uint8_t trg_random,
+ uint16_t trg_number,
+ uint32_t *data,
+ unsigned int size)
+{
+ int status;
+
+ if (data == NULL) return -1;
+
+ /* Init transfer IPU Channel */
+ if (trb_init_transfer(1) == -1) {
+ return -1;
+ }
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ fprintf(stderr, "Init_Transfer done.\n");
+ }
+
+ /* Prepare IPU channel */
+ write32_to_FPGA(CHANNEL_1_SENDER_ERROR, (((uint32_t)trg_info << 24) |
+ ((uint32_t)trg_random << 16) |
+ ((uint32_t)trg_number)
+ ));
+ write32_to_FPGA(CHANNEL_1_SENDER_CONTROL,
+ SHORT_TRANSFER | (uint32_t)(type & 0x0f));
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ fprintf(stderr, "CMD_IPU_DATA_READ started.\n");
+ }
+
+ status = trb_fifo_read(1, FIFO_MODE_IPU_DATA, data, size);
+
+ return status;
+}
+
+
+int trb_send_trigger(uint8_t trg_input,
+ uint8_t type,
+ uint8_t trg_info,
+ uint8_t trg_random,
+ uint16_t trg_number)
+{
+ int status;
+
+ /* Init transfer slowcontrol */
+ if (trb_init_transfer(3) == -1) {
+ return -1;
+ }
+
+ /* Init transfer trigger */
+ if (trb_init_transfer(0) == -1) {
+ return -1;
+ }
+
+ /* DEBUG INFO */
+ if (trb_debug > 0) {
+ fprintf(stderr, "Init_Transfer done.\n");
+ }
+
+ /* Prepare trigger channel */
+ write32_to_FPGA(CHANNEL_0_SENDER_ERROR, (((uint32_t)trg_info << 24) |
+ ((uint32_t)trg_random << 16) |
+ ((uint32_t)trg_number)
+ ));
+
+ /* Prepare slowcontrol channel */
+ write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, 0x0000ffff);/* all boards */
+ write32_to_FPGA(CHANNEL_3_SENDER_ERROR, 0x00000000);
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, (0x8080 | (uint32_t)trg_input));
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x0000dead); /*fake data is */
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x0000beef); /* discarded at ADCM */
+ write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000);
+
+ /* Send both fake trigger and LVL1 information */
+ write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_WRITE);
+ write32_to_FPGA(CHANNEL_0_SENDER_CONTROL,
+ SHORT_TRANSFER | (uint32_t)(type & 0x0f));
+
+ if (trb_debug > 0) {
+ fprintf(stderr, "trigger started.\n");
+ }
+
+ /* Check for replay packets (slowcontrol) */
+ status = trb_fifo_read(3, FIFO_MODE_NONE, NULL, 0);
+ if (status == -1) {
+ trb_fifo_flush(0);
+ return -1;
+ }
+
+ /* Check for replay packets (trigger) */
+ status = trb_fifo_read(0, FIFO_MODE_NONE, NULL, 0);
+ if (status == -1) return -1;
+
+ return 0;
+}
+
--- /dev/null
+#ifndef TRBNET_H
+#define TRBNET_H
+
+#include <stdint.h>
+#include <port.h>
+
+extern unsigned int trb_debug;
+extern unsigned int trb_lazy;
+extern unsigned int trb_dma;
+
+/* ---------------------------------------------------------------------- */
+
+int trb_fifo_flush(uint8_t channel);
+
+int trb_register_read(uint16_t trb_address,
+ uint16_t reg_address,
+ uint32_t* data,
+ unsigned int size);
+
+int trb_register_read_mem(uint16_t trb_address,
+ uint16_t reg_address,
+ uint8_t option,
+ uint32_t* data,
+ uint16_t size);
+
+int trb_register_write(uint16_t trb_address,
+ uint16_t reg_address,
+ uint32_t value);
+
+int trb_register_write_mem(uint16_t trb_address,
+ uint16_t reg_address,
+ uint8_t option,
+ const uint32_t* data,
+ uint16_t size);
+
+int trb_read_uid(uint16_t trb_address,
+ uint32_t* uidBuffer,
+ unsigned int size);
+
+int trb_set_address(uint64_t uid,
+ uint8_t endpoint,
+ uint16_t trb_address);
+
+
+int trb_ipu_data_read(uint8_t type,
+ uint8_t trg_info,
+ uint8_t trg_random,
+ uint16_t trg_number,
+ uint32_t* data,
+ unsigned int size);
+
+
+int trb_send_trigger(uint8_t input,
+ uint8_t type,
+ uint8_t info,
+ uint8_t random,
+ uint16_t number);
+
+/* ---------------------------------------------------------------------- */
+
+/************************************************************************/
+/* In case of an error trb_errno is set, see trberror.h for details. */
+/************************************************************************/
+
+
+/************************************************************************/
+/* int trb_register_read(uint16_t trb_address,
+ uint16_t reg_address,
+ uint32_t* data,
+ unsigned int size);
+
+ trb_address: TRB-Address of TRB-Endpoint
+ reg_address: Register-Address to be read
+ data: Pointer to uint32_t Data-Buffer
+ size: Size of the Data-Buffer in units of 32bit-words
+
+ ReturnValue: == -1 on error
+ >= 0 number of 32bit-words which were stored in Data-Buffer
+
+ TRB-Channel used: slow control (3)
+
+ reads the register reg_address of a TRB-Endpoint with address
+ trb_address. The received data is stored in the Data-Buffer data.
+ The format of the Data-Buffer is:
+ first word: TRB-Address of sender
+ second word: register value
+
+ --> Data-Buffer-Size size must be at least 2
+
+*/
+
+/* int trb_register_write(uint16_t trb_address,
+ uint16_t reg_address,
+ uint32_t value);
+
+ trb_address: TRB-Address of TRB-Endpoint
+ reg_address: Register-Address to be written
+ value: 32bit-word to write to register
+
+ ReturnValue: == -1 on error
+ >= 0 number of 32bit-words which were stored in Data-Buffer
+
+ TRB-Channel used: slow control (3)
+
+ writes value to the register reg_address of a TRB-Endpoint with address
+ trb_address.
+*/
+
+
+
+
+
+#endif