From: hadaq Date: Sun, 5 Jul 2009 23:27:30 +0000 (+0000) Subject: new repository for rich trb slowcontrol functions X-Git-Tag: v6.0~419 X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=8874681818887d1e821723de91643980e7812ee6;p=trbnettools.git new repository for rich trb slowcontrol functions . --- diff --git a/trbrich/Makefile b/trbrich/Makefile new file mode 100644 index 0000000..3d99569 --- /dev/null +++ b/trbrich/Makefile @@ -0,0 +1,79 @@ +AXIS_USABLE_LIBS = UCLIBC GLIBC +include $(AXIS_TOP_DIR)/tools/build/Rules.axis + +CFLAGS = -pipe -g -Wall -Winline -O3 -finline-functions -finline-limit=600000 #-DHEXMODE + +CPPFLAGS = + +INCDIR = -I../libtrbnet + +LDFLAGS = +LIBDIR = -L../libtrbnet +LOADLIBES = -ltrbnet + +# ------------ Libaries ------------------------------------------------ + +AR = ar-cris +ARFLAGS = -srv + +# ------------ Install ------------------------------------------------- + +BIN.OBJS = +LIB.OBJS = +INC.OBJS = + +BIN_DIR = +LIB_DIR = +INC_DIR = + +# ------------ Objects ------------------------------------------------- + +TARGETS = pulser trb_i2c + +pulser.OBJS = pulser.o + +trb_i2c.OBJS = pulser.o + +# ------------ Library-Objects ---------------------------------------- + +LIB_TARGETS = + +# ------------ Suffix Rules ------------------------------------------- + +.SUFFIXES: + +# ----- C Code --------- +%.o: %.c + $(CC) $< -c $(CPPFLAGS) $(CFLAGS) $(INCDIR) -o $@ + +.SUFFIXES: .o .c + +# ------------ Targets ------------------------------------------------- + +all: $(TARGETS) $(LIB_TARGETS) + +pulser: $(pulser.OBJS) + @echo LINKING $@ + $(CC) $(pulser.OBJS) $(LDFLAGS) $(LIBDIR) $(LOADLIBES) -o $@ + @echo DONE! + +trb_i2c: $(trb_i2c.OBJS) + @echo LINKING $@ + $(CC) $(pulser.OBJS) $(LDFLAGS) $(LIBDIR) $(LOADLIBES) -o $@ + @echo DONE! + +lib: $(LIB_TARGETS) + +distclean: clean + rm -f $(TARGETS) $(LIB_TARGETS) + rcsclean -u + +clean: + rm -f *.o core core.* + rcsclean + +# ------------ Dependencies -------------------------------------------- + +pulser.o: pulser.c + +trb_i2c.o: trb_i2c.c diff --git a/trbrich/pulser.c b/trbrich/pulser.c new file mode 100644 index 0000000..3457ab8 --- /dev/null +++ b/trbrich/pulser.c @@ -0,0 +1,172 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#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] " + "[-t triggerType] [-i input]\n", + progName); + printf("Options:\n"); + printf(" -h give this help\n"); + printf(" -d turn on Debugging Information\n"); + printf(" -f write to outFileName\n"); + printf(" -n process numEvents triggers\n"); + printf(" -t send triggerType (default 0)\n"); + printf(" -i use triggerInput input(default 0)\n"); +} + +int main(int argc, char ** argv) +{ + char hldFileName[256] = "pulser.hld"; + uint16_t trgNumber = 0; + uint8_t triggerType = 0; + uint8_t input = 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:t:i:")) != -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; + case 't': + triggerType = (uint8_t)strtoul(optarg, NULL, 0); + break; + case 'i': + input = (uint8_t)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) { + unsigned int len; + + /* Block signals */ + sigprocmask(SIG_BLOCK, &blockSet, NULL); + + /* Send Trigger and get Data */ + if (trb_send_trigger_rich(input, triggerType, 0xcc, 0xdd, 0xaabb) == -1) { + trb_error("Error send_trigger"); + exit(EXIT_FAILURE); + } + + size = trb_ipu_data_read(triggerType, 0xcc, 0xdd, 0xaabb, + buffer, bufferSize); + if (size == -1) { + fprintf(stderr, "Error IPU Read\n"); + exit(EXIT_FAILURE); + } + + /* There must be a DHDR --> size must be at least >= 2 */ + if (size < 2) { + fprintf(stderr, "DHRD error, size=%d\n", size); + exit(EXIT_FAILURE); + } + len = ((buffer[1] >> 16) & 0xffff) + 2; + if (len >= size) { + fprintf(stderr, "DHRD len error, len=%d size=%d\n", len, size); + exit(EXIT_FAILURE); + } + /*fprintf(stderr, "number padding zeros: %d\n", size - len);*/ + if (writeToStdout == 1) { + fprintf(stdout, "Trigger# %d\n", trgNumber); + for (i = 0; i < len; i++) { + fprintf(stdout, "0x%08x\n", buffer[i]); + } + } else { + if (fwrite((void*)buffer, 4, len, hldFile) != len) { + 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); +} diff --git a/trbrich/trb_i2c.c b/trbrich/trb_i2c.c new file mode 100644 index 0000000..150cf39 --- /dev/null +++ b/trbrich/trb_i2c.c @@ -0,0 +1,285 @@ +#define _GNU_SOURCE +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define BUFFER_SIZE 4096 + +static const uint16_t trb_i2c_register = 0x8040; + +static const unsigned int timeout = 100; + +void usage(const char *progName) +{ + printf("Usage: %s [-h] [-d level] \n", progName); + printf("Options:\n"); + printf(" -h give this help\n"); + printf(" -d turn on Debugging Information\n"); + printf("\nCommands:\n"); + printf(" w -> " + "write to \n"); + printf(" r -> " + "read from \n"); + printf(" c " + "clear I2C-Bus on \n"); +} + +/* ------ MAIN ---------------------------------------------------------- */ + +/* + Write bit definition + ==================== + + D[31] I2C_GO 0 => don't do anything on I2C, 1 => start I2C access + D[30] I2C_ACTION 0 => write byte, 1 => read byte + D[29:24] I2C_SPEED set to all '1' + D[23:16] I2C_ADDRESS address of I2C chip + D[15:8] I2C_CMD command byte for access + D[7:0] I2C_DATA data to be written + + + Read bit definition + =================== + + D[31:24] status status information + D[31] RUNNING whatever + D[30] I2C_DONE whatever + D[29] ERROR_RADDACK no acknowledge for repeated address byte + D[28] ERROR_RSTART generation of repeated START condition failed + D[27] ERROR_DATACK no acknowledge for data byte + D[26] ERROR_CMDACK no acknowledge for command byte + D[25] ERROR_ADDACK no acknowledge for address byte + D[24] ERROR_START generation of START condition failed + D[23:21] reserved reserved + D[20:16] debug subject to change, don't use + D[15:8] reserved reserved + D[7:0] I2C_DATA result of I2C read operation +*/ + +typedef enum I2C_ERROR { + ERROR_RADDACK, + ERROR_RSTART, + ERROR_DATACK, + ERROR_CMDACK, + ERROR_ADDACK, + ERROR_START +} I2C_STATUS_BITS; + +static int readI2CRegister(uint16_t trb_address, int checkStatus, + uint32_t* buffer, unsigned int bufferSize) +{ + unsigned int ctr = 0; + int status; + int error = 0; + int i; + + while ((status = trb_register_read(trb_address, trb_i2c_register, + buffer, BUFFER_SIZE)) == -1) { + ctr++; + /* Check timeout */ + if (ctr >= timeout) { + fprintf(stderr, "Error I2C not ready, timeout\n"); + return -1; + } + + /* check trb_statusbits == no_more_data --> continue */ + if ((trb_errno == TRB_TERM_ERRBIT) && + (((trb_statusbits >> 16) & 0x0004) != 0)) { + continue; + } + trb_error("Error I2C not ready"); + return -1; + } + + if (checkStatus == 0) return status; + + /* Check all StatusBits */ + for (i = 0; i < status; i += 2) { + if (((buffer[i + 1] >> 24) & 0x3f) != 0) { + fprintf(stderr, "ErrorStatusBit set on 0x%04x: 0x%02x\n", + buffer[i], (buffer[i + 1] >> 24 & 0x3f) + ); + error = 1; + } + } + + return error == 0 ? status : -1; +} + +int clearI2C(uint16_t trb_address) +{ + if (trb_register_write(trb_address, trb_i2c_register, 0x3f000000) == -1) { + trb_error("Error clearing I2C"); + return -1; + } + + return 0; +} + +int main(int argc, char** argv) +{ + static const uint16_t trb_i2c_register = 0x8040; + + int i; + + trb_debug = 0; + trb_lazy = 0; + + /* Parse Arguments */ + while ((i = getopt(argc, argv, "+hd:")) != -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; + default: + break; + } + } + + if (optind >= argc) { + usage(basename(argv[0])); + exit(EXIT_FAILURE); + } + + /* Open port */ + init_ports(); + + if (strcmp(argv[optind], "w") == 0) { + + /*************************************************/ + /* I2C write */ + /*************************************************/ + + uint32_t buffer[BUFFER_SIZE]; + uint32_t value = 0; + uint16_t trb_address = 0; + uint8_t i2c_chip = 0; + uint8_t i2c_register = 0; + uint8_t i2c_value = 0; + int status = 0; + + if (argc - optind != 5) { + usage(argv[0]); + exit(EXIT_FAILURE); + } + + trb_address = (uint16_t)strtoul(argv[optind + 1], NULL, 0); + i2c_chip = (uint8_t)strtoul(argv[optind + 2], NULL, 0); + i2c_register = (uint8_t)strtoul(argv[optind + 3], NULL, 0); + i2c_value = (uint8_t)strtoul(argv[optind + 4], NULL, 0); + + /* Check whether I2C is ready */ + if (readI2CRegister(trb_address, 0, buffer, BUFFER_SIZE) == -1) { + exit(EXIT_FAILURE); + } + + /* Write value */ + value = 0xbf000000 | (i2c_chip << 16) | (i2c_register << 8) | i2c_value; + if (trb_register_write(trb_address, trb_i2c_register, value) == -1) { + trb_error("Error writing value"); + clearI2C(trb_address); + exit(EXIT_FAILURE); + } + + /* Wait for ACK */ + if ((status = readI2CRegister(trb_address, 1, buffer, BUFFER_SIZE)) + == -1) { + clearI2C(trb_address); + exit(EXIT_FAILURE); + } + + /* Clear IC2 bus */ + if (clearI2C(trb_address) == -1) { + exit(EXIT_FAILURE); + } + + } else if (strcmp(argv[optind], "r") == 0) { + + /*************************************************/ + /* I2C read */ + /*************************************************/ + + uint32_t buffer[BUFFER_SIZE]; + int status = 0; + uint16_t trb_address = 0; + uint32_t value = 0; + uint8_t i2c_chip = 0; + uint8_t i2c_register = 0; + + int i; + + if (argc - optind != 4) { + usage(argv[0]); + exit(EXIT_FAILURE); + } + + trb_address = (uint16_t)strtoul(argv[optind + 1], NULL, 0); + i2c_chip = (uint8_t)strtoul(argv[optind + 2], NULL, 0); + i2c_register = (uint8_t)strtoul(argv[optind + 3], NULL, 0); + + /* Check whether I2C is ready */ + if (readI2CRegister(trb_address, 0, buffer, BUFFER_SIZE) == -1) { + exit(EXIT_FAILURE); + } + + /* Read Value */ + value = 0xff000000 | (i2c_chip << 16) | (i2c_register << 8); + if (trb_register_write(trb_address, trb_i2c_register, value) == -1) { + trb_error("Error reading value"); + clearI2C(trb_address); + exit(EXIT_FAILURE); + } + + /* Wait for ACK */ + if ((status = readI2CRegister(trb_address, 1, buffer, BUFFER_SIZE)) + == -1) { + clearI2C(trb_address); + exit(EXIT_FAILURE); + } + + /* Clear IC2 bus */ + if (clearI2C(trb_address) == -1) { + exit(EXIT_FAILURE); + } + + /* Print results */ + for (i = 0; i < status; i += 2) { + printf("0x%04x 0x%02x\n", buffer[i], buffer[i + 1] & 0xff); + } + + } else if (strcmp(argv[optind], "c") == 0) { + + /*************************************************/ + /* I2C clear */ + /*************************************************/ + + uint16_t trb_address; + + if (argc - optind != 2) { + usage(argv[0]); + exit(EXIT_FAILURE); + } + + trb_address = (uint16_t)strtoul(argv[optind + 1], NULL, 0); + exit((clearI2C(trb_address) == 0 ? EXIT_SUCCESS : EXIT_FAILURE)); + + } else { + usage(basename(argv[0])); + exit(EXIT_FAILURE); + } + + exit(EXIT_SUCCESS); +}