From b5a18349de64a43b151779e27ad8f08c57c01e46 Mon Sep 17 00:00:00 2001 From: hadaq Date: Thu, 9 Jul 2009 16:48:49 +0000 Subject: [PATCH] new handling of Term Status-bits. . --- libtrbnet/trbnet.c | 118 +++++++++++++++++++++++++++++++++------------ 1 file changed, 86 insertions(+), 32 deletions(-) diff --git a/libtrbnet/trbnet.c b/libtrbnet/trbnet.c index 0f9f203..7616af2 100644 --- a/libtrbnet/trbnet.c +++ b/libtrbnet/trbnet.c @@ -195,7 +195,7 @@ static void TRB_Package_dump(const TRB_Package* pkg) (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, "F2: 0x%04x --> length\n", pkg->F2); fprintf(stderr, "F3: 0x%04x --> sequence: 0x%02x datatype: 0x%01x\n", pkg->F3, (pkg->F3 & MASK_SEQNR) >> SHIFT_SEQNR, @@ -453,8 +453,9 @@ static int trb_fifo_read(uint8_t channel, fprintf(stderr, "-------------------------------------------------\n"); } - /* First package: headerType must be HDR or TRM */ + if (trb_lazy == 0) { + /* First package: headerType must be HDR or TRM */ if (packageCtr == 0) { if (!((headerType == HEADER_HDR) | (headerType == HEADER_TRM))) { trb_fifo_flush(channel); @@ -587,24 +588,50 @@ static int trb_fifo_read(uint8_t channel, break; case FIFO_MODE_IPU_DATA: - if (headerType == HEADER_TRM) break; - - if ((headerType == HEADER_DAT) && (packageCtr > 0)) { - if (headerType != HEADER_DAT) { + { + static unsigned int len = 0; + unsigned int i; + + switch (headerType) { + + case HEADER_TRM: + if ((packageCtr > 0) && (dataCtr != len)) { + /* Error invalid length */ + trb_errno = TRB_HDR_DLEN; + return -1; + } + break; + + case HEADER_HDR: + if (packageCtr != 0) { + trb_fifo_flush(channel); + trb_errno = TRB_FIFO_INVALID_CONTENT; + return -1; + } + len = (unsigned int)package.F2; + break; + + case HEADER_DAT: + for (i = 0; (i < 2) && (dataCtr < len); i++) { + if (dataCtr < dsize) { + data[dataCtr++] = i == 0 + ? (((uint32_t)package.F0 << 16) | + ((uint32_t)package.F1)) + : (((uint32_t)package.F2 << 16) | + ((uint32_t)package.F3)); + } 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; } - if ((dataCtr + 1) < dsize) { - 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; @@ -693,31 +720,39 @@ static int trb_fifo_read(uint8_t channel, } } + + /* Copy StatusBits and Sequenze of TerminationPackage */ + trb_term.status_common = package.F2; + trb_term.status_channel = package.F1; + trb_term.sequenz = package.F3; + trb_term.channel = channel; + 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 = ((package.F2 == 0x0000) && (package.F1 == 0x0000)) - ? TRB_ENDPOINT_NOT_REACHED - : TRB_TERM_ERRBIT; - + if ((trb_term.status_common == 0) && (trb_term.status_channel == 0)) { + trb_errno = TRB_ENDPOINT_NOT_REACHED; + return -1; + } + + if ((trb_term.status_common & 0x0036) != 0) { + trb_errno = TRB_STATUS_ERROR; + return -1; + } + + if ((channel == 3) && ((trb_term.status_channel & 0x0003) != 0)) { + trb_errno = TRB_STATUS_ERROR; return -1; } } @@ -733,6 +768,8 @@ int trb_fifo_flush(uint8_t channel) uint32_t fifoAddress; unsigned int counter = 0; + trb_errno = TRB_NONE; + if (channel >= 4) { trb_errno = TRB_INVALID_CHANNEL; return -1; @@ -752,7 +789,7 @@ int trb_fifo_flush(uint8_t channel) counter++; } } while ((tmp & MASK_FIFO_VALID) != 0); - + return 0; } @@ -763,6 +800,8 @@ int trb_register_read(uint16_t trb_address, { int status = 0; + trb_errno = TRB_NONE; + /* Init transfer */ if (trb_init_transfer(3) == -1) { return -1; @@ -793,7 +832,7 @@ int trb_register_read(uint16_t trb_address, trb_errno = TRB_INVALID_PKG_NUMBER; return -1; } - + return status; } @@ -808,7 +847,8 @@ int trb_register_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; @@ -866,6 +906,8 @@ int trb_register_write(uint16_t trb_address, uint16_t reg_address, uint32_t value) { + trb_errno = TRB_NONE; + /* Init transfer */ if (trb_init_transfer(3) == -1) { return -1; @@ -901,6 +943,8 @@ int trb_register_write_mem(uint16_t trb_address, { uint16_t config; uint16_t i; + + trb_errno = TRB_NONE; /* check size and set write-mode */ config = dsize & 0x7fff; @@ -948,6 +992,8 @@ int trb_read_uid(uint16_t trb_address, unsigned int dsize) { int status; + + trb_errno = TRB_NONE; /* Init transfer */ if (trb_init_transfer(3) == -1) { @@ -989,6 +1035,8 @@ int trb_set_address(uint64_t uid, uint16_t trb_address) { int status; + + trb_errno = TRB_NONE; /* check for valid TRBnet address to be assigned */ if (trb_address >= 0xff00 ) { @@ -1044,6 +1092,8 @@ int trb_ipu_data_read(uint8_t type, unsigned int dsize) { int status; + + trb_errno = TRB_NONE; if (data == NULL) return -1; @@ -1082,6 +1132,8 @@ int trb_send_trigger(uint8_t type, uint16_t trg_number) { int status; + + trb_errno = TRB_NONE; /* Init transfer trigger */ if (trb_init_transfer(0) == -1) { @@ -1121,6 +1173,8 @@ int trb_send_trigger_rich(uint8_t trg_input, uint16_t trg_number) { int status; + + trb_errno = TRB_NONE; /* Init transfer slowcontrol */ if (trb_init_transfer(3) == -1) { -- 2.43.0