From: hadaq Date: Sun, 22 May 2011 20:49:22 +0000 (+0000) Subject: pexor dma support added X-Git-Tag: v6.0~157 X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=0ab058469444149c5d96930282873f66e4a731fc;p=trbnettools.git pexor dma support added --- diff --git a/libtrbnet/trbnet.c b/libtrbnet/trbnet.c index e501589..26307c4 100644 --- a/libtrbnet/trbnet.c +++ b/libtrbnet/trbnet.c @@ -1,4 +1,4 @@ -const char trbnet_version[] = "$Revision: 4.3 $"; +const char trbnet_version[] = "$Revision: 4.4 $"; #include #include @@ -9,19 +9,29 @@ const char trbnet_version[] = "$Revision: 4.3 $"; #include #include #include +#include #include +#include +#include #ifdef PEXOR #include #include #define PCIBAR 0 -static int pexorFileHandle = -1; + +#define DATA_BUFFER_SIZE 4096000 /* in 32-Bit words */ +static uint32_t dataBuffer[DATA_BUFFER_SIZE]; +static unsigned int dataBufferSize = 0; + +static struct pexor_trbnet_io pexorDescriptor; +int dma_size = 0; char pexor_deviceName[256] = "/dev/pexor-0"; +int pexorFileHandle = -1; +int pexor_dma = 1; #endif #include - #include "trbnet.h" /* TRBNet Header word definitions */ @@ -133,7 +143,6 @@ char pexor_deviceName[256] = "/dev/pexor-0"; /* Other */ #define MAX_TIMEOUT 5000000 -#define DATA_BUFFER_SIZE 8192 /* ---------------------------------------------------------------------- */ @@ -146,7 +155,6 @@ static int semid = -1; static const key_t sem_key = 0x545242; unsigned int trb_debug = 0; -unsigned int trb_dma = 0; /* Declaration of a TRB-Package */ @@ -166,7 +174,7 @@ typedef struct { #define FIFO_TOGGLE_BIT 0x10000 static uint32_t fifoToggleBit = 0; -static volatile uint32_t* GPIOB_IN_OFFSET = NULL; +static volatile uint32_t* GPIOB_IN_OFFSET = NULL; static volatile uint32_t* GPIOC_IN_OFFSET = NULL; static volatile uint32_t* GPIOC_OUT_OFFSET = NULL; @@ -195,7 +203,7 @@ static inline void clrbitsPC(uint32_t bitmask) *GPIOC_OUT_OFFSET &= ~bitmask; } -static inline void write32_to_FPGA(uint16_t address, uint32_t value) +static inline int write32_to_FPGA(uint16_t address, uint32_t value) { /* writes a 32bit word to a given address on a given device */ @@ -212,9 +220,11 @@ static inline void write32_to_FPGA(uint16_t address, uint32_t value) fifoToggleBit ^= FIFO_TOGGLE_BIT; writePC((value & 0xffff) | fifoToggleBit); + + return 0; } -static inline void read32_from_FPGA(uint16_t address, uint32_t* value) +static inline int read32_from_FPGA(uint16_t address, uint32_t* value) { /* reads a 32bit word from a given address on a given device */ @@ -233,14 +243,8 @@ static inline void read32_from_FPGA(uint16_t address, uint32_t* value) *value |= (readPB() & 0xffff); fifoToggleBit ^= FIFO_TOGGLE_BIT; writePC(fifoToggleBit); -} -static inline int read32_from_FPGA_dma(uint16_t fifo_address, - uint32_t* values, - uint32_t size) -{ - /* Do Not Used */ - return -1; + return 0; } static inline void com_reset_FPGA() @@ -248,7 +252,7 @@ static inline void com_reset_FPGA() setbitsPC(0x30000); clrbitsPC(0x30000); usleep(100); - + /* Reset FifoToggleBit */ fifoToggleBit = 0; } @@ -259,21 +263,23 @@ static inline int write32_to_FPGA(uint32_t address, uint32_t value) { struct pexor_reg_io descriptor; int status = 0; - + if (pexorFileHandle == -1) { + trb_errno = TRB_PEXOR_OPEN; return -1; } - + descriptor.address = address * 4; descriptor.bar = PCIBAR; descriptor.value = value; - + status = ioctl(pexorFileHandle, PEXOR_IOC_WRITE_REGISTER, &descriptor); - if(status) { + if(status == -1) { + trb_errno = TRB_PEXOR_DEVICE_ERROR; return -1; } - - return 0; + + return 0; } static inline int read32_from_FPGA(uint32_t address, uint32_t* value) @@ -282,29 +288,23 @@ static inline int read32_from_FPGA(uint32_t address, uint32_t* value) int status = 0; if (pexorFileHandle == -1) { + trb_errno = TRB_PEXOR_OPEN; return -1; } - + descriptor.address = address * 4; descriptor.bar = PCIBAR; descriptor.value = 0; - + status = ioctl(pexorFileHandle, PEXOR_IOC_READ_REGISTER, &descriptor); - if(status) { + if(status == -1) { + trb_errno = TRB_PEXOR_DEVICE_ERROR; return -1; } *value = descriptor.value; - - return 0; -} - -static inline int read32_from_FPGA_dma(uint32_t fifo_address, - uint32_t* values, - uint32_t size) -{ - /* Do Not Used */ - return -1; + + return 0; } static inline void com_reset_FPGA() @@ -422,7 +422,11 @@ static void fifo_flush(uint8_t channel) uint32_t tmp = 0; uint32_t fifoAddress; unsigned int counter = 0; - + +#ifdef PEXOR + if (pexor_dma != 0) return; +#endif + fifoAddress = CHANNEL_N_RECEIVER_DATA | ((channel * 2 + 1) << 4); do { unsigned int timeout = 0; @@ -432,7 +436,7 @@ static void fifo_flush(uint8_t channel) /* DEBUG INFO */ if ((trb_debug > 1) && ((tmp & MASK_FIFO_VALID) != 0)) { fprintf(stderr, "FLUSH_FIFO_%03d: 0x%08x\n", counter, tmp); - counter++; + counter++; } } while ((tmp & MASK_FIFO_VALID) != 0); } @@ -441,7 +445,7 @@ static void fifo_flush(uint8_t channel) static int trb_wait_tx_not_busy(uint8_t channel) { uint32_t tmp = 0; - + if (channel >= 4) { trb_errno = TRB_INVALID_CHANNEL; return -1; @@ -452,7 +456,7 @@ static int trb_wait_tx_not_busy(uint8_t channel) trb_errno = TRB_TX_BUSY; return -1; } - + return 0; } #endif @@ -465,7 +469,7 @@ static int trb_init_transfer(uint8_t channel) trb_errno = TRB_INVALID_CHANNEL; return -1; } - + /* Check for TX not Busy */ #ifndef PEXOR read32_from_FPGA(CHANNEL_N_SENDER_STATUS | ((channel * 2 + 1) << 4), &tmp); @@ -479,24 +483,24 @@ static int trb_init_transfer(uint8_t channel) trb_errno = TRB_TX_BUSY; return -1; } - + /* Check receiver FIFO empty */ #ifndef PEXOR - read32_from_FPGA(CHANNEL_N_RECEIVER_FIFO_STATUS | ((channel * 2 + 1) << 4), + read32_from_FPGA(CHANNEL_N_RECEIVER_FIFO_STATUS | ((channel * 2 + 1) << 4), &tmp); if ((tmp & MASK_FIFO_EMPTY) == 0) { /* FIFO_TOGGLE_BIT-BUG Workaround */ com_reset_FPGA(); } #endif - read32_from_FPGA(CHANNEL_N_RECEIVER_FIFO_STATUS | ((channel * 2 + 1) << 4), + read32_from_FPGA(CHANNEL_N_RECEIVER_FIFO_STATUS | ((channel * 2 + 1) << 4), &tmp); if ((tmp & MASK_FIFO_EMPTY) == 0) { fifo_flush(channel); trb_errno = TRB_FIFO_NOT_EMPTY; return -1; } - + /* No Errors */ return 0; } @@ -518,54 +522,62 @@ static int trb_fifo_read(uint8_t channel, uint32_t data[], unsigned int dsize) { - static uint32_t dataBuffer[DATA_BUFFER_SIZE]; - uint32_t *tmp = dataBuffer; - int dma_size; +#ifndef PEXOR + static uint32_t dataBuffer = 0; + uint32_t* tmp = &dataBuffer; +#else /* Pexor DMA */ + uint32_t* tmp = dataBuffer; +#endif + + uint32_t fifoBuffer = 0; + unsigned int timeout = 0; TRB_Package package = {0,0,0,0,0}; int headerType = 0; - uint32_t fifoBuffer = 0; + unsigned int counter = 0; unsigned int dataCtr = 0; int packageCtr = -1; int fifoDebugCtr = -1; unsigned int endPointCtr = 0; - + int userBufferOvf = 0; - unsigned int timeout = 0; + uint32_t* lastHeader = NULL; /* used by FIFO_MODE_REG_READ_MEM Mode */ - uint32_t memLen = 0; /* used by FIFO_MODE_REG_READ_MEM + uint32_t memLen = 0; /* used by FIFO_MODE_REG_READ_MEM and FIFO_MODE_IPU_DATA Mode */ - /* Determin FIFO-Address */ - if (channel >= 4) { - trb_errno = TRB_INVALID_CHANNEL; - return -1; - } - fifoBuffer = CHANNEL_N_RECEIVER_DATA | ((channel * 2 + 1) << 4); +#ifdef PEXOR + if (pexor_dma != 0) { + if (dataBufferSize == 0) { + trb_errno = TRB_PEXOR_DMA_ERROR; + return -1; + } + } else { +#endif - /* Check for FIFO Ready */ - timeout = 0; + /* Determin FIFO-Address */ + if (channel >= 4) { + trb_errno = TRB_INVALID_CHANNEL; + return -1; + } + fifoBuffer = CHANNEL_N_RECEIVER_DATA | ((channel * 2 + 1) << 4); - if (trb_dma == 1) { - /* DMA-Readout */ - do { - dma_size = - read32_from_FPGA_dma(fifoBuffer, tmp, DATA_BUFFER_SIZE); - } while ((dma_size == 0) && (++timeout < MAX_TIMEOUT)); - } else { - /* Standard */ + /* Check for FIFO Ready */ + timeout = 0; do { read32_from_FPGA(fifoBuffer, tmp); } while (((*tmp & MASK_FIFO_VALID) == 0) && (++timeout < MAX_TIMEOUT)); - } - if (timeout >= MAX_TIMEOUT) { - fifo_flush(channel); - trb_errno = TRB_FIFO_TIMEOUT; - return -1; + if (timeout >= MAX_TIMEOUT) { + fifo_flush(channel); + trb_errno = TRB_FIFO_TIMEOUT; + return -1; + } +#ifdef PEXOR } +#endif /* Read FIFO-Buffer, copy to User-Buffer */ while ((*tmp & MASK_FIFO_VALID) != 0) { @@ -623,23 +635,23 @@ static int trb_fifo_read(uint8_t channel, 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(); } @@ -666,7 +678,6 @@ static int trb_fifo_read(uint8_t channel, trb_errno = TRB_FIFO_INVALID_HEADER; return -1; } - #ifndef PEXOR /* Check Header H0 */ if (((package.H0 & MASK_HEADER_REPLY) >> SHIFT_HEADER_REPLY @@ -689,12 +700,12 @@ static int trb_fifo_read(uint8_t channel, if (packageCtr > 0) { fifo_flush(channel); trb_errno = TRB_INVALID_PKG_NUMBER; - return -1; + return -1; } if (headerType != HEADER_TRM) { fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_HEADER; - return -1; + return -1; } break; @@ -726,7 +737,7 @@ static int trb_fifo_read(uint8_t channel, data[dataCtr++] = (((uint32_t)package.F1 << 16) | ((uint32_t)package.F2)); #ifdef TRB_DEBUGGER - fprintf(stderr, "0x%08x\n", data[dataCtr - 1]); + fprintf(stderr, "0x%08x\n", data[dataCtr - 1]); #endif endPointCtr++; } else { @@ -744,7 +755,7 @@ static int trb_fifo_read(uint8_t channel, } break; - + case FIFO_MODE_REGTIME_READ: switch (headerType) { case HEADER_HDR: @@ -762,7 +773,7 @@ static int trb_fifo_read(uint8_t channel, userBufferOvf = 1; } break; - + case HEADER_DAT: if ((packageCtr - endPointCtr * 2) != 1) { fifo_flush(channel); @@ -773,26 +784,26 @@ static int trb_fifo_read(uint8_t channel, data[dataCtr++] = (((uint32_t)package.F1 << 16) | ((uint32_t)package.F2)); data[dataCtr++] = (uint32_t)package.F3; - + #ifdef TRB_DEBUGGER - fprintf(stderr, "0x%08x 0x%04x\n", - data[dataCtr - 2], data[dataCtr - 1]); + fprintf(stderr, "0x%08x 0x%04x\n", + data[dataCtr - 2], data[dataCtr - 1]); #endif endPointCtr++; } else { userBufferOvf = 1; } break; - + case HEADER_TRM: break; - + default: fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_HEADER; return -1; } - + break; case FIFO_MODE_REG_READ_MEM: @@ -820,7 +831,7 @@ static int trb_fifo_read(uint8_t channel, ((uint32_t)package.F2)); #ifdef TRB_DEBUGGER fprintf(stderr, - "D: 0x%04x 0x%08x\n", memLen, data[dataCtr - 1]); + "D: 0x%04x 0x%08x\n", memLen, data[dataCtr - 1]); #endif memLen++; } else { @@ -859,50 +870,50 @@ static int trb_fifo_read(uint8_t channel, userBufferOvf = 1; } break; - + case HEADER_DAT: if (dataCtr + 1 < dsize) { if (package.F0 == 0x0000) break; /* it a hack, ask Jan */ data[dataCtr++] = (((uint32_t)package.F1 << 16) | ((uint32_t)package.F2)); - data[dataCtr++] = (uint32_t)package.F3; + data[dataCtr++] = (uint32_t)package.F3; #ifdef TRB_DEBUGGER fprintf(stderr, - "D: 0x%04x 0x%08x\n", memLen, data[dataCtr - 1]); + "D: 0x%04x 0x%08x\n", memLen, data[dataCtr - 1]); #endif memLen++; } else { userBufferOvf = 1; } break; - + case HEADER_TRM: if (lastHeader != NULL) { *lastHeader |= (memLen << 16); } break; - + default: fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_HEADER; return -1; } break; - + case FIFO_MODE_REG_WRITE: switch (headerType) { case HEADER_HDR: case HEADER_DAT: case HEADER_TRM: break; - + default: fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_HEADER; return -1; } - break; - + break; + case FIFO_MODE_IPU_DATA: { unsigned int i; @@ -916,7 +927,7 @@ static int trb_fifo_read(uint8_t channel, } memLen = (unsigned int)package.F2; break; - + case HEADER_DAT: for (i = 0; (i < 2) && (dataCtr < memLen); i++) { if (dataCtr < dsize) { @@ -925,7 +936,7 @@ static int trb_fifo_read(uint8_t channel, ((uint32_t)package.F1)) : (((uint32_t)package.F2 << 16) | ((uint32_t)package.F3)); -#ifdef TRB_DEBUGGER +#ifdef TRB_DEBUGGER fprintf(stderr, "D: 0x%08x\n", data[dataCtr - 1]); #endif } else { @@ -933,7 +944,7 @@ static int trb_fifo_read(uint8_t channel, } } break; - + case HEADER_TRM: if ((packageCtr > 0) && (dataCtr != memLen)) { /* Error invalid length */ @@ -966,7 +977,7 @@ static int trb_fifo_read(uint8_t channel, } sourceAddress = (uint32_t)package.F0; break; - + case HEADER_DAT: if ((packageCtr - endPointCtr * 3) == 1) { uidHigh = (((uint32_t)package.F0 << 0) | @@ -987,7 +998,7 @@ static int trb_fifo_read(uint8_t channel, #ifdef TRB_DEBUGGER fprintf(stderr, "D: 0x%04x 0x%08x%08x 0x%02x\n", (uint32_t)sourceAddress, - uidLow, uidHigh, + uidLow, uidHigh, (uint32_t)package.F0); #endif } else { @@ -995,7 +1006,7 @@ static int trb_fifo_read(uint8_t channel, } break; } - + case HEADER_TRM: break; @@ -1013,27 +1024,27 @@ static int trb_fifo_read(uint8_t channel, trb_errno = TRB_INVALID_PKG_NUMBER; return -1; } - + switch (headerType) { case HEADER_HDR: break; - + case HEADER_DAT: if ((packageCtr == 1) && (package.F0 == NET_ACKADDRESS)) { dataCtr++; } break; - + case HEADER_TRM: break; - + default: fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_HEADER; return -1; } break; - + default: fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_MODE; @@ -1046,9 +1057,16 @@ static int trb_fifo_read(uint8_t channel, if (headerType == HEADER_TRM) { break; } - if (trb_dma == 1) { + +#ifdef PEXOR + if (pexor_dma != 0) { + if (tmp - dataBuffer >= dataBufferSize) { + trb_errno = TRB_PEXOR_DMA_ERROR; + return -1; + } tmp++; } else { +#endif timeout = 0; do { read32_from_FPGA(fifoBuffer, tmp); @@ -1059,7 +1077,9 @@ static int trb_fifo_read(uint8_t channel, trb_errno = TRB_FIFO_TIMEOUT; return -1; } +#ifdef PEXOR } +#endif } /* Copy StatusBits and Sequenze of TerminationPackage */ @@ -1067,7 +1087,7 @@ static int trb_fifo_read(uint8_t channel, trb_term.status_channel = package.F1; trb_term.sequence = package.F3; trb_term.channel = channel; - + /* Check UserBufferOvf */ if (userBufferOvf == 1) { trb_errno = TRB_USER_BUFFER_OVF; @@ -1085,23 +1105,23 @@ static int trb_fifo_read(uint8_t channel, trb_errno = TRB_FIFO_MISSING_TERM_HEADER; return -1; } - + /* Check StatusBits of TerminationPackage */ if ((trb_term.status_common & 0x0003e) != 0) { trb_errno = TRB_STATUS_ERROR; return -1; } - + if ((channel == 3) && ((trb_term.status_channel & 0x0002) != 0)) { trb_errno = TRB_STATUS_ERROR; return -1; } - - if ((trb_term.status_common != 0x01) || + + if ((trb_term.status_common != 0x01) || (trb_term.status_channel != 0)) { trb_errno = TRB_STATUS_WARNING; } - + return dataCtr; } @@ -1114,27 +1134,32 @@ static int lockPorts(int masterLock) -1, /* sem_op: decrement semaphore by 1, i.e. lock it */ SEM_UNDO /* sem_flg: remove lock if process gets killed */ }; - + if ((master_lock == 1) && (masterLock == 0)) { return 0; } - + /* Block Signals */ - if (sigprocmask(SIG_BLOCK, &blockSet, &blockSetOld) == -1) return -1; - + if (sigprocmask(SIG_BLOCK, &blockSet, &blockSetOld) == -1) { + trb_errno = TRB_SEMAPHORE; + return -1; + } + /* Wait for semaphore and lock it */ if (semop(semid, &sops, 1) == -1) { trb_errno = TRB_SEMAPHORE; + + /* Unblock signals */ + sigprocmask(SIG_SETMASK, &blockSetOld, NULL); return -1; } - -#ifndef PEXOR +#ifndef PEXOR /* Get FifoToggleBit-Status, needed by read32_from_FPGA ... */ fifoToggleBit = readPC() & FIFO_TOGGLE_BIT; #endif if (masterLock != 0) master_lock = 1; - + return 0; } @@ -1145,33 +1170,39 @@ static int unlockPorts(int masterLock) 1, /* sem_op: increment semaphore by 1, i.e. unlock it */ SEM_UNDO /* sem_flg: remove lock if process gets killed */ }; - + int ret = 0; + if ((master_lock == 1) && (masterLock == 0)) { return 0; } + if (masterLock != 0) master_lock = 0; + /* Release semaphore */ if (semop(semid, &sops, 1) == -1) { trb_errno = TRB_SEMAPHORE; + ret = -1; return -1; } - - if (masterLock != 0) master_lock = 0; - + /* Unblock Signals */ - if (sigprocmask(SIG_SETMASK, &blockSetOld, NULL) == -1) return -1; - - return 0; + if (sigprocmask(SIG_SETMASK, &blockSetOld, NULL) == -1) { + trb_errno = TRB_SEMAPHORE; + ret = -1; + } + + return ret; } + static int init_semaphore() { trb_errno = TRB_NONE; - + /* Set signal mask to block ALL signals */ sigfillset(&blockSet); sigemptyset(&blockSetOld); - + /* Get / Create semaphore */ if ((semid = semget(sem_key, 1, IPC_CREAT | IPC_EXCL | @@ -1196,7 +1227,7 @@ static int init_semaphore() return -1; } } - + return 0; } @@ -1204,52 +1235,52 @@ static int init_semaphore() #ifndef PEXOR /* Etrax-Board */ -/* Intit FPGA Interface */ +/* Init FPGA Interface */ int init_ports() { static const uint32_t GPIO_OFFSET = 0x1a000 / sizeof(uint32_t); static const uint32_t GPIOB_OE_PINS = 0x0; static const uint32_t GPIOC_OE_PINS = 0x3ffff; - + volatile uint32_t* GPIOC_OE_OFFSET = NULL; volatile uint32_t* GPIOB_OE_OFFSET = NULL; uint32_t* GPIO_PTR = NULL; - + int memfd; uint32_t *mem = NULL; - + /* Init semaphore and signal handling */ if (init_semaphore() == -1) return -1; - + /* Open shared memory and initialize FIFO pointers */ memfd = open("/dev/mem", O_RDWR); if (memfd < 0) { trb_errno = TRB_FIFO_SHARED_MEM; return -1; } - - mem = (uint32_t*)mmap((void*)0, + + mem = (uint32_t*)mmap(NULL, 2 * 4 * 4 * 8192, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, 0xb0000000); - + if ((void*)mem == MAP_FAILED) { trb_errno = TRB_FIFO_SHARED_MEM; return -1; } - + /* GPIO */ GPIO_PTR = mem + GPIO_OFFSET; - + GPIOB_IN_OFFSET = (0x24 / sizeof(uint32_t)) + GPIO_PTR; GPIOC_OUT_OFFSET = (0x30 / sizeof(uint32_t)) + GPIO_PTR; GPIOB_OE_OFFSET = (0x28 / sizeof(uint32_t)) + GPIO_PTR; GPIOC_IN_OFFSET = (0x34 / sizeof(uint32_t)) + GPIO_PTR; GPIOC_OE_OFFSET = (0x38 / sizeof(uint32_t)) + GPIO_PTR; - + close(memfd); if (lockPorts(0) == -1) return -1; @@ -1259,55 +1290,68 @@ int init_ports() (*GPIOC_OE_OFFSET != GPIOC_OE_PINS)) { /* read: all bits on portB */ *GPIOB_OE_OFFSET = GPIOB_OE_PINS; - + /* write: portC[17-0] */ *GPIOC_OE_OFFSET = GPIOC_OE_PINS; } - + /* Reset Ports */ com_reset_FPGA(); - + if (unlockPorts(0) == -1) return -1; - + return 0; } void close_ports() { - GPIOB_IN_OFFSET = NULL; + GPIOB_IN_OFFSET = NULL; GPIOC_IN_OFFSET = NULL; GPIOC_OUT_OFFSET = NULL; } - #else /* PEXOR */ -int init_ports() +void close_ports() { - /* Init semaphore and signal handling */ - if (init_semaphore() == -1) return -1; - - pexorFileHandle = open(pexor_deviceName, O_RDWR); - if (pexorFileHandle < 0) { - fprintf(stderr, "open of device '%s' failed\n", pexor_deviceName); - trb_errno = TRB_PEXOR_OPEN; - return -1; + /* Close FileHandler */ + if (pexorFileHandle >= 0) { + close(pexorFileHandle); + pexorFileHandle = -1; } - - return 0; } -void close_ports() +int init_ports() { - if (pexorFileHandle >= 0) { - close(pexorFileHandle); + if (trb_debug > 0) { + fprintf(stderr, "init_ports: called\n"); } + if (pexorFileHandle == -1) { + pexorFileHandle = open(pexor_deviceName, O_RDWR); + if (pexorFileHandle < 0) { + trb_errno = TRB_PEXOR_OPEN; + return -1; + } + } + + if (trb_debug > 0) { + fprintf(stderr, "init_ports: pexorFileHandle = %d\n", pexorFileHandle); + } + + /* Init semaphore and signal handling */ + if (init_semaphore() == -1) return -1; + + return 0; } -#endif /* End Pexor */ +#endif /* End Pexor */ int trb_fifo_flush(uint8_t channel) { +#ifdef PEXOR + int dma; +#endif + trb_errno = TRB_NONE; if (channel >= 4) { @@ -1321,8 +1365,14 @@ int trb_fifo_flush(uint8_t channel) } if (lockPorts(0) == -1) return -1; - +#ifdef PEXOR + dma = pexor_dma; + pexor_dma = 0; +#endif fifo_flush(channel); +#ifdef PEXO + pexor_dma = dma; +#endif if (unlockPorts(0) == -1) return -1; @@ -1351,20 +1401,42 @@ int trb_register_read(uint16_t trb_address, fprintf(stderr, "Init_Transfer done.\n"); } - /* Build package and start transfer */ +#ifdef PEXOR + if (pexor_dma == 0) { +#endif + /* Build package and start transfer */ #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address); + write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address); #endif - 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_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); #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_READ); + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_READ); #else - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, - (uint32_t)trb_address << 16 | CMD_REGISTER_READ); + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, + (uint32_t)trb_address << 16 | CMD_REGISTER_READ); + } else { + /* Send command to pexor driver */ + pexorDescriptor.trb_address = trb_address; + pexorDescriptor.reg_address = reg_address; + pexorDescriptor.dma_addr = (unsigned long)dataBuffer; + pexorDescriptor.dma_size = DATA_BUFFER_SIZE * 4; + pexorDescriptor.command = PEXOR_TRBNETCOM_REG_READ; + + status = ioctl(pexorFileHandle, + PEXOR_IOC_TRBNET_REQUEST, + &pexorDescriptor); + + if (status != 0) { + unlockPorts(0); + trb_errno = TRB_PEXOR_DEVICE_ERROR; + return -1; + } + dataBufferSize = pexorDescriptor.dma_size; + } #endif /* DEBUG INFO */ @@ -1380,7 +1452,7 @@ int trb_register_read(uint16_t trb_address, trb_errno = TRB_INVALID_PKG_NUMBER; return -1; } - + return status; } @@ -1406,36 +1478,56 @@ int trb_registertime_read(uint16_t trb_address, fprintf(stderr, "Init_Transfer done.\n"); } - /* Build package and start transfer */ +#ifdef PEXOR + if (pexor_dma == 0) { +#endif + /* Build package and start transfer */ #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address); + write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address); #endif - 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_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); #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_READ); + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_READ); #else - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, - (uint32_t)trb_address << 16 | CMD_REGISTER_READ); + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, + (uint32_t)trb_address << 16 | CMD_REGISTER_READ); + } else { + /* Send command to pexor driver */ + pexorDescriptor.trb_address = trb_address; + pexorDescriptor.reg_address = reg_address; + pexorDescriptor.dma_addr = (unsigned long)dataBuffer; + pexorDescriptor.dma_size = DATA_BUFFER_SIZE * 4; + pexorDescriptor.command = PEXOR_TRBNETCOM_REG_READ; + status = ioctl(pexorFileHandle, + PEXOR_IOC_TRBNET_REQUEST, + &pexorDescriptor); + if (status != 0) { + unlockPorts(0); + trb_errno = TRB_PEXOR_DEVICE_ERROR; + return -1; + } + dataBufferSize = pexorDescriptor.dma_size; + } #endif - + /* DEBUG INFO */ if (trb_debug > 0) { fprintf(stderr, "CMD_REGISTER_READ started.\n"); } - status = trb_fifo_read(3, FIFO_MODE_REGTIME_READ, data, dsize); - + status = trb_fifo_read(3, FIFO_MODE_REGTIME_READ, data, dsize); + if (unlockPorts(0) == -1) return -1; - + if ((status > 0) && (status % 3 != 0)) { trb_errno = TRB_INVALID_PKG_NUMBER; return -1; } - + return status; } @@ -1473,23 +1565,43 @@ int trb_register_read_mem(uint16_t trb_address, if (trb_debug > 0) { fprintf(stderr, "Init_Transfer done.\n"); } - - /* Build package and start transfer */ +#ifdef PEXOR + if (pexor_dma == 0) { +#endif + /* Build package and start transfer */ #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address); + write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address); #endif - 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_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); #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_READ_MEM); + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_READ_MEM); #else - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, - (uint32_t)trb_address << 16 | CMD_REGISTER_READ_MEM); + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, + (uint32_t)trb_address << 16 | CMD_REGISTER_READ_MEM); + } else { + /* Send command to pexor driver */ + pexorDescriptor.trb_address = trb_address; + pexorDescriptor.reg_address = reg_address; + pexorDescriptor.arg0 = length; + pexorDescriptor.dma_addr = (unsigned long)dataBuffer; + pexorDescriptor.dma_size = DATA_BUFFER_SIZE * 4; + pexorDescriptor.command = PEXOR_TRBNETCOM_REG_READ_MEM; + status = ioctl(pexorFileHandle, PEXOR_IOC_TRBNET_REQUEST, + &pexorDescriptor); + if (status != 0) { + + unlockPorts(0); + trb_errno = TRB_PEXOR_DEVICE_ERROR; + return -1; + } + dataBufferSize = pexorDescriptor.dma_size; + } #endif - + /* DEBUG INFO */ if (trb_debug > 0) { fprintf(stderr, "CMD_REGISTER_READ_MEM started.\n"); @@ -1528,9 +1640,9 @@ int trb_registertime_read_mem(uint16_t trb_address, int status; const uint32_t *p = NULL; const uint32_t *end = NULL; - + trb_errno = TRB_NONE; - + /* check size and set reading-mode */ length = size & 0x7fff; if ((size == 0) || (size != length)) { @@ -1551,33 +1663,55 @@ int trb_registertime_read_mem(uint16_t trb_address, if (trb_debug > 0) { fprintf(stderr, "Init_Transfer done.\n"); } - - /* Build package and start transfer */ +#ifdef PEXOR + if (pexor_dma == 0) { +#endif + /* Build package and start transfer */ #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address); + write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address); #endif - 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_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); #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_READ_MEM); + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_READ_MEM); #else - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, - (uint32_t)trb_address << 16 | CMD_REGISTER_READ_MEM); + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, + (uint32_t)trb_address << 16 | CMD_REGISTER_READ_MEM); + } else { + /* Send command to pexor driver */ + pexorDescriptor.trb_address = trb_address; + pexorDescriptor.reg_address = reg_address; + pexorDescriptor.arg0 = length; + pexorDescriptor.dma_addr = (unsigned long)dataBuffer; + pexorDescriptor.dma_size = DATA_BUFFER_SIZE * 4; + pexorDescriptor.command = PEXOR_TRBNETCOM_REG_READ_MEM; + status = ioctl(pexorFileHandle, + PEXOR_IOC_TRBNET_REQUEST, + &pexorDescriptor); + if (status != 0) { + unlockPorts(0); + trb_errno = TRB_PEXOR_DEVICE_ERROR; + return -1; + } + dataBufferSize = pexorDescriptor.dma_size; + } #endif /* DEBUG INFO */ if (trb_debug > 0) { fprintf(stderr, "CMD_REGISTER_READ_MEM started.\n"); } - + status = trb_fifo_read(3, FIFO_MODE_REGTIME_READ_MEM, data, dsize); - + if (unlockPorts(0) == -1) return -1; - - if (status == -1) return status; + + if (status == -1) { + return status; + } /* Check size */ p = data; @@ -1616,20 +1750,41 @@ int trb_register_write(uint16_t trb_address, fprintf(stderr, "Init_Transfer done.\n"); } - /* Build package */ +#ifdef PEXOR + if (pexor_dma == 0) { +#endif + /* Build package */ #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address); + write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address); #endif - 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_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); #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_WRITE); + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_WRITE); #else - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, - (uint32_t)trb_address << 16 | CMD_REGISTER_WRITE); + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, + (uint32_t)trb_address << 16 | CMD_REGISTER_WRITE); + } else { + /* Send command to pexor driver */ + pexorDescriptor.trb_address = trb_address; + pexorDescriptor.reg_address = reg_address; + pexorDescriptor.arg0 = value; + pexorDescriptor.dma_addr = (unsigned long)dataBuffer; + pexorDescriptor.dma_size = DATA_BUFFER_SIZE * 4; + pexorDescriptor.command = PEXOR_TRBNETCOM_REG_WRITE; + status = ioctl(pexorFileHandle, + PEXOR_IOC_TRBNET_REQUEST, + &pexorDescriptor); + if (status != 0) { + unlockPorts(0); + trb_errno = TRB_PEXOR_DEVICE_ERROR; + return -1; + } + dataBufferSize = pexorDescriptor.dma_size; + } #endif /* DEBUG INFO */ @@ -1667,7 +1822,7 @@ int trb_register_write_mem(uint16_t trb_address, config = config | (option == 0 ? 0x8000 : 0x0000); if (lockPorts(0) == -1) return -1; - + while (ctr < size) { uint16_t len = (size - ctr) >= blockSize ? blockSize : (size - ctr); /* Init transfer */ @@ -1675,46 +1830,75 @@ int trb_register_write_mem(uint16_t trb_address, unlockPorts(0); return -1; } - + /* DEBUG INFO */ if (trb_debug > 0) { fprintf(stderr, "Init_Transfer done.\n"); } - - /* Build package */ + +#ifdef PEXOR + if (pexor_dma == 0) { +#endif + /* Build package */ #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address); + write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address); #endif - write32_to_FPGA(CHANNEL_3_SENDER_ERROR, 0x00000000); - if (option == 0) { - write32_to_FPGA(CHANNEL_3_SENDER_DATA, reg_address + ctr); - } else { - 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 < len; i++, ctr++) { + write32_to_FPGA(CHANNEL_3_SENDER_ERROR, 0x00000000); + if (option == 0) { + write32_to_FPGA(CHANNEL_3_SENDER_DATA, reg_address + ctr); + } else { + 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, (data[ctr] >> 16) & 0xffff); - write32_to_FPGA(CHANNEL_3_SENDER_DATA, data[ctr] & 0xffff); write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000); - } + for (i = 0; i < len; i++, ctr++) { + write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000); + write32_to_FPGA(CHANNEL_3_SENDER_DATA, (data[ctr] >> 16) & 0xffff); + write32_to_FPGA(CHANNEL_3_SENDER_DATA, data[ctr] & 0xffff); + write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000); + } #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_WRITE_MEM); + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_WRITE_MEM); #else - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, - (uint32_t)trb_address << 16 | CMD_REGISTER_WRITE_MEM); + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, + (uint32_t)trb_address << 16 | CMD_REGISTER_WRITE_MEM); + } else { + /* Send command to pexor driver */ + pexorDescriptor.trb_address = trb_address; + if (option == 0) { + pexorDescriptor.reg_address = reg_address + ctr; + } else { + pexorDescriptor.reg_address = reg_address; + } + pexorDescriptor.arg0 = config; + pexorDescriptor.arg1 = (unsigned long)data; + pexorDescriptor.arg2 = len; + pexorDescriptor.dma_addr = (unsigned long)dataBuffer; + pexorDescriptor.dma_size = DATA_BUFFER_SIZE * 4; + pexorDescriptor.command = PEXOR_TRBNETCOM_REG_WRITE_MEM; + + status = ioctl(pexorFileHandle, + PEXOR_IOC_TRBNET_REQUEST, + &pexorDescriptor); + if (status != 0) { + unlockPorts(0); + trb_errno = TRB_PEXOR_DEVICE_ERROR; + return -1; + } + dataBufferSize = pexorDescriptor.dma_size; + ctr += len; + } #endif - + /* DEBUG INFO */ if (trb_debug > 0) { fprintf(stderr, "CMD_REGISTER_WRITE_MEM started %d.\n", len); } - + status = trb_fifo_read(3, FIFO_MODE_REG_WRITE, NULL, 0); } - + if (unlockPorts(0) == -1) return -1; return status; @@ -1741,20 +1925,39 @@ int trb_read_uid(uint16_t trb_address, fprintf(stderr, "Init_Transfer done.\n"); } - /* Build package and start transfer */ +#ifdef PEXOR + if (pexor_dma == 0) { +#endif + /* Build package and start transfer */ #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address); + write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, trb_address); #endif - 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_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); #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_NETADMINISTRATION); + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_NETADMINISTRATION); #else - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, - (uint32_t)trb_address << 16 | CMD_NETADMINISTRATION); + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, + (uint32_t)trb_address << 16| CMD_NETADMINISTRATION); + } else { + /* Send command to pexor driver */ + pexorDescriptor.trb_address = trb_address; + pexorDescriptor.dma_addr = (unsigned long)dataBuffer; + pexorDescriptor.dma_size = DATA_BUFFER_SIZE * 4; + pexorDescriptor.command = PEXOR_TRBNETCOM_READ_UID; + status = ioctl(pexorFileHandle, + PEXOR_IOC_TRBNET_REQUEST, + &pexorDescriptor); + if (status != 0) { + unlockPorts(0); + trb_errno = TRB_PEXOR_DEVICE_ERROR; + return -1; + } + dataBufferSize = pexorDescriptor.dma_size; + } #endif /* DEBUG INFO */ @@ -1802,25 +2005,48 @@ int trb_set_address(uint64_t uid, fprintf(stderr, "Init_Transfer done.\n"); } - /* Build package and start transfer */ +#ifdef PEXOR + if (pexor_dma == 0) { +#endif + /* Build package and start transfer */ #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, 0xffff); /* always broadcast */ + write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, 0xffff); /* always broadcast */ #endif - 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_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); #ifndef PEXOR - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_NETADMINISTRATION); + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_NETADMINISTRATION); #else - write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, 0xffff0000 | CMD_NETADMINISTRATION); /* always broadcast */ + } else { + /* Send command to pexor driver */ + pexorDescriptor.trb_address = trb_address; + pexorDescriptor.arg0 = (unsigned long)(uid & 0xffffffff); + pexorDescriptor.arg1 = (unsigned long)(uid >> 32 & 0xffffffff); + pexorDescriptor.arg2 = endpoint; + pexorDescriptor.dma_addr = (unsigned long)dataBuffer; + pexorDescriptor.dma_size = DATA_BUFFER_SIZE * 4; + pexorDescriptor.command = PEXOR_TRBNETCOM_SET_ADDRESS; + status = ioctl(pexorFileHandle, + PEXOR_IOC_TRBNET_REQUEST, + &pexorDescriptor); + if (status != 0) { + unlockPorts(0); + trb_errno = TRB_PEXOR_DEVICE_ERROR; + return -1; + } + dataBufferSize = pexorDescriptor.dma_size; + } #endif + /* DEBUG INFO */ if (trb_debug > 0) { fprintf(stderr, "CMD_SETADDRESS started.\n"); @@ -1829,7 +2055,7 @@ int trb_set_address(uint64_t uid, status = trb_fifo_read(3, FIFO_MODE_SET_ADDRESS, NULL, 0); if (unlockPorts(0) == -1) return -1; - + if (status == -1) return -1; if (status != 1) { trb_errno = TRB_ENDPOINT_NOT_REACHED; @@ -1846,6 +2072,9 @@ int trb_ipu_data_read(uint8_t type, uint32_t *data, unsigned int dsize) { +#ifdef PEXOR + int dma = pexor_dma; +#endif int status; trb_errno = TRB_NONE; @@ -1878,8 +2107,17 @@ int trb_ipu_data_read(uint8_t type, fprintf(stderr, "CMD_IPU_DATA_READ started.\n"); } +#ifdef PEXOR + pexor_dma = 0; +#endif + + /* Get IPU Data */ status = trb_fifo_read(1, FIFO_MODE_IPU_DATA, data, dsize); +#ifdef PEXOR + pexor_dma = dma; +#endif + if (unlockPorts(0) == -1) return -1; return status; @@ -1891,6 +2129,9 @@ int trb_send_trigger(uint8_t type, uint8_t trg_random, uint16_t trg_number) { +#ifdef PEXOR + int dma = pexor_dma; +#endif int status; trb_errno = TRB_NONE; @@ -1913,10 +2154,10 @@ int trb_send_trigger(uint8_t type, ((uint32_t)trg_random << 16) | ((uint32_t)trg_number) )); - + write32_to_FPGA(CHANNEL_0_SENDER_TRIGGER_INFO, (trg_info >> 8) & 0xffff); - + /* Send trigger */ write32_to_FPGA(CHANNEL_0_SENDER_CONTROL, @@ -1926,9 +2167,18 @@ int trb_send_trigger(uint8_t type, fprintf(stderr, "trigger started.\n"); } + +#ifdef PEXOR + pexor_dma = 0; +#endif + /* Check for replay packets (trigger) */ status = trb_fifo_read(0, FIFO_MODE_TERM_ONLY, NULL, 0); +#ifdef PEXOR + pexor_dma = dma; +#endif + if (unlockPorts(0) == -1) return -1; if (status == -1) return -1; @@ -1942,6 +2192,9 @@ int trb_send_trigger_rich(uint8_t trg_input, uint8_t trg_random, uint16_t trg_number) { +#ifdef PEXOR + int dma = pexor_dma; +#endif int status; trb_errno = TRB_NONE; @@ -1949,7 +2202,7 @@ int trb_send_trigger_rich(uint8_t trg_input, if (trg_input > 3) { return -1; } - + if (lockPorts(0) == -1) return -1; /* Init transfer slowcontrol */ @@ -1974,21 +2227,26 @@ int trb_send_trigger_rich(uint8_t trg_input, ((uint32_t)trg_random << 16) | ((uint32_t)trg_number) )); - + write32_to_FPGA(CHANNEL_0_SENDER_TRIGGER_INFO, (trg_info >> 8) & 0xffff); - + /* Prepare slowcontrol channel */ #ifndef PEXOR write32_to_FPGA(CHANNEL_3_TARGET_ADDRESS, 0x0000fffb); /* RICH Subnet only */ #endif write32_to_FPGA(CHANNEL_3_SENDER_ERROR, 0x00000000); write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x0020); - write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000 | (0x01 << trg_input)); - write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000); + write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000 | (0x01 << trg_input)); + write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000); write32_to_FPGA(CHANNEL_3_SENDER_DATA, 0x00000000); /* Send both fake trigger and LVL1 information */ +#ifndef PEXOR write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, CMD_REGISTER_WRITE); +#else + write32_to_FPGA(CHANNEL_3_SENDER_CONTROL, + 0xfffb | CMD_REGISTER_WRITE); /* RICH Subnet only */ +#endif usleep(1000); write32_to_FPGA(CHANNEL_0_SENDER_CONTROL, SHORT_TRANSFER | (uint32_t)(type & 0x0f)); @@ -1997,8 +2255,18 @@ int trb_send_trigger_rich(uint8_t trg_input, fprintf(stderr, "trigger started.\n"); } - /* Check for replay packets (slowcontrol) */ + +#ifdef PEXOR + pexor_dma = 0; +#endif + + /* Check for reply packets (slowcontrol) */ status = trb_fifo_read(3, FIFO_MODE_TERM_ONLY, NULL, 0); + +#ifdef PEXOR + pexor_dma = dma; +#endif + if (status == -1) { fifo_flush(0); unlockPorts(0); @@ -2021,6 +2289,8 @@ int fpga_register_read(uint16_t reg_address, uint32_t* value) int fpga_register_read(uint32_t reg_address, uint32_t* value) #endif { + int status = 0; + trb_errno = TRB_NONE; if (lockPorts(0) == -1) return -1; @@ -2030,11 +2300,11 @@ int fpga_register_read(uint32_t reg_address, uint32_t* value) fprintf(stderr, "fpga_register_read started.\n"); } - read32_from_FPGA(reg_address, value); + status = read32_from_FPGA(reg_address, value); if (unlockPorts(0) == -1) return -1; - return 0; + return status; } #ifndef PEXOR @@ -2043,6 +2313,8 @@ int fpga_register_write(uint16_t reg_address, uint32_t value) int fpga_register_write(uint32_t reg_address, uint32_t value) #endif { + int status = 0; + trb_errno = TRB_NONE; if (lockPorts(0) == -1) return -1; @@ -2052,19 +2324,21 @@ int fpga_register_write(uint32_t reg_address, uint32_t value) fprintf(stderr, "fpga_register_write started.\n"); } - write32_to_FPGA(reg_address, value); + status = write32_to_FPGA(reg_address, value); if (unlockPorts(0) == -1) return -1; - return 0; + return status; } #ifdef PEXOR -int fpga_register_read_mem(uint32_t reg_address, +int fpga_register_read_mem(uint32_t reg_address, uint32_t* data, unsigned int size) { unsigned int i = 0; + int status = 0; + trb_errno = TRB_NONE; if (lockPorts(0) == -1) return -1; @@ -2073,37 +2347,36 @@ int fpga_register_read_mem(uint32_t reg_address, if (trb_debug > 0) { fprintf(stderr, "fpga_register_read_mem started.\n"); } - - for (i = 0; i < size; i++) { - read32_from_FPGA(reg_address + i, &data[i]); + + for (i = 0; (i < size) && (status == 0); i++) { + status = read32_from_FPGA(reg_address + i, &data[i]); } - + if (unlockPorts(0) == -1) return -1; - - return 0; -} + return status; +} -int fpga_register_write_mem(uint32_t reg_address, +int fpga_register_write_mem(uint32_t reg_address, const uint32_t* data, unsigned int size) { unsigned int i = 0; trb_errno = TRB_NONE; - + if (lockPorts(0) == -1) return -1; - + /* DEBUG INFO */ if (trb_debug > 0) { fprintf(stderr, "fpga_register_write_mem started.\n"); } - + for (i = 0; i < size; i++) { write32_to_FPGA(reg_address + i, data[i]); } - + if (unlockPorts(0) == -1) return -1; - + return 0; } #endif @@ -2111,44 +2384,44 @@ int fpga_register_write_mem(uint32_t reg_address, int network_reset() { trb_errno = TRB_NONE; - + if (lockPorts(0) == -1) return -1; com_reset_FPGA(); - + /* DEBUG INFO */ if (trb_debug > 0) { fprintf(stderr, "network_reset started.\n"); } - - write32_to_FPGA(0x10, 0x0000); + + write32_to_FPGA(0x10, 0x0000); usleep(1000); - + write32_to_FPGA(0x10, 0x8000); sleep(8); - + com_reset_FPGA(); - + if (unlockPorts(0) == -1) return -1; - + return 0; } int com_reset() { trb_errno = TRB_NONE; - + if (lockPorts(0) == -1) return -1; /* DEBUG INFO */ if (trb_debug > 0) { fprintf(stderr, "com_reset started.\n"); } - + com_reset_FPGA(); - + if (unlockPorts(0) == -1) return -1; - + return 0; } @@ -2165,22 +2438,22 @@ int trb_register_modify(uint16_t trb_address, int singleWrite = 0; uint32_t *data = NULL; int i; - + if (lockPorts(1) == -1) return -1; - + data = (uint32_t *) malloc(sizeof(uint32_t) * NUM_ENDPOINTS * 2); if (data == NULL) abort(); - + status = trb_register_read(trb_address, reg_address, data, NUM_ENDPOINTS * 2); if (status == -1) { free(data); unlockPorts(1); - return -1; + return -1; } - + /* Now set bits on all endpoints */ - /* check, whether all registers are the same */ + /* check, whether all registers are the same */ singleWrite = 1; value = data[1]; for (i = 2; (i + 1) < status; i += 2) { @@ -2189,7 +2462,7 @@ int trb_register_modify(uint16_t trb_address, break; } } - + /* Write modified register value(s) */ for (i = 0; (i + 1) < (singleWrite == 0 ? status : 2); i += 2) { if (singleWrite == 0) { @@ -2200,30 +2473,30 @@ int trb_register_modify(uint16_t trb_address, case 1: value |= bitMask; break; - + case 2: value &= ~bitMask; break; - + case 3: value = (value & ~bitMask) | (bitValue & bitMask); break; - + default: free(data); unlockPorts(1); return -1; } - + if (trb_register_write(trb_address, reg_address, value) == -1) { free(data); unlockPorts(1); return -1; - } - } - + } + } + free(data); if (unlockPorts(1) == -1) return -1; - + return 0; }