From a4573c5011f7aa5e6c5de744e676cc068e38fee2 Mon Sep 17 00:00:00 2001 From: hadaq Date: Sun, 2 Aug 2009 23:26:44 +0000 Subject: [PATCH] . --- libtrbnet/fs_fpga_int_mem.c | 3 +- libtrbnet/trbcmd.c | 3 +- libtrbnet/trberror.c | 3 +- libtrbnet/trberror.h | 4 +- libtrbnet/trbnet.c | 194 +++++++++++++++++++++++++++--------- libtrbnet/trbnet.h | 33 ++++++ 6 files changed, 188 insertions(+), 52 deletions(-) diff --git a/libtrbnet/fs_fpga_int_mem.c b/libtrbnet/fs_fpga_int_mem.c index 0e38ec4..86fdfb5 100644 --- a/libtrbnet/fs_fpga_int_mem.c +++ b/libtrbnet/fs_fpga_int_mem.c @@ -1,12 +1,13 @@ #include #include +#include #include "fs_fpga_int_mem.h" /* clean exit when Ctrl-C is pressed */ void ctrl_c_catched() { - close_ports(); + port_close_ports(); #if DEBUG fprintf(stderr, "got ctrl-c and close gpio\n"); #endif diff --git a/libtrbnet/trbcmd.c b/libtrbnet/trbcmd.c index f09dda6..a9475a2 100644 --- a/libtrbnet/trbcmd.c +++ b/libtrbnet/trbcmd.c @@ -1,4 +1,3 @@ -static char rcsId[]=""; #define _GNU_SOURCE #include #include @@ -16,7 +15,7 @@ static char rcsId[]=""; #define HEXMODE 0 #endif -#define VERSION_NUMBER "2.00 20090723" +#define VERSION_NUMBER "2.02 20090730" static int hexMode = HEXMODE; diff --git a/libtrbnet/trberror.c b/libtrbnet/trberror.c index 57a680b..01c04bc 100644 --- a/libtrbnet/trberror.c +++ b/libtrbnet/trberror.c @@ -51,9 +51,10 @@ const char* trb_strerror(int errno) "ReadMem invalid size", "Invalid data-length give by Header", "FIFO Incomplete, missing", + "SEMAPHORE Error" }; - if (errno < 24) { + if (errno < 25) { return errorstring[errno]; } else { return "Unknown Errno"; diff --git a/libtrbnet/trberror.h b/libtrbnet/trberror.h index 35ed32b..2a7eed2 100644 --- a/libtrbnet/trberror.h +++ b/libtrbnet/trberror.h @@ -27,8 +27,8 @@ typedef enum { TRB_DMA_TIMEOUT = 20, TRB_READMEM_INVALID_SIZE = 21, TRB_HDR_DLEN = 22, - TRB_FIFO_INCOMPLETE - + TRB_FIFO_INCOMPLETE = 23, + TRB_SEMAPHORE = 24 } TRB_ERROR; extern int trb_errno; diff --git a/libtrbnet/trbnet.c b/libtrbnet/trbnet.c index 1580f1f..fe247c7 100644 --- a/libtrbnet/trbnet.c +++ b/libtrbnet/trbnet.c @@ -1,6 +1,10 @@ #include #include #include +#include +#include +#include + #include #include #include @@ -124,10 +128,15 @@ /* ---------------------------------------------------------------------- */ -static sigset_t blockSet; /* Used for blocking Signals SIGINT and SIGTERM */ +/* Used for blocking Signals SIGINT and SIGTERM */ +static sigset_t blockSet; static sigset_t blockSetOld; static int signalsBlocked = 0; +/* Semaphore handling */ +static int semid = -1; +static const key_t sem_key = 0x545242; + unsigned int trb_debug = 0; unsigned int trb_lazy = 0; unsigned int trb_dma = 0; @@ -281,6 +290,23 @@ static void TRB_Package_dump(const TRB_Package* pkg) } } +static void fifo_flush(uint8_t channel) +{ + uint32_t tmp; + uint32_t fifoAddress; + unsigned int counter = 0; + + 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); +} + static int trb_wait_tx_not_busy(uint8_t channel) { uint32_t tmp = 0; @@ -384,7 +410,7 @@ static int trb_fifo_read(uint8_t channel, } if (timeout >= MAX_TIME_OUT) { - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_FIFO_TIMEOUT; return -1; } @@ -403,7 +429,7 @@ static int trb_fifo_read(uint8_t channel, counter = 0; } else { /* Error: invalid buffer content, flush FIFO-BUFFER and exit */ - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_FIFO_INCOMPLETE_PACKAGE; return -1; } @@ -413,7 +439,7 @@ static int trb_fifo_read(uint8_t channel, (((*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); + fifo_flush(channel); trb_errno = TRB_FIFO_SEQUENZ; return -1; } @@ -464,7 +490,7 @@ static int trb_fifo_read(uint8_t channel, /* First package: headerType must be HDR or TRM */ if (packageCtr == 0) { if (!((headerType == HEADER_HDR) | (headerType == HEADER_TRM))) { - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_HEADER; return -1; } @@ -477,7 +503,7 @@ static int trb_fifo_read(uint8_t channel, != channel)) { /* Error Package inconsistencies, flush FIFO-BUFFER and exit */ - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_FIFO_HEADERS; return -1; } @@ -494,14 +520,14 @@ static int trb_fifo_read(uint8_t channel, switch (headerType) { case HEADER_HDR: if ((packageCtr - endPointCtr * 2) != 0) { - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_HEADER; return -1; } if (dataCtr < dsize) { data[dataCtr++] = (uint32_t)package.F0; } else { - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_USER_BUFFER_OVF; return -1; } @@ -509,7 +535,7 @@ static int trb_fifo_read(uint8_t channel, case HEADER_DAT: if ((packageCtr - endPointCtr * 2) != 1) { - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_HEADER; return -1; } @@ -518,7 +544,7 @@ static int trb_fifo_read(uint8_t channel, ((uint32_t)package.F2)); endPointCtr++; } else { - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_USER_BUFFER_OVF; return -1; } @@ -528,7 +554,7 @@ static int trb_fifo_read(uint8_t channel, break; default: - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_HEADER; return -1; } @@ -550,7 +576,7 @@ static int trb_fifo_read(uint8_t channel, lastHeader = &data[dataCtr]; data[dataCtr++] = (uint32_t)package.F0; } else { - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_USER_BUFFER_OVF; return -1; } @@ -562,7 +588,7 @@ static int trb_fifo_read(uint8_t channel, ((uint32_t)package.F2)); memLen++; } else { - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_USER_BUFFER_OVF; return -1; } @@ -575,7 +601,7 @@ static int trb_fifo_read(uint8_t channel, break; default: - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_HEADER; return -1; } @@ -586,7 +612,7 @@ static int trb_fifo_read(uint8_t channel, if (headerType == HEADER_TRM) break; if (packageCtr > 1) { - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_INVALID_PKG_NUMBER; return -1; } @@ -602,7 +628,7 @@ static int trb_fifo_read(uint8_t channel, case HEADER_TRM: if ((packageCtr > 0) && (dataCtr != len)) { /* Error invalid length */ - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_HDR_DLEN; return -1; } @@ -610,7 +636,7 @@ static int trb_fifo_read(uint8_t channel, case HEADER_HDR: if (packageCtr != 0) { - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_HEADER; return -1; } @@ -626,7 +652,7 @@ static int trb_fifo_read(uint8_t channel, : (((uint32_t)package.F2 << 16) | ((uint32_t)package.F3)); } else { - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_USER_BUFFER_OVF; return -1; } @@ -634,7 +660,7 @@ static int trb_fifo_read(uint8_t channel, break; default: - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_HEADER; return -1; } @@ -650,7 +676,7 @@ static int trb_fifo_read(uint8_t channel, switch (headerType) { case HEADER_HDR: if ((packageCtr - endPointCtr * 3) != 0) { - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_HEADER; return -1; } @@ -675,7 +701,7 @@ static int trb_fifo_read(uint8_t channel, data[dataCtr++] = (uint32_t)sourceAddress; endPointCtr++; } else { - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_USER_BUFFER_OVF; return -1; } @@ -685,7 +711,7 @@ static int trb_fifo_read(uint8_t channel, break; default: - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_HEADER; return -1; } @@ -697,13 +723,13 @@ static int trb_fifo_read(uint8_t channel, if ((packageCtr == 1) && (headerType == HEADER_DAT)) { if (package.F0 != NET_ACKADDRESS) { - trb_fifo_flush(channel); + fifo_flush(channel); return -1; } } if (packageCtr > 1) { - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_INVALID_PKG_NUMBER; return -1; } @@ -712,7 +738,7 @@ static int trb_fifo_read(uint8_t channel, break; default: - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_FIFO_INVALID_MODE; return -1; } @@ -731,7 +757,7 @@ static int trb_fifo_read(uint8_t channel, } while (((*tmp & MASK_FIFO_VALID) == 0) && (++timeout < MAX_TIME_OUT)); if (timeout >= MAX_TIME_OUT) { - trb_fifo_flush(channel); + fifo_flush(channel); trb_errno = TRB_FIFO_INCOMPLETE; return -1; } @@ -763,7 +789,7 @@ static int trb_fifo_read(uint8_t channel, return -1; } - if ((trb_term.status_common & 0x0036) != 0) { + if ((trb_term.status_common & 0x003e) != 0) { trb_errno = TRB_STATUS_ERROR; return -1; } @@ -791,6 +817,47 @@ static void unblockSignals() sigprocmask(SIG_SETMASK, &blockSetOld, NULL); } +static int lockPorts() +{ + struct sembuf sops[2] = { + { + 0, /* sem_num: We only use one track */ + 0, /* sem_op: wait for semaphore flag to become zero */ + SEM_UNDO /* sem_flg: remove sem if process gets killed */ + }, + { + 0, /* sem_num: We only use one track */ + 1, /* sem_op: increment semaphore, i.e. lock it */ + SEM_UNDO | IPC_NOWAIT /* sem_flg: remove sem if process gets killed */ + } + }; + + if (semop(semid, sops, 2) == -1) { + trb_errno = TRB_SEMAPHORE; + return -1; + } + + return 0; +} + +static int unlockPorts() +{ + struct sembuf sops[1] = { + { + 0, /* sem_num: We only use one track */ + -1, /* sem_op: decrement semaphore, i.e. unlock it */ + IPC_NOWAIT /* */ + } + }; + + if (semop(semid, sops, 1) == -1) { + trb_errno = TRB_SEMAPHORE; + return -1; + } + + return 0; +} + /* ----- Global Functions ----------------------------------------------- */ /* Intit FPGA Interface */ @@ -807,6 +874,12 @@ int init_ports() return -1; } + /* Get / Create semaphore */ + if ((semid = semget(sem_key, 1, IPC_CREAT | 0666)) == -1) { + trb_errno = TRB_SEMAPHORE; + return -1; + } + return 0; } @@ -817,10 +890,6 @@ void close_ports() int trb_fifo_flush(uint8_t channel) { - uint32_t tmp; - uint32_t fifoAddress; - unsigned int counter = 0; - trb_errno = TRB_NONE; if (channel >= 4) { @@ -833,19 +902,15 @@ int trb_fifo_flush(uint8_t channel) fprintf(stderr, "Flushing FIFO of channel# %d\n", channel); } + if (lockPorts() == -1) return -1; + blockSignals(); - 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); - + fifo_flush(channel); + unblockSignals(); + + if (unlockPorts() == -1) return -1; return 0; } @@ -859,6 +924,8 @@ int trb_register_read(uint16_t trb_address, trb_errno = TRB_NONE; + if (lockPorts() == -1) return -1; + /* Init transfer */ if (trb_init_transfer(3) == -1) { return -1; @@ -888,7 +955,9 @@ int trb_register_read(uint16_t trb_address, status = trb_fifo_read(3, FIFO_MODE_REG_READ, data, dsize); unblockSignals(); - + + if (unlockPorts() == -1) return -1; + if ((status > 0) && (status % 2 != 0)) { trb_errno = TRB_INVALID_PKG_NUMBER; return -1; @@ -919,6 +988,8 @@ int trb_register_read_mem(uint16_t trb_address, } length = length | (option == 0 ? 0x8000 : 0x0000); + if (lockPorts() == -1) return -1; + /* Init transfer */ if (trb_init_transfer(3) == -1) { return -1; @@ -928,7 +999,7 @@ int trb_register_read_mem(uint16_t trb_address, if (trb_debug > 0) { fprintf(stderr, "Init_Tranfer done.\n"); } - + blockSignals(); /* Build up package and start transfer */ @@ -949,6 +1020,8 @@ int trb_register_read_mem(uint16_t trb_address, unblockSignals(); + if (unlockPorts() == -1) return -1; + if (status == -1) return status; /* Check size */ @@ -975,6 +1048,8 @@ int trb_register_write(uint16_t trb_address, trb_errno = TRB_NONE; + if (lockPorts() == -1) return -1; + /* Init transfer */ if (trb_init_transfer(3) == -1) { return -1; @@ -1005,6 +1080,8 @@ int trb_register_write(uint16_t trb_address, unblockSignals(); + if (unlockPorts() == -1) return -1; + return status; } @@ -1028,6 +1105,8 @@ int trb_register_write_mem(uint16_t trb_address, } config = config | (option == 0 ? 0x8000 : 0x0000); + if (lockPorts() == -1) return -1; + /* Init transfer */ if (trb_init_transfer(3) == -1) { return -1; @@ -1064,17 +1143,21 @@ int trb_register_write_mem(uint16_t trb_address, unblockSignals(); + if (unlockPorts() == -1) return -1; + return status; } int trb_read_uid(uint16_t trb_address, - uint32_t* uidBuffer, + uint32_t* data, unsigned int dsize) { int status; trb_errno = TRB_NONE; + if (lockPorts() == -1) return -1; + /* Init transfer */ if (trb_init_transfer(3) == -1) { return -1; @@ -1101,10 +1184,12 @@ int trb_read_uid(uint16_t trb_address, fprintf(stderr, "CMD_READ_UNIQUE_ID started.\n"); } - status = trb_fifo_read(3, FIFO_MODE_UID, (uint32_t*)uidBuffer, dsize); + status = trb_fifo_read(3, FIFO_MODE_UID, (uint32_t*)data, dsize); unblockSignals(); + if (unlockPorts() == -1) return -1; + if ((status > 0) && (status % 4 != 0)) { trb_errno = TRB_INVALID_PKG_NUMBER; return -1; @@ -1128,6 +1213,8 @@ int trb_set_address(uint64_t uid, return -1; } + if (lockPorts() == -1) return -1; + /* Init transfer */ if (trb_init_transfer(3) == -1) { return -1; @@ -1162,6 +1249,8 @@ int trb_set_address(uint64_t uid, unblockSignals(); + if (unlockPorts() == -1) return -1; + if (status == -1) return -1; if (status != 2) { trb_errno = TRB_ENDPOINT_NOT_REACHED; @@ -1184,6 +1273,8 @@ int trb_ipu_data_read(uint8_t type, if (data == NULL) return -1; + if (lockPorts() == -1) return -1; + /* Init transfer IPU Channel */ if (trb_init_transfer(1) == -1) { return -1; @@ -1213,6 +1304,8 @@ int trb_ipu_data_read(uint8_t type, unblockSignals(); + if (unlockPorts() == -1) return -1; + return status; } @@ -1226,6 +1319,8 @@ int trb_send_trigger(uint8_t type, trb_errno = TRB_NONE; + if (lockPorts() == -1) return -1; + /* Init transfer trigger */ if (trb_init_transfer(0) == -1) { return -1; @@ -1256,6 +1351,8 @@ int trb_send_trigger(uint8_t type, status = trb_fifo_read(0, FIFO_MODE_NONE, NULL, 0); unblockSignals(); + + if (unlockPorts() == -1) return -1; if (status == -1) return -1; @@ -1272,6 +1369,8 @@ int trb_send_trigger_rich(uint8_t trg_input, trb_errno = TRB_NONE; + if (lockPorts() == -1) return -1; + /* Init transfer slowcontrol */ if (trb_init_transfer(3) == -1) { return -1; @@ -1315,8 +1414,9 @@ int trb_send_trigger_rich(uint8_t trg_input, /* Check for replay packets (slowcontrol) */ status = trb_fifo_read(3, FIFO_MODE_NONE, NULL, 0); if (status == -1) { - trb_fifo_flush(0); + fifo_flush(0); unblockSignals(); + if (unlockPorts() == -1) return -1; return -1; } @@ -1325,6 +1425,8 @@ int trb_send_trigger_rich(uint8_t trg_input, unblockSignals(); + if (unlockPorts() == -1) return -1; + if (status == -1) return -1; return 0; diff --git a/libtrbnet/trbnet.h b/libtrbnet/trbnet.h index 81b4568..7661dc9 100644 --- a/libtrbnet/trbnet.h +++ b/libtrbnet/trbnet.h @@ -103,6 +103,39 @@ int trb_fifo_flush(uint8_t channel); */ + +/************************************************************************/ +/* 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); + + trb_address: TRB-Address of the TRB-Endpoint + reg_address: Register-Address to be read from, broadcasts are supported + uint8_t option: + uint16_t size: Number of 32Bit-words to be read + data: Pointer to a uint32_t Data-Buffer + dsize: Size of the Data-Buffer in units of 32bit-words + + ReturnValue: == -1 on error, trberrno will be set + >= 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 the sender + second word: register value + + --> The size of the Data-Buffer must be at least >= 2 + +*/ + + /************************************************************************/ /* int trb_register_write(uint16_t trb_address, uint16_t reg_address, -- 2.43.0