From f735d1cd7d21feaf7b8679c1fc162a7d01db630c Mon Sep 17 00:00:00 2001 From: hadaq Date: Tue, 19 Oct 2010 15:56:20 +0000 Subject: [PATCH] added 2 new functions to trbnet.h, time stamping FPGA support --- libtrbnet/trbcmd.c | 122 +++++++++++++++++++++- libtrbnet/trbnet.c | 249 ++++++++++++++++++++++++++++++++++++++++++--- libtrbnet/trbnet.h | 15 ++- 3 files changed, 367 insertions(+), 19 deletions(-) diff --git a/libtrbnet/trbcmd.c b/libtrbnet/trbcmd.c index e1699d0..7ce8d1e 100644 --- a/libtrbnet/trbcmd.c +++ b/libtrbnet/trbcmd.c @@ -25,7 +25,7 @@ static int hexMode = HEXMODE; -static const char trbcmd_version[] = "$Revision: 2.57 $"; +static const char trbcmd_version[] = "$Revision: 2.58 $"; #define BACKLOG 10 static uint16_t tcp_port = 55555; @@ -109,10 +109,16 @@ void usage(const char *progName) fprintf(stdout, "\nCommands:\n"); fprintf(stdout, " r -> " "read register\n"); + fprintf(stdout, " rt -> " + "read register&TimeStamp\n"); fprintf(stdout, " w -> " "write register\n"); fprintf(stdout, " rm -> " "read register-memory\n"); + fprintf(stdout, " rmt -> " + "read register-memory&\n" + " " + "TimeStamp\n"); fprintf(stdout, " wm -> " "write to register-memory\n" " " @@ -393,6 +399,53 @@ int start(int argc, char **argv) } free(data); + } else if (strncmp(cmd[0], "rt", CMD_SIZE) == 0) { + + /*******************************************/ + /* Register Read plus TimeStamp */ + /*******************************************/ + + int status = 0; + uint32_t *data = NULL; + int i; + + if (cmdLen != 3) { + logError(ERROR, "Invalid command, try -h option\n"); + return -1; + } + + trb_address = strtoul(cmd[1], NULL, hexMode == 1 ? 16 : 0); + reg_address = strtoul(cmd[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); + } + + data = (uint32_t *) malloc(sizeof(uint32_t) * NUM_ENDPOINTS * 2); + if (data == NULL) + abort(); + + status = trb_registertime_read(trb_address, reg_address, + data, NUM_ENDPOINTS * 2); + if (status == -1) { + logError(ERROR, "read_register failed: %s\n", trb_strerror()); + } else { + for (i = 0; i < status; i += 3) { + fprintf(stdout, "0x%04x 0x%08x 0x%04x\n", + data[i], data[i + 1], data[i + 2]); + } + + /* Check Status-Bits */ + if (trb_errno == TRB_STATUS_WARNING) { + logError(WARNING, "Status-Bit(s) have been set:\n%s\n", + trb_termstr(trb_term)); + } + } + free(data); + } else if (strncmp(cmd[0], "rm", CMD_SIZE) == 0) { /*******************************************/ @@ -458,7 +511,74 @@ int start(int argc, char **argv) } } free(data); + + } else if (strncmp(cmd[0], "rmt", CMD_SIZE) == 0) { + + /*******************************************/ + /* Register Read Memory plus TimeStamp */ + /*******************************************/ + + uint32_t *data = NULL; + uint16_t size = 0; + uint8_t option = 0; + int status; + const uint32_t *p; + const uint32_t *end = NULL; + unsigned int len; + unsigned int i; + + if (cmdLen != 5) { + logError(ERROR, "Invalid command, try -h option\n"); + return -1; + } + + trb_address = strtoul(cmd[1], NULL, hexMode == 1 ? 16 : 0); + reg_address = strtoul(cmd[2], NULL, hexMode == 1 ? 16 : 0); + size = strtoul(cmd[3], NULL, hexMode == 1 ? 16 : 0); + option = strtoul(cmd[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); + } + + data = (uint32_t *) malloc(sizeof(uint32_t) * USER_BUFFER_SIZE); + if (data == NULL) + abort(); + status = trb_registertime_read_mem(trb_address, reg_address, option, + size, data, USER_BUFFER_SIZE); + if (status == -1) { + logError(ERROR, "read_registertime_mem failed: %s\n", + trb_strerror()); + return -1; + } else { + /* Print data-buffer */ + p = data; + end = p + status; + while (p < end) { + len = (*p >> 16) & 0xffff; + fprintf(stdout, "H: 0x%04x 0x%04x\n", (*p++) & 0xffff, len); + for (i = 0; (i < len) && (p < end); i++) { + fprintf(stdout, "0x%04x 0x%08x 0x%04x\n", + (option == 0 ? reg_address + i : i), + *p, *(p + 1)); + p += 2; + } + } + /* Check Status-Bits */ + if (trb_errno == TRB_STATUS_WARNING) { + logError(WARNING, "Status-Bits are active:\n%s\n", + trb_termstr(trb_term)); + } + } + free(data); + } else if (strncmp(cmd[0], "wm", CMD_SIZE) == 0) { /*******************************************/ diff --git a/libtrbnet/trbnet.c b/libtrbnet/trbnet.c index 835e4d4..227a6fa 100644 --- a/libtrbnet/trbnet.c +++ b/libtrbnet/trbnet.c @@ -1,4 +1,4 @@ -const char trbnet_version[] = "$Revision: 2.77 $"; +const char trbnet_version[] = "$Revision: 2.78 $"; #include #include @@ -451,7 +451,9 @@ static int trb_init_transfer(uint8_t channel) enum FIFO_READ_MODE { FIFO_MODE_TERM_ONLY, FIFO_MODE_REG_READ, + FIFO_MODE_REGTIME_READ, FIFO_MODE_REG_READ_MEM, + FIFO_MODE_REGTIME_READ_MEM, FIFO_MODE_REG_WRITE, FIFO_MODE_IPU_DATA, FIFO_MODE_UID, @@ -633,7 +635,7 @@ static int trb_fifo_read(uint8_t channel, break; case FIFO_MODE_REG_READ: - + switch (headerType) { case HEADER_HDR: if ((packageCtr - endPointCtr * 2) != 0) { @@ -679,6 +681,57 @@ static int trb_fifo_read(uint8_t channel, } break; + + case FIFO_MODE_REGTIME_READ: + + switch (headerType) { + case HEADER_HDR: + if ((packageCtr - endPointCtr * 2) != 0) { + fifo_flush(channel); + trb_errno = TRB_FIFO_INVALID_HEADER; + return -1; + } + if (dataCtr < dsize) { + data[dataCtr++] = (uint32_t)package.F0; +#ifdef TRB_DEBUGGER + fprintf(stderr, "D: 0x%04x ", data[dataCtr - 1]); +#endif + } else { + userBufferOvf = 1; + } + break; + + case HEADER_DAT: + if ((packageCtr - endPointCtr * 2) != 1) { + fifo_flush(channel); + trb_errno = TRB_FIFO_INVALID_HEADER; + return -1; + } + if ((dataCtr + 1) < dsize) { + 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]); +#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: { @@ -731,6 +784,59 @@ static int trb_fifo_read(uint8_t channel, } break; + + case FIFO_MODE_REGTIME_READ_MEM: + { + static uint32_t* lastHeader = NULL; + static uint32_t memLen = 0; + + switch (headerType) { + case HEADER_HDR: + if (dataCtr < dsize) { + if (lastHeader != NULL) { + *lastHeader |= (memLen << 16); + } + memLen = 0; + lastHeader = &data[dataCtr]; + data[dataCtr++] = (uint32_t)package.F0; +#ifdef TRB_DEBUGGER + fprintf(stderr, "D: H: 0x%04x\n", data[dataCtr - 1]); +#endif + } else { + 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; +#ifdef TRB_DEBUGGER + fprintf(stderr, + "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: if (headerType == HEADER_TRM) break; break; @@ -912,13 +1018,6 @@ static int trb_fifo_read(uint8_t channel, } /* Check StatusBits of TerminationPackage */ -#if 0 - if ((trb_term.status_common == 0) && (trb_term.status_channel == 0)) { - trb_errno = TRB_ENDPOINT_NOT_REACHED; - return -1; - } -#endif - if ((trb_term.status_common & 0x0003e) != 0) { trb_errno = TRB_STATUS_ERROR; return -1; @@ -972,9 +1071,9 @@ static int lockPorts(int masterLock) static int unlockPorts(int masterLock) { struct sembuf sops = { - 0, /* sem_num: We only use one track */ - 1, /* sem_op: decrement semaphore, i.e. unlock it */ - SEM_UNDO /* */ + 0, /* sem_num: We only use one track */ + 1, /* sem_op: increment semaphore by 1, i.e. unlock it */ + SEM_UNDO /* */ }; if ((master_lock == 1) && (masterLock == 0)) { @@ -1176,6 +1275,54 @@ int trb_register_read(uint16_t trb_address, return status; } +int trb_registertime_read(uint16_t trb_address, + uint16_t reg_address, + uint32_t *data, + unsigned int dsize) +{ + int status = 0; + + trb_errno = TRB_NONE; + + if (lockPorts(0) == -1) return -1; + + /* Init transfer */ + if (trb_init_transfer(3) == -1) { + unlockPorts(0); + 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_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; +} + int trb_register_read_mem(uint16_t trb_address, uint16_t reg_address, uint8_t option, @@ -1247,6 +1394,77 @@ int trb_register_read_mem(uint16_t trb_address, return status; } +int trb_registertime_read_mem(uint16_t trb_address, + uint16_t reg_address, + uint8_t option, + uint16_t size, + uint32_t *data, + unsigned int dsize) +{ + uint16_t length; + 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)) { + trb_errno = TRB_INVALID_LENGTH; + return -1; + } + length = length | (option == 0 ? 0x8000 : 0x0000); + + if (lockPorts(0) == -1) return -1; + + /* Init transfer */ + if (trb_init_transfer(3) == -1) { + unlockPorts(0); + 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, 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"); + } + + status = trb_fifo_read(3, FIFO_MODE_REGTIME_READ_MEM, data, dsize); + + if (unlockPorts(0) == -1) return -1; + + if (status == -1) return status; + + /* Check size */ + p = data; + end = p + status; + while (p < end) { + uint16_t len; + len = (*p >> 16) & 0xffff; + if (len > size) { + trb_errno = TRB_READMEM_INVALID_SIZE; + return -1; + } + p += len + 1; + } + + return status; +} + int trb_register_write(uint16_t trb_address, uint16_t reg_address, uint32_t value) @@ -1771,7 +1989,7 @@ int trb_register_modify(uint16_t trb_address, case 1: value |= bitMask; break; - + case 2: value &= ~bitMask; break; @@ -1779,15 +1997,14 @@ int trb_register_modify(uint16_t trb_address, 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) && - (trb_errno != TRB_ENDPOINT_NOT_REACHED)) { + if (trb_register_write(trb_address, reg_address, value) == -1) { free(data); unlockPorts(1); return -1; diff --git a/libtrbnet/trbnet.h b/libtrbnet/trbnet.h index f6cc54c..48967b2 100644 --- a/libtrbnet/trbnet.h +++ b/libtrbnet/trbnet.h @@ -23,14 +23,25 @@ int trb_register_read(uint16_t trb_address, uint16_t reg_address, uint32_t* data, unsigned int dsize); - + +int trb_registertime_read(uint16_t trb_address, + uint16_t reg_address, + uint32_t* data, + unsigned int dsize); + int trb_register_read_mem(uint16_t trb_address, uint16_t reg_address, uint8_t option, uint16_t size, uint32_t* data, unsigned int dsize); - + +int trb_registertime_read_mem(uint16_t trb_address, + uint16_t reg_address, + uint8_t option, + uint16_t size, + uint32_t* data, + unsigned int dsize); int trb_register_write(uint16_t trb_address, uint16_t reg_address, -- 2.43.0